Waits in Selenium Webdriver

What is wait ? why we need it ?

It is the process of matching the speed of action and reaction, selenium does the action and web application shows the reaction.

Example: Click Login button gmail login (selenium does this action) web application navigates to the inbox(reaction)


Click on Compose button in Gmail

						public class Gmail 
						{
							public static void main(String[] args)
							{
								//open firefox browser
								WebDriver driver=new FirefoxDriver();
								//goto gmail.com
								driver.get("http://www.gmail.com");
								//enter text in username
								driver.findElement(By.xpath("//*[@id='email' type='email'   ]")).sendKeys("username");
								//enter text in password
								driver.findElement(By.xpath("//*[@id='Passwd']")).sendKeys("password");
								//click on the signin button
								driver.findElement(By.xpath("//*[@id='signIn']")).click();
								//click on the compose button
								driver.findElement(By.cssSelector("div[class='T-I J-J5-Ji T-I-KE L3']")).click();	
							}
						}


					

If you run the above program you might face "NoSuchElementException" Exception because selenium starts searching for the compose button immediately after clicking on the SignIn button it waits for few milli-seconds but normally gmail takes 3 to 4 second to open so selenium will not able to find it.

In most of the cases the selenium does the action in micro or milli-seconds but the application takes time in seconds.

At the same time selenium will not wait till it loads or becomes visible at the time selenium will not able to find the element within the java processing time so selenium throws “NoSuchElementException᾿.

We cannot alter the speed of the application, so we must slow down selenium.

Type of Waits in selenium webdriver

There are several ways to synchronize the selenium with application

  • Sleep
  • pageLoadTimeout
  • setScriptTimeout
  • ImplicitlyWait
  • ExplicitWait or WebdriverWait
  • FluentWait

Sleep() in Selenium webdriver

Sleep() is a method present in thread class, most of the java people might be familiar with this. It makes selenium to sleep for the specified time, we can specify the time

If you mention Thread.sleep(20); then selenium waits for 20 milli-seconds sleep method takes argument in milli-seconds as the input. If you want make the selenium to sleep for the 20 seconds means we need to mention like this Thread.sleep(20000);

Sleep() method will not worry about whether the element is present or not, it just sleeps till mentioned time. This is also called as static wait or blind wait, dead wait.


						Syntax : Thread.sleep(Long milli-seconds);
						


Complete program for Sleep()

						public class A 
						{
							public static void main(String[] args) throws InterruptedException 
							{
								//open firefox
								WebDriver driver=new FirefoxDriver();
								//open google.com
								driver.get("https://oogle.com");
								//wait for 5 seconds
								Thread.sleep(5000);
								//send text to the search bar
								driver.findElement(By.name("search bar")).sendKeys("selenium-webdriver");
								//click on the search button
								driver.findElement(By.id("q")).click();		
							}
						}

					

Create Custom By class Locator in Selenium

Code Example 2 for Sleep()

						public class GmailLogin 
						{
							public static void main(String[] args) throws InterruptedException							{
								//open the firefox
								WebDriver driver=new FirefoxDriver();
								
								//sleep for 5 seconds
								Thread.sleep(5000);
								
								//open gmail.com
								driver.get("http://www.gmail.com");
								
								//sleep for 5 seconds
								Thread.sleep(5000);
								
								//enter the user name in the Email field
								driver.findElement(By.id("Email")).sendKeys("username");
								
								//sleep for 5 seconds
								Thread.sleep(5000);
								
								//enter the password in the password field
								driver.findElement(By.id("Passwd")).sendKeys("password");
								
								//sleep for 5 seconds
								Thread.sleep(5000);
								
								//sends the enter to the password field
								//sendKeys always append the text present in the element
								//it never erases the text in the element
								driver.findElement(By.id("Passwd")).click();		
							}
						}

					

Consider the above program in which we are using sleep() method every time it waits for 10 seconds.

Let us consider practical application in that we are having more the 8 pages and 50 operations if we use Thread.sleep(10000) for 50 times then it is 500 seconds around 10 minutes, so the dead time is more but no one prefer to wait .

How to handle browser windows using selenium webdriver

Timeouts Interface in Selenium Webdriver

Timouts interface manges all the waits of the driver instances, This is inner Interface of Webdriver Interface on other words Timouts interface is enclosed by Webdriver interface.

Timeouts interface has three abstract methods, which are :

  • implicitlyWait
  • setScriptTimeout
  • pageLoadTimeout

There is no implementation present for these methods in Timeouts interface, the browser classes(FirefoxDriver, ChromeDriver..) provides the implemetations for these methods because browser classes implements Webdriver Interface.

Learn about ScriptTimeoutException in Selenium

Implicitly Wait in Selenium Webdriver

Now day most of application are formed using ajax statements, ajax makes the DOM elements to load at different times but selenium tries to find the element after the moment, it completes the previous line execution.

Due following reasons application element may take a while to load.

  • Poor Server Response time
  • Ajax Loading
  • Size of the page
  • Internet Speed
  • System hardware
  • Browser slowness / less responsive ness
  • Element created using javascript

Selenium Webdriver tries to find the element without bothering about whether elements are loaded or not, and selenium webdriver throws NoSuchElementException if element is not present.

Implicitly wait is one of the way to request selenium not throw any exception untill provided time. Default wait time of the selenium is 500 milli-seconds, implicitly wait overrides the default wait time of the selenium webdriver.

If element is found before implicitly wait time, selenium moves to next commands in the program without waiting to complete the implicitly wait time, this wait is also called dynamic wait. Implicit wait is set for the entire duration of your webdriver and is set at the start of your program. Most of the automation tester writes the implicit wait after creation of browser object.

Implicit wait tries to find the element in first go, if element is not present implicit wait tries to find the element after 500ms of first polling, if element is not available on second time also then implicit wait tries third time after 500 ms of second try and it goes on till the time reaches the 30 seconds

What it does is, in case while executing, if your webdriver doesn't finds any element then instead of throwing an exception, implicit wait makes your driver to wait for the specified wait time and then try to find the element once again.

If the driver still does not finds the element then it throws exception. Implicit wait does the same for all the elements in your program, so you just have to set it once.


						WebDriver driver = new ChromeDriver(); 
						// set implicit wait tme as 30 Seconds
						driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
						

Ex: Let's say that you give an Implicit wait of 30 sec, now while executing, your webdriver is not able to find an element, but since you've set implicit wait, the webdriver waits instead of throwing exception.

Lets say the time the webdriver searched for element is t=0.Now the webdriver waits for 30 sec, and at t=30.500( polling time of the implicitly wait is 500 milli-seconds) driver tries to find the element again, if it finds the element then it performs the particular action on the element and if it doesn't, it throws NoSuchElementException exception.


Complete Implicitly wait program

						public class MultiValueDropdownSelectByValue {
							public static void main(String[] args) throws Exception {
								// set the geckodriver.exe property
								System.setProperty("webdriver.gecko.driver", "C:/~/geckodriver.exe");
								// open firefox
								WebDriver driver = new FirefoxDriver();
								// set implicitly wait time for 1 Minute
								driver.manage().timeouts().implicitlyWait(1, TimeUnit.MINUTES);
								// open webpage
								driver.get("http://chercher.tech/practice/practice-dropdowns");
								// find the dropdown using xpath
								WebElement dropdownElement = driver.findElement(By.xpath("//select[@id='second']"));
								// create object for Select class
								Select dropdown = new Select(dropdownElement);
								// select options from the dropdown options which have value as 'donut', 'burger'
								dropdown.selectByValue("donut");
							}
						}

						

Handle dropdowns in selenium

Scope of Implicitly Wait in Selenium Webriver

Implicitly Wait is applicable only to findElement and findElements no other statement in selenium.

Once set, the implicit wait is set for the life of the WebDriver object instance. You can re-assign the implicit wait time anywhere you want.

When does Implicitly Wait is applicable for findElements method. :

Implicit wait in selenium is applicable for all findElement statements, but applicability of implicit wait to the findElements is Limited.

Implicitly wait is applicable on findElements only when there is no elements present, selenium webdriver moves to next command the moment it finds a single element.

If there is Zero matching elements selenium waits till the time it reaches provided implicitly wait

Scenario 1 : Consider a page having 100 checkboxes and applied implicit wait is 30 Seconds
When the page is loading selenium tries to find all the matching elements, but at there moment there no matching elements .

After 10 seconds of wait 1 check box is loaded, now selenium finds that one checkbox and concludes that there is only one element, so it ends the wait and moves to next command.

Selenium doesnot wait till 100 check boxes loaded into page, as webdriver doesnot know how many elements going to to be present on the page.

Scenario 2 : Consider a page having 0 checkboxes and applied implicit wait is 30 Seconds
Selenium tries to find all the matching elements inDOM, but so far no check box is loaded.

Now there is zero match so selenium waits till 30 seconds, and if doesnot find element after 30 seconds selenium webdriver throws NoSuchElementEXception

Supported Timeunits with Implicit Wait

Implicitly wait in selenium webdriver supports all the time unit from nano-Seconds to Days, all the units are present in the TimeUnit abstract class.

