是否需要使用driver.close()方法?

时间:2013-08-14 09:36:14

标签: java selenium window webdriver selenium-webdriver

让我们说

  1. 我有window 1。我在window 1上发布了一个使window 2出现的活动。

  2. 现在我切换到window 2并点击了一个关闭window 2的按钮。

  3. 如果我在执行导致窗口关闭的事件后使用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();
    

    以上行可能会抛出异常,因为驱动程序正在尝试切换到已关闭的窗口“

6 个答案:

答案 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会抛出错误,因为你说

所以我没有尝试关闭第二个窗口,而是尝试使用

切换回窗口1
driver.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,

  1. 某些窗口关闭,同时单击外部窗口内容,在这种情况下不需要driver.close()方法。

  2. 但是对于某些窗口,单击窗口内容外部,窗口无法关闭(即单击关闭按钮后窗口关闭),在这种情况下需要使用driver.close()方法关闭此窗口