提问人:Ramesh Roddam 提问时间:7/10/2018 最后编辑:Vy DoRamesh Roddam 更新时间:7/4/2020 访问量:595
nosuchwindowexception 带有 PhantomJS Java 的 Selenium
nosuchwindowexception Selenium with PhantomJS Java
问:
我正在使用无头 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 配合使用效果很好。
答:
首先,当您从 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
) 之前,请始终将 WebDriverwait 与 ExpectedConditions 方法numberOfWindowsToBe(int)
结合使用。 - 调用
driver.switchTo().window(windowHandle);
将 WebDriverWait 与 ExpectedConditions 方法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
评论
with firefox its working fine
这可能是一个需要带给 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">
这可能并非适用于每个站点,但可能是值得一看的地方。如果您是网站所有者,也可以尝试在自己身上添加此标记。
评论
driver.quit()
driver.close()