Stop Guessing with Thread.sleep: Use Selenium Explicit Waits
Replace brittle fixed sleeps in Selenium tests with WebDriverWait and ExpectedConditions for reliable, faster synchronization.
11 Jul 2025, 02:53 UTC

The problem: fixed sleeps make tests slow and unreliable
A common Selenium test failure looks like this: a button exists in the HTML but is not yet clickable because a JavaScript call is still finishing. A team adds Thread.sleep(5000) before clicking it. Sometimes five seconds is not enough; often it is far more than needed. The test either races past the element or wastes time waiting for every run.
The useful takeaway is to replace arbitrary pauses with condition-based synchronization. Selenium's WebDriverWait polls the page until a specific condition is true or a timeout expires, so tests move forward as soon as the application is ready.
How explicit waits work
WebDriverWait is a Selenium class that repeatedly checks the DOM at a default interval until an ExpectedCondition returns true. The DOM is the browser's live representation of the page. An ExpectedCondition is a reusable check, such as whether an element is visible or enabled. If the condition becomes true before the timeout, the test continues. If the timeout expires first, Selenium throws TimeoutException.
Explicit waits apply to one WebDriver instance and one maximum wait time. They differ from implicit waits, which set a global default for the driver's lifetime. Mixing the two in the same session can produce unpredictable wait lengths, so choose one style per project.
| Wait type | Scope | Behavior |
|---|---|---|
| Implicit wait | Global for driver lifetime | Applies to every element search |
| Explicit wait | Single call and timeout | Polls until a specific condition is true |
Worked example: wait for a JavaScript-loaded button
Assume a page loads a submit button asynchronously. Instead of sleeping, wait for it to be clickable.
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
WebDriver driver = ...; // your Chrome, Firefox, or Edge driver
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement submit = wait.until(ExpectedConditions.elementToBeClickable(By.id("submit-order")));
submit.click();
Where to run: any Java test class using Selenium 4 bindings, locally or in CI. Required permissions: none beyond normal test execution. Placeholders: replace driver with your initialized browser driver and submit-order with your actual element ID. Expected check: the test proceeds only when the button is clickable, or fails with TimeoutException after ten seconds if it never appears. Risk: a wrong locator or an element that never becomes clickable will fail the test, which is the intended signal rather than a silent pass.
Limitations and how to verify
Explicit waits synchronize timing; they do not repair broken locators or application bugs. Long timeouts can hide performance regressions and lengthen the suite. Some conditions behave differently across Chrome, Firefox, and Edge because of browser event dispatch.
Practical check: write a test that waits for visibilityOfElementLocated on an element loaded by JavaScript. Confirm it passes without fixed sleeps. Then set the timeout below the element's actual appearance time and verify the test throws TimeoutException. Also confirm your project's Selenium dependency resolves WebDriverWait from org.openqa.selenium.support.ui.
Closing recommendation
Adopt explicit waits as the default synchronization strategy in new Selenium tests. Remove existing Thread.sleep calls where possible, set timeouts based on observed application behavior rather than guesswork, and avoid mixing implicit and explicit waits in the same driver session. The result is fewer flaky tests and less wasted time.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.