Back to cheat sheet hub

Selenium Waits Cheat Sheet

A synchronization reference for Selenium tests that need to survive real-world loading delays and dynamic UI behavior.

Selenium Module 4 Synchronization Flakiness reduction

Main principle

Wait for the right condition, not for an arbitrary amount of time.

Avoid

Thread.sleep() as a default tool. It slows tests and still misses the real readiness signal.

Default choice

Use explicit waits for important interactions and assertions.

Best pair

Use clean locators and clean waits together. One without the other still flakes.

Thread.sleep Anti-pattern

Hard sleeps block execution whether the app is ready or not.

// Avoid as a default strategy
Thread.sleep(5000);

Implicit Wait

Implicit wait applies globally to element lookup, but it is blunt and limited.

driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));

Explicit Wait

Explicit waits are targeted and usually the most useful default for UI automation.

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement button = wait.until(
    ExpectedConditions.elementToBeClickable(By.id("submit"))
);

Visibility and Presence

Choose the condition that matches what the test really needs next.

wait.until(ExpectedConditions.presenceOfElementLocated(By.id("email")));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("email")));

Common ExpectedConditions

These conditions cover most dynamic UI cases.

ExpectedConditions.elementToBeClickable(locator);
ExpectedConditions.textToBe(locator, "Success");
ExpectedConditions.urlContains("dashboard");
ExpectedConditions.alertIsPresent();

Fluent Wait

Fluent wait is helpful when you need custom polling and exception handling.

Wait wait = new FluentWait<>(driver)
    .withTimeout(Duration.ofSeconds(20))
    .pollingEvery(Duration.ofMillis(500))
    .ignoring(NoSuchElementException.class);

Custom Wait Conditions

Use custom conditions when the built-in ones do not model the readiness you need.

wait.until(driver ->
    driver.findElement(By.id("status")).getText().equals("Completed")
);

Stale Elements and Refreshing DOM

Re-find elements after DOM changes instead of holding stale references too long.

wait.until(ExpectedConditions.stalenessOf(oldElement));
WebElement fresh = wait.until(
    ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".updated-card"))
);

Good Waiting Strategy

Target the exact event that makes the next step safe.

// good pattern
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.className("spinner")));
wait.until(ExpectedConditions.elementToBeClickable(By.id("continue")));