FluentWait Vs WebDriverWait in Selenium WebDriver

FluentWait Vs WebDriverWait” , A hot topic in Selenium WebDriver but still confuses many. Let’s see if I can help you to understand the difference between these two.

Class WebDriverWait is a disciplined child (Specialization) of Class FluentWait and grand child of interface Wait. In short, Class FluentWait implements Wait interface and WebDriverWait extends FluentWait.

So there are many things common in WebDriverWait and FluentWait instances such as :-

  1. You can set polling interval in both instances.
  2. You can ignore any exceptions in both instances.
  3. You can use ExpectedConditions methods in both instances.
  4. You can override apply() method in both instances.

This I have tried to explain in WebDriverWait & FluentWait in Selenium WebDriver – Let’s Deep Dive.

Are you thinking that If they are common then why WebDriverWait is given? We could have used FluentWait itself.

That is a valid doubt. But the major difference between them is that WebDriverWait is a specialization of FluentWait which uses WebDriver instance and this class have added specific mechanism related to WebDriver.

Do you believe in learning differences from example? Let’s try it.

I have created a basic html page where an element is visible after some time. I will implement both FluentWait and WebDriverWait to wait for element to be displayed. We can use Implicit wait as well but for this example, we will not consider that. Anyway implicit wait should be ignored because at many places in scripts we unknowingly mix waits which is not a good practice and can get unexpected result.

HTML Code :-


   
      
      
      
      
      
   
   
      Wait till link text is displayed here :- 
   

Selenium WebDriver code with FluentWait :-

package WaitExamples;

import java.time.Duration;
import java.util.Date;
import java.util.function.Function;

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

import io.github.bonigarcia.wdm.WebDriverManager;

public class WebDriverVsFluentWait1 {

	public static void main(String[] args) {

		// Browser initialization
		WebDriverManager.chromedriver().setup();
		WebDriver driver = new ChromeDriver();
		String fileURL = System.getProperty("user.dir");
		driver.get(fileURL + "/src/test/resources/htmlFiles/DynamicInnterText.html");

		// Setting FluentWait for list
		FluentWait wait = new FluentWait(driver)
				// Check for condition in every 2 seconds
				.pollingEvery(Duration.ofSeconds(2))
				// Till time out i.e. 30 seconds
				.withTimeout(Duration.ofSeconds(30));
		
		WebElement ele = wait.until(new Function() {
			@Override
			public WebElement apply(WebDriver driver) {
				System.out.println("Rechecking at time "+new Date());
				return driver.findElement(By.linkText("Here You Go...."));
			}
		});
		
		System.out.println("Condition satisfied and text is "+ ele.getText());
		driver.quit();
	}
}

Output :-

Rechecking at time Sun Apr 19 17:39:03 IST 2020
Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"link text","selector":"Here You Go…."} (Session info: chrome=80.0.3987.163)

Selenium WebDriver code with WebDriverWait :-

package WaitExamples;

import java.time.Duration;
import java.util.Date;
import java.util.function.Function;

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

import io.github.bonigarcia.wdm.WebDriverManager;

public class WebDriverVsFluentWait2 {

	public static void main(String[] args) {

		// Browser initialization
		WebDriverManager.chromedriver().setup();
		WebDriver driver = new ChromeDriver();
		String fileURL = System.getProperty("user.dir");
		driver.get(fileURL + "/src/test/resources/htmlFiles/DynamicInnterText.html");

		// Setting FluentWait for list
		WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
		// Check for condition in every 2 seconds and overriding default interval 500 MS
		wait.pollingEvery(Duration.ofSeconds(2));
		
		WebElement ele = wait.until(new Function() {
			@Override
			public WebElement apply(WebDriver driver) {
				System.out.println("Rechecking at time "+new Date());
				return driver.findElement(By.linkText("Here You Go...."));
			}
		});
		
		System.out.println("Condition satisfied and text is "+ ele.getText());
		driver.quit();
	}
}

Output :-

