Is there a universal approach for Selenium to wait till all ajax content has loaded? (not tied to a specific website - so it works for every ajax website)
Asked
Active
Viewed 3.3k times
4 Answers
31
You need to wait for Javascript and jQuery to finish loading. Execute Javascript to check if jQuery.active
is 0
and document.readyState
is complete
, which means the JS and jQuery load is complete.
public boolean waitForJSandJQueryToLoad() {
WebDriverWait wait = new WebDriverWait(driver, 30);
// wait for jQuery to load
ExpectedCondition<Boolean> jQueryLoad = new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
return ((Long)((JavascriptExecutor)getDriver()).executeScript("return jQuery.active") == 0);
}
catch (Exception e) {
// no jQuery present
return true;
}
}
};
// wait for Javascript to load
ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor)getDriver()).executeScript("return document.readyState")
.toString().equals("complete");
}
};
return wait.until(jQueryLoad) && wait.until(jsLoad);
}

LINGS
- 3,560
- 5
- 34
- 47
-
1Thanks :) Will this work with every website or only with the websites using jQuery? – Fabian Lurz Oct 26 '15 at 15:15
-
Will work on any website, it handles presence and absence of Jquery and JS – LINGS Oct 26 '15 at 15:16
-
Thanks - i'll give it a try now – Fabian Lurz Oct 26 '15 at 15:16
-
Great. It seems to work - does this also work with angularjs? Also - i'm not 100 aware of document.readyState - does this include if a webpage loads content via ajax? (e.g. Pinterest?) – Fabian Lurz Oct 26 '15 at 15:33
-
@FabianLurz Yes I have been using it on pages with angularJs, it works well. AJAX page load will also fall under jQuery/JS and hence it should handle it as well. – LINGS Oct 26 '15 at 15:42
-
@FabianLurz remember to make a call to this method every time your action on the webpage could potentially trigger an AJAX call or JS/Jquery load. Sometimes, the load may be complete but the element you want to interact with may not be accessible, in that case you have to wait for the element. – LINGS Oct 26 '15 at 15:45
-
Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/93383/discussion-between-lings-and-fabian-lurz). – LINGS Oct 26 '15 at 15:45
-
This is great! Thanks for sharing. – JeffC Oct 26 '15 at 16:53
-
@LINGS What is a correct method to call this with waiting? – Ishita Shah Apr 09 '18 at 05:33
-
Quick question guys, I'm just starting with a Cucumber Java framework and still don't know where all parts go. I tried creating a "public bool waitForJSandJQueryToLoad" method under "src/test/java/pages/helpers", but IntelliJ IDE fails to recognising it saying => "class or interface expected". Do you know where or how I should integrate this with my framework? – mickael Jul 07 '18 at 19:09
4
As Mark Collin described in his book "Mastering Selenium Webdriver", use JavascriptExecutor let you figure out whether a website using jQuery has finished making AJAX calls
public class AdditionalConditions {
public static ExpectedCondition<Boolean> jQueryAJAXCallsHaveCompleted() {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
return (Boolean) ((JavascriptExecutor) driver).executeScript("return (window.jQuery != null) && (jQuery.active === 0);");
}
};
}
}

T J
- 42,762
- 13
- 83
- 138

Slav Kurochkin
- 444
- 3
- 9
-
-
Well if you have other javascript library you would need to rely on it. In the same book he has example for AngularJS, otherwise I would agree with another answer you have to be domain specific, and use [Explicit and Implicit Waits](http://www.seleniumhq.org/docs/04_webdriver_advanced.jsp#explicit-and-implicit-waits) – Slav Kurochkin Oct 26 '15 at 15:15
2
I have been using this simple do while to iterate until an AJAX is finished. It consistently works for me.
public void waitForAjax() throws InterruptedException{
while (true)
{
Boolean ajaxIsComplete = (Boolean) ((JavascriptExecutor)driver).executeScript("return jQuery.active == 0");
if (ajaxIsComplete){
info("Ajax Call completed. ");
break;
}
Thread.sleep(150);
}
}

Aniket Wadkar
- 31
- 3
0
I don't believe that there is a universal approach out of the box. I typically make a method that does a .waituntilrowcount(2)
or waituntilvisible()
that polls an element.
-
Hm - dammn. Is there any other library that is capable of crawling ajax websites? Tried selenium, htmlunit and crawljax. Problem htmlunit: Very sensitive against error and u can't turn it off. Crawljax: Probably capable of crawling ajax but you can't get the html of a webpage - ouch selenium: see question ;) – Fabian Lurz Oct 26 '15 at 15:05