All the values (variable ) present in the TimeUnit are Constants, I guess you already got that from the UPPERCASE style itself. UPPERCASE is used to mean a value is constant

  • TimeUnit.NANOSECONDS : represents nano seconds (10pow-9 of a second is nano second)
  • TimeUnit.MICROSECONDS : represents micro seconds (10pow-6 of a second is micro second)
  • TimeUnit.MILLISECONDS : represents mill seconds (10pow-3 of a second is micro second i.e 1000 milli seconds is a second)
  • TimeUnit.SECONDS : represent a second
  • TimeUnit.MINUTES : represent minutes, a minute is 60 seconds
  • TimeUnit.HOURS : represent hour, a hour is 60 minutes
  • TimeUnit.DAYS : represents a day, a day is 24 hours
Implement ImplicitWait using sleep method in selenium

We can implement Implicitly Wait using Thread.sleep() method, by dividing the total wait time with 300ms time and we have to store that value in a variable for looping purpose, then we have make the thread to sleep for the 300ms and then re-try to find the element. Follow below steps to implement.

Explanation :Let's understand the principle of the implicitly wait, implicitlyWait waits for the element to present on webpage with given time limit, implicitly wait keeps trying to find the element till the time expires.

Steps to Implement :
1. Create a class called ImplicitWaitWithSleep.

2. Create a static method called implicitlyWithSleep and method should accept seconds as parameter.

3. Initiator the count variable for counting purpose.

4. For calculating purpose we have to convert seconds into milli-seconds, as implicit wait polls once in 300 milli-seconds.

5. Create a while loop with condition as true, this is also called as infinite loop as we donot have any condition

6. Write our finding element code inside the try block, so that we can catch exceptions if element is not there, make sure what kind of exception you want to catch ( for implicit wait we have to catch NoSuchElementException ).

8. We have to break the loop when we find the element (inside try block).

7. Verify the condition that our tries( count ) exceeded the max time limit, if it crosses throw a new NoSuchElementException exception.

8. We have make the program to sleep for 300 milli-seconds before polling again. With this end the implicitlyWithSleep method.

9. Open and navigate to google page in browser inside the main method.

10. Access the method to set the text to google search bar


						public class ImplicitWaitWithSleep {
							public static WebDriver driver;
							public static void main(String[] args) {
								// set chrome driver exe path
								System.setProperty("webdriver.chrome.driver", "C:/~/chromedriver.exe");
								// create object for chrome browser
								 driver = new ChromeDriver();
								// navigate to google
								driver.get("http://google.com/");
								implicitlyWithSleep(30);
							}
							
							public static void implicitlyWithSleep(long timeLimit){
								System.out.println("Custom implicitly wait with selenium");
								//set the counter for terminate purpose
								long count = 0;
								// calculate the number of tries 
								long tries = (timeLimit * 1000) /300;
								while(true){
									try {
										System.out.println("Trying for : "+count+" time(s)");
										// try to find the element and send keys
										driver.findElement(By.xpath("//input[@name='q']")).sendKeys("Implicit wait with sleep");
										System.out.println("element found");
										// end the loop as we found the element 
										break;
									} catch (NoSuchElementException e) {
										if (count > tries) {
											// throw exception if element not found after exception. 
											throw new NoSuchElementException("Element not fount after : "+timeLimit+"seconds");
										}
										// sleep for 300 milli seconds,
										// try to find the element after 30 seconds of sleep
										try {
											Thread.sleep(300);
										} catch (InterruptedException e1) {
											System.out.println("Sleep interupted");
										}
									}
									count++;
								}
							}
						}
						

Learn about Parameterized Constructor in Selenium and Java

Page Load Timeout in Selenium Webdriver

Page load timeout in selenium requests/set the time limit for a page to load, If the page is not loaded within the given time frame selenium throws TimeOutException exception

We can set the page load timeout using pageLoadTimeout method present in Browser classes(FirefoxDriver, ChromeDriver..)


						driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
						

Page load timeout is useful when we perform performance test, or when we test execution in IE.

Page Load timeout is applicable only to driver.get() and driver.navigate().to() methods in selenium webdriver

Setting Negative time limit makes the selenium to wait for the page load infinitely


						// set page load time as infinite (by giving minus value)
						driver.manage().timeouts().pageLoadTimeout(-10, TimeUnit.SECONDS);
						

Note : Page load timeout is not applicable when user clicks a link to open a page.


Complete program for Page load timeout


						public class PageLoadTimeTest {
							public static void main(String[] args) {
								// set chrome driver exe path
								System.setProperty("webdriver.chrome.driver", "C:/~/chromedriver.exe");
								WebDriver driver = new ChromeDriver();
								driver.get("http://chercher.tech/");
								// set the time of 30 seconds for page to complete the loading
								driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
							}
						}
						

Set Script Load timeout

setScriptTimeout sets the time limit for asynchronous script to finish execution, if process is not completed before the time limit selenium throws TimeoutException exception

The setScriptTimeout method affects only JavaScript code executed with executeAsyncScript and nothing else. In particular, executeScript is not affected by it.

