// Sleep until the div we want is visible or 5 seconds is over
long end = System.currentTimeMillis() + 5000;
while (System.currentTimeMillis() < end) {
// Browsers which render content (such as Firefox and IE) return "RenderedWebElements"
RenderedWebElement resultsDiv = (RenderedWebElement) driver.findElement(By.className("gac_m"));
// If results have been returned, the results are displayed in a drop down.
if (resultsDiv.isDisplayed()) {
break;
}
}
public void waitForBrowserToLoadCompletely() {
String state = null;
String oldstate = null;
try {
System.out.print("Waiting for browser loading to complete");
int i = 0;
while (i < 5) {
Thread.sleep(1000);
state = ((JavascriptExecutor) driver).executeScript("return document.readyState;").toString();
System.out.print("." + Character.toUpperCase(state.charAt(0)) + ".");
if (state.equals("interactive") || state.equals("loading"))
break;
/*
* If browser in 'complete' state since last X seconds. Return.
*/
if (i == 1 && state.equals("complete")) {
System.out.println();
return;
}
i++;
}
i = 0;
oldstate = null;
Thread.sleep(2000);
/*
* Now wait for state to become complete
*/
while (true) {
state = ((JavascriptExecutor) driver).executeScript("return document.readyState;").toString();
System.out.print("." + state.charAt(0) + ".");
if (state.equals("complete"))
break;
if (state.equals(oldstate))
i++;
else
i = 0;
/*
* If browser state is same (loading/interactive) since last 60
* secs. Refresh the page.
*/
if (i == 15 && state.equals("loading")) {
System.out.println("\nBrowser in " + state + " state since last 60 secs. So refreshing browser.");
driver.navigate().refresh();
System.out.print("Waiting for browser loading to complete");
i = 0;
} else if (i == 6 && state.equals("interactive")) {
System.out.println(
"\nBrowser in " + state + " state since last 30 secs. So starting with execution.");
return;
}
Thread.sleep(4000);
oldstate = state;
}
System.out.println();
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
30 回答
如果有人使用硒化物:
更多条件可以在这里找到:http://selenide.org/javadoc/3.0/com/codeborne/selenide/Condition.html
所有这些解决方案都适用于特定情况,但它们至少会遇到以下几个问题之一:
它们不够通用 - 它们希望您提前知道某些特定条件对于您要访问的页面是否正确(例如,将显示某个元素)
他们对竞争条件持开放态度,您可以使用旧页面上实际存在的元素以及新页面 .
这是我尝试避免这个问题的通用解决方案(在Python中):
首先,一个通用的“等待”函数(如果你愿意,可以使用WebDriverWait,我发现它们很难看):
接下来,该解决方案依赖于selenium为页面上的所有元素记录(内部)id号的事实,包括顶级
<html>
元素 . 当页面刷新或加载时,它会获得一个带有新ID的新html元素 .因此,假设您要单击带有文本“我的链接”的链接,例如:
对于更多Pythonic,可重用的通用助手,您可以创建一个上下文管理器:
然后你可以在任何硒交互中使用它:
我认为那是防弹的!你怎么看?
更多信息blog post about it here
Ruby实现:
您可以使用以下现有方法在下面的示例中设置pageeLoadTimeout的时间,如果页面加载时间超过20秒,则会抛出页面重新加载的异常
SeleniumWaiter :
给你 use it :
我的简单方法:
我是第一个选择,因为您通常知道您将在等待加载的页面上与下一个交互的元素 . 我的方法一直是构建谓词/函数,如
waitForElementByID(String id)
和waitForElemetVisibleByClass(String className)
等,然后在我需要的地方使用和重用它们,无论是页面加载还是页面内容更改,我都在等待 .例如,
在我的测试类中:
在我的测试类父级中:
虽然这看起来很多,但它会为您重复检查,并且可以在超时之前设置检查频率的间隔以及最终等待时间 . 此外,您将重用此类方法 .
在此示例中,父类定义并启动了
WebDriver driver
和WebDriverWait driverWait
.我希望这有帮助 .
隐式使用等待页面上每个元素的等待直到给定时间 .
这等待页面上的每个元素持续30秒 .
另一个等待是在此等待中显式等待或有条件等待,直到给定条件 .
在id中,只要加载页面,就会在页面上显着地显示静态元素id .
在仅更改文档的一部分的情况下,您可以从文档更改为元素 .
这项技术的灵感来自于自上而下的答案 .
使用类WebDriverWait
另见here
你可以期待展示一些元素 . 像C#中的东西:
使用WebDriver的Java绑定时等待页面加载的最佳方法是使用PageFart设计模式和PageFactory . 这允许您使用
AjaxElementLocatorFactory
,它只是作为所有元素的全局等待 . 它对诸如下拉框或复杂的javascript转换等元素有限制,但它会大大减少所需的代码量并加快测试时间 . 在这篇博文中可以找到一个很好的例子 . 假设对Core Java有基本的了解 .http://startingwithseleniumwebdriver.blogspot.ro/2015/02/wait-in-page-factory.html
WebDriver driver = new ff / chrome / anyDriverYouWish(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
等待最多10秒 .WebDriverWait wait = new WebDriverWait(driver, 10); wait.until(ExpectedConditions.visibilityOf(WebElement element));
FluentWait<Driver> fluentWait; fluentWait = new FluentWait<>(driver).withTimeout(30, TimeUnit.SECONDS) .pollingEvery(200, TimeUnit.MILLISECONDS) .ignoring(NoSuchElementException.class);
最后一个选项的优点是您可以包含预期的异常,以便继续执行 .
如果设置驱动程序的隐式等待,然后对预期在加载页面上的元素调用
findElement
方法,则WebDriver将轮询该元素,直到找到该元素或达到超时值 .来源:implicit-waits
如果要等待加载特定元素,可以在
RenderedWebElement
上使用isDisplayed()
方法:(例子来自The 5 Minute Getting Started Guide)
NodeJS Solution:
在 Nodejs 你可以通过承诺得到它...
如果您编写此代码,则可以确保在到达当时页面已完全加载...
如果您编写此代码,您将导航,selenium将等待3秒......
来自Selenium文档:
this.get(url)→那么
安排命令导航到给定的URL .
返回在文档具有 finished loading 时将解析的promise .
Selenium Documentation (Nodejs)
你可以使用等待 . 在硒中基本上有两种等待
隐含等待
明确等待
- Implicit wait
这很简单请看下面的语法:
- Explicit wait
明确地等待或条件等待在此等待直到给定条件发生 .
您可以使用其他属性,如
visblityOf()
,visblityOfElement()
How to get Selenium to wait for page load after a click提供了以下有趣的方法:
从旧页面存储对
WebElement
的引用 .单击链接 .
继续调用
WebElement
上的操作,直到抛出StaleElementReferenceException
.示例代码:
使用if条件和任何存在的元素
这似乎是WebDriver的严重限制 . 显然等待一个元素并不意味着页面被加载,特别是DOM可以完全构建(onready状态),JS仍在执行,CSS和图像仍在加载 .
我相信最简单的解决方案是在初始化所有内容后在onload事件上设置一个JS变量,并在Selenium中检查并等待这个JS变量 .
您还可以使用以下代码检查pageloaded
您可以显式等待元素显示在网页上,然后才能执行任何操作(如element.click())
这是我用于类似场景的工作,它工作正常 .
通常,使用Selenium 2.0时,Web驱动程序只应在确定页面已加载后才将控制权返回给调用代码 . 如果没有,你可以调用
waitforelemement
,它循环调用findelement
直到它被找到或超时(可以设置超时) .调用以下功能
您可以尝试使用此代码让页面完全加载,直到找到元素 .
您还可以使用类:
ExpectedConditions
显式等待元素显示在网页上,然后您可以采取任何操作进一步操作您可以使用
ExpectedConditions
类来确定元素是否可见:有关您可以检查的所有条件的列表,请参阅
ExpectedConditions class Javadoc
.您可以删除
System.out
行 . 它是为了调试目的而添加的 .在此等待中明确等待或有条件等待,直到给出此条件 .
这将等待每个web元素60秒 .
隐式使用等待页面上每个元素的等待直到给定时间 .
这将等待每个web元素60秒 .
最简单的方法是等待一些元素出现在加载的页面上 .
如果您想在页面加载后单击某个按钮,可以使用等待并单击:
Imran的回答重新针对Java 7: