如何让Selenium 2.0等待页面加载?
当前回答
对于使用java 8向前的程序员,可以使用下面的代码来使用显式等待等待页面加载。
JavascriptExecutor js = (JavascriptExecutor) driver;
new WebDriverWait(driver, 10).until(webDriver ->
(js).executeScript("return document.readyState;").equals("complete"));
注意:在我上面的代码中使用Lambda表达式,它只在java 8的后续版本中可用。
对于使用低版本Java(即Java 8以下)的程序员,可以使用:
ExpectedCondition<Boolean> cond = new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver input) {
JavascriptExecutor js = (JavascriptExecutor) driver;
return js.executeScript("return document.readyState;").equals("complete");
}
};
new WebDriverWait(driver, 100).until(cond);
其他回答
我的方法很简单:
long timeOut = 5000;
long end = System.currentTimeMillis() + timeOut;
while (System.currentTimeMillis() < end) {
if (String.valueOf(
((JavascriptExecutor) driver)
.executeScript("return document.readyState"))
.equals("complete")) {
break;
}
}
下面是一个Java 8版本的目前被点赞最多的答案:
WebDriverWait wait = new WebDriverWait(myDriver, Duration.ofSeconds(15));
wait.until(webDriver -> "complete".equals(((JavascriptExecutor) webDriver)
.executeScript("return document.readyState")));
其中myDriver是一个WebDriver对象(前面声明过)。
注意:注意这个方法(document.readyState)只检查DOM。
如果你设置了驱动程序的隐式等待,然后调用findElement方法在你期望加载页面上的元素上,WebDriver将轮询该元素,直到找到该元素或达到超时值。
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
来源:implicit-waits
您可以尝试这段代码,让页面完全加载,直到找到元素为止。
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();
}
}
一般来说,使用Selenium 2.0时,web驱动程序应该只在确定页面已加载后才将控制权返回给调用代码。如果没有,您可以调用waitforeleement,它循环调用findelement,直到找到它或超时(可以设置超时)。
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap