How to Handle Ajax call in Selenium Webdriver?

A common problem we face during automation using selenium webdriver to handle the ajax calls. we never know when the call is complete and page has been updated. there are several ways to handle the ajax calls. in this post we will see them one by one.

We can able to handle Ajax calls in following ways:

1) JAVA: Thread.Sleep(<time in ms>);

this is most commonly used method in java but this is never recommended while doing the automation. so always try to avoid it. only in some exceptional cases use it if you do not find any other alternative.

2) Explicit Waits :

An explicit waits is code you define to wait for a certain condition to occur before proceeding further in the code.

Code:

WebDriver driver = new FirefoxDriver();
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));

 

3) Implicit Waits:

An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available. The default setting is 0. Once set, the implicit wait is set for the life of the WebDriver object instance.

Code:

WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));

 

4) Executing Javascript using Java and applies wait:

If your application triggers an ajax call, you don’t want to carry on until that call has finished, but how do you know? You might be okay just to use one of the wait conditions above, but this isn’t a very clean approach, and it only works for ajax calls that result in changes to the browser DOM. i.e. it won’t work for calls that simply send data to the server without any changes in the browser html. Wouldn’t it be nice to be more certain when the call was finished? Well, if you are using jQuery to make your ajax calls, you can do so by exploiting the fact that most web driver implementations can run javascript. jQuery keeps a count of how many ajax calls are active in its jquery.active variable. Here’s an example of a helper method to wait for an ajax call to finish:
Code:

public void waitForAjax(int timeoutInSeconds) {
System.out.println("Checking active ajax calls by calling jquery.active");
try {
if (driver instanceof JavascriptExecutor) {
       JavascriptExecutor jsDriver = (JavascriptExecutor)driver;

for (int i = 0; i< timeoutInSeconds; i++) 
    {
       Object numberOfAjaxConnections = jsDriver.executeScript("return jQuery.active");
       // return should be a number
       if (numberOfAjaxConnections instanceof Long) {
       Long n = (Long)numberOfAjaxConnections;
       System.out.println("Number of active jquery ajax calls: " + n);
       if (n.longValue() == 0L)
       break;
     }
     Thread.sleep(1000);
     }
}
     else {
           System.out.println("Web driver: " + driver + " cannot execute javascript");
           }
}
          catch (InterruptedException e) {
          System.out.println(e);
          }
}

 

5) Using FluentWait :

Selenium webdriver provides FluentWait option to handle uncertain waits. The advantage of this approach is that element polling mechanism is configurable. The code example below waits for 3 second and polls for a textarea every 100 milliseconds.

    FluentWait<By> fluentWait = new FluentWait<By>(By.tagName("TEXTAREA"));  \\ define element for which you want to poll
        fluentWait.pollingEvery(300, TimeUnit.MILLISECONDS); \\ it will ping for every 3 sec
        fluentWait.withTimeout(1000, TimeUnit.MILLISECONDS);  \\ max time out
        fluentWait.until(new Predicate<By>() {
            public boolean apply(By by) {
                try {
                    return browser.findElement(by).isDisplayed();
                } catch (NoSuchElementException ex) {
                    return false;
                }
            }
        });
        browser.findElement(By.tagName("TEXTAREA")).sendKeys("text to enter");

 6) Using WebdriverWait:

Another approach is to use ExpectedCondition and WebDriverWait strategy. The code below waits for 20 seconds or till the element is available, whichever is the earliest.

      public ExpectedCondition<WebElement> visibilityOfElementLocated(final By by) {
        return new ExpectedCondition<WebElement>() {
          public WebElement apply(WebDriver driver) {
            WebElement element = driver.findElement(by);
            return element.isDisplayed() ? element : null;
          }
        };
      }
      
      public void performSomeAction() {
        ..
        ..
        Wait<WebDriver> wait = new WebDriverWait(driver, 20);
        WebElement element = wait.until(visibilityOfElementLocated(By.tagName("a")));
        ..        
      }

You might also like More from author