nosuchwindowexception 带有 PhantomJS Java 的 Selenium

nosuchwindowexception Selenium with PhantomJS Java

提问人:Ramesh Roddam 提问时间:7/10/2018 最后编辑:Vy DoRamesh Roddam 更新时间:7/4/2020 访问量:595

问:

我正在使用无头 PhantomJS 浏览器使用带有 selenium 的 phantomjs 驱动程序来自动化应用程序。(Selenium Java 版本 3.5.2 和 PhantomJS.exe)

我有一个场景,我将填写表单并提交它,然后浏览器关闭,关闭浏览器后,我重用驱动程序引用来获取 URL。当我将 firefox 驱动程序与 selenium 2.47.0 一起使用时,它运行良好。

现在我切换到 selenium phontamjsdriver 和 phantombrowser。在这里,当我调用 driver.get(url);浏览器关闭后,它会抛出 NosuchWindowException,指出窗口已关闭或处于非活动状态。但是,相同的代码适用于 firefox 驱动程序

例:

driver.get(url);// first time works  
submitForm(driver);//browser window gets closed.  
driver.get(url); 

最后一行抛出异常:

nosuchwindowexception(selenium java with 3.5.2 version and phantomjs.exe). 

但与带有 selenium 2.4.7 的 firefoxbrowser 配合使用效果很好。

java selenium selenium-webdriver webdriver webdriver phantomjs

评论

0赞 cruisepandey 7/17/2018
你是如何关闭浏览器的,或者你是否也在使用无头FF?driver.quit()driver.close()
0赞 Ramesh Roddam 7/17/2018
我没有使用 Phantom 驱动程序关闭浏览器。这是应用程序的行为:提交表格后,Broswer 窗口会自动关闭。它在代码中以编程方式关闭
0赞 cruisepandey 7/17/2018
AFAIU ,您在应用程序中打开一个页面,然后单击某个位置,然后打开一个新窗口,其中包含表单,然后您填写表单并自行关闭,然后使用 driver.get('some url') 导航到某个 URL,对吧?
0赞 Ramesh Roddam 7/17/2018
我在应用程序中打开一个页面,然后单击链接。它在同一窗口上打开表单,然后我填写表单,它被 ItSeft 关闭。然后我使用 driver.get(“url”) 打开具有相同驱动程序实例的浏览器。然后它抛出 nosuch 窗口异常。但同样的代码适用于Firefox浏览器。看起来 Phantom 浏览器和 Firefox 的行为不一样
1赞 cruisepandey 7/17/2018
您是否使用显式等待?你也能分享你的代码吗?我需要先看代码,然后才能得出任何结论。

答:

0赞 undetected Selenium 7/18/2018 #1

首先,当您从 Selenium v2.47.0 迁移到 Selenium v3.5.2 时,值得一提的是,随着 Selenium 3.x 的推出,很多变化都发生了变化。现在 Selenium-WebDriver 是 W3C 推荐候选者,并且符合 WebDriver W3C 编辑草案


NoSuchWindowException

NoSuchWindowException 类扩展了 NotFoundException,并且在尝试时主要抛出:

WebDriver.switchTo().window(String windowName);

现在,关于你的用例、相关 HTML你的代码块的更多细节会给我们更多的想法,让我们知道出了什么问题。也许submitForm(driver)的定义是解决问题的关键。


最佳实践

