Learn Selenium Wait Commands: Implicit, Explicit and Fluent Waits

1. Introduction to Selenium Wait Commands

Selenium Wait Commands are an essential aspect of automated testing with Selenium WebDriver. They allow us to synchronize our test scripts with the application under test, ensuring that the desired elements are present and in the expected state before performing actions on them. Waiting for elements or conditions to be met is crucial for reliable and stable test execution.


Table of Contents:

Introduction to Selenium Wait Commands 1.1 Why are Wait Commands Important? 1.2 Types of Wait Commands in Selenium Implicit Wait 2.1 How Implicit Wait Works 2.2 Setting Implicit Wait in Selenium Explicit Wait 3.1 What is Explicit Wait? 3.2 Conditions for Explicit Wait 3.3 Using Expected Conditions in Explicit Wait 3.4 Examples of Explicit Wait Fluent Wait 4.1 What is Fluent Wait? 4.2 Customizing Fluent Wait Conditions 4.3 Examples of Fluent Wait Thread.sleep() vs. Selenium Wait Commands 5.1 Differences between Thread.sleep() and Selenium Wait Commands 5.2 When to Use Thread.sleep() and When to Use Selenium Wait Commands Best Practices for Using Selenium Wait Commands 6.1 Avoid Using Hardcoded Wait Times 6.2 Combine Different Types of Wait Commands 6.3 Handle Timeout Exceptions Properly Conclusion


1.1 Why are Wait Commands Important?

Wait commands are important in Selenium automation testing for the following reasons:

  • Synchronization: Web applications may have dynamic content or elements that load asynchronously. Without proper synchronization, there is a risk of interacting with elements that are not yet available, resulting in test failures. Wait commands help us synchronize our test scripts with the application, ensuring that elements are ready before interacting with them.
  • Stability and Reliability: By incorporating wait commands, we can avoid race conditions and timing issues in our tests. Waiting for elements to be visible, clickable, or in a specific state improves the stability and reliability of our test scripts, making them less prone to false positives or false negatives.
  • Improved Test Performance: Wait commands allow us to optimize test performance by reducing unnecessary waiting time. Instead of using static waits, wait commands dynamically wait only as long as necessary, making our tests more efficient.

1.2 Types of Wait Commands in Selenium

Selenium provides different types of wait commands to handle various synchronization scenarios. The commonly used types of wait commands are:

1. Implicit Wait:

Implicit Wait is a global wait that sets a maximum time limit for the WebDriver to wait for an element to be present or visible. It is set once and applies to all subsequent commands. If an element is not immediately available, WebDriver waits for the specified time before throwing an exception.

2. Explicit Wait:

Explicit Wait is a more precise and granular way of waiting for specific conditions to be met before proceeding with the test execution. It allows us to define the maximum time to wait and the condition that needs to be satisfied. It waits until the condition is met or the timeout is reached, whichever occurs first.

3. Fluent Wait:

Fluent Wait is an advanced form of explicit wait that provides more flexibility in defining custom conditions and polling intervals. It allows us to define the maximum time to wait, the frequency of polling, and the conditions for waiting.

Each type of wait command has its own advantages and use cases. Understanding when and how to use them appropriately is crucial for effective test automation.

2. Implicit Wait

2.1 How Implicit Wait Works

Implicit Wait is a global wait that sets a maximum time limit for the WebDriver to wait for an element to be present or visible. It is set once and applies to all subsequent commands. If an element is not immediately available, WebDriver waits for the specified time before throwing an exception.

Implicit Wait operates in the background, silently waiting for elements to appear. It ensures that each WebDriver command is given enough time to execute before timing out. This wait is applied to all elements or actions, irrespective of whether explicit waits are used or not.

When the WebDriver tries to locate an element using a selector (e.g., by ID, class name, XPath, etc.), if the element is not immediately found, WebDriver waits for the implicit wait time before throwing a NoSuchElementException. If the element is found within the specified time, WebDriver proceeds with the command.

Implicit Wait is useful for handling scenarios where elements may take some time to load or appear on the page, providing a default wait time for all elements.

2.2 Setting Implicit Wait in Selenium

To set the implicit wait in Selenium, you need to instantiate the WebDriver and set the wait time using the implicitly_wait() method. The wait time is specified in seconds.

Here's an example of how to set the implicit wait in Selenium WebDriver using different programming languages:

