1.Overview
In this article, we’ll look at the most fundamental mechanism in selenium – synchronisation(wait).
2. Synchronisation in Selenium
- Synchronisation helps the user to troubleshoot issues when launching or navigating to different web pages while executing the selenium scripts.
- When the entire web page gets refreshed or elements are getting re-loaded there should be synchronisation between the selenium scripts, script execution speed and web application speed.
- At times, there can be a lot of Ajax components or some images and when we want to interact with these elements it may not visible. Thus, a time fall back can be seen in such cases and we get an exception as “ElementNotVisibleException“.
- Selenium doesn’t provide any default synchronisation but it provides synchronisation in the form of different types of waits which we will see below.
3. Different Types of waits in Selenium WebDriver
- Implicit Wait
- Explicit Wait
- Fluent Wait
These waits are dynamic waits. To understand the statement let’s consider a situation when you have given a TimeOut value of 20 seconds. If the element is loaded in 5 seconds, then rest 15 seconds will be ignored.
Let’s have a look at each one of these commands:
- Implicit Wait
As per Selenium Documentation, An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available. The default setting is 0. Once set, the implicit wait is set for the life of the WebDriver object instance.
- Implicit wait waits for a certain time till page gets loaded. After setting a particular time web driver will wait for that time before throwing an exception “No Such Element Exception“.
- Implicitly wait is applied globally, which means it is always available for all the web elements throughout the driver instance.
- Syntax: driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
- Implicitly accepts two parameters the first parameter time: 10 given as timeout wait and other is TimeUnit can be given in seconds, minutes, hours days just put dot key after TimeUnit, we can see all the options available.
Let me tell you one thing : <Always use explicit wait. Forget that implicit wait exists> --Naveen Khunteta
2. Explicit Wait
Explicit wait is of two types:
a) WebDriverWait (Class) :
b) FluentWait (Class)
Both are classes and implements Wait interface.
WebDriverWait class is an extension of FluentWait class. It doesn’t have its own methods.
- Explicit wait waits for a certain condition till specific element is not loaded.
- Its implementation is given by WebDriverWait Class in selenium with some expected conditions.
- This can be useful when certain elements on the webpage are not available immediately and need some time to load for e.g when you click on some submit button after you fill some registration form, then it takes some time in processing and displaying the data on UI.
- Selenium has its predefined conditions provided in ExpectedConditions class.
- Below is the syntax to define explicit wait and the expected conditions to be selected based on our needs:
So do I need to use Explicit Wait? Answer is YESSSS..
- documented and defined behaviour.
- runs in the local part of selenium (in the language of your code).
- works on any condition you can think of.
- returns either success or timeout error.
- can define absence of element as success condition.
- can customise delay between retries and exceptions to ignore.
Fluent Wait:
As per Official Selenium API Documentation, FluentWait is:
An implementation of the Wait
interface that may have its timeout and polling interval configured on the fly.
Each FluentWait instance defines the maximum amount of time to wait for a condition, as well as the frequency with which to check the condition. Furthermore, the user may configure the wait to ignore specific types of exceptions whilst waiting, such as NoSuchElementExceptions
when searching for an element on the page.
- FluentWait is used when we can define the maximum time to wait for a condition, It also defines the frequency with which WebDriver will check if the condition appears before throwing the “ElementNotVisibleException”.
- We can configure the wait to ignore specific types of exceptions while waiting, such as NoSuchElementException when searching for an element on the page.
- The fluent wait is a class and an implementation of Wait interface and also parent class of WebDriverWait.
- We can customise the below apply method to give any conditions based on our specifications.
Syntax:
Let’s below code snippet :
package com.example.automation;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.*;
import java.time.Duration;
import java.util.function.Function;
/**
* @author Mandeep Kaur
* @Date 2 May,2020
*/
public class SeleniumConfig {
public static void main(String[] args) {
String path = System.getProperty("user.dir");
System.setProperty("webdriver.chrome.silentOutput", "true");
System.setProperty("webdriver.chrome.driver", path + "/chromedriver");
WebDriver driver = new ChromeDriver();
driver.get("https://www.facebook.com/");
// Create object of WebDriverWait class
Wait wait = new FluentWait(driver)
//Wait for the condition
.withTimeout(Duration.ofSeconds(10))
//checking for its presenceonce every 5 seconds.
.pollingEvery(Duration.ofSeconds(5))
//Which will ignore the Exception
.ignoring(Exception.class);
WebElement element = wait.until(new Function<WebDriver, WebElement>() {
@Override
public WebElement apply(WebDriver driver) {
return driver.findElement(By.name("lastname"));
}
});
element.sendKeys("Martin");
}
}
Explanation:
To put it simply, Fluent Wait looks for a web element repeatedly at regular intervals until timeout happens or until the object is found.
- The above code defines time out value as 10 seconds and polling frequency as 5 seconds that means for every 5 seconds it keeps on checking for element.
- It directs WebDriver to wait for a maximum of 10 seconds to verify a specific condition. If the condition occurs during those 10 seconds, it will perform the next step in the test script. If not, it will throw an “ElementNotVisibleException”.
So when should I use FluentWait?
- When you do not see suitable expected wait condition in explicit wait.
- To handle dynamic AJAX web elements with polling mechansim
- You need to do more than just waiting along with Polling Mechanism, IgnoredException and when you want to create your own custom wait condition (in apply method) for non WebDriver use cases as well.
Ans: Yes, of course you can do that, as I have explained earlier WebDriverWait is child class of FluentWait, so it has access on all parent class public methods.
Refer this WebDriver API on GIT:
Final Conclusion:
a. Wait is an Interface in Selenium and having only one method declaration:
public interface Wait {
until(Function<? super F, T> isTrue);
}
b. FluentWait is a class which is implementing Wait Interface, it’s having its own methods shown above and overridden until() method from the wait Interface.
public class FluentWait implements Wait<T> { }
c. WebDriverWait is extending FluentWait class but has no methods init except one overridden method, that is: timeoutException(){}.
FluentWait can be used for both WebDriver and non WebDriver use cases. It just needs a condition – waitForCondition.
3. Concept of Thread.sleep()
- It is a static wait and execution of the scripts will be on hold till specified time configured in the function.
- Thread is a class in JAVA and sleep is static method.
- sleep() methods accept duration in milliseconds. ( 1 s= 1000 ms).
- It throws IllegalArgumentException – if the value of ms is negative.
- sleep() throws a checked exception which we must either throw or handle it using try catch like done below
- Syntax:
try{
Thread.sleep(5000);
}
catch(InterruptedException e){
}
Note: it’s never a good idea to use thread.sleep () as unlike dynamic waits it will wait for the entire time configured in the function till the element gets loaded.
4. PageLoadTimeOut & SetScriptTimeOut property
PageLoadTimeOut
- PageLoadTimeOut is focused on the time a webpage needs to be loaded – the page load timeout limits the time that the script allows for a web page to be displayed.
- If the page loads within the time, then the script continues. If the page does not load within the timeout the script will be stopped by a TimeoutException.
- The timeout is set at the driver level. After creating the driver instance with the appropriate driver capabilities.
- Syntax :
driver.manage().timeouts().pageLoadTimeout(2, TimeUnit.SECONDS);
SetScriptTimeOut
- From WebDriver documentation: setScriptTimeout(long time, java.util.concurrent.TimeUnit unit) sets the amount of time to wait for an asynchronous script to finish execution before throwing an error.
- This works only for Async scripts (executeAsyncScript: calls which takes some time to respond back)
- Syntax:
driver.manage().timeouts().setScriptTimeout(1, TimeUnit.SECONDS);
5. Conclusion:
In this article , we learnt about the various waits in selenium WebDriver.
Some References taken from:
- Official documentation (does not really explain the problematic other than warning from mixing implicit and explicit wait).
- Answer on a related question from Jim Evans. Jim Evans is a maintainer of selenium. Summary: don’t mix implicit and explicit wait.
- Two blog posts explaining implicit and explicit wait in great detail:
- Selected bugs about implicit and explicit wait in selenium:
- Code
Author: Mandeep Kaur
Mandeep, having 5+ years of Testing experience in automation using Selenium (Java). Expertise in API and Performance testing using JMeter.
https://www.linkedin.com/in/mandeepkaur93
Reviewer: Naveen Khunteta
https://www.linkedin.com/in/naveenkhunteta
I’ve been surfing online more than 4 hours today, yet I never found any interesting article like yours.
It’s pretty worth enough for me.