In Selenium, what does a WebDriverWait do when you call until() with a condition?
answer
- It runs in the test, not the browser
- A loop with a deadline
- Sleep, re-ask, compare the answer
- Returns the first usable value
- The clock ends it the other way
basics
~10 sWebDriverWait repeatedly applies the condition from the test process until it produces a usable value, which until() then returns. If the deadline passes first, the wait throws TimeoutException instead of returning.
solid answer
~40 s`WebDriverWait` is a client-side polling loop. You build it from the driver and a timeout — `new WebDriverWait(driver, Duration.ofSeconds(10))` in Selenium 4 — and hand `until()` a condition. The wait applies that condition to the driver; if the result is `null` or `Boolean.FALSE` it sleeps and applies it again, roughly twice a second, until the deadline. The first result that is neither `null` nor `false` ends the loop, and `until()` returns that value — often the `WebElement` the condition found, so you can act on it directly rather than looking it up a second time. If the deadline passes with nothing usable, the wait throws `org.openqa.selenium.TimeoutException`. Nothing runs inside the browser: every attempt is an ordinary command sent from your test.
code
java · 16 linesimport java.time.Duration;
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;
public class BakeryPreOrder {
public static String confirmationText(WebDriver driver) {
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement banner = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("preorder-confirmation")));
return banner.getText();
}
}go deeper
Be ready to build a WebDriverWait from a driver and a Duration, call until() with a condition, and say in one sentence that it retries until the condition gives something usable or the time runs out.
Explain the loop order and the exit test: apply the condition, accept any non-null, non-false result, otherwise check the clock and sleep. Know that the returned value is the condition's own result.
Show that you treat the return value as part of the API rather than a side effect, and that you can reason about a wait's real cost as a number of round trips rather than as one opaque blocking call.
Be able to argue where a polling client-side wait is the right instrument at all, given that it can only re-ask questions a command can answer and never observes the application's internal work directly.
## What the object is and how you build it `WebDriverWait` lives in `org.openqa.selenium.support.ui` and is a **client-side polling loop** — plain code that runs in your test process, not anything injected into the browser. You build it from the driver you want it to interrogate and a deadline, then hand it a condition. - In **Selenium 4** the constructor takes a `java.time.Duration`: `new WebDriverWait(driver, Duration.ofSeconds(10))`. The Selenium 3 spelling that took a bare `long` number of seconds is gone. - Constructing the wait does nothing on its own. It records a timeout, a polling interval and a set of exceptions to tolerate, and then sits there. All the work happens when you call `until()`. - `WebDriverWait` extends `FluentWait<WebDriver>`, which is where the loop itself is implemented; the subclass exists mostly to bind the loop to a driver and pick sensible defaults. ## What until() does, attempt by attempt `until()` takes a **condition** — anything that can be applied to the `WebDriver` and produce a value — and drives it: 1. Work out the deadline as *now plus the timeout*. 2. Apply the condition to the driver and look at the value that comes back. 3. If that value is usable, stop immediately and hand it to the caller. 4. Otherwise, check the clock; if the deadline has passed, throw `TimeoutException`. 5. Otherwise sleep for the polling interval, which defaults to 500 milliseconds, and go back to step 2. Because the condition is applied **before** the first clock check, a condition that is already satisfied returns on the very first attempt without ever sleeping. That is the property that makes waits cheap: on a bakery pre-order page that has already rendered its confirmation banner, `until()` costs one round trip, not ten seconds. ## What counts as a usable result The loop's exit test is deliberately loose — it accepts anything that is neither `null` nor the boolean `false`: | What the condition returns | What `until()` does | |---|---| | a `WebElement`, a `String`, any non-null object | returns it and exits the loop | | `Boolean.TRUE` | returns `true` and exits the loop | | `Boolean.FALSE` | treats it as "not yet" and polls again | | `null` | treats it as "not yet" and polls again | - The rule is **non-null and non-false**, not "truthy". An **empty** `List<WebElement>` is a non-null object that is not a `Boolean`, so a condition returning one ends the wait straight away — a classic surprise for people who expect an empty collection to read as "not ready". - Only an actual `Boolean` gets the false test. Any other type is judged purely on being non-null. ## The return value is part of the API `until()` is a function, not a barrier. Whatever the condition produced comes back to you: - A condition that located the bakery's confirmation banner returns that `WebElement`, so you can read or click it directly. - Throwing that value away and re-finding the element with a second `findElement` call costs an extra round trip and opens a window in which the page can re-render between the two lookups. - Assigning the result — `WebElement banner = wait.until(...)` — is therefore the idiomatic shape, not an optimisation. ## Where the loop runs, and what that costs Every evaluation of the condition is one or more ordinary WebDriver commands sent from your test to the driver and on to the browser. Nothing is subscribed, nothing is pushed back, and the browser is never told that anyone is waiting. - A ten-second wait against a condition that never succeeds is roughly twenty request/response cycles, not one long-lived call. - The wait can only observe what a command can observe. It cannot see an in-flight fetch or a pending timer directly; it can only re-ask a question and compare the answer. - One `WebDriverWait` instance can be reused for several `until()` calls; each call starts its own deadline from the moment it is invoked. ## The shape of the loop, condensed ```java Instant end = clock.instant().plus(timeout); while (true) { V value = condition.apply(driver); if (value != null && (Boolean.class != value.getClass() || Boolean.TRUE.equals(value))) { return value; } if (end.isBefore(clock.instant())) { throw new TimeoutException("Expected condition failed: ..."); } sleeper.sleep(interval); } ``` That is the whole mechanism. Everything else about explicit waits — which conditions exist, how to change the interval, what the ignored exceptions are — is configuration layered on top of these few lines.
- Does building a WebDriverWait cost anything before until() is called?No. The constructor only records the driver, the timeout, the polling interval and the ignored exception types. No command reaches the browser until `until()` runs, so a wait can be created once in a page helper and reused for several calls, each starting a fresh deadline from the moment it is invoked.
- What happens if the condition returns an empty List<WebElement>?The wait ends immediately and returns that empty list. The exit test is non-null and non-`false`, not "truthy": only an actual `Boolean` is checked for falseness, so any other non-null object — including an empty collection — counts as a usable result and stops the polling.
- Why assign the result of until() instead of finding the element again?The returned value is usually the `WebElement` the condition just located. Re-finding it costs another round trip and, worse, opens a gap in which the page can re-render between the wait and the lookup, so the second find can miss or return a different node than the one the wait approved.
It is like phoning the bakery every half minute to ask whether your pre-order is boxed: you keep calling back until someone says yes, and you give up when your lunch break runs out.
saying these in an interview costs you the question
- Says the wait runs inside the browser rather than in the test process
- Thinks until() returns nothing useful and the element must be found again
- Believes an already-satisfied condition still costs the full timeout
- Assumes until() can only ever yield true or false
- Cannot name what ends the loop apart from the clock