So why do you want to set a timeout for executeAsyncScript?
    The default timeout for setScriptTimeout method is 0 (zero), if we donot set any time our executeAsyncScript method may fail because the javascript code may take more than zero seconds. So to avoid unnecessary failures we have to set the setScriptTimeout.

Run a simple javascript: (Do not set setScriptTimeout ) - Now this shall execute without throwing any issue.


						((JavascriptExecutor) driver).executeScript("alert('I am alert');");
						

Run a simple Assync Script: ( Do not set setScriptTimeout) - This shall fail with error - "Timed out waiting for async script result after 0ms"


						((JavascriptExecutor) driver).executeAsyncScript("document.getElementById('dummy')");
						

To resolve above issue add below given setScriptTimeout


						driver.manage().timeouts().setScriptTimeout(10, TimeUnit.SECONDS);
						((JavascriptExecutor) driver).executeAsyncScript("document.getElementById('dummy')");
						

Wait Interface in Selenium Webdriver

Wait is the generic interface, which makes selenium webdriver to wait for particular time with associated event. Events like element to be clickable, element to present.

Wait interface present under org.openqa.selenium.support.ui package, FluentWait and WebdriverWait implements Wait interface.


Until Method in WebdriverWait :

until is a abstract method present in Wait interface, whichever driver implements Webdriver the also must implement Wait interface.

Which means browser classes (FirefxDriver, ChromeDriver...) must implement methods present in Wait and Webdriver interfaces.

until method accepts a ExpectedConditions values as parameter, class must wait till the given condition neither becomes null nor false when they implement until method. So until methods implementation must not have return type as void.

FluentWait class implements Wait Interface and WebdriverWait class extends FluentWait class, this is called as multi-level inheritance in java. wait-fluent-implicit-selenium-webdriver

Fluent Wait in Selenium Webdriver

FluentWait class implements Wait interface in selenium webdriver, FluentWait object defines the maximum amount of time to wait for a condition. Below is the example for common way of using Fluent Wait,


						// create object for FluentWait class
						FluentWait fw = new FluentWait(driver);
						// max time limit is 30 seconds
						fw.withTimeout(30, TimeUnit.SECONDS);
						


User can configure the frequency with which to check the condition.


						// polls once in every 5 seconds
						fw.pollingEvery(5, TimeUnit.SECONDS);
						


User may configure the Fluentwait to ignore specific types of exceptions whilst waiting for the condition.


						// ignore the Exception
						fw.ignoring(NoSuchElementException.class);
						


User can configure the error message to display in case of TimeoutException occurs


						// custom message to show if exception occurs
						fw.withMessage("Time exceeded");
						


Mis-Conception : You might have heard that FluentWait is another kind of WebdriverWait/ExplicitWait but the reality is, WebdriverWait is another kind of FluentWait

Methods / Features of Fluent Wait in selenium webdriver

These are the methods present in the FluentWait, we may not use all of the methods in our practical use, but we can use use it reap the maximum benefit.


						FluentWait fw = new FluentWait(driver);
						


withTimeout : This method set the time limit for Fluent wait i.e how much time to wait for an condition when Fluent wait is used. withTimeout method accepts two parameter first parameter is amount of time, and second parameter is what is the TimeUnit for tha amount of time. TimeUnit could be from Nano-seconds to Days.


						// maximum time limit is 1 minute	
						fw.withTimeout(1, TimeUnit.MINUTES);
						


pollingEvery : frequencey of polling the webpage for particular element/condition, if give 10 Seconds FluentWait polls the webpage once in ever 10 seconds. Default polling time in FluentWait is 500 Milli-seconds


						// polls once in every 5 seconds
						fw.pollingEvery(5, TimeUnit.SECONDS);
						


ignoring : ignoring method makes the fluent wait to ignore the particular exception throwed during the wait time, in below line Fluent wait ignores if NoSuchElementException, and FluentWait continues to poll for the condition, ignoring method is overloaded and it can accept two Exceptions as well


						fw.ignoring(NoSuchElementException.class);
						//overloaded method
						fw.ignoring(NoSuchElementException.class, NoSuchWindowException.classs);
						


ignoreAll : ignores a list of exceptions that occour during the wait time, we have to pass Collection type parameter to this method, collection type could be List, Set, Queue.


						// create a array list to exceptions
						List allExceptions = new ArrayList();
						// add few exception to the list
						allExceptions.add(NoSuchElementException.class);
						allExceptions.add(ElementNotVisibleException.class);
						allExceptions.add(NoSuchFrameException.class);
						// ignore all the exception in the list
						fw.ignoreAll(allExceptions);
						


withMessage : given string message will be displayed at the final exception.


						// custom message to show if exception occurs
						fw.withMessage("THIS IS EXCEPTION MESSAGE");
						


