Selenium - 等待页面呈现动态页面

时间:2015-05-10 14:52:58

标签: java ajax angularjs selenium web

我有一个动态网页,可刷新并加载新数据。我正在使用Selenium,我需要等到页面完成渲染才能继续检查页面。我已经看过许多关于等待页面加载或使用显式等待的帖子(隐式等待可以解决问题,但是非常不优雅且不够快)。使用显式等待的问题是没有关于刷新后会出现什么的任何信息。我已经看到一些解决方案正在讨论等待服务器的所有连接结束,但这并不能保证实际的UI已经完成渲染。

我需要的是一种了解页面是否已完成呈现(不加载!!)的方法

3 个答案:

答案 0 :(得分:1)

首先,你要知道页面加载后会出现什么样的结构。您不知道页面上没有哪些标签,但您知道DOM的外观。这就是为什么通常使用页面文本进行测试的最差实践,但是只有DOM才能测试网站的好习惯。因此,根据页面上显示的结构,您需要有明确的方式等待特定标记出现在页面上。 还有一个解决方案(但正如我所说的那样,这不是最好的做法)是等待document.readystate完成"完成"。这种状态在任何情况下都无济于事,但是如果页面上还有某些内容仍在加载,那么在超过一半的情况下它将无法完成。所以,你应该有一些正在执行的隐式状态:

string readyState = javascript.ExecuteScript("if (document.readyState) return document.readyState;").ToString();

然后检查:

readyState.ToLower() == "complete";

顺便说一句,如果你将角度尺js应用程序测试执行器用作量角器,它会等待默认加载的角度页面,或者在一些困难的情况下你可以使用:

browser.waitForAngular();

或在回调中做某事

button.click().then(function() {
  // go next step
});

答案 1 :(得分:0)

我遇到了与我测试的产品类似的问题。我必须为click,click_checkbox,sendKeys和getText创建特殊函数。这些包括用于阻止NoSuchElement StaleElementReference异常的try catch方法。如果操作失败,它也会重试,例如发送错误的文本。

document.readyState

这对你来说还不够。它只等待DOM加载。加载HTML标记后,它将返回"完成"。所以你必须等待每个单独的项目。

答案 2 :(得分:0)

这对我来说很适合动态呈现的网站 - 我在获取数据时没有时间限制,因为它会在后台运行对我来说,如果效率是一个问题,这可能不是你的解决方案(50s任何网站在就绪状态完成后加载的时间都很长):

  1. 等待完整页面加载

WebDriverWait wait = new WebDriverWait(driver, 50); 
wait.until((ExpectedCondition<Boolean>) wd -> ((JavascriptExecutor) wd).executeScript("return document.readyState").equals("complete"));

  1. 使用总是失败的虚拟条件进行另一个隐式等待

  try {          
 wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(text(),'" + "This text will always fail :)" + "')]"))); // condition you are certain won't be true 
  } 
  catch (TimeoutException te) {
  }

  1. 最后,不是获取 html 源代码——这在大多数页面应用程序中会给你不同的结果,而是拉取第一个 html 标签的外层 html

String script = "return document.getElementsByTagName(\"html\")[0].outerHTML;"; 
content = ((JavascriptExecutor) driver).executeScript(script).toString();