如何在通过JS事件加载新页面时使Selenium WebDriver等待页面加载

Jon*_*ist 4 selenium webdriver

我正在努力自动化一个网站,该网站有许多通过JS事件加载新页面的链接.基本上,有些元素是可点击的,点击一个元素会导致一些JavaScript运行,这会导致表单被提交并路由到新页面.

现在,如果这些只是标准的HTML链接,那就没有问题,因为Selenium非常聪明,可以告诉他们有一个新页面即将来临并等待做事.但是,尽管如此,Selenium无法分辨出这个实例中的点击是否会导致新页面加载,因此它不会等待并且继续前进.因此它不会等待新页面,尝试查找不存在的元素,我的测试都会失败.游民.

作为临时解决方案,我只是将程序暂停三秒钟,如下所示:

oldPageDriver.clickThatButton();

try {
  Thread.sleep(3000);
} catch(InterruptedException ex) {
  Thread.currentThread().interrupt();
}

newPageDriver = new NewPageDriver(driver);
newPageDriver.doStuffOnNewPage();
Run Code Online (Sandbox Code Playgroud)

这有点工作.我不喜欢它,因为它是"hacky",只是打断程序而不是做一些更聪明的事情.因为延迟是在三秒钟硬编码,所以如果链接工作但是速度慢,我会失败.我已经考虑过类似于隐式等待的东西,但它完成了同样的事情,并且在经过大量研究后,我在Java中找不到可靠,可行的答案.

那么,任何人都可以建议解决这个问题吗?具体来说,如何让Selenium知道一个新的页面,并等到它可用?

Maa*_*eft 6

等待document.ready事件并不是解决此问题的全部方法,因为此代码仍处于竞争状态:有时在处理单击事件之前触发此代码,因此直接返回,因为浏览器尚未启动正在加载新页面.

经过一番搜索后,我在Obay上找到了一个测试山羊的帖子,它解决了这个问题.该解决方案的c#代码是这样的:

 IWebElement page = null;
 ...
 public void WaitForPageLoad()
 {
    if (page != null)
    {
       var waitForCurrentPageToStale = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
       waitForCurrentPageToStale.Until(ExpectedConditions.StalenessOf(page));
    }

    var waitForDocumentReady = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    waitForDocumentReady.Until((wdriver) => (driver as IJavaScriptExecutor).ExecuteScript("return document.readyState").Equals("complete"));

    page = driver.FindElement(By.TagName("html"));

}
Run Code Online (Sandbox Code Playgroud)

`我在driver.navigate.gotourl之后直接触发这个方法,以便它尽快得到页面的引用.玩得开心!


Rob*_*ham 3

您需要显式等待;

http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp

您可以直接将其添加到您的测试中,或者您可能想要将其干燥,特别是如果存在常见的等待期望,例如旋转图标消失。

您可以扩展 click 方法以在单击后始终等待,或者如果跟随页面对象,请将 wait_until_loaded 方法添加到基本页面类。还有许多其他有效的方法,但取决于 AUT 的实现方式