Java:

java
import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class ImplicitWaitExample { public static void main(String[] args) { // Set the system property for ChromeDriver System.setProperty("webdriver.chrome.driver", "path/to/chromedriver"); // Instantiate ChromeDriver WebDriver driver = new ChromeDriver(); // Set the implicit wait time to 10 seconds driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); // Rest of your test script // ... // Quit the driver driver.quit(); } }

Python:

python
from selenium import webdriver # Set the path to chromedriver chromedriver_path = 'path/to/chromedriver' # Instantiate ChromeDriver driver = webdriver.Chrome(executable_path=chromedriver_path) # Set the implicit wait time to 10 seconds driver.implicitly_wait(10) # Rest of your test script # ... # Quit the driver driver.quit()

C#:

csharp
using OpenQA.Selenium; using OpenQA.Selenium.Chrome; class ImplicitWaitExample { static void Main() { // Set the path to chromedriver string chromedriverPath = "path/to/chromedriver"; // Instantiate ChromeDriver IWebDriver driver = new ChromeDriver(chromedriverPath); // Set the implicit wait time to 10 seconds driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10); // Rest of your test script // ... // Quit the driver driver.Quit(); } }

By setting the implicit wait time, WebDriver will wait for the specified duration before throwing a NoSuchElementException if an element is not found. If the element is found within the specified time, WebDriver proceeds with the subsequent commands.

3. Explicit Wait

3.1 What is Explicit Wait?

Explicit Wait is a type of wait in Selenium that allows you to wait for a specific condition to be met before proceeding with the execution of further commands. It gives you more control over waiting for elements or conditions on a web page.

Unlike Implicit Wait, which sets a global wait time for all elements, Explicit Wait is applied only to specific elements or conditions. It provides a more fine-grained approach to waiting, enabling you to wait for specific elements to be clickable, visible, or have certain attributes/values before proceeding with the test.

Explicit Wait is useful when you want to wait for certain conditions to be satisfied before performing actions on the web page. It helps make your tests more robust and reliable by ensuring that elements are ready and accessible before interacting with them.

3.2 Conditions for Explicit Wait

In Explicit Wait, you can define various conditions that WebDriver should wait for before continuing with the execution of commands. These conditions are defined using the ExpectedConditions class, which provides a set of pre-defined conditions you can use.

Syntax:
// Explicit Wait
 WebDriverWait wait = new WebDriverWait(driver, 10); 
 wait.until(ExpectedConditions.alertIsPresent());

3.2.1. All Conditions that Can be Used in Explicit Wait:

  • elementToBeClickable(By locator): Waits for the element specified by the locator to be clickable.
  • elementSelectionStateToBe(By locator, boolean selected): Waits for the element specified by the locator to have the specified selection state (selected or not selected).
  • presenceOfElementLocated(By locator): Waits for the presence of the element specified by the locator.
  • visibilityOfElementLocated(By locator): Waits for the element specified by the locator to be visible.
  • textToBePresentInElementLocated(By locator, String text): Waits for the element specified by the locator to contain the given text.
  • textToBePresentInElementValue(By locator, String text): Waits for the element specified by the locator to have the given text in its value attribute.
  • titleContains(String title): Waits for the page title to contain the given text.
  • titles (String title): Waits for the page title to be the given title.
  • frameToBeAvailableAndSwitchToIt(By locator): Waits for the frame specified by the locator to be available and switches to it.
  • invisibilityOfElementLocated(By locator): Waits for the element specified by the locator to be invisible.
  • elementToBeSelected(By locator): Waits for the element specified by the locator to be selected.
  • numberOfWindowsToBe(int number): Waits for the number of windows to be the specified number.
  • attributeContains(By locator, String attribute, String value): Waits for the element specified by the locator to have the attribute containing the specified value.
  • stalenessOf(WebElement element): Waits for the element to become stale (no longer attached to the DOM).
  • elementToBeSelected(WebElement element): Waits for the element to be selected.
  • elementToBeClickable(WebElement element): Waits for the element to be clickable.
  • visibilityOf(WebElement element): Waits for the element to be visible.

3.3 Using Expected Conditions in Explicit Wait

To use Expected Conditions in Explicit Wait, you need to create an instance of WebDriverWait and specify the wait time and the expected condition. Once the condition is met or the maximum wait time is reached, WebDriver proceeds with the execution of further commands.

Here's an example of using Expected Conditions in Explicit Wait:

Java:

java
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.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; public class ExplicitWaitExample { public static void main(String[] args) { // Set the system property for ChromeDriver System.setProperty("webdriver.chrome.driver", "path/to/chromedriver"); // Instantiate ChromeDriver WebDriver driver = new ChromeDriver(); // Navigate to the web page driver.get("https://www.example.com"); // Create WebDriverWait instance with a wait time of 10 seconds WebDriverWait wait = new WebDriverWait(driver, 10); // Wait for the element with ID "myElement" to be clickable WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("myElement"))); // Perform actions on the element element.click(); // Rest of your test script // ... // Quit the driver driver.quit(); } }

Python:

python
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # Set the path to chromedriver chromedriver_path = 'path/to/chromedriver' # Instantiate ChromeDriver driver = webdriver.Chrome(executable_path=chromedriver_path) # Navigate to the web page driver.get("https://www.example.com") # Create WebDriverWait instance with a wait time of 10 seconds wait = WebDriverWait(driver, 10) # Wait for the element with ID "myElement" to be clickable element = wait.until(EC.element_to_be_clickable((By.ID, "myElement"))) # Perform actions on the element element.click() # Rest of your test script # ... # Quit the driver driver.quit()

C#:

csharp
using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Support.UI; class ExplicitWaitExample { static void Main() { // Set the path to chromedriver string chromedriverPath = "path/to/chromedriver"; // Instantiate ChromeDriver IWebDriver driver = new ChromeDriver(chromedriverPath); // Navigate to the web page driver.Navigate().GoToUrl("https://www.example.com"); // Create WebDriverWait instance with a wait time of 10 seconds WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); // Wait for the element with ID "myElement" to be clickable IWebElement element = wait.Until(ExpectedConditions.ElementToBeClickable(By.Id("myElement"))); // Perform actions on the element element.Click(); // Rest of your test script // ... // Quit the driver driver.Quit(); } }

In the above examples, we first navigate to a web page and then create an instance of WebDriverWait with a specified wait time. We use the until() method along with the desired condition from ExpectedConditions to wait for the element to satisfy the condition.

Once the condition is met or the maximum wait time is reached, WebDriver proceeds with the execution of further commands.


3.4 Examples of Explicit Wait

Let's consider a couple of examples to illustrate the usage of Explicit Wait:

Example 1: Wait for an Element to be Visible

java
WebDriverWait wait = new WebDriverWait(driver, 10); WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("myElement")));

In this example, we wait for the element with ID "myElement" to be visible on the page before proceeding.

Example 2: Wait for Page Title to be a Specific Value

java
WebDriverWait wait = new WebDriverWait(driver, 10); wait.until(ExpectedConditions.titleIs("My Page Title"));

In this example, we wait for the page title to be "My Page Title" before continuing with the execution.

These examples demonstrate how Explicit Wait can be used to wait for specific conditions to be met, providing more control and reliability to your tests.


4. Fluent Wait

4.1 What is Fluent Wait?

Fluent Wait is an advanced form of Explicit Wait in Selenium that allows for more customized and flexible waiting strategies. It provides a way to define the polling interval and the conditions to wait for during test execution. With Fluent Wait, you can create more complex wait conditions by combining multiple Expected Conditions.

Fluent Wait provides the ability to define the maximum amount of time to wait for a specific condition, as well as the frequency at which Selenium should check for the condition. This flexibility makes it a powerful tool for handling dynamic web elements and situations where fixed wait times may not be suitable.

Syntax:

// Fluent Wait
 Wait wait = new FluentWait(WebDriver reference)
   .withTimeout(timeout, SECONDS)
   .pollingEvery(timeout, SECONDS)
   .ignoring(Exception.class);

 WebElement foo = wait.until(new Function() {
  public WebElement applyy(WebDriver driver) {
   return driver.findElement(By.id("foo"));
  }
 });

4.2 Customizing Fluent Wait Conditions

To customize Fluent Wait conditions, you need to use the FluentWait class and its associated methods. Here are the key steps to customize Fluent Wait conditions:

Step 1: Create an instance of the FluentWait class by passing the WebDriver and the timeout duration as parameters.

java
Wait<WebDriver> wait = new FluentWait<>(driver) .withTimeout(Duration.ofSeconds(30)) .pollingEvery(Duration.ofSeconds(5)) .ignoring(NoSuchElementException.class);

Step 2: Define the conditions using the until() method of the FluentWait class. You can use the Expected Conditions provided by Selenium or create your custom conditions.

java
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("myElement")));

In the above example, the condition waits for the element with the specified ID to be visible. You can customize the condition based on your requirements using various methods from the ExpectedConditions class.

Step 3: Handle any exceptions that may occur during the wait. In the example above, NoSuchElementException is ignored, which means that if the element is not found, the wait will continue until the timeout is reached.


4.3 Examples of Fluent Wait

Here are a few examples of using Fluent Wait in Selenium:

Example 1: Waiting for an element to be clickable:

java
Wait<WebDriver> wait = new FluentWait<>(driver) .withTimeout(Duration.ofSeconds(30)) .pollingEvery(Duration.ofSeconds(5)) .ignoring(NoSuchElementException.class); WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("myElement")));

Example 2: Waiting for an element's text to contain specific content:

java
Wait<WebDriver> wait = new FluentWait<>(driver) .withTimeout(Duration.ofSeconds(30)) .pollingEvery(Duration.ofSeconds(5)) .ignoring(NoSuchElementException.class); boolean textContains = wait.until(ExpectedConditions.textToBePresentInElementLocated(By.id("myElement"), "expected text"));

Example 3: Waiting for an element to disappear:

java
Wait<WebDriver> wait = new FluentWait<>(driver) .withTimeout(Duration.ofSeconds(30)) .pollingEvery(Duration.ofSeconds(5)) .ignoring(NoSuchElementException.class); boolean elementNotVisible = wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("myElement")));

