PAGE 10 : SYNCHRONIZATION IN SELENIUM WEBDRIVER

SYNCHRONIZATION : It is a mechanism which involves more than one components to work parallel with Each other.
Generally in Test Automation, we have two components
1. Application Under Test
2. Test Automation Tool.
Both these components will have their own speed. We should write our scripts in such a way that both the components should move with same and desired speed, so that we will not encounter "Element Not Found" errors which will consume time again in debugging.
Synchronization can be classified into two categories:
1. Unconditional 
2. Conditional Synchronization
Unconditional :
In this we just specify timeout value only. We will make the tool to wait until certain amount of time and then proceed further.
Examples: Wait() and Thread.Sleep();
The main disadvantage for the above statements are, there is a chance of unnecessary waiting time even though the application is ready.
The advantages are like in a situation where we interact for third party systems like interfaces, it is not possible to write a condition or check for a condition. Here in this situations, we have to make the application to wait for certain amount of time by specifying the timeout value.
Conditional Synchronization :

The biggest challenge in automating a web application is, the loading of a web page is always in the mercy of certain conditions, They are -:


 1) Load on the server

 2) Network speed 

 3) Performance of AUT

 4) Ajax call to load an element


So the major task in automating such application is to wait for the HTML element to appear in the page before your automation test code start performing action on them. So you need to make sure that the Web Element is present before the code start working on it. 


This can be achieved by waiting for the element to appear in the page. But how to do that?  


1) Putting the current thread to sleep mode for definite time period.


What does it mean? When your Test automation is executing the code, put the current thread to sleep for definite time period like 

Thread.sleep(timeToSleep) 


The drawback of using such a way is, the wait time specified is a definite time that means if you specify wait time is 5 Secs then your element appears after 1 sec then you wasted 4 secs and the thread will only wake up after 5 secs. It does not care about whether your element appears by that time or before the time.


2) Have a mechanism to wait in synchronized mode.


Lets see what do we mean by synchronized wait. Synchronized wait means, wait till the condition satisfied once the condition satisfied, come out from the sleep and continue the test execution.


Ok, So far we know why do we need to wait for the element, how to achieve that using sleep methods both synchronized and non synchronized. Now let us go and see how this can be achieved in Selenium/Web Driver.


In Selenium 2.0, this can be achieved via both Explicit and implicit wait. We will see how to implement both in the code below.


In Selenium we have implicit Wait and Explicit Wait conditional statements.

  1. Implicit waits
  2. Explicit waits






IMPLICIT WAIT:


The Implicit Wait will tell the Web Driver to poll the DOM for a certain duration when trying to find the element, this will be useful when certain elements on the webpage will not be available immediately and needs some time to load.

By default it ill take the value to 0, for the life of the Web Driver object instance through out the test script.


WHY IMPLICIT WAIT IS REQUIRED IN WEB DRIVER:

As you knows sometimes, some elements takes some time to appear on software web application page when browser is loading the page. In this case, sometime your web driver test will fail if you have not applied Implicit wait in your test case. If implicit wait is applied in your test case then web driver will wait for specified amount of time if targeted element not appears on page.

If you write implicit wait statement in you web driver software testing script then it will be applied automatically to all elements of your test case. I am suggesting you to use Implicit wait in your all test script of software web application with 10 to 15 seconds. 

In web driver, Implicit wait statement is as bellow.
driver.manage().timeouts().implicitlyWait(time period, TimeUnit.SECONDS);

EXAMPLE:

package implicitWait;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

import org.openqa.selenium.firefox.FirefoxDriver;

import org.testng.annotations.Test;



public class ImplicitWaitExample{

WebDriver driver;



@Test

public void Example() {
driver = new FirefoxDriver();
driver.get("http://facebook.com");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

//because my Applications takes few seconds to load the User Interface. So I set 2 seconds implicit wait
//TimeUnit :An interface for managing timeout behavior for WebDriver instances.

driver.get("http://facebook.com");
WebElement element= driver.findElement(By.id("email"));
}

}


Explicit Wait:

Explicit wait is a programmatic approach to problem of waiting for specific elements. Contrary to Implicit Wait t Explicit Wait requires more coding but also gives much more flexibility.This provide you better option than implicit wait.

Using ExpectedCondition class, you can wait for an alert to be present, for an element to be staled while loading another page, for an element to be ready for a click operation, and many more.

EXAMPLE:

package dropDownSelection;



import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

import org.openqa.selenium.firefox.FirefoxDriver;

import org.openqa.selenium.support.ui.ExpectedConditions;

import org.openqa.selenium.support.ui.WebDriverWait;

import org.testng.annotations.Test;



public class SelectByValue {
WebDriver driver;

@Test
public void selectByValueExample() {
driver = new FirefoxDriver();
driver.get("http://facebook.com");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

driver.get("http://facebook.com");

// explicit wait for search field
WebDriverWait wait = new WebDriverWait(driver, 10);

//Below is the syntax to check if the element is present on the DOM of a page and visible. Visibility means that the element is not just displayed but also should also has a height and width that is greater than 0.

wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("searchInput")));
driver.findElement(By.id("searchInput")).clear();
driver.findElement(By.id("searchInput")).sendKeys("India");
driver.findElement(By.id("searchButton")).click();

}
}

