Careeroza
Waits and Synchronization
What are the types of waits in Selenium?
| Wait | How | Scope |
|---|---|---|
| Implicit | driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)) | every findElement for the whole session; only "element present" |
| Explicit | new WebDriverWait(driver, Duration.ofSeconds(10)).until(ExpectedConditions...) | one condition at one place: visible, clickable, text, URL... |
| Fluent | new FluentWait<>(driver).withTimeout(..).pollingEvery(..).ignoring(..) | explicit wait with custom polling and ignored exceptions |
Thread.sleep is not a wait strategy: it always waits the full time and still fails when the app is slower.
Why should you not mix implicit and explicit waits?
The two waits work at different layers (the driver vs the client) and can add up unpredictably. With implicit 10 s and an explicit wait for invisibilityOf of 15 s, each poll inside the explicit wait may itself block for 10 s, so the timeout can stretch to 20+ seconds and checks for "element is gone" become very slow. The Selenium docs say: do not mix them. Most frameworks set implicit wait to 0 and use explicit waits in the BasePage.
Write an explicit wait that waits for a button to be clickable and clicks it.
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions.elementToBeClickable(By.id("checkout"))).click();
// custom condition with a lambda: wait until the cart badge shows 2
wait.until(d -> d.findElement(By.id("cart-count")).getText().equals("2"));Example
when it times outExample output
org.openqa.selenium.TimeoutException: Expected condition failed: waiting for element to be clickable: By.id: checkout (tried for 10 second(s) with 500 milliseconds interval)
How do you handle StaleElementReferenceException?
It means the element you found earlier was removed or re-rendered (common after AJAX updates, sorting or page reloads). Fixes:
- Find the element again right before using it (keep
Bylocators, notWebElementfields). - Wait for the refresh to finish:
wait.until(ExpectedConditions.stalenessOf(oldElement)), then find again. - Use
ExpectedConditions.refreshed(...)or a FluentWait that ignoresStaleElementReferenceException.