timeoutException : timeoutException is protected method of the FluentWait class, we have to override this method to raise our own messages.


						@override
						public RuntimeException timeoutException(String message, Throwable lastException) {
							throw new NoSuchFrameException(message, lastException);
						  }
						


until : until method recursively calls ( calls the self i.e same function ) its input value to the given function until the function returns neither null nor false based on the the polling interval, until method throws exception if the method returns a null or false after the time limit.
      This particular step will be completed when the functions return type is true or not null, until method accepts Predicate or Function Interface types


						until(java.util.function.Function<? super T,V> isTrue)
						


until method's Termination : until methods in FluentWait gets terminated on below scenarios.

When apply function returns a value other than null or false
When apply function throws an unignored( We provide the ignoring Exception(s) ) exception
When the time limit reached
When current thread is interrupted by other threads

Function Interface with FluentWait in Selenium Webdrivers

If you keenly notice .until() method in the accepts Function Interface type or Predicate Interface type.

Function Interface:
Function Interface helps user to implement their own implementation for the apply method, which is nothing but what kind of operation you want to perform like check whether a element present, check whether alert present, check whether title is changed so on..

Function interface is generic Interface and it is represented as Function<T,R> where T is the type of object passed to apply method and R is the type of object returned by the apply function.

If we are implementing Function interface, we must provide implementation for the abstract apply() method present in the Function Interface.

Function can return any value, that we mentioned in the Function interface generic.

Skeleton Example for Function Interface:


						Function<T, R> function = new Function()
							{
								public R apply(T arg0) {
									return r;
								}
							}
						


T apply method's parameter type and it could be WebDriver, WebElement, String, basically it could be anything..

R apply method's return type and it could be WebDriver, WebElement, String, basically it could be anything..

Practical Example :
1. We are accepting WebDriver type parameter to the apply method and returning WebElement type object.

2. We are overriding the apply method to find the element and return the element


						WebElement feelingLuckyButton = (WebElement) fw.until(new Function<WebDriver, WebElement>() {
							public WebElement apply(WebDriver driver) {
								System.out.println("Polling for feeling Lucky Button");
								// return the button as webelement
								return driver.findElement(By.xpath("//input[@name='btnI-fail']"));
							}
						});
						

Predicate Interface with FluentWait in Selenium Webdriver


Predicate Interface : Depreciated from Selenium version 3.2.0 onwards

Predicate interface is almost same as Function Interface, the only difference is Predicate return only boolean Object where as Function Interface returns any value.

Predicate Interface accepts generic type as parameter (any value), We have to implement the test() method from the Predicate Interface.


						Predicate<T> pr = new Predicate<T>() {
								@Override
								public boolean test(T arg0) {
									// TODO Auto-generated method stub
									return boolean;
								}
							};
						


T is the Generic and it could be anything, like WebElement, Webdriver, String or anything..

Practical example for Predicate Interface:
Below example checks Whether the given page title is 'Google' or not and it waits till the page title becomes 'Google', when the test method return 'false' the same test method will be recalled, till return value becomes true or the time limit reaches.


						boolean pageTitle = fw.until(new Predicate<WebDriver>() {
								@Override
								public boolean test(WebDriver arg0) {
									// check whether URL of the page contains 'doodle'
									if(arg0.getTitle().equals("Google")){
										return true;
									}
									else{
										// return false if the URL of the page doesnot contains 'doodle'
										return false;
									}
								}
							});
						

Static Method Along with Until in FluentWait

We can pass static and non static methods to the until , until method calls these methods until the methods returns neither false nor null.

Until with static method :
1. Create a class called CustomFluent

2. Create a static method waitTillURLContains, this method will be used by FluentWait to wait till URL contains particuar String or till time expires.

3. waitTillURLContains accept only Webdriver parameter.

4. Write condition to check if the URL contains doodle string, return true if it contains otherwise return false.


						static boolean waitTillURLContains(WebDriver arg) {
								if(arg.getTitle().equals("Googl-e")){
									System.out.println("URL contains 'doodle'");
									return true;
								}else{
									System.out.println("URL does not contain 'doodle'");
									return false;
								}
							}
						


5. Create the browser object and navigate to the google page.

6. Create object for FluentWait and register the polling time(10 seconds) and the total timeout(60 seconds).

7. Click the I'm Feeling Lucky button

8. Call the waitTillURLContains method to check whether URL contains 'doodle' or not. We know that until method recalls the given method repeatedly with polling frequency till it receives true or not null object from the given function.


						// wait till the URL contains 'doodle' string
						wait.until(AA::waitTillURLContains);
						


9. If you notice on above program we have used :: to call a method. We normally use class name(CustomFluent) .(dot) method name for the methods, for static method we use ClassName.MethodName(), for non-static methods we use classObject.MethodName().

