Wait Interface in Selenium

Wait is the generic interface, which makes selenium to wait for particular time with associated event. Events like element to be click-able, 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

Explicitly Wait

Fluent Wait in Selenium

FluentWait class implements Wait interface in selenium, 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

Implicitly Wait in selenium

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 :

frequency 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 threw 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.class);
						

ignoreAll :

ignores a list of exceptions that occur 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 un-ignored( We provide the ignoring Exception(s) ) exception
  • When the time limit reached
  • When current thread is interrupted by other threads

Page Load Timeout

Function Interface with FluentWait in Webdriver

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']"));
							}
						});
						

Database Testing in Selenium

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 does not contains 'doodle'
										return false;
									}
								}
							});
						

API testing with selenium

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 particular 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 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("https://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);
						

Docker with Selenium

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("https://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();
							}
						}
						

Cucumber With Selenium

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 Fluent 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("https://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.

  • org.openqa.selenium.TimeoutException is throwed by webdriver, as we have not written any custom exception the default TimeoutException is throwed when there is no matching element
  • THIS IS EXCEPTION MESSAGE exception detail contains our custom message, that we have set
  • tried for 30 second(s) shows what is the maximum time that fluent wait waited for the matching element
  • 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.
  • org.openqa.seleniumNoSuchElementException is the actual root exception, which occurred after 30 seconds, this exception turned on the TimeoutException

Take Page & Element Screenshot, Compare Screenshots in selenium

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

Recent Addition

new tutorial Protractor Online Training : We have closed registration for training

Please do email to chercher.tech@gmail.com for any queries

If you already registered then please do check your email for the Webex link for the training starting from 15th Nov 2018
 
Join My Facebook Group
Join Group