Handle Ajax Elements

To properly handle Ajax elements, we need to understand:

  • What triggers the Ajax call?
    So that we know WHEN we shall start to address ajax
  • What elements are affected by the call?
    So that we know WHAT elements that we shall handle specially.

What triggers Ajax call?
Most time Ajax calls are triggered by user interactions, such as submitting a form, clicking a certain button, leaving certain input field can all trigger ajax call and result in partial page update.

Another typical use of ajax is when a page contains multiple drop downs and one or more drop down options are depending upon the user’s choice of preceding one. Such as user chooses a country in the first drop down (choose a country), then an ajax call is triggered to fetch the options for the second drop down field(Such as city drop down).

Ajax call can also be automatically triggered based on timing or certain element’s status change, with no user interaction at all. One example is a player embedded in the page to play music track after track, where the next track info is automatically retrieved via Ajax once the current track is done.


Figure 2: Player whose track info is retrieved via Ajax Call

Identify Ajax Calls
To investigate what ajax calls are triggered by what user interaction, we can:

  • go to that page in chrome and
  • right click, then inspect -> Network –> XHR

then play around with the page and observe the xhr network traffic to get a clear idea on what triggers ajax calls, and what sections of page are affected by the call(aka repainted with data from ajax response).

Handle Ajax Elements
One way to handle ajax is: Don’t interact with ajax elements till ajax call is complete.

Sample code to wait for ajax call to complete if your web is using JQUERY:

Boolean isJqueryUsed = (Boolean)((JavascriptExecutor)driver).executeScript(“return (typeof(jQuery) != ‘undefined’)”));
if(isJqueryUsed){
while (true){
// JavaScript test to verify jQuery is active or not
Boolean ajaxIsComplete = (Boolean)(((JavascriptExecutor)driver).executeScript(“return jQuery.active == 0”));
if (ajaxIsComplete) break;
try{
Thread.sleep(100);
}catch (InterruptedException e) {}
}
}

If your web is not using JQuery, inject JQuery into the page and then check as above.

Another way to handle ajax elements is by RE-LOCATE the element for a new refreshing reference
Since we have no idea when the ajax call will be complete, we simply re-locate the element if we catch StaleElementReferenceException:

WebElement getStaleElem(By by, WebDriver driver) {
try {
//if implicitWait is set, driver will wait a few millisecond every time if it tries to locate it.
return driver.findElement(by);
} catch (StaleElementReferenceException) {
System.out.println(“Got StaleElementReferenceException. “);
return getStaleElem(by, driver);
}
}

Note: If the locator has a misspelling or incorrect, then this piece of code will enter an infinite loop. To prevent that from happening, probably we shall put a timeout or total retry count limit in the code.

Note: Only fluent-Wait on the element will not solve problem. Must re-locate the element to get a new reference. And always test-run your code in the fasted browser( It is always Chrome for me)

Leave a Reply

Your email address will not be published. Required fields are marked *