When we use .(dot) notation, the method returns exact return type. When we call a method using ::, method doesnot explicitly return any type, during runtime the return type is decided.


						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.FluentWait;

						public class CustomFluent {
							
							static boolean waitTillURLContains(WebDriver arg) {
								if(arg.getTitle().equals("Googl-e")){
									System.out.println("URL contains 'doodle'");
									return true;
								}else{
									System.out.println("URL does not contain 'doodle'");
									return false;
								}
							}
							
							public static void main(String[] args) throws InterruptedException {
								// set chrome driver exe path
								System.setProperty("webdriver.chrome.driver", "C:/~/chromedriver.exe");
								
								// create object for chrome browser
								WebDriver driver = new ChromeDriver();
								
								// navigate to google
								driver.get("http://google.com/");
								
								//create Fluent Wait object
								FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver);
								
								// set the polling frquency as 10 seconds
								wait.pollingEvery(10,  TimeUnit.SECONDS);
								
								// set total timeout as 60 seconds
								wait.withTimeout(60, TimeUnit.SECONDS);
								
								// ignore the NoSuchElementException Exception if occurs
								wait.ignoring(NoSuchElementException.class); 
								
								//click the Feeling lucky button
								driver.findElement(By.xpath("//input[@id='btnK']")).click();
								
								// wait till the URL contains 'doodle' string
								wait.until(CustomFluent::waitTillURLContains);
							}
						}
						


Similar way we can also access non-static method using object reference like below


						//create object for the CustomFluent class
						CustomFluent abc = new CustomFluent();

						// wait till the URL contains 'doodle' string
						wait.until(abc::waitTillURLContains);
						

FluentWait with PASS Scenario

Lets test the Fluent wait with pass scenario, Click the Google's Feeling Lucky button with Fluent button

1. Create browser instance/object and navigate to Url.

2. Create fluent wait object


						// create object for FluentWait class
						FluentWait fw = new FluentWait(driver);
						


3. Set the Fluent wait timeout as 30 seconds


						// max time limit is 30 seconds
						fw.withTimeout(30, TimeUnit.SECONDS);
						


4. Check whether element is present on the webpage once in every 5 seconds


						// polls once in every 5 seconds
						fw.pollingEvery(5, TimeUnit.SECONDS);
						


5. Ignore if selenium throws NoSuchelementException, because element is not there


						// ignore the Exception
						fw.ignoring(NoSuchElementException.class);
						