以下是可以遵循的一些最佳做法,以避免 NoSuchWindowException

  • 始终在变量中对父窗口句柄进行遍历,以便可以根据通常的需要遍历回父窗口
  • 在调用 driver.switchTo().window(windowHandle) 之前,请始终将 WebDriverwaitExpectedConditions 方法 numberOfWindowsToBe(int) 结合使用。
  • 调用 driver.switchTo().window(windowHandle);WebDriverWaitExpectedConditions 方法 titleContains(java.lang.String title) 结合使用,等待页面加载完成,以便在新打开的窗口上继续测试步骤
  • 若要切换回父窗口,请使用以前存储的窗口句柄
  • 下面是演示 Window/Tab 处理的示例代码块:

    package demo;
    
    import java.util.Set;
    
    import org.openqa.selenium.JavascriptExecutor;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.firefox.FirefoxDriver;
    import org.openqa.selenium.support.ui.ExpectedConditions;
    import org.openqa.selenium.support.ui.WebDriverWait;
    
    public class WINDOW_HANDLE_ITERATE_Firefox 
    {
        public static void main(String[] args) throws Exception 
        {
            System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
            WebDriver driver =  new FirefoxDriver();
            driver.get("http://www.google.com");
            String parent_window = driver.getWindowHandle();
            System.out.println("Parent Window Handle is: "+driver.getWindowHandle());
            System.out.println("Page Title is: "+driver.getTitle());
            ((JavascriptExecutor) driver).executeScript("window.open('http://facebook.com/');");
            new WebDriverWait(driver,10).until(ExpectedConditions.numberOfWindowsToBe(2));
            Set<String> allWindows_1 = driver.getWindowHandles();
            System.out.println("Total Windows: "+allWindows_1.size());
            for(String hand1:allWindows_1)
            if(!parent_window.equals(hand1))
            {
                driver.switchTo().window(hand1);
                new WebDriverWait(driver,10).until(ExpectedConditions.titleContains("Facebook"));
                String first_child_window = driver.getWindowHandle();
                System.out.println("First Child Window Handle is: "+first_child_window);
                System.out.println("First Child Window Page Title is: "+driver.getTitle());
                driver.close();
            }
            driver.switchTo().window(parent_window);
            System.out.println("Current Window Handle is : "+driver.getWindowHandle()+ " which is same as "+parent_window +", which is the parent window handle" );
            driver.quit();
        }
    }
    
  • 控制台输出:

    1531917836983   geckodriver INFO    geckodriver 0.20.1
    1531917836993   geckodriver INFO    Listening on 127.0.0.1:9993
    1531917837915   mozrunner::runner   INFO    Running command: "C:\\Program Files\\Mozilla Firefox\\firefox.exe" "-marionette" "-profile" "C:\\Users\\ATECHM~1\\AppData\\Local\\Temp\\rust_mozprofile.W5WqVulBNm9x"
    1531917842220   Marionette  INFO    Listening on port 35364
    1531917843126   Marionette  WARN    TLS certificate errors will be ignored for this session
    Jul 18, 2018 6:14:03 PM org.openqa.selenium.remote.ProtocolHandshake createSession
    INFO: Detected dialect: W3C
    Parent Window Handle is: 4294967297
    Page Title is: Google
    Total Windows: 2
    First Child Window Handle is: 4294967301
    First Child Window Page Title is: Facebook – log in or sign up
    Current Window Handle is : 4294967297 which is same as 4294967297, which is the parent window handle
    

评论

0赞 Ramesh Roddam 7/23/2018
在我的场景中。我没有导航到新窗口或在新窗口中打开链接。我只有一个窗口,一旦提交应用程序及其应用程序行为,它就会关闭。我没有明确关闭窗口。因此,在窗口关闭后,我无法重用相同的驱动程序实例来打开窗口,并且它抛出异常。但是使用Firefox,它可以正常工作。如果我创建新的 Phantomdriver 实例并调用 driver.get(url)。它正在重定向到创建新会话的登录页面。
0赞 undetected Selenium 7/24/2018
@RamRamesh 你能用你的代码块更新主要问题吗?with firefox its working fine
0赞 Ramesh Roddam 7/24/2018
myPage.getSubmit().click();this.clickMsgBoxOK(driver,“此表单已成功提交。-------一旦执行此代码,窗口就会在验证警报框上的数据后获得。现在我正在尝试获取具有相同驱动程序实例的 url。通常它应该能够重新创建浏览器窗口实例并获取我请求的 URL.driver.get(MYREQUESTS_URL);当我调用最后一行代码时,它的抛出异常。基本上,我只有一个窗口并关闭并尝试使用与我拥有的相同驱动程序实例重新创建窗口实例。
0赞 Ramesh Roddam 7/24/2018
这与适用于 Firefox 的代码相同。driver.get(url);// 第一次工作 submitForm(driver);//浏览器窗口关闭。driver.get(网址);引发异常
0赞 Ramesh Roddam 7/24/2018
准确地说......public void testSubmit (WebDriver driver) throws Exception { MyPage myPage = (myPage) PageFactory.createPage(MyPage.class, driver);MyPage.switchToMe();MyPage.getSubmit().click();MyPage.getSubmit().click();this.clickMsgBoxYes(driver,“您即将提交此表单,您确定要继续吗?this.clickMsgBoxOK(driver,“此表单已成功提交。driver.get(MYREQUESTS_URL);}
0赞 Bluejuice 7/18/2018 #2

这可能是一个需要带给 PhantomJS 团队的问题 https://github.com/ariya/phantomjs/issues

不幸的是,Selenium 中的屏幕截图仅捕获 DOM 而不是地址栏。如果您能够保存页面源代码,则可以提取网址。查看此页面的页面源代码时,我看到列出了各种第三方应用程序的标签,其中有一个列出 URL 的内容源。

<meta name="twitter:app:url:googleplay" content="http://stackoverflow.com/questions/51255939/nosuchwindowexception-selenium-with-phantomjs-java">

这可能并非适用于每个站点,但可能是值得一看的地方。如果您是网站所有者,也可以尝试在自己身上添加此标记。