Rechecking at time Sun Apr 19 17:36:19 IST 2020
Rechecking at time Sun Apr 19 17:36:21 IST 2020
Rechecking at time Sun Apr 19 17:36:23 IST 2020
Rechecking at time Sun Apr 19 17:36:25 IST 2020
Rechecking at time Sun Apr 19 17:36:27 IST 2020
Rechecking at time Sun Apr 19 17:36:29 IST 2020
Rechecking at time Sun Apr 19 17:36:31 IST 2020
Rechecking at time Sun Apr 19 17:36:33 IST 2020
Rechecking at time Sun Apr 19 17:36:35 IST 2020
Rechecking at time Sun Apr 19 17:36:37 IST 2020
Rechecking at time Sun Apr 19 17:36:39 IST 2020
Condition satisfied and text is Here You Go….

Did you notice that when we used WebDriverWait, WebDriver waits for element to be present and does not throw NoSuchElementException which happened in FluentWait example ? You got it. That is a major difference between FluentWait and WebDriverWait.

FluentWait is a generic class and WebDriverWait is its specialization class with WebDriver instance. Since WebDriverWait is specialization class of FluentWait class, it ignores instances of NotFoundException that are encountered (thrown) by default in the ‘until’ condition, and immediately propagate all others.

  /**
   * @param driver the WebDriver instance to pass to the expected conditions
   * @param clock used when measuring the timeout
   * @param sleeper used to make the current thread go to sleep
   * @param timeout the timeout when an expectation is called
   * @param sleep the timeout used whilst sleeping
   */
  public WebDriverWait(
      WebDriver driver, Duration timeout, Duration sleep, Clock clock, Sleeper sleeper) {
    super(driver, clock, sleeper);
    withTimeout(timeout);
    pollingEvery(sleep);
    ignoring(NotFoundException.class);
    this.driver = driver;
  }

NotFoundException is a sub class of WebDriverException and NoAlertPresentExceptionNoSuchContextExceptionNoSuchCookieExceptionNoSuchElementExceptionNoSuchFrameExceptionNoSuchWindowException are direct sub classes of it. So in above example we already saw that WebDriverWait instance ignored NoSuchElementException. In fact it will ignore other mentioned exception by default which is not in case of FluentWait. If you need to ignore any exception in FluentWait instance, you need to mention it explicitly as below :-

package WaitExamples;

import java.time.Duration;
import java.util.Date;
import java.util.function.Function;

import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.FluentWait;
import io.github.bonigarcia.wdm.WebDriverManager;

public class WebDriverVsFluentWait3 {

	public static void main(String[] args) {

		// Browser initialization
		WebDriverManager.chromedriver().setup();
		WebDriver driver = new ChromeDriver();
		String fileURL = System.getProperty("user.dir");
		driver.get(fileURL + "/src/test/resources/htmlFiles/DynamicInnterText.html");

		// Setting FluentWait for list
		FluentWait wait = new FluentWait(driver)
				// Check for condition in every 2 seconds
				.pollingEvery(Duration.ofSeconds(2))
				// Till time out i.e. 30 seconds
				.withTimeout(Duration.ofSeconds(30))
				.ignoring(NoSuchElementException.class);

		WebElement ele = wait.until(new Function() {
			@Override
			public WebElement apply(WebDriver driver) {
				System.out.println("Rechecking at time " + new Date());
				return driver.findElement(By.linkText("Here You Go...."));
			}
		});

		System.out.println("Condition satisfied and text is " + ele.getText());
		driver.quit();
	}
}

Output will be same as WebDriverWait.

Some myths about FluentWait and WebDriverWait :-

  1. FluentWait allows to set polling interval while WebDriverWait does not. Fact – You can set in both after all WebDriverWait extends FluentWait and all configurable methods are public in FluentWait.
  2. We can not use conditions defined in class ExpectedConditions in FluentWait instance and override apply method in WebDriverWait instance. Fact – You can use any one in any instance.

WebDriverWait is a ready to use class for WebDriver. WebDriverWait can not be used for a non-selenium waiting condition while FluentWait can be used.

I have covered FluentWait in much details on my blog. You can find the details below:-

How to Fluent With FluentWait in Selenium WebDriver? – Part 1

How to Fluent With FluentWait in Selenium WebDriver? – Part 2

You can clone the above example from my repo.

If you have any doubt, feel free to comment below.
If you like my posts, please like, comment, share and subscribe.
#ThanksForReading
#HappyLearning

You can find all Selenium related post here.
You can find all API manual and automation related posts here.
You can find frequently asked Java Programs here.

1 thought on “FluentWait Vs WebDriverWait in Selenium WebDriver

Leave a Reply

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