If you have been testing with Selenium for a while, you know how frustrating timing failures can be. A test tries to click a button before it becomes active, or it looks for an element a second before the page adds it. You rerun the same test and it passes without any code changes.
Fixed delays may seem like an easy fix, but they make tests slower and still do not guarantee that the element will be ready. Fluent Wait gives you more control. You can set how long Selenium should wait, how often it should check the condition, and which temporary exceptions it should ignore during that time.
When used correctly, Fluent Wait helps you deal with elements whose loading time is difficult to predict without making every test wait longer than necessary.
What are Wait Commands in Selenium?
When working with web applications, elements don’t always load or become ready immediately. Wait commands in Selenium are designed to handle these delays by pausing the execution of a script until the conditions required for interacting with an element are met.
Selenium offers three main types of wait commands: Implicit Wait, Explicit Wait, and Fluent Wait. Each serves a specific purpose, helping to make automation scripts more robust and reliable.
1. Implicit Waits
Implicit waits establish a default waiting period for the entire session. Whenever Selenium tries to find an element, it waits for the specified duration before throwing a NoSuchElementException. This is a simple way to handle delays without needing to specify conditions repeatedly.
Syntax Example (Java):
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
- Best for: Handling basic, consistent delays across all elements.
- Limitation: Not suitable for scenarios where conditions need to be specified.
2. Explicit Waits
Explicit waits are more precise. They allow for defining specific conditions for individual elements. Selenium will pause until these conditions are met or the maximum time limit is reached.
Example Conditions: Element visibility, clickability, or specific text presence.
Syntax Example (Java):
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("example")));- Best for: Scenarios requiring targeted waiting logic for certain elements.
- Limitation: It can lead to complex code if overused.
3. Fluent Waits
Fluent waits build on the concept of explicit waits, offering more customization. They allow setting the polling interval, ignoring specific exceptions, and defining timeout durations.
Key Features:
- Polls for conditions at regular intervals instead of checking continuously.
- It can be configured to handle exceptions like NoSuchElementException.
Syntax Example (Java):
Wait<WebDriver> wait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofSeconds(5))
.ignoring(NoSuchElementException.class);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("example")));- Best for: Dynamic applications with irregular or unpredictable delays.
What is Fluent Wait in Selenium?
Fluent Wait is a specialized waiting mechanism in Selenium that offers more flexibility and control over how scripts handle delays.
Unlike implicit or explicit waits, Fluent Wait allows customization of the polling interval and the exceptions to ignore during the waiting period. This makes it ideal for scenarios where conditions are unpredictable, or elements take varying amounts of time to appear or become actionable.
Key Features of Fluent Wait:
- Custom Polling: Checks for conditions at defined intervals rather than continuously.
- Exception Handling: Allows ignoring specific exceptions, such as NoSuchElementException, during the wait period.
- Timeout Configuration: Provides precise control over the maximum time to wait for a condition to be met.
Fluent Wait is particularly useful in dynamic web applications, where elements might load inconsistently due to network delays or complex JavaScript execution.
Syntax of Fluent Wait in Selenium
Here is the standard syntax for Fluent Wait in Selenium using Java:
Wait<WebDriver> wait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(30)) // Maximum wait time
.pollingEvery(Duration.ofSeconds(5)) // Interval between condition checks
.ignoring(NoSuchElementException.class); // Exceptions to ignore
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("example")));Explanation of the Code:
- withTimeout(Duration.ofSeconds(30)): Specifies the total duration Selenium will wait for the condition to be fulfilled.
- pollingEvery(Duration.ofSeconds(5)): Specifies the interval at which Selenium will check the condition.
- ignoring(NoSuchElementException.class): Ensures that the script continues to wait even if the element is not found during polling.
- until(ExpectedConditions.visibilityOfElementLocated(…): Defines the condition to wait for,in this case, the visibility of a specific element.
This structure provides the flexibility needed to handle unpredictable delays and ensures reliable test execution, even under challenging conditions.
Why are Fluent Wait Commands Important in Selenium?
The main value of Fluent Wait is not that it makes Selenium wait longer. It lets you control what Selenium should retry and what must be true before the test moves on.
That matters when the page changes after the initial load. In such cases, the first failed check may be expected rather than a real test failure.
Fluent Wait is useful when:
- An element is added after an API response: NoSuchElementException may occur during the first few checks while the page is still rendering the result.
- A button changes state before it can be clicked: Finding the button is not enough if it remains disabled until validation or background processing finishes.
- The DOM is re-rendered: Frameworks such as React may replace an existing element with a new one. Your wait condition may need to locate the element again instead of reusing an old reference.
- Test environments respond at different speeds: The same request may finish quickly on a local machine but take longer in a shared test environment.
Read more: Understanding Selenium Timeouts
Key Components of Fluent Wait
Fluent Wait is made up of a few essential components that work together to provide precise control over how Selenium waits for conditions to be met:
1. Timeout Duration:
This is the maximum time Selenium will wait for an element to meet the specified condition before throwing an error.
.withTimeout(Duration.ofSeconds(30)); // Sets a 30-second max wait
2. Polling Interval:
This defines how often Selenium checks if the condition has been met during the wait period. Instead of constantly checking, Selenium waits for the specified interval (for example, every 5 seconds).
.pollingEvery(Duration.ofSeconds(5)); // Checks every 5 seconds
3. Ignored Exceptions:
Fluent Wait allows ignoring certain exceptions while waiting. For example, you might want to skip NoSuchElementException during the wait so that Selenium can keep checking without stopping.
.ignoring(NoSuchElementException.class); // Ignores specific exceptions
4. Condition to Wait For:
The most important part is the conditions that must be met before the wait to finish. This could be an element becoming visible, clickable, or any other state you define.
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("example"))); // Wait until the element is visibleThese four components give you fine control over how and when Selenium waits, making Fluent Wait an ideal choice for handling dynamic elements that don’t follow a fixed loading pattern.
Key Features of Fluent Wait in Selenium
Fluent Wait provides more control over how Selenium handles waiting for conditions compared to standard wait mechanisms.
Its main features include:
- Custom polling interval: You can choose how often Selenium checks the condition. A shorter interval gives the test more chances to detect a quick state change, while a longer interval avoids repeated checks for slower operations.
- Selective exception handling: You can ignore exceptions that are expected during the wait. For example, NoSuchElementException may be safe to ignore while an element is still being added to the DOM. Exceptions that point to a real test problem should not be ignored.
- Support for custom conditions: Fluent Wait is not limited to built-in ExpectedConditions. You can wait for application-specific states, such as a status changing to “Completed,” a table reaching a required row count, or a loading indicator disappearing.
- Early completion: The timeout is only the maximum waiting period. Selenium continues as soon as the condition returns a valid result, so a 30-second wait does not automatically pause the test for 30 seconds.
- Flexible wait targets: FluentWait<T> can work with types other than WebDriver. Although WebDriver is the common choice, the generic design allows you to build reusable waits around other objects when your test framework requires it.
How Fluent Wait Works?
Fluent Wait works by asking Selenium to check the same condition again and again for a limited time.
Suppose your test is waiting for a Submit button to become clickable. You set:
- A timeout of 20 seconds
- A polling interval of 2 seconds
- An exception to ignore while waiting
Selenium then follows this process:
- It checks whether the button is clickable.
- If the button is ready, the wait ends and the test continues.
- If the button is not ready, Selenium waits for 2 seconds.
- It checks the button again.
- This continues until the button becomes clickable or 20 seconds pass.
The test does not always wait for the full 20 seconds. If the button becomes clickable after 6 seconds, Selenium moves to the next command at that point.
Some checks may throw temporary exceptions. For example, Selenium may get a NoSuchElementException because the button has not been added to the page yet. When you configure Fluent Wait to ignore that exception, Selenium does not fail immediately. It waits for the next polling interval and tries again.
If the condition is still not met when the timeout ends, Fluent Wait throws a TimeoutException. This tells you that Selenium kept checking, but the expected state did not appear within the allowed time.
How to implement Fluent Wait in Selenium (Code Examples)?
Fluent Wait in Selenium allows you to define custom waiting behavior for dynamic web elements. Below are code examples showing how to implement Fluent Wait using Selenium with Java in different scenarios.
Example 1: Waiting for an Element to Become Visible: This example waits for a web element to become visible on the page:
// Import required classes
import org.openqa.selenium.*;
import org.openqa.selenium.support.ui.*;
import java.time.Duration;
Wait<WebDriver> fluentWait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(30)) // Maximum wait time
.pollingEvery(Duration.ofSeconds(5)) // Check every 5 seconds
.ignoring(NoSuchElementException.class); // Ignore "No Such Element" errors
WebElement element = fluentWait.until(ExpectedConditions.visibilityOfElementLocated(By.id("example")));
System.out.println("Element is visible: " + element.getText());Example 2: Waiting for an Element to Be Clickable: This example waits for a button to become clickable before attempting to click it:
Wait<WebDriver> fluentWait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(20)) // Wait up to 20 seconds
.pollingEvery(Duration.ofSeconds(2)) // Poll every 2 seconds
.ignoring(ElementNotInteractableException.class); // Ignore interactable errors
WebElement button = fluentWait.until(ExpectedConditions.elementToBeClickable(By.id("submitButton")));
button.click();Example 3: How to Use Fluent Wait with Custom Conditions: Sometimes, you may need to define a custom condition that ExpectedConditions don’t provide. Here’s how to create one:
Wait<WebDriver> fluentWait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(25))
.pollingEvery(Duration.ofSeconds(3))
.ignoring(NoSuchElementException.class);
WebElement customElement = fluentWait.until(driver -> {
WebElement element = driver.findElement(By.id("customElement"));
return element.isDisplayed() && element.getText().contains("Ready") ? element : null;
});
System.out.println("Custom element is ready: " + customElement.getText());Example 4: Handling Nested Elements: Fluent Wait can also handle elements inside frames or iframes:
driver.switchTo().frame("frameName");
Wait<WebDriver> fluentWait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofSeconds(4))
.ignoring(NoSuchElementException.class);
WebElement nestedElement = fluentWait.until(ExpectedConditions.presenceOfElementLocated(By.id("nestedElement")));
System.out.println("Nested element found: " + nestedElement.getAttribute("value"));
driver.switchTo().defaultContent(); // Switch back to the main pageBest Practices for using Fluent Wait in Selenium
Fluent Wait works well when you know which temporary state you are waiting through. If you add it after every failed element lookup, you may only hide a weak locator, a slow backend request, or an application bug.
The following practices help you use it without making failures harder to understand.
1. Wait for the state required by the next action
Do not wait for an element to be present when the next command needs it to be clickable. Presence only confirms that the element exists in the DOM. It may still be hidden, disabled, or covered by another element.
Match the condition to what the test does next:
- Use visibility before reading text or checking displayed content.
- Use clickability before clicking a button or link.
- Wait for invisibility when a loader or overlay blocks the page.
- Use a custom condition when the application has a specific ready state.
A wait is only useful when its condition proves that the next command can run.
2. Find the element again during each poll
Avoid locating a dynamic element before the wait and then reusing the same WebElement reference.
WebElement status = driver.findElement(By.id("status"));
wait.until(driver -> status.getText().equals("Completed"));If the page re-renders the element, the stored reference may become stale. Locate it inside the condition instead:
wait.until(driver ->
driver.findElement(By.id("status"))
.getText()
.equals("Completed")
);Each poll now checks the current element in the DOM rather than an older reference.
3. Ignore only exceptions that are expected
Fluent Wait can continue polling after certain exceptions, but that does not mean every exception should be ignored.
Ignoring NoSuchElementException makes sense when the element is expected to appear later. Ignoring unrelated exceptions can hide a broken locator, an incorrect frame, or invalid test logic until the timeout expires.
Be especially careful with StaleElementReferenceException. Ignoring it without locating the element again usually causes Selenium to repeat the same failing action.
4. Keep polling intervals realistic
A very short polling interval does not automatically make the test better. Checking every few milliseconds may repeatedly query the browser for a state that changes only after a network request or page update.
At the same time, a long interval can make the test slower than necessary. An element that becomes ready just after a check must wait until the next poll.
Choose the interval based on the behaviour you are waiting for. Interface changes may need frequent checks. Long-running background operations can use a wider interval.
5. Avoid combining Fluent Wait with a large implicit wait
An implicit wait also affects findElement() calls made inside the Fluent Wait condition. If the implicit wait is set to 10 seconds, one polling attempt may spend up to 10 seconds looking for the element before Fluent Wait can try again.
This can make the real wait time much longer than the timeout suggests.
Keep the implicit wait low or disabled when your test suite relies on condition-based waits. It makes polling and timeout behaviour easier to predict.
Read More: Best Practices for Selenium Test Automation
Conclusion
Fluent Wait is useful when your Selenium test needs to deal with an element that does not reach the required state at a predictable time. Instead of pausing the test for a fixed duration, you can keep checking the right condition and continue as soon as it is met.
The result still depends on how you configure the wait. Choose a condition that matches the next action, use a sensible polling interval, and ignore only the exceptions you expect during that wait. Done properly, Fluent Wait reduces timing failures without hiding real application or test issues.