我有一个动态网页,可刷新并加载新数据。我正在使用Selenium,我需要等到页面完成渲染才能继续检查页面。我已经看过许多关于等待页面加载或使用显式等待的帖子(隐式等待可以解决问题,但是非常不优雅且不够快)。使用显式等待的问题是没有关于刷新后会出现什么的任何信息。我已经看到一些解决方案正在讨论等待服务器的所有连接结束,但这并不能保证实际的UI已经完成渲染。
我需要的是一种了解页面是否已完成呈现(不加载!!)的方法
答案 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任何网站在就绪状态完成后加载的时间都很长):
WebDriverWait wait = new WebDriverWait(driver, 50);
wait.until((ExpectedCondition<Boolean>) wd -> ((JavascriptExecutor) wd).executeScript("return document.readyState").equals("complete"));
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) {
}
String script = "return document.getElementsByTagName(\"html\")[0].outerHTML;";
content = ((JavascriptExecutor) driver).executeScript(script).toString();