I have a rather ajax-heavy web application that I am testing with Selenium, and Selenium IDE. Everything works fine until the final submit. Usually it errors out due to the outstanding number of ajax requests that are still in process (usually around 20). Is there any way to have selenium wait for all ajax requests to be complete? I have tried waitForEval Value = "$.active==0" (pictured below) but that doesn't seem to do anything
Is this something that is possible with Selenium IDE?
Note - I do have to use the IDE due to the fact that the business types and I are passing the scripts back and forth.
jQuery ajaxStop() Method The ajaxStop() method specifies a function to run when ALL AJAX requests have completed. When an AJAX request completes, jQuery checks if there are any more AJAX requests. The function specified with the ajaxStop() method will run if no other requests are pending.
Moreover, the JavaScript Executor can be used to wait for an Ajax call. The executeScript method is used to run a JavaScript command in Selenium. The waiting is done till jQuery. active command yields 0.
Hey Firoz, wait methods which can be used in Selenium Webdriver to handle AJAX calls are as follows: Thread. Sleep(): Thread. Sleep () suspends the current thread for the specified amount of time.
This can be done by using the Thread. Here, the wait time (10 seconds) is passed as a parameter to the method. We can also use the synchronization concept in Selenium for waiting. There are two kinds of wait − implicit and explicit.
The answer turned out to be rather simple - all you have to do is check the number of active requests (selenium.browserbot.getUserWindow().$.active) with the waitForEval command, and set the value to 0 - and it all happens in the ide.
I haven't used IDE in a while. This is what I use for WebDriver. But the algorithms translate; JavaScript is JavaScript. That being said, it depends on your framework.
For Angular, I use this:
public boolean waitForAngularToLoad(WebDriver driver, int waitTimeInSeconds) {
WebDriverWait wait = new WebDriverWait(driver, waitTimeInSeconds, 2000L);
ExpectedCondition<Boolean> libraryLoad = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
try {
return ((Boolean)((JavascriptExecutor)driver).executeScript(
"return angular.element(document.body).injector().get(\'$http\').pendingRequests.length == 0;"
));
}
catch (Exception e) {
// Angular not found
log.info("Not found: " + "return angular.element(document.body).injector().get(\'$http\').pendingRequests.length == 0;");
return true;
}
}
};
// wait for browser readystate complete; it is arguable if selenium does this all the time
ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor)driver).executeScript("return document.readyState;")
.toString().equals("complete");
}
};
return wait.until(libraryLoad) && wait.until(jsLoad);
}
For Prototype I use:
public boolean waitForPrototypeToLoad(WebDriver driver, int waitTimeInSeconds) {
WebDriverWait wait = new WebDriverWait(driver, waitTimeInSeconds, 2000L);
// wait for jQuery to load
ExpectedCondition<Boolean> libraryLoad = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
try {
return ((Boolean)((JavascriptExecutor)driver).executeScript("return Ajax.activeRequestCount == 0;"));
}
catch (Exception e) {
// Prototype not found
log.info("Not found: " + "return Ajax.activeRequestCount == 0;");
return true;
}
}
};
// wait for browser readystate complete; it is arguable if selenium does this all the time
ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor)driver).executeScript("return document.readyState;")
.toString().equals("complete");
}
};
return wait.until(libraryLoad) && wait.until(jsLoad);
}
For jQuery, I use this (you have to customize the wait for spinner logic, everybody does it differently):
public boolean waitForJSandJQueryToLoad(WebDriver driver, long waitTimeInSeconds) {
WebDriverWait wait = new WebDriverWait(driver, waitTimeInSeconds, 2000L);
/*
* If you are curious about what follows see:
* http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/support/ui/ExpectedCondition.html
*
* We are creating an anonymous class that inherits from ExpectedCondition and then implements interface
* method apply(...)
*/
ExpectedCondition<Boolean> libraryLoad = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
boolean isAjaxFinished = false;
boolean isLoaderSpinning = false;
boolean isPageLoadComplete = false;
try {
isAjaxFinished = ((Boolean)((JavascriptExecutor)driver).executeScript("return jQuery.active == 0;"));
} catch (Exception e) {
// no Javascript library not found
isAjaxFinished = true;
}
try { // Check your page, not everyone uses class=spinner
// Reduce implicit wait time for spinner
driver.manage().timeouts().implicitlyWait(10L, TimeUnit.SECONDS);
// isLoaderSpinning = driver.findElement(By.className("spinner")).isDisplayed(); // This is the default
// Next was modified for GoComics
isLoaderSpinning = driver.findElement(By.cssSelector("#progress_throbber > ul > li:nth-child(1) > img[alt='spinner']")).isDisplayed();
if (isLoaderSpinning)
log.info("jquery loader is spinning");
} catch (Exception f) {
// no loading spinner found
isLoaderSpinning = false;
} finally { // Restore implicit wait time to default
driver.manage().timeouts().implicitlyWait(new DriverFactory().getImplicitWait(), TimeUnit.SECONDS);
}
isPageLoadComplete = ((JavascriptExecutor)driver).executeScript("return document.readyState;")
.toString().equals("complete");
if (!(isAjaxFinished & !(isLoaderSpinning) & isPageLoadComplete))
log.info(isAjaxFinished + ", " + !(isLoaderSpinning) +", " + isPageLoadComplete);
return isAjaxFinished & !(isLoaderSpinning) & isPageLoadComplete;
}
}; // Terminates statement started by ExpectedCondition<Boolean> libraryLoad = ...
return wait.until(libraryLoad);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With