Fluent Wait in Selenium sets the maximum time for WebDriver to wait for a web element to become visible. It determines the frequency of checks before handling 'ElementNotVisibleException,' enhancing effective automation script execution.
In this blog, we will learn about the fluent wait in selenium. We will learn its step-by-step process to use fluent wait in selenium.
What are Wait commands in Selenium?
Wait commands in Selenium pause test execution until certain conditions are met, ensuring that web elements are loaded or become interactable before actions are performed. There are three primary types:
Implicit Wait: Automatically applies to all elements in a test, providing a default waiting time (if specified) before throwing an exception if the component is not found.
Explicit Wait: Applies only to specified elements with specific conditions, such as an element becoming visible or clickable.
Fluent Wait: Allows for more complex conditions, specifying the maximum time to wait for a condition and the frequency with which to check the condition. It also allows ignoring specific types of exceptions while waiting.
Why do Users Need Selenium to Wait for Commands?
Users need Selenium's wait commands to ensure that web elements are fully loaded and interactable before automation scripts attempt to interact with them. Since web pages often load content dynamically, elements might not be immediately available. Without waits, Selenium might try to interact with elements that haven't yet appeared, leading to errors in the automation script. These wait commands help avoid such issues, making scripts more reliable and reducing the likelihood of false negatives in automated testing scenarios.
The Necessity of Wait Commands
Selenium waits are necessary to ensure that web elements are interactable before performing any operations on them. Without waits, tests may attempt to interact with elements that haven't yet loaded, leading to errors and failed test cases.
Implement Waits in Tests with Selenium WebDriver
Implicit Wait
Implicit Wait sets a default waiting time throughout the WebDriver instance, which is applied if the element is not immediately available.
Explicit Wait
Explicit Wait allows you to wait for a specific condition to be met before proceeding. It's more precise than Implicit Wait and is used when certain conditions need to be met.
Fluent Wait
Fluent Wait is a type of Explicit Wait that provides additional configuration options. It's particularly useful when you need to poll for a condition at regular intervals and want to ignore certain types of exceptions during the waiting period.
Fluent Wait in Selenium
Step-by-Step Explanation of Fluent Wait
Here's a step-by-step breakdown of how to set up and use Fluent Wait in a Selenium script:
Initialization of Fluent Wait:
FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofSeconds(5))
.ignoring(NoSuchElementException.class);
FluentWait<WebDriver>: This initializes a new Fluent Wait object for the WebDriver.
.withTimeout(Duration.ofSeconds(30)): Sets the maximum time to wait for the condition to 30 seconds.
.pollingEvery(Duration.ofSeconds(5)): Configures the wait to check the condition every 5 seconds.
.ignoring(NoSuchElementException.class): Instructs Fluent Wait to ignore NoSuchElementException during the polling period.
wait.until(...): Tells Fluent Wait to start waiting for the given condition.
ExpectedConditions.elementToBeClickable(...): The condition we're waiting for is for an element to be clickable.
By.id("submit-button"): The element we're waiting on is identified by its ID, "submit-button".
.click(): Once the element is clickable, this method clicks it.
A Working Example of Fluent Wait
Let's create a more detailed example that includes a scenario where Fluent Wait is particularly useful:
// Initialize WebDriver and navigate to the desired URL
WebDriver driver = new ChromeDriver();
driver.get("http://example.com/wait-for-this-element");
// Define Fluent Wait with a 30-second timeout and 5-second polling interval
FluentWait<WebDriver> fluentWait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofSeconds(5))
.ignoring(NoSuchElementException.class);
// Use Fluent Wait to wait for an element with ID 'dynamic-element' to be visible
WebElement dynamicElement = fluentWait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.id("dynamic-element"));
}
});
// Perform actions on the element after it's found
dynamicElement.click();
In this example, we're waiting for an element with the ID dynamic-element to become visible. This element might be loaded dynamically via JavaScript after performing some actions on the page. Fluent Wait checks every 5 seconds to see if the element has appeared, and once it's visible, it clicks on the element.
Differential Features Of Fluent Wait
Fluent Wait in Selenium stands out due to its flexibility and configurability. Here are some of its distinguishing features:
Customizable Polling Frequency
Unlike Implicit Wait, which checks for the presence of an element at fixed intervals, Fluent Wait allows you to define the frequency of polling. This means you can set it to check for the condition every few milliseconds, seconds, or any duration that suits your test.
Ignoring Specific Exceptions
Fluent Wait can be configured to ignore one or more exceptions that you expect to occur during the waiting period. Commonly ignored exceptions include NoSuchElementException and ElementNotVisibleException. This feature prevents your test from failing while waiting for an element to appear or become clickable.
Custom Timeout and Exception Message
You can specify a timeout for Fluent Wait and customize the exception message to be thrown if the timeout is exceeded without the condition being met. This helps in debugging, as the message can provide insights into what went wrong.
Use of Functional Interfaces
Fluent Wait uses functional interfaces, which means you can pass a lambda expression or an anonymous class that defines the condition to wait for. This provides a lot of flexibility in terms of what conditions you can wait for.
Integration with ExpectedConditions
Fluent Wait can be used with the ExpectedConditions utility class provided by Selenium, which offers a variety of pre-defined conditions such as element visibility, clickability, presence of elements, etc.
Example: Differential Features in Action
Here's an example that showcases some of the differential features of Fluent Wait:
WebDriver driver = new ChromeDriver();
driver.get("http://example.com/dynamic-content");
FluentWait<WebDriver> fluentWait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(45))
.pollingEvery(Duration.ofSeconds(5))
.ignoring(NoSuchElementException.class)
.withMessage("Element to be clickable not found within the time frame.");
WebElement dynamicButton = fluentWait.until(driver -> {
WebElement button = driver.findElement(By.id("dynamic-button"));
if (button.isEnabled()) {
return button;
} else {
return null;
}
});
dynamicButton.click();
In this script:
We've set a timeout of 45 seconds to wait for a dynamic button to become clickable.
The polling frequency is every 5 seconds.
We're ignoring NoSuchElementException during the wait.
A custom message is provided for better debugging in case of a timeout.
We're using a lambda expression to define our wait condition, checking if the button is enabled before returning it.
Frequently Asked Questions
How does Fluent Wait handle AJAX elements?
Fluent Wait is ideal for AJAX elements as it can be configured to poll the DOM at regular intervals, waiting for the element to be loaded dynamically.
Can Fluent Wait be used for non-visible elements?
Yes, Fluent Wait can wait for various conditions, including the presence of elements in the DOM that are not necessarily visible.
Is Fluent Wait affected by the performance of the application under test?
Fluent Wait is designed to handle variations in application performance, as it polls for the condition and can ignore intermittent exceptions.
Conclusion
Fluent Wait in Selenium is a powerful synchronization mechanism that provides granular control over how your tests wait for conditions to be met. By using Fluent Wait, you can create more reliable and robust automated tests that can handle the unpredictable load times of web elements.