Tuesday, February 16, 2016

Implicit/Explicit / Fluent Waits




WebDriver supports two waits in order to handle the synchronisation problems.
  • Implicit Wait
  • Explicit Wait
Let us discuss each of them in details considering practical approach.

WebDriver Implicit Wait

Implicit waits are used to provide a default waiting time (say 30 seconds) between each consecutive test step/command across the entire test script. Thus, subsequent test step would only execute when the 30 seconds have elapsed after executing the previous test step/command.
Syntax : Syntax
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
The above snippet code will take two parameters, the first indicates the tie in numeric that system need to wait and the second parameter indicates the time measurement. so in this case it will wait for 10 seconds, and Once set, the implicit wait is set for the life of the WebDriver object instance.

Ex. 

WebDriver driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://timetracker.anuko.com/login.php"); WebElement loginelement = driver.findElement(By.id("login"));


When to use: Not recommended

WebDriver explicit waits

An explicit waits is code you define to wait for a certain condition to occur before proceeding further in the code. The worst case of this is Thread.sleep(), which sets the condition to an exact time period to wait. There are some convenience methods provided that help you write code that will wait only as long as required. WebDriverWait in combination with ExpectedCondition is one way this can be accomplished.

WebDriver driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://timetracker.anuko.com/login.php");
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
  .until(ExpectedConditions.visibilityOf(By.id("login")));

Please refer this docs for more details for other method options. 

Will see live implementation :
1. Launch google chrome 
2. open time tracker login page
3. before enter the username data check whether element is present or not and then enter the value
4. Also will create a common method to wait for element present
public class ExplicitWaits {
public static WebDriver driver=null;
public static WebDriverWait wait;
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
System.setProperty("webdriver.chrome.driver","D:\\chromedriver.exe");
driver = new ChromeDriver();
driver.get("https://timetracker.anuko.com/login.php");
// waits are of two types implicit waits and explicit waits..
// implicit.. wait....
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
// get the id of username textbox and then pass to wait for element method to check whether element exist or not
WebElement enterusername=driver.findElement(By.id("login"));
waitforelement(enterusername);
// if success then enter data to username
enterusername.sendKeys("tesetuser@gmail.com");
}
// common method waitforelement
public static String waitforelement(WebElement element) throws IOException{
String msg;
try {
WebDriverWait wait = new WebDriverWait(driver, 30);
// below method will check for visibility of the element i.e in this case its username element
wait.until(ExpectedConditions.visibilityOf(element));
msg="PASS";
System.out.println(msg);
} catch (Exception e) {
System.out.println("waitForElementPresent method failed! "+ e.getMessage());
msg="FAIL -waitForElementPresent method failed! "+ e.getMessage() ;
}
return msg;
}



Fluent wait :


For each FluentWait instance, you can specify:
  1. Frequency with which FluentWait has to check the conditions defined.
  2. Ignore specific types of exception waiting such as NoSuchElementExceptions while searching for an element on the page.
  3. Maximum amount of time to wait for a condition
When to use FluentWait: When you try to test the presence of an element that may appear after every x seconds/minutes (Just an example, this is my guess of where such a thing can be used).

Ex :



// Waiting 30 seconds for an element to be present on the page, checking
// for its presence once every 5 seconds.
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
    .withTimeout(30, SECONDS)
    .pollingEvery(5, SECONDS)
    .ignoring(NoSuchElementException.class);

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



Example that covers fluent waits 

package com.session9;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;
public class FluentWaits {
static WebDriverWait wait;
public static void main(String[] args) {
// TODO Auto-generated method stub
System.setProperty("webdriver.chrome.driver","yourpath//chromedriver");
WebDriver driver = new ChromeDriver();
driver.get("http://admin-demo.nopcommerce.com/login");
//driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
//driver.findElement(By.xpath(".//*[@id='Email']")).sendKeys("admin@yourstore.com");
//driver.findElement(By.xpath(".//*[@id='Password']")).sendKeys("admin");
// explicit waits//
By email = By.xpath(".//*[@id='Email']");
wait = new WebDriverWait(driver,10);
wait.until(ExpectedConditions.presenceOfElementLocated(email));
driver.findElement(By.xpath(".//*[@id='Email']")).sendKeys("admin@yourstore.com");
// fluent wait...
// polling every 5 sec will check for the element..
By pwd = By.xpath("//*[@id='Password']");
Wait<WebDriver> newwait = new FluentWait<>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
newwait.until(ExpectedConditions.presenceOfElementLocated(pwd));
// end fluent wait..
driver.findElement(By.xpath("//*[@id='Password']")).sendKeys("admin");
}
}
// Go https://jqueryui.com/progressbar/#label
// in the process bar check for loading... label
package com.test;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;
public class ProcessingIcon {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
System.setProperty("webdriver.chrome.driver","/yourpath//chromedriver");
WebDriver driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver, 30);
driver.get("https://jqueryui.com/progressbar/#label");
//*[@id="progressbar"]/div[1]
// demo-frame
By FrameLocator = By.xpath("//*[@id='content']/iframe");
WebElement frameelement = driver.findElement(FrameLocator);
wait = new WebDriverWait(driver,10);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(frameelement));
// using fluent wait..
By icon = By.xpath("//*[@id='progressbar']/div[1]");
String t = driver.findElement(By.xpath("//*[@id='progressbar']/div[1]")).getText();
System.out.println(t);
Wait<WebDriver> newwait = new FluentWait<>(driver)
.withTimeout(60, TimeUnit.SECONDS)
.pollingEvery(2, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
Boolean c=false;
c=newwait.until(ExpectedConditions.
textToBePresentInElementLocated(icon, t));
System.out.println(c);
}
}





