A common cause of flaky Selenium tests is the inability of scripts to synchronize with the actual behavior of web elements. Modern web applications rely heavily on JavaScript, AJAX, and dynamic content rendering, which means elements often take time to load or change state. Without proper synchronization, tests fail intermittently—sometimes passing, sometimes breaking.
To address this, Selenium provides wait commands that align test execution speed with the readiness of the application under test.
Wait commands in Selenium are synchronization mechanisms that instruct the WebDriver to pause execution until certain conditions are satisfied.
Rather than relying on arbitrary Thread.sleep() statements that halt execution for a fixed period, waits dynamically adjust based on the actual responsiveness of the application. This ensures that scripts wait only as long as necessary, improving both efficiency and stability.
Waits serve as a bridge between the automation script and the runtime behavior of the browser. They ensure that Selenium interacts with elements only when those elements are present and ready. Key benefits include:
Selenium offers multiple types of waits, each suited for different synchronization needs:
Implicit wait sets a default timeout for the WebDriver to search for elements before throwing an exception. Once defined, it applies throughout the WebDriver instance.
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;
public class ImplicitWaitExample {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("https://example.com");
// Selenium will wait up to 10 seconds for elements before throwing an exception
driver.findElement(By.id("dynamicElement")).click();
driver.quit();
}
}
Explicit wait is applied to specific elements and allows waiting for predefined conditions such as element visibility, clickability, or text presence. Unlike implicit wait, it is not global and is used in scenarios where element states are unpredictable.
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.By;
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) {
WebDriver driver = new ChromeDriver();
driver.get("https://example.com");
WebDriverWait wait = new WebDriverWait(driver, 15);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("submitBtn")));
element.click();
driver.quit();
}
}
Fluent wait extends the capabilities of explicit wait by providing additional customization:
Fluent wait is particularly useful when dealing with elements that appear unpredictably or require continuous polling.
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.FluentWait;
import java.time.Duration;
import java.util.function.Function;
public class FluentWaitExample {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.get("https://example.com");
FluentWait<WebDriver> wait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(20))
.pollingEvery(Duration.ofSeconds(2))
.ignoring(Exception.class);
WebElement element = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.id("delayedElement"));
}
});
element.click();
driver.quit();
}
}
To understand their differences more clearly, consider the following comparison:
Improper use of waits often leads to test instability. Frequent errors include:
Efficient wait usage requires strategic planning rather than arbitrary settings. Consider the following practices:
Even with well-implemented waits, local environments may not replicate real-world conditions. BrowserStack Automate allows execution of Selenium tests on 3500+ real browsers and devices, ensuring that wait commands behave as intended across environments. Teams benefit from:
Wait commands in Selenium are crucial for synchronizing test execution with application behavior. By mastering implicit, explicit, and fluent waits, testers can eliminate flaky tests and improve reliability.
Combined with real device testing platforms like BrowserStack Automate, teams gain confidence that their applications perform consistently under diverse conditions, ultimately delivering a smoother user experience.
Run Selenium Tests on Cloud
Get visual proof, steps to reproduce and technical logs with one click
Continue reading
Try Bird on your next bug - you’ll love it
“Game changer”
Julie, Head of QA
Try Bird later, from your desktop