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

Java 是否需要使用driver.close()方法?,java,selenium,window,webdriver,selenium-webdriver,Java,Selenium,Window,Webdriver,Selenium Webdriver,比方说 我有一个窗口1。我在窗口1上执行了一个事件,使窗口2出现 现在我切换到窗口2,并单击其上的一个按钮,关闭窗口2 如果在执行导致窗口关闭的事件后使用driver.close(),有时它会抛出NoSuchWindowException 如果我不使用driver.close(),那么有时driver.getWindowHandles().size()会返回2,即使只有一个窗口,并且我已经等待了足够的时间,使窗口数变为1 我刷新driver.getWindowHandles()并检查driver

比方说

  • 我有一个
    窗口1
    。我在
    窗口1
    上执行了一个事件,使
    窗口2
    出现

  • 现在我切换到
    窗口2
    ,并单击其上的一个按钮,关闭
    窗口2

  • 如果在执行导致窗口关闭的事件后使用
    driver.close()
    ,有时它会抛出
    NoSuchWindowException

    如果我不使用
    driver.close()
    ,那么有时
    driver.getWindowHandles().size()
    会返回
    2
    ,即使只有一个窗口,并且我已经等待了足够的时间,使窗口数变为
    1

    我刷新
    driver.getWindowHandles()
    并检查
    driver.getWindowHandles().size()
    是否变为
    1
    ,但有时不会

    我的问题是,单击导致窗口关闭的按钮后,是否需要使用方法
    driver.close()
    ?如何正确使用
    驱动程序.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();
    

    由于驱动程序正试图切换到一个已经关闭的窗口,上述行可能会引发异常“

    不,您不需要这样做。因为第二个窗口已经关闭,如果您使用方法
    driver.close()
    ,它将关闭您的第一个窗口和浏览器本身(因为浏览器窗口中只剩下一个选项卡)。

    它取决于窗口

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

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


  • 不,您不需要执行驱动程序。关闭(),如果在执行驱动程序时有任何内容处于打开状态。在测试结束时退出(),WebDriver将进行清理并确保所有内容都正确关闭

    Selenium可以跟踪打开的窗口数量,如果您看到关闭的窗口的窗口句柄听起来像是一个潜在的错误。请记住,Selenium可能需要一些时间才能意识到窗口已关闭,您可以尝试使用显式等待,等待窗口句柄数降回到1,您将需要添加以下预期条件:

      public static ExpectedCondition<Boolean> numberOfWindowsToBe(final int numberOfWindows) {
        return new ExpectedCondition<Boolean>() {
          @Override
          public Boolean apply(WebDriver driver) {
            return driver.getWindowHandles().size() == numberOfWindows;
          }
        };
      }
    
    或者您可以通过执行driver.close()并捕获NoSuchWindowException来尝试关闭窗口,例如

    try{
        driver.close();
    } catch(NoSuchWindowException ignored){
        System.out.println("Window already closed");
    }
    
    这应该让Selenium意识到窗户已经关上了(尽管说实话,我不想麻烦)

    *编辑*

    因此,问题似乎在于您有多个窗口句柄,而您不知道哪一个是已关闭的窗口,哪一个是新打开的窗口。一种解决方法是在地图中跟踪窗口句柄。每次打开新窗口时,将窗口句柄存储在地图中,如下所示:

    Map<String, String> openedWindows = new HashMap<String, String>();
    openedWindows.put("Window 1", driver.getWindowHandle());
    
    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;
    }
    
    Map openedWindows=newhashmap();
    put(“窗口1”,driver.getWindowHandle());
    
    然后,您将知道哪个窗口句柄与您的窗口相关联,然后您可以在窗口关闭时从映射中删除这些窗口。您将知道哪些仍在报告中的句柄实际上已关闭,哪些正在报告错误


    实际上,这听起来像是Selenium窗口处理中的一个bug,我建议您在问题跟踪器上提出一个问题,并使用一个最小的测试脚本来重现该问题。当然,上面的另一个选项仍然有效,请尝试关闭窗口,但捕获异常,并查看这是否为Selenium提供了从li中删除该问题所需的提示st of window handles。

    我知道这有点像黑客……但我从未见过像您所描述的那样的东西,因此我认为值得一试。更改此代码:

    driver.switchTo().window();
    
    对这样的事情:

    Map<String, String> openedWindows = new HashMap<String, String>();
    openedWindows.put("Window 1", driver.getWindowHandle());
    
    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;
    }
    

    我的问题与您面临的问题完全相同。

    在执行弹出第二个窗口的操作之前,我初始化

    String window = driver.getWindowHandle();   
    
    后来我单击了填充窗口2的链接1,并切换到该窗口

    driver.switchTo().window(window name);
    
    我在窗口2中执行了我的操作,当我单击窗口2中的链接时,如果我使用
    driver.close()
    它不会发生,因为webdriver会像你说的那样抛出错误

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

    driver.switchTo().window(window);
    
    这是因为,由于窗口2是自动关闭的,而且控件没有传递到窗口1,因此会发生错误。因此没有必要关闭窗口2。相反,我们可以切换回默认窗口,继续或关闭默认窗口。

    我写了一个对我来说非常有效的方法。

    public静态布尔letWebDriverRealizeThis窗口已关闭(WebDriver,
    字符串闭合(句柄){
    /**
    *为了避免无限循环,一定要在经过确定的时间后写一个中断
    */
    /**
    *通常,如果窗口关闭,此方法返回true
    */
    布尔值isWebDriverRealized=false;
    长启动=System.currentTimeMillis();
    长端=开始+(30*1000);//30秒
    而(!isWebDriverRealized
    &&System.currentTimeMillis()