Some more option :


The following expected conditions can be used for finding a web element.
It is recommended that they are used instead driver.findElement().





elementToBeClickable
ExpectedCondition
elementToBeClickable(By locator)
ExpectedCondition
elementToBeClickable(WebElement element)
Defines an expectation for checking that an element is visible and enabled such that you can click it.
Example
The next 2 lines of code search for the element matched by the locator.
If the element can be found in the browser DOM and has the clickable status within 10 seconds, it is returned and saved in a WebElement variable.
The locator can be by xpath, css, id or name locator.
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element;
element = wait.until(ExpectedConditions.
elementToBeClickable(locator));
presenceOfElementLocated
ExpectedCondition
presenceOfElementLocated(By locator)
Defines an expectation for checking that an element is present on the DOM of a page.
Example
The next 2 lines of code search for the element matched by the locator.
If the element can be found in the browser DOM within 10 seconds, it is returned and saved in a WebElement variable.
The locator can be by xpath, css, id or name locator.
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element;
element = wait.until(ExpectedConditions.
presenceOfElementLocated(locator));
visibilityOfElementLocated
ExpectedCondition
visibilityOfElementLocated(By locator)
ExpectedCondition
visibilityOf(WebElement element)
Defines an expectation for checking that an element is present on the DOM of a page and visible.
Example
The next 2 lines of code search for the element matched by the locator.
If the element can be found in the browser DOM and is visible within 10 seconds, it is returned and saved in a WebElement variable.
The locator can be by xpath, css, id or name locator.
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element;
element = wait.until(ExpectedConditions.
visibilityOfElementLocated(locator));
The following expected conditions can be used for checking the web page title and url.
It is recommended that they are used instead of driver.getTitle() and driver.getCurrentUrl().
titleContains
ExpectedCondition
titleContains(java.lang.String title)
An expectation for checking that the title contains a case-sensitive substring
Example
The next 2 lines of code verify if the page title contains a keyword.
If the keyword is included in page title within 10 seconds, the explicit wait returns true.
Otherwise, the explicit wait returns false.
WebDriverWait wait = new WebDriverWait(driver, 10);
assertTrue(wait.until(ExpectedConditions.
titleContains(keyword)));
titleIs
ExpectedCondition
titleIs(java.lang.String title)
Defines an expectation for checking the title of a page.
Example
The next 2 lines of code verify if the page title is equal to a specific value.
If the page title is equal to a specific value within 10 seconds, the explicit wait returns true.
Otherwise, the explicit wait returns false.
WebDriverWait wait = new WebDriverWait(driver, 10);
assertTrue(wait.until(ExpectedConditions.
titleIs(titleValue)));
urlContains
ExpectedCondition
urlContains(java.lang.String fraction)
Defines an expectation for the URL of the current page to contain specific text.
Example
The next 2 lines of code verify if the page url contains a keyword.
If the keyword is included in the page url within 10 seconds, the explicit wait returns true.
Otherwise, the explicit wait returns false.
WebDriverWait wait = new WebDriverWait(driver, 10);
assertTrue(wait.until(ExpectedConditions.
urlContains(keyword)));
urlToBe
ExpectedCondition
urlToBe(java.lang.String url)
An expectation for the URL of the current page to be a specific url.
Example
The next 2 lines of code verify if the page url is equal to a specific value.
If the page url is equal to a specific value within 10 seconds, the explicit wait returns true.
Otherwise, the explicit wait returns false.
WebDriverWait wait = new WebDriverWait(driver, 10);
assertTrue(wait.until(ExpectedConditions.
urlToBe(urlValue)));
urlMatches
ExpectedCondition
urlMatches(java.lang.String regex)
Expectation for the URL to match a specific regular expression
Example
The next 2 lines of code verify if the page url matches a regular expression.
If the page url matches the regular expression within 10 seconds, explicit wait returns true.
Otherwise, the explicit wait returns false.
WebDriverWait wait = new WebDriverWait(driver, 10);
assertTrue(wait.until(ExpectedConditions.
urlMatches(regularExpression)));
textToBePresentInElement
ExpectedCondition
textToBePresentInElement(WebElement element, java.lang.String text)
ExpectedCondition
textToBePresentInElementLocated(By locator, java.lang.String text)
An expectation for checking if the given text is present in the element that matches the given locator.
Example
The next 2 lines of code verify if a keyword is included in an element.
If the keyword is included in the element within 10 seconds, the explicit wait returns true.
Otherwise, the explicit wait returns false.
WebDriverWait wait = new WebDriverWait(driver, 10);
assertTrue(wait.until(ExpectedConditions.
textToBePresentInElementLocated(locator, keyword)));
textToBePresentInElementValue
ExpectedCondition
textToBePresentInElementValue(By locator, java.lang.String text)
ExpectedCondition
textToBePresentInElementValue(WebElement element, java.lang.String text)
Defines an expectation for checking if the given text is present in the specified elements value attribute.
Example
The next 2 lines of code verify if a keyword is included in the value attribute of an element.
If the keyword is included in the value attribute of the element within 10 seconds, the explicit wait returns true.
Otherwise, the explicit wait returns false.
WebDriverWait wait = new WebDriverWait(driver, 10);
assertTrue(wait.until(ExpectedConditions.
textToBePresentInElementValue(locator, keyword)));
view raw WaitsDesc.txt hosted with ❤ by GitHub