Friday 7 March 2014

Implicit and Explicit Waits


Explicit Wait is related with certain conditions to wait; Implicit Wait with specific time to wait for an Element.


Explicit Wait

Here, the driver waits for 10 secs till the web element is found;  If not, it simply throws a Timeout Exception.

WebElement element = (new WebDriverWait(driver, 10))
  .until(ExpectedConditions.presenceOfElementLocated(By.id("Value")));

or|

WebDriverWait wait = new WebDriverWait(driver, 20);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("Value")));


WebDriverWait can't be declared globally and throw NullPointerException; whereas the below snippets will help you to do so.


// Handles any locator
@Test
public void Test01() throws Exception {
  driver.get("www.xyz.com");
  wait().until(ExpectedConditions.presenceOfElementLocated(By.xpath("Value")));
  }

private WebDriverWait wait()
   {
    return new WebDriverWait(driver, 20);
   }


// Handles any locator [This method works for page object pattern]
private WebDriver driver;
private final Wait<WebDriver> wait;

public Classname(WebDriver driver) { //constructor
   this.driver = driver;
   wait = new WebDriverWait(driver, 20);
 }

@Test
public void Test01() throws Exception {
  driver.get("www.xyz.com");
  wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("Value")));
  }


// Handle the locators by id, name, xpath, css, etc.,
@Test
public void Test02() throws Exception {
  driver.get("www.xyz.com");
  waitForID("Value");
   }

public void waitForID(String id) 
   {         
    WebDriverWait wait = new WebDriverWait(driver, 10);      
    wait.until(ExpectedConditions.presenceOfElementLocated(By.id(id)));      
   }


In Java, Expected Conditions include:
























#PYTHON
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

try:
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "Value")))
except:
    print "Element is not present"
    self.fail()

print "Element is present"

or|

wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.ID,"Value")))


Following link has entire Python Expected conditions:
http://selenium.googlecode.com/git/docs/api/py/webdriver_support/selenium.webdriver.support.expected_conditions.html


Fluent Wait

WebDriverWait is an extension of FluentWait. Fluent wait uses a Polling Technique;  i.e, It will be keep on Polling every Fixed interval for a particular Element.


import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.WebDriverWait;
import com.google.common.base.Function;

@Test
public void Test02() throws Exception {
  driver.get("www.xyz.com");
  fluentWait(By.id("Value"));
   }

public WebElement fluentWait(final By locator) {
   FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver)
           .withTimeout(10, TimeUnit.SECONDS)
           .pollingEvery(2, TimeUnit.SECONDS)
           .ignoring(NoSuchElementException.class);

   WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
       public WebElement apply(WebDriver driver) {
           return driver.findElement(locator);
       }
   });

   return  foo;
};


Thread.sleep()

Thread.sleep() is not an ideal approach on handling Wait. The worst case of Explicit wait is Thread.sleep().

Thread.sleep(3000); // waits for 3 secs

#PYTHON
import time
time.sleep(3// waits for 3 secs

#RUBY
sleep 5 # wait for 5 secs
sleep(1.minutes)
sleep(2.hours)
sleep(3.days)



Implicit Wait

Every timeout depends upon Implicit Wait;  From the start till end, it acts as a master wait.  However, the explicit waits are highly recommended for its ease of use.

WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);


#PYTHON
self.driver.implicitly_wait(30)

#RUBY
@driver.manage.timeouts.implicit_wait = 30

2 comments: