skip to content

Synchronization Model

How Selenium makes a test wait for a browser that is still working: session timeouts the remote end enforces, client-side polling, and the checks that polling runs.

on this pageshow

explore

questions

page 1 of 2

In Selenium, which two checks does ExpectedConditions.elementToBeClickable actually perform before returning?

level: juniorimportance: must knowfreq 74%

answer

  1. Fewer checks than the name suggests
  2. Two booleans on one element
  3. Rendering first, then form state
  4. Nothing asks what is painted above
  5. isDisplayed then isEnabled, and stop

basics

~10 s

Just two: isDisplayed and isEnabled. Selenium's elementToBeClickable locates the element, confirms the browser renders it and that it is not disabled, then returns it. Nothing in the condition asks whether something covers it.

solid answer

~40 s

`ExpectedConditions.elementToBeClickable` is thinner than its name. On each poll it locates the element, calls `isDisplayed()`, then calls `isEnabled()`; if either is false the poll returns `null` and `WebDriverWait` sleeps and tries again. When both are true it returns the `WebElement` and `until` hands it back. That is the whole contract — “clickable” here means *shown and not disabled*, not *reachable by a pointer*. On a cinema showtime picker, a `19:45` button under a translucent “checking seat availability” panel is displayed and enabled, so the wait is satisfied on its first poll and the very next `click()` can still fail. Read it as a signal about the element itself, never as a promise about what is painted on top of it.

code

java · 21 lines
java
import 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 ShowtimePicker {

  public static void bookSevenFortyFive(WebDriver driver) {
    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    By slot = By.cssSelector(".showtime[data-time='19:45']");

    WebElement showtime = wait.until(ExpectedConditions.elementToBeClickable(slot));

    System.out.println(showtime.isDisplayed());
    System.out.println(showtime.isEnabled());

    showtime.click();
  }
}

go deeper

for a junior

Be ready to name the two checks without hedging: isDisplayed and isEnabled. Knowing that the condition returns the element itself, rather than a boolean, is the other half interviewers listen for.

for a middle

Explain the mechanics: each poll locates, checks the two booleans, and returns null to keep polling. Say which exceptions the poll swallows, and note that the two overloads differ only in whether they re-locate.

for a senior

Show that you design around the gap. Demonstrate that you pick predicates whose truth actually implies the next command can succeed, and that you can name why a passing wait is still followed by a failing click.

for a principal

Own the guidance that a wait predicate is a statement about one element and never about the page. Where a codebase treats elementToBeClickable as a safety guarantee, that assumption is the thing to name and remove.

## The condition is two boolean calls, in order `ExpectedConditions.elementToBeClickable` lives in Selenium 4's Java support library (`org.openqa.selenium.support.ui`), and its body is far smaller than its name suggests. Every time `WebDriverWait` polls it, the `By` overload runs exactly this sequence: 1. Call `driver.findElement(locator)`. If that raises `NoSuchElementException` or `StaleElementReferenceException`, the condition records a "was not found" message and returns `null`, which tells the wait to sleep and poll again. 2. Call `element.isDisplayed()`. If it is `false`, the condition records "was not visible" and returns `null`. 3. Call `element.isEnabled()`. If it is `false`, the condition records "was not enabled" and returns `null`. 4. Otherwise return the located `WebElement`, which ends `until` and becomes the value handed back to your test. There is no fifth step. **In Selenium's vocabulary "clickable" means displayed and enabled** — and that is the whole of it. The recorded message is only used to build the `TimeoutException` text if the wait runs out; it never adds a check. ## What each of the two checks actually answers - **`isDisplayed()`** is a rendering question answered by the browser. It accounts for `display: none`, `visibility: hidden`, a zero-width or zero-height box, and hidden ancestors. It is a statement about the element itself. - **`isEnabled()`** is a form-state question. On a form control it reports the inverse of the `disabled` state; on an ordinary element it is simply `true`, which means a `<div>` styled to look like a button passes this check unconditionally. - Neither call knows anything about **stacking order, overlays, pointer-events, animation, or what is painted on top of the target**. Those are properties of the page around the element, and the condition never asks the page about them. - Neither call is a promise about the future. It is a reading taken at one poll, on one element. ## The two overloads, and the one way they differ | Overload | Re-locates on every poll | A stale reference | Returns from `until` | |---|---|---|---| | `elementToBeClickable(By)` | yes — `findElement` runs each poll | caught, treated as "not yet"; the next poll re-finds, so a re-render is survived | the freshly located `WebElement` | | `elementToBeClickable(WebElement)` | no — it reuses the reference you passed | also caught and treated as "not yet", but nothing ever re-finds, so the wait spins out to `TimeoutException` | the same reference you passed in | The `WebElement` overload is the one that surprises people: handing it a reference captured before a re-render does not make the wait recover, it makes the wait fail slowly. ## A cinema showtime picker, and the shape of the failure Picture a screening-times page. Pick a date and the grid of showtime buttons is already in the markup and already enabled, but a translucent "checking seat availability" panel is drawn over the whole grid while the seat counts load. Every showtime button in that grid is **displayed** (it has a box, it is not `display: none`) and **enabled** (no `disabled` attribute). So: - `elementToBeClickable(By.cssSelector(".showtime[data-time='19:45']"))` is satisfied on its very first poll. - `until` returns immediately, typically in single-digit milliseconds, spending none of the timeout you configured. - The next line calls `click()`, the browser performs its own obstruction check as part of the click command, finds the panel over the button's centre, and the command fails with `ElementClickInterceptedException`. Nothing malfunctioned. The condition answered the question it was asked, truthfully; the question just was not the one the test needed answered. ## Using the condition for what it is - Treat it as a **readiness signal about one element's own state**, exactly equivalent to asserting `isDisplayed() && isEnabled()` in a loop. - It is genuinely the right tool when the thing you are waiting on **is** the element's own state — a submit button that starts disabled until a date is chosen, or a node that is rendered hidden and then revealed. - It is the wrong tool when the thing standing between you and the click is **something else on the page**. No amount of timeout makes a predicate check a property it never reads. - Because the condition returns the `WebElement` rather than a boolean, it is tempting to chain `wait.until(...).click()` on one line. That reads well and hides the fact that two independent operations, with a gap between them, are happening. The single sentence worth memorising: `elementToBeClickable` is `isDisplayed()` plus `isEnabled()`, and the word "clickable" in its name is aspiration, not contract.

  • How does the elementToBeClickable(WebElement) overload behave differently from the By overload?
    The `By` overload calls `findElement` on every poll, so a re-render is survived: the lookup exception is treated as “not yet” and the next poll finds the replacement. The `WebElement` overload runs the same `isDisplayed()`/`isEnabled()` pair against the reference you already hold. A stale reference is also swallowed as “not yet”, but nothing ever re-finds, so the wait simply spins until `TimeoutException`.
  • If the condition never checks obstruction, what does raise the error when something covers the button?
    The browser does, as part of executing the click command. When the target is obscured the remote end returns an `element click intercepted` error and the Java binding surfaces it as `ElementClickInterceptedException`, a subclass of `ElementNotInteractableException`. The check lives in the command, not in the wait, which is why a passing wait cannot predict it.
  • Does isEnabled() mean anything for an element that is not a form control?
    Very little. `isEnabled()` reports the inverse of a control's disabled state, and for an element that cannot be disabled it is simply `true`. A `<div>` or `<a>` styled as a showtime button therefore passes that half of `elementToBeClickable` unconditionally, leaving `isDisplayed()` as the only check with any content.

saying these in an interview costs you the question

  • Says elementToBeClickable guarantees the click will succeed
  • Thinks the condition inspects overlays, z-index or stacking order
  • Believes it waits for animations or CSS transitions to finish
  • Assumes displayed and enabled means reachable by a pointer
  • Claims a passing wait makes the following line safe
open as a page

In Selenium's Java bindings, what does the FluentWait class let a test configure about a wait?

level: juniorimportance: must knowfreq 62%

basics

~10 s

FluentWait is Selenium's configurable wait. withTimeout sets how long it keeps trying, pollingEvery sets the gap between tries, ignoring and ignoreAll list exception types to swallow and retry, and withMessage sets the timeout text.

open as a page

In Selenium, what happens if you set an implicit wait and also use WebDriverWait in the same session?

level: juniorimportance: must knowfreq 76%

basics

~10 s

Wait times become unpredictable. Selenium's documentation warns against mixing the two, and gives the example of a 10-second implicit wait with a 15-second explicit wait producing a timeout after 20 seconds.

open as a page

In Selenium, how does ExpectedConditions.stalenessOf decide that the element it was given is gone?

level: middleimportance: must knowfreq 53%

basics

~20 s

By calling a method on the reference each poll and watching for it to fail. Selenium 4 calls isEnabled and discards the result; when that raises a stale element reference or no such element error, the condition returns true.

open as a page

In Selenium's ExpectedConditions, which helpers hand back a usable WebElement and which only hand back a Boolean?

level: middleimportance: must knowfreq 61%

basics

~20 s

Helpers that ask for a node return it: presenceOfElementLocated, visibilityOfElementLocated, visibilityOf and elementToBeClickable give a WebElement, the all-elements helpers give a list, alertIsPresent gives an Alert. Helpers that assert a page fact, such as invisibilityOfElementLocated, stalenessOf and titleIs, give only a Boolean.

open as a page

In Selenium 4, how do the pageLoadStrategy values normal, eager and none change when navigation returns?

level: middleimportance: must knowfreq 62%

basics

~10 s

Selenium's pageLoadStrategy picks which document readiness state a navigation waits for: normal waits for complete, eager waits for interactive, and none returns straight away. Normal is the default in Selenium 4.

open as a page

In Selenium, why can a click throw ElementClickInterceptedException on the line right after elementToBeClickable passed?

level: seniorimportance: must knowfreq 61%

basics

~20 s

Because the two ask different questions at different moments. The wait only confirmed displayed and enabled; obstruction is checked by the browser when the click command runs, and the page is free to change in between.

open as a page

In Selenium's ExpectedConditions, how do or(), and(), not() and refreshed() compose other conditions?

level: seniorimportance: must knowfreq 48%

basics

~20 s

or() passes when any branch is satisfied, and() when every branch is, and not() when the wrapped one is not. All three yield a Boolean, losing any element. refreshed() wraps a single condition, keeps its return type, and absorbs staleness so the poll retries.

open as a page

In Selenium, what shape must a custom condition passed to WebDriverWait.until have?

level: juniorimportance: should knowfreq 64%

basics

~20 s

A function from WebDriver to some value. The wait passes the driver in on every poll, and the first result that is neither null nor false ends the wait and becomes the return value of until.

open as a page

In a Selenium custom wait condition, how do you poll a page state that no element reflects?

level: juniorimportance: should knowfreq 41%

basics

~20 s

Cast the driver the wait hands you to JavascriptExecutor and return the result of executeScript from the condition. The fragment needs an explicit return statement, or every poll receives null and the wait just times out.

open as a page

In Selenium's ExpectedConditions, what do presenceOfElementLocated, visibilityOfElementLocated and elementToBeClickable each check?

level: juniorimportance: should knowfreq 72%

basics

~10 s

presenceOfElementLocated only requires the element to exist in the DOM. visibilityOfElementLocated additionally requires it to be displayed with a non-zero box. elementToBeClickable requires that displayed state plus the element reporting itself as enabled.

open as a page

In Selenium, what happens when a WebDriverWait's condition never returns a usable value before the timeout?

level: juniorimportance: should knowfreq 66%

basics

~10 s

The wait throws org.openqa.selenium.TimeoutException. Its message names the condition it was waiting on plus the timeout and interval in force, and any exception the last attempt threw is attached as the cause.

open as a page

In Selenium, what does a WebDriverWait do when you call until() with a condition?

level: juniorimportance: should knowfreq 78%

basics

~10 s

WebDriverWait 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.

open as a page

In Selenium 4, what does manage().timeouts().pageLoadTimeout(Duration) control, and what is its default?

level: juniorimportance: should knowfreq 58%

basics

~20 s

Selenium's page load timeout caps how long a navigation command may block before the driver gives up and raises TimeoutException. The W3C default is 300,000 milliseconds, five minutes, and Selenium 4 takes it as a Duration.

open as a page

In Selenium, why can a wait on presenceOfElementLocated pass while the element is still invisible?

level: middleimportance: should knowfreq 57%

basics

~10 s

Because presence only means the lookup succeeded. Selenium's presenceOfElementLocated calls findElement and returns whatever it finds; it never calls isDisplayed, so a node hidden by CSS or a collapsed parent satisfies it immediately.

open as a page

In Selenium's Java WebDriverWait, which values returned by a custom condition keep it polling?

level: middleimportance: should knowfreq 58%

basics

~20 s

Only two: null, and a Boolean whose value is false. Every other result ends the wait and is returned by until, including an empty list, an empty string and a zero, which is why an empty findElements result never waits.

open as a page

In Selenium, which page states make ExpectedConditions.invisibilityOfElementLocated return true instead of polling again?

level: middleimportance: should knowfreq 50%

basics

~20 s

Three states satisfy it: the element is found but not displayed, the locator matches nothing, or the element went stale mid-check. It returns a Boolean, not the element, and passes instantly when the locator never matched.

open as a page

Why can a Selenium WebDriverWait with a 10-second timeout take noticeably longer than 10 seconds to fail?

level: middleimportance: should knowfreq 45%

basics

~20 s

The wait checks the clock only between attempts, never during one. It evaluates the condition first, so an attempt that starts just before the deadline runs to completion, and total elapsed time is the timeout plus that final attempt.

open as a page

In Selenium, why can a FluentWait with pollingEvery(Duration.ofSeconds(2)) check its condition less often than every two seconds?

level: middleimportance: should knowfreq 44%

basics

~10 s

Because pollingEvery sets a sleep between attempts, not a fixed cadence. The time the condition itself takes is added on top, so the real gap is the evaluation time plus the interval.

open as a page

With a Selenium implicit wait of 10 seconds, how long does findElements take when nothing matches, and what does it return?

level: middleimportance: should knowfreq 56%

basics

~10 s

It blocks for the full ten seconds and then returns an empty list without throwing. The driver keeps retrying while the result is empty, so proving that nothing matches always costs the whole timeout.

open as a page

In Selenium, where does an implicit wait's retry loop run, and how long does the setting stay in force?

level: middleimportance: should knowfreq 38%

basics

~20 s

The loop runs in the driver on the remote end, not in the client library. The value is session state, so it applies to every later element search on that driver until something changes it or the session ends.

open as a page

In Selenium, why can a 15-second WebDriverWait fail only after about 20 seconds when a 10-second implicit wait is set?

level: middleimportance: should knowfreq 62%

basics

~20 s

Each poll of the explicit wait runs a find that the remote end retries for the full implicit wait, and Selenium checks the deadline only after a poll returns, so the last poll overshoots it.

open as a page

In Selenium, why does waiting on invisibilityOfElementLocated get slow once the session also has an implicit wait?

level: middleimportance: should knowfreq 47%

basics

~20 s

Selenium's invisibility condition succeeds by catching a not-found error from findElement. With an implicit wait set, the remote end retries the lookup for the whole implicit timeout before reporting not-found, so every success pays that cost.

open as a page

Why must a custom condition passed to Selenium's WebDriverWait.until be free of side effects?

level: seniorimportance: should knowfreq 52%

basics

~20 s

The condition is re-evaluated on every poll until it succeeds or times out, so any action inside it runs many times over. Selenium documents conditions as idempotent: keep the body to reads and act after until returns.

open as a page

Your custom Selenium wait condition reuses a WebElement found before the wait and dies with StaleElementReferenceException. Why?

level: seniorimportance: should knowfreq 47%

basics

~20 s

The lambda captured an element handle taken before the page re-rendered, so a later poll touches a detached node. WebDriverWait ignores only NotFoundException by default, and staleness is not one, so it aborts the wait.

open as a page

In Selenium, why does a WebDriverWait on a wrong locator fail with TimeoutException rather than NoSuchElementException?

level: seniorimportance: should knowfreq 52%

basics

~10 s

WebDriverWait registers NotFoundException as ignored, so every not-found thrown inside the condition is caught, recorded and retried until the deadline. The recorded exception then becomes the cause of the TimeoutException the wait finally throws.

open as a page

A Selenium FluentWait set to ignoring(WebDriverException.class) stopped failing on a flaky page. What did that hide?

level: seniorimportance: should knowfreq 37%

basics

~20 s

Almost every Selenium error subclasses WebDriverException, so stale elements, intercepted clicks, bad selectors, script errors and even a dead session are now retried in silence. The only failure left is a TimeoutException that names nothing.

open as a page

In a Selenium 4 suite, some executeAsyncScript calls fail with ScriptTimeoutException while others pass. How do you diagnose that?

level: seniorimportance: should knowfreq 36%

basics

~20 s

Read the session's real script timeout with getScriptTimeout() first. It is session state an earlier test may have lowered, drivers differ from the specified 30 second default, and the exception only means the callback never fired.

open as a page

In Selenium, what does driver.manage().timeouts().implicitlyWait(Duration) change, and what is its default?

level: juniorimportance: nice to knowfreq 52%

basics

~10 s

It sets how long the browser driver keeps retrying an element search before giving up, for every search in that session. The default is zero, so an unmatched locator fails immediately.

open as a page

A Selenium test with a 20-second implicit wait reads an element's text and gets a placeholder. Why doesn't the wait retry?

level: seniorimportance: nice to knowfreq 44%

basics

~20 s

Because an implicit wait only governs the search that locates an element. Once the element is found the wait is finished, and reading its text is a separate command that returns whatever the page says at that moment.

open as a page

showing 1–30 of 31