I have a Dynamic web page that refreshes and loads new data. I am using Selenium and I need to wait till the page has finished rendering before I can continue checking the page. I have seen many posts about waiting for the page to load or using explicit waits (implicit wait could solve the problem but is very unelegant and not fast enough). The problem with using explicit waits is not having any info on what will come up after the refresh. I have seen some solutions talking about waiting for all the connections to the server to end but that will not promise me that the actual UI has finished rendering.
What I need is a way to know if a page has finished to render (not load!!)
First of all you DO KNOW what sctructure will come after the page will load. You don't know what tags were not on the page, but you know what DOM will look like. That's why usually it's worst practice to test with page text, but a good one to have a website tested by DOM only. So, depending on what structure appears on the page you will need to have explicit ways waiting for specific tags will appear on the page.
One more solution (but as I told it's not really the best practice) is to wait for document.readystate is "complete". This state will not help in every situation, but if you have something still loading on the page, in more then half cases it will not return complete. So, you should have some kind of implicit state that is executing:
string readyState = javascript.ExecuteScript("if (document.readyState) return document.readyState;").ToString();
and then checking:
readyState.ToLower() == "complete";
btw if you will use protractor as an angular js application test executor, it's waiting for angular page loaded by default, or in some difficult situations you can use:
browser.waitForAngular();
OR do something in a callback
button.click().then(function() {
// go next step
});
I have had similar problem with the product I am testing. I had to create special functions for click,click_checkbox,sendKeys and getText for example. These include try catch methods for cathcing NoSuchElement StaleElementReference exceptions. Also it retries if the actions fail, like sending the wrong text.
document.readyState
This isnt enough for you. It only waits for the DOM to load. WHen the HTML tag are loaded, it returns "complete". So you have to wait for each individual item.
This works for me well with dynamically rendered websites - I do not have a time constraint in getting the data as it would run in background for me, if efficiency is an issue may be this is not the solution for you (50s is a huge time for any website to load after the ready state is completed) :
Wait for complete page to load
WebDriverWait wait = new WebDriverWait(driver, 50);
wait.until((ExpectedCondition<Boolean>) wd -> ((JavascriptExecutor) wd).executeScript("return document.readyState").equals("complete"));
Make another implicit wait with a dummy condition which would always fail
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) {
}
Finally, instead of getting the html source - which would in most of one page applications would give you a different result , pull the outerhtml of the first html tag
String script = "return document.getElementsByTagName(\"html\")[0].outerHTML;";
content = ((JavascriptExecutor) driver).executeScript(script).toString();
Related
We have many e2e test written by Selenide.
To avoid failing test in test server, I would like selenide to wait for html element appearing.
I know some scripts like wait.until(...) for this. But, I don't want to fix all test code.
Is there any global switch or setting for Selenide ? ( in detail, I hope the option making cssselector waiting )
My question is resolved by this post
Implicit Wait is the way to configure the WebDriver instance to poll the HTML DOM (DOM Tree)
for a configured amount of time when it tries to find an element
or find a group/collection of elements if they are not immediately available.
As per the current W3C specification the default time is configured to 0.
We can configure the time for the Implicit Wait any where within our script/program and can reconfigure it as per our necessity.
Once we set Implicit Wait it will be valid for the lifetime of the WebDriver instance.
I think implicit wait time is almost the global switch I expected.
Before performing any action, selenide provides methods to look up for Conditions.
$("By Locator").shouldBe(Condition."Desired Condition").
I might be late for this question. But for anyone who still needs help in selenide wait, my answer might still be helpful.
For selenium if you have wait method like:
element = (new WebDriverWait(driver, <timeOutForElement>))
.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(<cssSelector>)));
You can perform the same in Selenide with element = $(<cssSelector>).should(exist);
For
element = (new WebDriverWait(driver, <timeOutForElement>))
.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(<cssSelector>)));
We just go with element = $(<cssSelector>).shouldBe(visible);
Reference Page Here.
I'm working on big liferay project and I have the following problem :
everytime when something is loading, processing etc. I should change cursor to waiting gif. It's easy when using Ajax, but in many cases here I don't use it. So I thought maybe if I could catch any action phase I'd somehow set cursor to wait at the beginning of action method and then turn back to regular 'auto' at the end.
Is that possible ? I don't like this 'solution' but I can't think of any better. Currently I have div with loading image in my jsp which is then removed by jquery document.ready() - not satisfied at all, because all the proccessing have been performed earlier in action phase.
I'd appreciate any suggestions.
Well, if you are not using Ajax, it might be difficult to achieve what you are looking for.
You could start showing the throbber ("loading image") once the link on the first page is clicked, keep it on the next page and remove it on document.ready().
But you'll still have a few ms or seconds without throbber, during page load.
If the processing time is really long, you could do the following :
The idea is to use a thread for the processing. A reference to the thread is stored in server's session. When the link is clicked :
Display a page with the loading image and start the processing in the thread
Poll the server every X second to check if the thread (in session !) is done
When the thread is done, display the result.
I am testing a web application which needs to refresh one of the header elements every 5 seconds. That header element updates all the users with a message whenever a Quote/Policy is issued through anyone using this same application in a group. So for that, our developers are doing AJAX calls continuously every 5 seconds on all pages and for all users.
For navigating through different pages, I was initially using implicit wait like,
DRIVER.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
After that continuous AJAX calls, I had to use WebDriver wait explicit function and look for object visibility when navigating through pages; like,
Wait<WebDriver> wait = new WebDriverWait(DRIVER, 20);
wait.until(visibilityOfElementLocated(By.id(objID)));
(Please note visibilityOfElementLocated is another function which also handles exception handling.)
My issue now is, this explicit calls code changes works great when I run the scripts in IE 8. But, when I run this on IE 9 it still behaves the same and endlessly wait for page to load (or wait for that AJAX call to finish). And, if I stop the browser calls (by pressing Esc or x link), my script continues for that page and hangs again for next page.
Any idea, why IE 9 doesn't work as IE 8 does for page load? Is there a way I can debug this?
PS: I tried updating IEDriverServer but in vain. Also, this works fine on Chrome and FF browser.
I can't say why IE 8/9 behave differently.
If you want to wait for AJAX to complete you can call a Javascript statement to check for active calls.
JQuery (which I assume you are using) has $.active which gives you the number of currently running ajax calls. So you can use the WebDriver as JavascriptExecutor and call this JS snippet:
return typeof $ === 'function' && $.active === 0;
When the result is true there is no AJAX in progress and you can continue with your test.
Looks like I figured the reason (sadly not the solution). It's a known issue in IEDriverServer of WebDriver for IE9.
Refer below link:
Issue 6402: IEDriverServer always returns document.readyState != complete for application using SignalR - library
https://code.google.com/p/selenium/issues/detail?id=6402
I am using selenium to do the UI automation for a web application.
1) My doubt is
when i use the click() method like, right_btn.click() whether it just clicks the right_btn and comes out or it just waits for the underlying actions to be completed before it moves out???
bcoz i read this
When i googled for WebElement.click() http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/WebElement.html it says like, it gets blocked whenever the click() involves opening a new page but here it doesnt opens a new page rather it involves in service call.
2) What i actually want to know?
I want to know this actually to calculate the latency involved in carrying out each actions in the UI. Is there any way to calculate the latency for each UI actions, just like we can see the latency time when we use inspect element in chrome. Thanks in advance.
In java, you can make a Date a = new date() object with the current time, just before your right_btn.click() and then wait for the resulting page to open, (if in a new tab/window - switch to it) and then find some element on that page
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("someid")));
After that returns the element, make another Date b = new Date()
The latency is the difference in milliseconds int millis = b-a;
Yes, a small part of that total time is Selenium searching for the 2nd element, but I'm afraid this might be the best you can do with java/selenium for your purpose.
I am not too sure if I understood your question exactly
How to calculate Latency is hard , but for intercepting calls you can use browserMobProxy in your code and check if particular call is complete and move on
Clicking on a button in my web page sometimes causes the entire page to load, and sometimes only part of it to load.
How can I call waitForPageToLoad without the page loading, and to be able to run additional commands after all elements are present, or what other command can I use, that will wait for the page to be loaded and enable me to run additional commands on the page.
(Using selenium 2.)
Clicking on a button in my web page sometimes causes the entire page to load, and sometimes only part of it to load.
I assume this is by design, and not the problem.
If you are testing, then you should know which behavior you are expecting. If you are expecting a full page load, then use clickAndWait. If you are expecting a partial load, then use click followed by waitForCondition.
You can use the wait() command to wait a specified amount of time, and continue with your actions afterward.
synchronized (driver) {
try {
driver.wait(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
It may be better to use clickAndWait or waitForCondition, but this is an alternative for just waiting in general.
Wait for element you want to proceed with instead of wait for page to load