6. Implement Function interface with until method, we can also implement predicate in until method. Please refer Function and Predicate Section for more details about them.


						// create a the function which finds the element and returns
						WebElement feelingLuckyButton = (WebElement) fw.until(new Function<WebDriver, WebElement>() {
						


7. Return the WebElement (Feeling Lucky Button ) from the apply button.


						// return the button as webelement
						return driver.findElement(By.xpath("//input[@name='btnI-']"));
						


8. Click the returned element


						// click feeling lucky button
						feelingLuckyButton.click();
						

Complete program for FluentWait with pass scenario

						public class CustomImplicitWait {
	
							@SuppressWarnings("unchecked")
							public static void main(String[] args) {
								// set chrome driver exe path
								System.setProperty("webdriver.chrome.driver", "C:/~/chromedriver.exe");
								WebDriver driver = new ChromeDriver();
								driver.get("http://google.com");
								// create object for FluentWait class
								FluentWait fw = new FluentWait(driver);
								// max time limit is 30 seconds
								fw.withTimeout(30, TimeUnit.SECONDS);
								// polls once in every 5 seconds
								fw.pollingEvery(5, TimeUnit.SECONDS);
								// ignore the Exception
								fw.ignoring(NoSuchElementException.class);
								
								// custom message to show if exception occurs
								fw.withMessage("THIS IS EXCEPTION MESSAGE");
								
								// create a the function which finds the element and returns
								WebElement feelingLuckyButton = (WebElement) fw.until(new Function<WebDriver, WebElement>() {
									public WebElement apply(WebDriver driver) {
										System.out.println("Polling for feeling Lucky Button");
										// return the button as webelement
										return driver.findElement(By.xpath("//input[@name='btnI']"));
									}
								});
								System.out.println("clicking feeling lucky button");
								// click feeling lucky button
								feelingLuckyButton.click();
							}
						}
						

Fluent Wait with FAILURE scenario

In this, we are going to learn what happens when fluent wait failure occurs, lets modify above program.

1. Change the locator from xpath("//input[@name='btnI-']") to xpath("//input[@name='btnI-fail']"), added -fail in the xpath which is not match with any element on google page

2. Create Fulent Wait object and set the polling time and ignore.

3. Provide custom message for exception, so that when there is no element this message will be Shown along with exception


						// custom message to show if exception occurs
						fw.withMessage("THIS IS EXCEPTION MESSAGE");
						
Complete program for Fluent Wait failure scenario

						public class CustomImplicitWait {
	
							@SuppressWarnings("unchecked")
							public static void main(String[] args) {
								// set chrome driver exe path
								System.setProperty("webdriver.chrome.driver", "C:/~/chromedriver.exe");
								WebDriver driver = new ChromeDriver();
								driver.get("http://google.com");
								// create object for FluentWait class
								FluentWait fw = new FluentWait(driver);
								// max time limit is 30 seconds
								fw.withTimeout(30, TimeUnit.SECONDS);
								// polls once in every 5 seconds
								fw.pollingEvery(5, TimeUnit.SECONDS);
								// ignore the Exception
								fw.ignoring(NoSuchElementException.class);
								
								// custom message to show if exception occurs
								fw.withMessage("THIS IS EXCEPTION MESSAGE");
								
								// create a the function which finds the element and returns
								WebElement feelingLuckyButton = (WebElement) fw.until(new Function<WebDriver, WebElement>() {
									public WebElement apply(WebDriver driver) {
										System.out.println("Polling for feeling Lucky Button");
										// return the button as webelement
										return driver.findElement(By.xpath("//input[@name='btnI-fail']"));
									}
								});
								System.out.println("clicking feeling lucky button");
								// click feeling lucky button
								feelingLuckyButton.click();
							}
						}
						


Analysis of Fluent Wait program's run fluent-wait-selenium-webdriver

Please refer above image for number details.
1. org.openqa.selenium.TimeoutException is throwed by selenium webdriver, as we have not written any custom exception the default TimeoutException is throwed when there is no matching element

2. THIS IS EXCEPTION MESSAGE exception detail contains our custom message, that we have set

3. tried for 30 second(s) shows what is the maximum time that fluent wait waited for the matching element

4. with 5 SECONDS interval shows the frequency of polling, we have 5 seconds frequency for 30 seconds which means it tried for 6 times along with default time, at 0'th moment fluent wait tries to find the element but if element is not present, it tries after 5 seconds(for 6 times), so there will be 7 attempts, Because of which there 7 polling statements.

5. org.openqa.selenium.NoSuchElementException is the actual root exception, which occured after 30 seconds, this exception turned on the TimeoutException

Take Page & Element Screenshot, Compare Screenshots in selenium

Explicit Wait in selenium webdriver

The explicit wait is used to tell the Web Driver to wait for certain conditions or the maximum time limit before throwing an Exception .

We can reuse the WebdriverWait object once we create it.Explicit wait will be applicable for only one line, we have to use it with ExpectedConditions class.

ExplicitWait does not have any effect on findElement and findElements.ExplicitWait also called as WebdriverWait.

WebDriverWait by default calls the ExpectedCondition every 500 milliseconds until it returns successfully.


							Syntax : WebDriverWait wait=new WebDriverWait( driver, timeoutInSeconds);
						


Below are few Expected Conditions :

alertIsPresent()
elementSelectionStateToBe(locator, selected)
elementToBeClickable(locator)
elementToBeSelected(locator)
frameToBeAvailableAndSwitchToIt(locator)-(will see in advanced topic)
presenceOfElementLocated(locator)
textToBePresentInElement(locator, text)
title)
titleIs(title)
visibilityOf(element)

alertIsPresent()

Selenium waits for an alert to be present when user writes 'alertIsPresent()', when selenium finds the alert it moves to next line of code, in case if alert is not present before the specified time, then selenium Throws 'TimoutException'


						public class A
						{
							public static void main(String[] args) throws InterruptedException
							{
								//open firefox
								WebDriver driver=new FirefoxDriver();
								//open google.com
								driver.get("https://chercher.tech/practice/explicit-wait-sample-selenium-webdriver");
								driver.findElement(BY.xpath("//button[@class='alert']")).click();
								WebDriverWait wait = new WebDriverWait(driver, 30 /*timeout in seconds*/);
								//throws TimeoutException if no alert is present
								wait.until(ExpectedConditions.alertIsPresent());
								driver.switchTo().alert().dismiss();
							}
						}
						

elementToBeClickable()

Selenium waits for an element to become clickable like disabled state to normal state, selenium moves to next line of code if the element becomes clickable before the timeout otherwise selenium throws 'TimoutException'

Executing below code will fail as the button is disabled


public class A
{
  public static void main(String[] args) throws InterruptedException
  {
      //open firefox
      WebDriver driver=new FirefoxDriver();
      //open google.com
      driver.get("https://chercher.tech/practice/explicit-wait-sample-selenium-webdriver");
      driver.findElement(By.xpath("//button[@id='btn1']")).click();
                 
  }
}


In below code wait statement makes selenium to wait for 30 or till the button gets enabled, if button is not enabled in specified time limit selenium throws 'Timeout Exception'

public class A
{
  public static void main(String[] args) throws InterruptedException
  {
      //open firefox
      WebDriver driver=new FirefoxDriver();
      //open google.com
      driver.get("https://chercher.tech/practice/explicit-wait-sample-selenium-webdriver");
      WebDriverWait wait = new WebDriverWait(driver, 30 /*timeout in seconds*/);
      //throws TimeoutException if no alert is present
      wait.until(ExpectedConditions.wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[@id='btn1']"))));
      driver.findElement(By.xpath("//button[@id='btn1']")).click();
                 
  }
}

elementToBeSelected()

Selenium waits for an element to be selected when we use 'elementToBeSelected()', when selenium finds the element is selected it moves to next line of code, in case if element is not selected before the specified time, then selenium Throws 'TimoutException'


public class A
{
  public static void main(String[] args) throws InterruptedException
  {
      //open firefox
      WebDriver driver=new FirefoxDriver();
      //open google.com
      driver.get("https://chercher.tech/practice/explicit-wait-sample-selenium-webdriver");
      driver.findElement(BY.xpath("//button[@class='alert']")).click();
      WebDriverWait wait = new WebDriverWait(driver, 30 /*timeout in seconds*/);
      //throws TimeoutException if no alert is present
      wait.until(ExpectedConditions.wait.until(ExpectedConditions.elementToBeSelected(By.xpath("//input[@id='hidden]"))));
  }
}

textToBePresentInElement()

Selenium waits for an element to have particular text when we use 'textToBePresentInElement()', when selenium finds the element have particular text it moves to next line of code, in case if element doesnot have text before the specified time, then selenium Throws 'TimoutException'


public class A
{
  public static void main(String[] args) throws InterruptedException
  {
      //open firefox
      WebDriver driver=new FirefoxDriver();
      //open google.com
      driver.get("https://chercher.tech/practice/explicit-wait-sample-selenium-webdriver");
      driver.findElement(BY.xpath("//button[@class='alert']")).click();
      WebDriverWait wait = new WebDriverWait(driver, 30 /*timeout in seconds*/);
      //throws TimeoutException if no alert is present
      wait.until(ExpectedConditions.wait.until(ExpectedConditions.textToBePresentInElement(By.xpath("//input[@id='h2]"))));
  }
}

titleIs()

Selenium waits for an webpage to have a particular title when we use 'titleIs()', when selenium finds webpage with given title, it moves to next line of code, in case if webpage doesnot have title before the specified time, then selenium Throws 'TimoutException'


public class A
{
  public static void main(String[] args) throws InterruptedException
  {
      //open firefox
      WebDriver driver=new FirefoxDriver();
      //open google.com
      driver.get("https://chercher.tech/practice/explicit-wait-sample-selenium-webdriver");
      driver.findElement(BY.xpath("//button[@class='alert']")).click();
      WebDriverWait wait = new WebDriverWait(driver, 30 /*timeout in seconds*/);
      //throws TimeoutException if no alert is present
      wait.until(ExpectedConditions.wait.until(ExpectedConditions.titleIs("selenium webdriver sample")));
  }
}

visibilityOfElementLocated()

Selenium waits for visibility of element when we use 'visibilityOfElementLocated()', when element is visible, it moves to next line of code, in case if element is not visible before the specified time, then selenium Throws 'TimoutException'


public class A
{
  public static void main(String[] args) throws InterruptedException
  {
    //open firefox
    WebDriver driver=new FirefoxDriver();
    //open google.com
    driver.get("https://chercher.tech/practice/explicit-wait-sample-selenium-webdriver");
    driver.findElement(BY.xpath("//button[@class='alert']")).click();
    WebDriverWait wait = new WebDriverWait(driver, 30 /*timeout in seconds*/);
    //throws TimeoutException if no alert is present
    wait.until(ExpectedConditions.wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//input[@id='hidden]"))));
  }
}

Frequently Asked Questions


What are we waiting for?
Waiting for .until condition is satisfied, until method gets satisfied when it receives neither null nor false.

How long do we wait?
It is defined explicitly in timeout parameter of .withTimeout() method

How often we can check the result?
Defined in pollingFrequency.

When to use?
When we try to test the presence of an element that may appear after particular seconds/minutes, and many other things like wait till an element’s property satisfy certain condition or alerts or titles so on.

About Author

Myself KarthiQ, I am the author of this blog, I know ways to write a good article but some how I donot have the skills to make it to reach people, would you like help me to reach more people By sharing this Article in the social media.

Share this Article Facebook
Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions
  • Pradeep
    The spelling is not at all taken care
    Reply
    • karthiQ [admin]
      Thanks for highlighting it Pradeep,  It would be great if if you can mention the words.
      Reply
  • Copyright © CherCher Tech