Saturday, May 11, 2013

Wait in Selenium WebDriver

There are many types of waits in selenium WebDriver.
  1. Thread.sleep()
  2. Implicit Wait
  3. WebDriver Wait
  4. Wait for the Ajax call
  5. Wait for the page to load
1. Thread.sleep()

Here we can't predict the exact required wait time. With this we may need to wait for some extra seconds which decreases performances. These extra seconds became more when we execute multiple tests which increases the overhead. This wait is not recommended and we should not use this in our test.

2. Implicit Wait

This is the wait provided by WebDriver which is used, in general, for waiting for an element. This is recommended and we can use it. For example,
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
When we use this statement, the WebDriver waits for the element(on which next action is performed) till 30 seconds if that is not available immediately. After the timeout period, if the element is not available, it throws NoSuchElementException.
Use of this at the beginning of each test is very profitable and a best practice.
3. WebDriver Wait

This wait waits for a condition. This is also recommended and we can use it. This checks the condition in every 500 milliseconds until it returns true or the timeout. For example,
WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(xpath)));
Here the condition is "ExpectedConditions.presenceOfElementLocated(By.xpath(xpath))" and this condition is checked in every 500 milliseconds until it is timed out by the timeout specified in timeOutInSeconds.

WebDriver wait is an explicit wait. You can refer here for more about implicit and explicit waits.


4. Wait for the AJAX call to complete

This is also recommended and very useful when we need to wait for some elements on the web page which is updating upon ajax calls.
You can refer the my post "Wait For Ajax call" for how to use this.

5. Wait for page to load

This is also recommended and very useful when you need to wait for a web page to load completely.
You can refer the my post "Wait for Page to load" for how to use this.

Friday, May 10, 2013

Wait for AJAX call to complete in WebDriver

Sometimes in our web application only part of the web page gets loaded upon certain actions, at that time actually an ajax call happens and depending upon the ajax response the page part loads. So in this case we need to wait till the ajax call is completed to test anything on that part of the webpage, if you don't want to do that by waiting for a specific element to be available. Below is the code that waits till the ajax calls completed:
/**
 * Waits until there are no more active ajax connection and until the
 * specified timeoutInSeconds is timeout
 * 
 * @param timeoutInSeconds
 */
public void waitForAjax(long timeoutInSeconds) {
 log.info("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;
     log.info("Number of active jquery ajax calls: " + n);
     if (n.longValue() == 0L)
      break;
    }
    Thread.sleep(1000);// 1 second sleep
   }
  } else {
   log.error("Web driver: " + driver
     + " cannot execute javascript");
  }
 } catch (Exception e) {
  log.error("Failed to wait for ajax response: " + e);
 }
}
In this code snippet we are checking the number of active Ajax connections by executing the javascript code jQuery.active then depending upon the result we are waiting for the ajax calls to complete until the timeout specified in timeoutInSeconds paameter

Wait for page to load in WebDriver

Unlike Selenium RC(selenium 1) have waitForPageToLoad method to wait until the page to load, WebDriver(selenium 2) doesn't have any method in the API to wait until the page to load. Here is a way to wait until the page elements load properly.
/**
 * Waits for a page to load for timeOutInSeconds number of
 * seconds.
 * 
 * @param timeOutInSeconds
 */
public void waitForPageToLoad(long timeOutInSeconds) {
 ExpectedCondition expectation = new ExpectedCondition() {
  public Boolean apply(WebDriver driver) {
   return ((JavascriptExecutor) driver).executeScript(
     "return document.readyState").equals("complete");
  }
 };
 try {
  log.info("Waiting for page to load...");
  WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
  wait.until(expectation);
 } catch (Throwable error) {
  log.error("Timeout waiting for Page Load Request to complete after "
    + timeOutInSeconds + " seconds");
  Assert.assertFalse(true,
    "Timeout waiting for Page Load Request to complete.");
 }
}
Here we are checking for the "complete" loading state of the web page by JavascriptExecutor and until that we are waiting till the timeout period specified in timeOutInSeconds parameter.