让我们说
我有window 1
。我在window 1
上发布了一个使window 2
出现的活动。
现在我切换到window 2
并点击了一个关闭window 2
的按钮。
如果我在执行导致窗口关闭的事件后使用driver.close()
,有时会抛出NoSuchWindowException
。
如果我不使用driver.close()
,那么有时driver.getWindowHandles().size()
会返回2
,即使只有一个窗口,我也有足够的时间来编号windows成为1
。
我刷新driver.getWindowHandles()
并检查driver.getWindowHandles().size()
成为1
但有时不会。
我的问题是,在点击导致窗口关闭的按钮后,是否需要使用方法driver.close()
?如何正确使用driver.close()
。
编辑:是的,这是一个问题。如果selenium没有意识到window2
已被关闭,它会一直将句柄返回2
。假设我已关闭window2
并切换回window1
并执行了一个打开window3
的事件。现在我想切换到window3
。这是问题,因为Selenium仍然认为windows2
存在,现在根据Selenium有三个窗口。
String window1Handle = driver.getWindowHandle();
//Now I have oepend window3
//According to the Selenium there are 3 windows
// So driver.getWindowHandles().size() returns 3
for (String window : driver.getWindowHandles() {
if (!window.equals(window1Handle)) {
driver.switchTo().window();
以上行可能会抛出异常,因为驱动程序正在尝试切换到已关闭的窗口“
答案 0 :(得分:3)
当你在测试结束时执行driver.quit()时,你不需要执行driver.close(),如果有任何东西打开,WebDriver将清理并确保一切都关闭正确地说。
Selenium可以跟踪打开多少个窗口,如果你看到关闭的窗口的窗口句柄听起来像一个潜在的bug。请记住,Selenium可能需要一些时间才能意识到窗口已经关闭,您可以尝试使用显式等待等待窗口句柄的数量降回到1,您需要添加以下内容ExpectedCondition:
public static ExpectedCondition<Boolean> numberOfWindowsToBe(final int numberOfWindows) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
return driver.getWindowHandles().size() == numberOfWindows;
}
};
}
然后您可以通过以下方式使用它:
WebDriverWait wait = new WebDriverWait(driver, 15, 100);
wait.until(numberOfWindowsToBe(1));
或者您可以尝试通过执行driver.close()并捕获NoSuchWindowException来关闭窗口,例如。
try{
driver.close();
} catch(NoSuchWindowException ignored){
System.out.println("Window already closed");
}
这应该让Selenium能够意识到窗户已经关闭了(虽然说实话我不会打扰)。
*的 修改 * 强>
所以听起来问题是你有多个窗口句柄,你不知道哪一个是已关闭的窗口,哪一个是你新打开的窗口。一种解决方法是跟踪Map中的窗口句柄。每次打开一个新窗口时,都会在地图中存储窗口句柄,如下所示:
Map<String, String> openedWindows = new HashMap<String, String>();
openedWindows.put("Window 1", driver.getWindowHandle());
然后您将知道哪个窗口句柄与您的窗口关联,然后您可以在关闭时从地图中删除窗口。您将知道仍然报告的哪些句柄实际上已关闭,哪些句柄报告错误。
实际上这听起来像Selenium窗口处理中的一个错误,我建议你在问题跟踪器上提出一个问题,使用最小的测试脚本来重现问题。当然上面的其他选项仍然有效,尝试并关闭窗口但是捕获异常并查看是否为Selenium提供了从窗口句柄列表中删除它所需的踢法。
答案 1 :(得分:0)
我知道这有点像黑客......但我从未见过像你所描述的那样,所以我觉得值得一试。更改此代码:
driver.switchTo().window();
这样的事情:
try{
driver.switchTo().window();
perform action that will throw error
return; //will return if error wasn't thrown
catch(Error thrown if on bad window){
//continue in your for loop to switch to the next window;
}
答案 2 :(得分:0)
我遇到的问题与您面临的问题相同。
在我执行弹出第二个窗口的动作之前,我已经开始了
String window = driver.getWindowHandle();
后来我点击了链接1,它填充了窗口2,我切换到那个窗口
driver.switchTo().window(window name);
我在Window 2中执行了我的操作,当我单击Window 2中的链接时,我的窗口自动关闭,如果我使用driver.close()
它不会发生因为webdriver会抛出错误,因为你说
所以我没有尝试关闭第二个窗口,而是尝试使用
切换回窗口1driver.switchTo().window(window);
这是因为窗口2自动关闭,并且由于控件未传递到窗口1,因此会发生错误。因此没有必要关闭窗口2. 而是我们可以切换回来到我们的默认窗口并继续或关闭默认窗口..
答案 3 :(得分:0)
我写了一个对我有用的方法。
public static boolean letWebDriverRealizeThisWindowHasBeenClosed(WebDriver driver,
String closedWindowHandle) {
/**
* to avoid infinite loop, do write a break when definite time has been passed
*/
/**
* Generally, this method returns true given that window is closed
*/
boolean isWebDriverRealized = false;
long start = System.currentTimeMillis();
long end = start + (30 * 1000); //30 seconds
while (!isWebDriverRealized
&& System.currentTimeMillis() < end) {
try {
driver.switchTo().window(closedWindowHandle);
} catch (NoSuchWindowException nswe) {
isWebDriverRealized = true;
}
}
return isWebDriverRealized;
}
如果此方法返回true
,则表示WebDriver
已意识到该窗口已为closed
。上述方法返回driver.getWindowHandles.size()
后,true
会返回正确数量的窗口。
答案 4 :(得分:-1)
不,你不需要这样做。因为第二个窗口已经关闭,如果您将使用方法driver.close()
,它将关闭您的第一个窗口和浏览器本身(因为浏览器窗口中只剩下一个选项卡)。
答案 5 :(得分:-1)
它取决于Window,
某些窗口关闭,同时单击外部窗口内容,在这种情况下不需要driver.close()
方法。
但是对于某些窗口,单击窗口内容外部,窗口无法关闭(即单击关闭按钮后窗口关闭),在这种情况下需要使用driver.close()
方法关闭此窗口