These examples demonstrate how to use Fluent Wait with different conditions. By customizing the Fluent Wait conditions, you can handle various dynamic scenarios and make your test scripts more reliable.

Fluent Wait offers great flexibility in defining the wait conditions, timeouts, and polling intervals, enabling you to create powerful and adaptable test scripts.


5. Thread.sleep() vs. Selenium Wait Commands

5.1. Differences between Thread.sleep() and Selenium Wait Commands

Thread.sleep()Selenium Wait Commands
PurposePause the execution of the current thread for a fixed duration.Wait for specific conditions or events before proceeding with the test execution.
ConsiderationDoes not consider the state of the web application or any specific conditions.Considers the state of the web application and waits until the desired condition is satisfied.
DelayStatic delay - pauses the execution for a fixed amount of time.Dynamic delay - waits until the desired condition is met.
PrecisionLess precise - introduces a fixed delay regardless of whether the condition is met or not.More precise - waits until the desired condition is met before proceeding.
Test ReliabilityLess reliable - may introduce unnecessary delays or fail to wait for the desired condition.More reliable - reduces the risk of false positives or negatives and improves test scripts' efficiency.
Test EfficiencyLess efficient - can lead to longer test execution times due to fixed delays.More efficient - eliminates unnecessary delays and optimizes test scripts' execution.
Web Application DynamicsNot adaptable to changes in the web application or element availability.Adaptable to dynamic web applications where element availability or timing may vary.
Code ReadabilityMay make the code less readable due to arbitrary sleep durations.Improves code readability by explicitly waiting for specific conditions.
Best PracticesGenerally recommended to avoid using Thread.sleep() in Selenium tests.Recommended to use Selenium Wait Commands for better control and reliability.