EXAMPLES FOR VARIOUS EXPLICIT WAITS:
  1. isElementClickable
  2. isElementVisible
  3. isElementInVisible
  4. isElementEnabled
  5. isElementDisplayed
  6. waitforinvisibilityofelement
  7. waitforinvisibilityofelementwithText
  8. waitForElementToBeClickable
  9. alertIsPresent
  10. titleIs
  11. frameToBeAvailableAndSwitchToIt

Let's discuss few of them:


1. elementToBeClickable() – The expected condition waits for an element to be clickable i.e. it should be present/displayed/visible on the screen as well as enabled.

wait.until(ExpectedConditions.elementToBeClickable(By.xpath(“//div[contains(text(),’COMPOSE’)]”)));

2. textToBePresentInElement() – The expected condition waits for an element having a certain string pattern.

wait.until(ExpectedConditions.textToBePresentInElement(By.xpath(“//div[@id= ‘forgotPass'”), “text to be found”));

3. alertIsPresent()- The expected condition waits for an alert box to appear.

wait.until(ExpectedConditions.alertIsPresent()) !=null);

4. titleIs() – The expected condition waits for a page with a specific title.

wait.until(ExpectedConditions.titleIs(“gmail”));

5. frameToBeAvailableAndSwitchToIt() – The expected condition waits for a frame to be available and then as soon as the frame is available, the control switches to it automatically.

wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id(“newframe”)));


Thread.Sleep:

Thread.Sleep waits stops the thread execution for the specified amount of seconds(Time is defined in milliseconds for this method.). During this time there is no other execution that happens in that thread.

  •  If your element is visible with in the the time limit specified in Thread.Sleep you can do anything, your thread will wait for the specified time before moving to the next statement in the code.
  •  However, in case of your implicitWait your code will not always wait for the time limit specified. It will wait till the time your element is visible or till the time you have specified. Basically till either of the two condition occurs first.

HOW DOES IMPLICIT WAIT ACHIEVE THAT:

Implicit wait consists of following steps
1. Look in the DOM for a particular element. If found move out of the wait.
2. If not found wait for 250 milli seconds.
3. After 250 mili seconds poll the DOM again and check for the element. If element found move out of the wait.
4. If element not found, go back to step number 2 and repeat the following steps.

Essentially in implicit wait you end up saving time.


A diagram of the sequence will look something like this





EXAMPLE OF THREAD.SLEEP

package com.helloselenium.selenium.test;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

public class OpenHelloSeleniumBlog{

 public static void main(String[] args) { 

  WebDriver driver = new FirefoxDriver();

  driver.get("http://helloselenium.blogspot.com");

  try{
   Thread.sleep(5000);
  }catch (InterruptedException ie1) {
    ie1.printStackTrace();
  } 
   
  driver.quit();
 }

}

QUESTION:
As we know that if we apply implicit wait in our script once and this will be applied to all code statement of the script.

But if we add explicit wait in addition to this wait for specific element, then does explicit wait actually overrides the implicit wait or not ?

ANS: Explicit will never override the Implicit wait.It will wait for a specific condition only .Once set, the implicit wait is set for the life of the WebDriver object instance.

TIMEOUTS:

We can set the page loadtime in webdriver.Suppose if we want facebook to be loaded within 60 sec then add below statement in your code

driver.manage().timeouts().pageLoadTimeout(60, TimeUnit.SECONDS); 
driver.get("http://facebook.com/");

WebElement myElem = findElement("Your code to Find Element");
try{
myElem.click()
}catch(Exception e){
sysout("Eating the Exception");
}

If facebook failed to load within 60sec then script will fail.
If you do not want script to fail in the above condition, put the code in try catch block and eat the exception. 

Make sure you know the timing of your page load or after page load wait for the elements to appear. It may make your test scripts flaky.

Apart from waits mentioned about, Selenium WebDriver provides timeouts. 
There are two timeouts supported: 
  1. pageLoadTimeout 
  2. setScriptTimeout. 
Let’s go through each one of them.


  • pageLoadTimeout: It sets the amount of time to wait for a page load to complete before throwing an error. If the timeout is negative, page loads can be indefinite. 

          Use below code to implement pageLoadTimeout.

          driver.manage().timeouts().pageLoadTimeout(100, SECONDS);


  • setScriptTimeout: It sets the amount of time to wait for an asynchronous script to finish execution before throwing an error. If the timeout is negative, then the script will be allowed to run indefinitely. 

         Use below code to implement setScriptTimeout.

         driver.manage().timeouts().setScriptTimeout(100,SECONDS);


QUESTION 
What is Selenium's default timeout for page loading?

The Firefox server defines its timeouts like this:
  • The implicit wait timeout is set to 0 by default. This means that if a command that finds elements does not find anything, it won't wait.
  • The page load timeout is set to -1 by default. This means that Selenium will wait indefinitely for the page to load.


No comments:

About Me

My photo
Pune, Maharastra, India
You can reach me out at : jimmiamrit@gmail.com