How do you make Selenium 2.0 wait for the page to load?

You can also check pageloaded using following code

IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(30.00));

 wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));
2017年12月07日38分14秒 Use class WebDriverWait Also see here You can expect to show some element. something like in C#: WebDriver _driver = new WebDriver();
WebDriverWait _wait = new WebDriverWait(_driver, new TimeSpan(0, 1, 0)); _wait.Until(d => d.FindElement(By.Id("Id_Your_UIElement"));
2017年12月07日38分14秒 If you set the implicit wait of the driver, then call the findElement method on an element you expect to be on the loaded page, the WebDriver will poll for that element until it finds the element or reaches the time out value. driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
source: implicit-waits 2017年12月07日38分14秒 In general, with Selenium 2.0 the web driver should only return control to the calling code once it has determined that the page has loaded. If it does not, you can call waitforelemement, which cycles round calling findelement until it is found or times out (time out can be set). 2017年12月07日38分14秒 Ruby implementation: wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until {
@driver.execute_script("return document.readyState;") == "complete"
}
2017年12月07日38分14秒 You may remove the System.out line. It is added for debug purposes. WebDriver driver_; public void waitForPageLoad() { Wait<WebDriver> wait = new WebDriverWait(driver_, 30);
wait.until(new Function<WebDriver, Boolean>() {
public Boolean apply(WebDriver driver) {
System.out.println("Current Window State : "
+ String.valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState")));
return String
.valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState"))
.equals("complete");
}
});
}
2017年12月07日38分14秒 You can also use the class: ExpectedConditions to explicitly wait for an element to show up on the webpage before you can take any action further actions You can use the ExpectedConditions class to determine if an element is visible: WebElement element = (new WebDriverWait(getDriver(), 10)).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("input#houseName")));
See ExpectedConditions class Javadoc for list of all conditions you are able to check. 2017年12月07日38分14秒 This seems to be a serious limitation of WebDriver. Obviously waiting for an element will not imply the page being loaded, in particular the DOM can be fully build (onready state) whereby JS is still executing and CSS and images are still loading. I believe the simplest solution is to set a JS variable upon the onload event after everything is initialized and check and wait for this JS variable in Selenium. 2017年12月07日38分14秒 All of these solutions are OK for specific cases, but they suffer from at least one of a couple of possible problems: They are not generic enough -- they want you to know, ahead of time, that some specific condition will be true of the page you are going to (eg some element will be displayed) They are open to a race condition where you use an element that is actually present on the old page as well as the new page. Here's my attempt at a generic solution that avoids this problem (in Python): First, a generic "wait" function (use a WebDriverWait if you like, I find them ugly): def wait_for(condition_function):
start_time = time.time()
while time.time() < start_time + 3:
if condition_function():
return True
else:
time.sleep(0.1)
raise Exception('Timeout waiting for {}'.format(condition_function.__name__))
Next, the solution relies on the fact that selenium records an (internal) id-number for all elements on a page, including the top-level <html> element. When a page refreshes or loads, it gets a new html element with a new ID. So, assuming you want to click on a link with text "my link" for example: old_page = browser.find_element_by_tag_name('html') browser.find_element_by_link_text('my link').click() def page_has_loaded():
new_page = browser.find_element_by_tag_name('html')
return new_page.id != old_page.id wait_for(page_has_loaded)
For more Pythonic, reusable, generic helper, you can make a context manager: from contextlib import contextmanager @contextmanager
def wait_for_page_load(browser):
old_page = browser.find_element_by_tag_name('html') yield def page_has_loaded():
new_page = browser.find_element_by_tag_name('html')
return new_page.id != old_page.id wait_for(page_has_loaded)
And then you can use it on pretty much any selenium interaction: with wait_for_page_load(browser):
browser.find_element_by_link_text('my link').click()
I reckon that's bulletproof! What do you think? More info in a blog post about it here 2017年12月07日38分14秒 If you want to wait for a specific element to load, you can use the isDisplayed() method on a RenderedWebElement : // 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;
}
}
(Example from The 5 Minute Getting Started Guide) 2017年12月07日38分14秒 Imran's answer rehashed for Java 7: WebDriverWait wait = new WebDriverWait(driver, 30); wait.until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver wdriver) {
return ((JavascriptExecutor) driver).executeScript(
"return document.readyState"
).equals("complete");
}
});
2017年12月07日38分14秒 I'm surprised that predicates weren't the first choice as you typically know what element(s) you will next interact with on the page you're waiting to load. My approach has always been to build out predicates/functions like waitForElementByID(String id) and waitForElemetVisibleByClass(String className), etc. and then use and reuse these wherever I need them, be it for a page load or page content change I'm waiting on. For example, In my test class: driverWait.until(textIsPresent("expectedText");
In my test class parent: protected Predicate<WebDriver> textIsPresent(String text){
final String t = text;
return new Predicate<WebDriver>(){
public boolean apply(WebDriver driver){
return isTextPresent(t);
}
};
} protected boolean isTextPresent(String text){
return driver.getPageSource().contains(text);
}
Though this seems like a lot, it takes care of checking repeatedly for you and the interval for how often to check can be set along with the ultimate wait time before timing out. Also, you will reuse such methods. In this example, the parent class defined and initiated the WebDriver driver and the WebDriverWait driverWait. I hope this helps. 2017年12月07日38分14秒 Use implicitly wait for wait of every element on page till given time. driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
this wait for every element on page for 30 sec. Another wait is Explicitly wait or conditional wait in this wait until given condition. WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
In id give static element id which is diffidently display on the page, as soon as page is load. 2017年12月07日38分14秒 /**
* Call this method before an event that will change the page.
*/
private void beforePageLoad() {
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("document.mpPageReloaded='notYet';");
} /**
* Call this method after an event that will change the page.
*
* @see #beforePageLoad
*
* Waits for the previous page to disappear.
*/
private void afterPageLoad() throws Exception {
(new WebDriverWait(driver, 10)).until(new Predicate<WebDriver>() { @Override
public boolean apply(WebDriver driver) {
JavascriptExecutor js = (JavascriptExecutor) driver;
Object obj = js.executeScript("return document.mpPageReloaded;");
if (obj == null) {
return true;
}
String str = (String) obj;
if (!str.equals("notYet")) {
return true;
}
return false;
}
});
}
You can change from the document to an element, in the case of where only part of a document is being changed. This technique was inspired by the answer from sincebasic. 2017年12月07日38分14秒 SeleniumWaiter: import com.google.common.base.Function;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.WebDriverWait; public class SeleniumWaiter { private WebDriver driver; public SeleniumWaiter(WebDriver driver) {
this.driver = driver;
} public WebElement waitForMe(By locatorname, int timeout){
WebDriverWait wait = new WebDriverWait(driver, timeout);
return wait.until(SeleniumWaiter.presenceOfElementLocated(locatorname));
} public static Function<WebDriver, WebElement> presenceOfElementLocated(final By locator) {
// TODO Auto-generated method stub
return new Function<WebDriver, WebElement>() {
@Override
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
};
}
}
And to you use it: _waiter = new SeleniumWaiter(_driver); try {
_waiter.waitForMe(By.xpath("//..."), 10);
}
catch (Exception e) {
// Error
}
2017年12月07日38分14秒 You can explicitly wait for an element to show up on the webpage before you can take any action (like element.click()) driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
.until(new ExpectedCondition<WebElement>(){
@Override
public WebElement apply(WebDriver d) {
return d.findElement(By.id("myDynamicElement"));
}});
This is what I used for a similar scenario and it works fine. 2017年12月07日38分14秒 My simple way: long timeOut = 5000;
long end = System.currentTimeMillis() + timeOut; while (System.currentTimeMillis() < end) { if (String.valueOf(
((JavascriptExecutor) driver)
.executeScript("return document.readyState"))
.equals("complete")) {
break;
}
}
2017年12月07日38分14秒 The best way to wait for page loads when using the Java bindings for WebDriver is to use the Page Object design pattern with PageFactory. This allows you to utilize the AjaxElementLocatorFactory which to put it simply acts as a global wait for all of your elements. It has limitations on elements such as drop-boxes or complex javascript transitions but it will drastically reduce the amount of code needed and speed up test times. A good example can be found in this blogpost. Basic understanding of Core Java is assumed. http://startingwithseleniumwebdriver.blogspot.ro/2015/02/wait-in-page-factory.html 2017年12月07日38分14秒 NodeJS Solution: In Nodejs you can get it via promises... If you write this code, you can be sure that the page is fully loaded when you get to the then... driver.get('www.sidanmor.com').then(()=> {
// here the page is fully loaded!!!
// do your stuff...
}).catch(console.log.bind(console));
If you write this code, you will navigate, and selenium will wait 3 seconds... driver.get('www.sidanmor.com');
driver.sleep(3000);
// you can't be sure that the page is fully loaded!!!
// do your stuff... hope it will be OK...
From Selenium documentation: this.get( url ) → Thenable Schedules a command to navigate to the given URL. Returns a promise that will be resolved when the document has finished loading. Selenium Documentation (Nodejs) 2017年12月07日38分14秒 You can use the below existing method to set the time for pageeLoadTimeout in below example if the page is taking more than 20 seconds to load , then it will throw an exception of page reload WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS)
2017年12月07日38分14秒 Explicitly wait or conditional wait in this wait until given condition. WebDriverWait wait = new WebDriverWait(wb, 60);
wait.until(ExpectedConditions.elementToBeClickable(By.name("value")));
This will wait for every web element for 60 seconds. Use implicitly wait for wait of every element on page till given time. driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
This will wait for every web element for 60 seconds. Both works fine. But my personal favorite is Explicitly wait because it is more stable one 2017年12月07日38分14秒 You can use wait. there are basically 2 types of wait in selenium Implicit wait
Explicit wait
- Implicit wait This is very simple please see syntax below: driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
- Explicit wait Explicitly wait or conditional wait in this wait until given condition is occurred. WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
You can use other properties like visblityOf(), visblityOfElement() 2017年12月07日38分14秒 driver.asserts().assertElementFound("Page was not loaded",
By.xpath("//div[@id='actionsContainer']"),Constants.LOOKUP_TIMEOUT);
2017年12月07日38分14秒 The easiest way is just wait for some element which will appear on loaded page. If you would like to click on some button already after page is loaded you could use await and click: await().until().at.most(20, TimeUnit.Seconds).some_element.isDisplayed(); // or another condition
getDriver().find(some_element).click;
2017年12月07日38分14秒 How to get Selenium to wait for page load after a click provides the following interesting approach: Store a reference to a WebElement from the old page.
Click the link.
Keep on invoking operations on the WebElement until StaleElementReferenceException is thrown.
Sample code: WebElement link = ...;
link.click();
new WebDriverWait(webDriver, timeout).until((org.openqa.selenium.WebDriver input) ->
{
try
{
link.isDisplayed();
return false;
}
catch (StaleElementReferenceException unused)
{
return true;
}
});
2017年12月07日38分14秒 use a if condition and for any of the element present try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
2017年12月07日38分14秒 You can try this code to let the page load completely until element is found. 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();
}
}
2017年12月07日38分14秒 private static void checkPageIsReady(WebDriver driver) {
JavascriptExecutor js = (JavascriptExecutor) driver; // Initially bellow given if condition will check ready state of page.
if (js.executeScript("return document.readyState").toString().equals("complete")) {
System.out.println("Page Is loaded.");
return;
} // This loop will rotate for 25 times to check If page Is ready after
// every 1 second.
// You can replace your value with 25 If you wants to Increase or
// decrease wait time.
for (int i = 0; i < 25; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
// To check page ready state.
if (js.executeScript("return document.readyState").toString().equals("complete")) {
break;
}
}
}
2017年12月07日38分14秒 You can use this snippet of code for the page to load: IWait wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver,TimeSpan.FromSeconds(30.00));
wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));
Or you can use waiter for any element to be loaded and become visible/clickable on that page, most probably which is going to be load at the end of loading like: Wait.Until(ExpectedConditions.ElementToBeClickable(By.XPath(xpathOfElement));
var element = GlobalDriver.FindElement(By.XPath(xpathOfElement));
var isSucceededed = element != null;
2017年12月07日38分14秒 The best way I've seen is to utilize the stalenessOf ExpectedCondition, to wait for the old page to become stale. Example: WebDriver driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver, 10); WebElement oldHtml = driver.findElement(By.tagName("html"));
wait.until(ExpectedConditions.stalenessOf(oldHtml));
It'll wait for ten seconds for the old HTML tag to become stale, and then throw an exception if it doesn't happen. 2017年12月07日38分14秒

  

判断Selenium加载完成的更多相关文章

  1. selenium加载时间过长

    为了获取网站js渲染后的html,需要利用selenium加载网站,但是会出现加载时间过长的现象,因此可以限制其加载时间以及强制关掉加载: # !/usr/bin/python3.4 # -*- co ...

  2. 动态加载JS过程中如何判断JS加载完成

    在正常的加载过程中,js文件的加载是同步的,也就是说在js加载的过程中,浏览器会阻塞接下来的内容的解析.这时候,动态加载便显得尤为重要了,由于它是异步加载,因此,它可以在后台自动下载,并不会妨碍其它内 ...

  3. JS判断页面加载完毕

    //JS判断页面加载完毕,再隐藏加载效果层,一个简单的JS加载效果. document.onreadystatechange = function () { if (document.readySta ...

  4. js判断页面加载完毕方法

    判断页面加载完成这个方法是很常见的,下面有三个常用的方法,各有利弊. 一.纯js方法 // (1).页面所有内容加载完成执行 window.onload = function(){ } // (2). ...

  5. selenium 加载jquery

    packagecom.example.tests; import staticorg.junit.Assert.*; importjava.util.*; importorg.junit.*; imp ...

  6. 判断iframe加载完成

    一.js判断 var parFrame = document.getElementById("oIframe"); if(parFrame.attachEvent){ parFra ...

  7. [f]动态判断js加载完成

    在正常的加载过程中,js文件的加载是同步的,也就是说在js加载的过程中,浏览器会阻塞接下来的内容的解析.这时候,动态加载便显得尤为重要了,由于它是异步加载,因此,它可以在后台自动下载,并不会妨碍其它内 ...

  8. Duilib中Webbrowser事件完善使其支持判断页面加载完毕

    在多iframe的页面中,需要结合DISPID_DOCUMENTCOMPLETE和DISPID_NAVIGATECOMPLETE2两个事件判断页面是否加载完毕,而duilib中没有提供对DISPID_ ...

  9. Webbrowser控件判断网页加载完毕的简单方法 (转)

    摘自:http://blog.csdn.net/cometnet/article/details/5261192 一般情况下,当ReadyState属性变成READYSTATE_COMPLETE时,W ...

随机推荐

  1. BZOJ 2039 人员雇佣(最小割)

    最小割的建图模式一般是,先算出总收益,然后再通过网络模型进行割边减去部分权值. 然后我们需要思考什么才能带来收益,什么才能有权值冲突. s连向选的点,t连向不选的点,那么收益的减少量应该就是将s集和t ...

  2. var和let使用上的对比

    var和let比较 1. let没有预解析,不存在变量提升.在代码块中,只要let定义变量,在之前使用,都是报错.先定义完再使用. let a = 12; function fn(){ alert(a ...

  3. C++解析(11):对象的构造

    0.目录 1.对象的初始化 2.构造函数 3.无参构造函数与拷贝构造函数 4.小结 1.对象的初始化 对象中成员变量的初始值是多少? 下面的类定义中成员变量i和j的初始值是什么? 从程序设计的角度,对 ...

  4. 【NuGet】使用NuGet打包并发布至ProGet过程 (步骤详细,附python脚本)【上篇】

    一.基本知识 (1)NuGet : NuGet是一个为大家所熟知的Visual Studio扩展,通过这个扩展,开发人员可以非常方便地在Visual Studio中安装或更新项目中所需要的第三方组件, ...

  5. 【BZOJ4522】密匙破解(Pollard_rho)

    [BZOJ4522]密匙破解(Pollard_rho) 题面 BZOJ 洛谷 题解 还是\(Pollard\_rho\)的模板题. 呜... #include<iostream> #inc ...

  6. Linux下chkconfig命令详解--(启动或停止)和查询系统服务的运行级信息

    chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息.谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接. 使用语法:chkconfig [--ad ...

  7. Win8Metro(C#)数字图像处理--2.40二值图像轮廓提取

    http://dongtingyueh.blog.163.com/blog/static/4619453201271481335630/ [函数名称] 二值图像轮廓提取         Contour ...

  8. springMVC和mybatis的原理

    mybatis是什么? mybatis是一个持久层框架,是apache下的开源项目,前身是itbatis,是一个不完全的ORM框架,mybatis提供输入和输出的映射,需要程序员自己写sql语句,my ...

  9. tf.session.run()单函数运行和多函数运行区别

    tf.session.run()单函数运行和多函数运行区别 觉得有用的话,欢迎一起讨论相互学习~Follow Me problem instruction sess.run([a,b]) # (1)同 ...

  10. 哪些window你不知道的却实用的小技巧----window小技巧

    前言 一直想要整理一篇有关于window比较全的使用小技巧,却又不知道从哪里开始写起.而让我准备动手写这边随笔的动力,还是在加入虫部落<一个绿色环保,充满朝气的好地方>,从大家的分享中,我 ...