It's important to note that using Selenium Wait Commands is generally preferred over Thread.sleep() in Selenium test scripts. Wait Commands provide more control, precision, and reliability by waiting for specific conditions to be met before proceeding with test execution. They also make the test scripts more adaptive to dynamic web applications, reducing unnecessary delays and improving efficiency.


5.2 When to Use Thread.sleep() and When to Use Selenium Wait Commands


The choice between Thread.sleep() and Selenium Wait Commands depends on the specific scenario and the nature of the test script. Here are some guidelines:

Use Thread.sleep() when:

  • Dealing with simple and static scenarios where the timing is not critical.
  • There is no need to wait for specific conditions, and a fixed delay is sufficient.
  • Writing quick and simple test scripts without much consideration for efficiency or precision.

Use Selenium Wait Commands when:

  • Waiting for specific events or conditions to occur, such as element visibility, clickability, or text presence.
  • Dealing with dynamic web applications where the timing and availability of elements may vary.
  • Improving the reliability and efficiency of test scripts by eliminating unnecessary delays and reducing the risk of false positives or negatives.
  • Writing robust and maintainable test scripts that can adapt to changes in the web application.

Example: Let's consider a scenario where you need to wait for an element to be visible before interacting with it. Here's how you can use Thread.sleep() and Selenium Wait Commands:

Using Thread.sleep():

java
Thread.sleep(5000); // Wait for 5 seconds WebElement element = driver.findElement(By.id("myElement")); element.click();

Using Selenium Wait Commands:

java
WebDriverWait wait = new WebDriverWait(driver, 10); WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("myElement"))); element.click();

In this example, the Thread.sleep() approach introduces a static delay of 5 seconds, regardless of whether the element is actually visible or not. This can lead to inefficient test execution and potential false positives.

On the other hand, the Selenium Wait Commands approach uses the visibilityOfElementLocated condition to wait until the element is visible before proceeding with the click action. This ensures that the action is performed only when the desired condition is met, making the test script more reliable and efficient.

By using Selenium Wait Commands, you can eliminate unnecessary delays and make your test scripts more precise and adaptive to dynamic web applications.

Note: It's generally recommended to avoid using Thread.sleep() in Selenium test scripts as it can lead to unreliable and inefficient tests. Selenium Wait Commands provide a more robust and targeted approach to waiting for specific conditions to be met.


6. Best Practices for Using Selenium Wait Commands:

6.1 Avoid Using Hardcoded Wait Times:

When using Selenium Wait Commands, it's important to avoid using hardcoded wait times, as they can lead to inefficient and unreliable test scripts. Instead, rely on wait conditions to determine when to proceed with the test. Hardcoding wait times can result in unnecessary delays or premature actions if the element or condition becomes available before the specified wait time. Here are some best practices to avoid hardcoded wait times:

  • Use implicit wait or explicit wait with appropriate conditions to wait for elements or conditions to be present, visible, or clickable.
  • Set a reasonable and sufficient implicit wait time at the beginning of the test script to handle most of the expected delays.
  • Use explicit wait conditions to wait for specific elements or conditions with a timeout, rather than relying on fixed wait durations.

6.2 Combine Different Types of Wait Commands:

To create more robust and efficient test scripts, consider combining different types of Selenium Wait Commands. Each type of wait command has its own advantages and use cases. By combining them, you can leverage their strengths and create more reliable and adaptable scripts. Here are some ways to combine different wait commands:

  • Start with an implicit wait to handle general delays at the beginning of the test.
  • Use explicit waits with specific conditions to wait for critical elements or conditions.
  • Combine explicit waits with fluent waits to create more customized and flexible wait strategies.
  • Use explicit waits within loops or iterations to wait for dynamic elements or conditions that may change during test execution.

6.3 Handle Timeout Exceptions Properly:

When using Selenium Wait Commands, it's crucial to handle timeout exceptions properly. Timeout exceptions occur when the specified condition is not met within the specified timeout period. Handling these exceptions gracefully ensures that your test script continues to run smoothly without abrupt failures. Here are some best practices for handling timeout exceptions:

  • Use appropriate try-catch blocks to catch and handle timeout exceptions.
  • Add meaningful error messages or logging statements to provide context when a timeout exception occurs.
  • Consider adding retries or fallback actions when a timeout exception occurs, depending on the specific scenario.
  • Use explicit wait conditions that provide additional flexibility for handling timeout exceptions, such as using ExpectedConditions.or() to wait for multiple conditions simultaneously.

Actions Class in Selenium  << Previous     ||     Next >>  Take Full and Partial Screenshots in Selenium


Author
Vaneesh Behl
Passionately writing and working in Tech Space for more than a decade.

Comments

Popular posts from this blog

Top 7 Web Development Trends in the Market

17 Best Demo Websites for Automation Testing Practice

What's New in Selenium-Automated Testing

Mastering Selenium WebDriver: 25+ Essential Commands for Effective Web Testing

Selenium IDE Tutorial: How to Automate Web Testing with Easy-to-Use Interface

Automation Practice: Automate Amazon like E-Commerce Website with Selenium

Mastering Selenium Practice: Automating Web Tables with Demo Examples

What Is Artificial Intelligence (AI) and How Does It Work?

Java Date Format Validation with Regular Expressions: A Step-by-Step Guide

Top 10 Highly Paid Indian CEOs in the USA