Where we learn technology

Difference between ImplicitlyWait, ExplicitWait and FluentWait in Selenium WebDriver

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:

  1. 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.

Implicit Wait
 

So do I need to use Implicitly Wait? Answer is really NO..

Dis-advantages of Implicitly Wait:

  • undocumented and practically undefined behaviour.
  • runs in the remote part of selenium (the part controlling the browser).
  • only works on find element(s) methods.
  • returns either element found or (after timeout) not found.
  • if checking for absence of element must always wait until timeout.
  • cannot be customised other than global timeout.

This list is gathered from observations and reading bug reports and cursory reading of selenium source code.

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:

Expected Conditions

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 :

Code for Fluent Wait

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.
So can I use FluentWait features like, polling interval, ignoreAll with WebDriverWait? 
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:

https://github.com/SeleniumHQ/selenium/blob/master/java/client/src/org/openqa/selenium/support/ui/FluentWait.java

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(){}.

WebDriverWait can use all the methods of FluentWait class – pollingEvery(), withMessage(), ignoreAll etc..

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:

 
Blog Contributors:
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
Please follow and like us:

1 Comment

  1. Bisnis Sampingan

    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.

Leave a Reply

Your email address will not be published. Required fields are marked *