skip to content

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%

answer

  1. the wait ends when the element is found
  2. reading a value is a separate command
  3. it retries the search, not the result
  4. presence is not the same as populated
  5. staleness and interactability are never retried

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.

solid answer

~40 s

The implicit wait timeout is consulted in exactly one place: the driver's routine for searching the document, which backs `findElement`, `findElements` and their element-scoped and shadow-root-scoped variants. Everything else — `getText()`, `getDomAttribute(...)`, `isDisplayed()`, `click()`, alerts, navigation, script execution — runs once and answers with the state at that instant. So the search for the element succeeded the moment the node was attached, and the following `getText()` read the placeholder that was in it. Raising the number cannot help, because the failing command never looked at it. The same reasoning explains why `StaleElementReferenceException` and `ElementNotInteractableException` are never retried: in both cases the element was already found.

go deeper

for a junior

Remember the boundary as one sentence: an implicit wait waits for an element to exist, and nothing more. Anything you do with the element afterwards happens straight away.

for a middle

Explain which commands consult the setting and which do not, and be able to say why a stale reference or a disabled control is never retried by it.

for a senior

Diagnose from evidence rather than by turning the number up. Show that you identify which command threw, recognise the state races the search routine cannot see, and reach for a condition-polling mechanism instead.

for a principal

Own the standard your suite holds itself to: a wait that proves a readiness condition rather than mere presence, and a policy that treats a raised timeout with no measured effect as a signal to re-diagnose.

## "Element location only" is a literal statement The implicit wait timeout is read at exactly one place in the WebDriver protocol: the routine that searches the document for elements. That routine backs six commands — find element, find elements, and the element-scoped and shadow-root-scoped variants of each. Every other command in the protocol runs once and answers with whatever is true at that instant. So the scope is not "Selenium waits a bit longer for things". It is: *the driver re-runs your locator until it matches something*. Once a matching element reference is in your hand, the implicit wait has done its entire job and is out of the picture. ## What happens after the reference comes back Consider a marina berth allocation grid where each row shows a berth, a status cell filled in by a later request, and an **Assign** button that stays disabled until pricing returns. ```java WebElement row = driver.findElement(By.cssSelector("tr[data-berth='A17']")); String status = row.findElement(By.className("berth-status")).getText(); ``` The first line may retry for as long as the implicit wait allows, and it succeeds the moment that row is attached to the document. The second line issues a **separate request** for the status cell, and once that cell exists the `getText()` is a third request that reads the DOM exactly as it stands right then. If the status text has not arrived, you get the placeholder. The implicit wait never sees this, because `getText()` is not a search. ## The failures it will never fix Each of these has bitten a suite that responded by raising the implicit wait: - **Empty or placeholder text.** `getText()` and `getDomAttribute(...)` return the current value once; there is no retry on "the value I wanted". - **Present but not interactable.** A disabled or zero-sized **Assign** button is found instantly, and the click throws `ElementNotInteractableException` with no retry. - **Covered by an overlay.** A "reallocating berths" spinner sitting over the grid still lets the row be found; the click lands on the overlay and fails. - **Stale references.** If the grid re-renders between the find and the next command, the reference you hold points at a detached element and every use of it throws `StaleElementReferenceException`. - **Wrong state, right element.** A row that exists but still shows last night's allocation satisfies the search perfectly, and the assertion fails on the value. - **Slow navigation or a slow script.** Page load and script execution are governed by their own separate timeouts in the same configuration, not by `implicit`. ## Diagnosing it in a real suite The pattern is recognisable once you know its shape: 1. A test fails on an assertion about a value, not on a `NoSuchElementException`. 2. The failure is intermittent and machine-speed dependent — it passes on a developer laptop and fails on a loaded CI host. 3. Somebody raises the implicit wait; the failure rate barely moves, and the suite gets slower. Step 3 is the diagnostic. If a larger implicit wait does not help, the thing you were waiting for was never a find in the first place. Confirm it by checking which command produced the exception: anything thrown from `getText`, `click`, `isDisplayed` or `getDomAttribute` is proof that the search already succeeded and the implicit wait was never in play. ## What the boundary means for design | Symptom | Did a find fail? | Does the implicit wait apply? | |---|---|---| | `NoSuchElementException` | yes | yes — it already retried | | `StaleElementReferenceException` | no, the reference aged out | no | | `ElementNotInteractableException` | no, the element was found | no | | Assertion on the wrong text | no, the read succeeded | no | The honest conclusion is that an implicit wait solves exactly one race: *the element does not exist yet*. That race is real and common, which is why the setting exists at all. But it is the easiest race on a modern page, and it is rarely the one making a suite unreliable. Waiting for a **condition** — text settled, control enabled, spinner gone — needs a mechanism that re-evaluates a predicate rather than one that re-runs a locator, and that is a different tool in Selenium entirely. A senior answer makes two moves: name the mechanism precisely — the driver re-runs the locator, and nothing more — and then name the class of failures that sits outside it and explain why raising the number cannot reach them.

  • How do you confirm from a failure that the implicit wait was never involved?
    Look at which command threw. Anything raised by `getText`, `click`, `isDisplayed` or `getDomAttribute` proves the search already returned an element, so the implicit wait had finished its work. Only a `NoSuchElementException` comes from the search itself, and that one did retry for the whole timeout.
  • A team doubles the implicit wait and the failure rate is unchanged. What does that tell you?
    That the race was not about the element's existence. If a longer retry window makes no difference, the element was being found on the first attempt and the problem lies in its state — text not yet populated, control not yet enabled, node about to be replaced — none of which the search routine inspects.
  • Does an implicit wait help with a StaleElementReferenceException?
    No. Staleness happens after a successful search, when the node you hold a reference to is detached from the document. Every command on that reference fails immediately, and the implicit wait does not re-run the original locator for you. Finding the element again is the only recovery.

saying these in an interview costs you the question

  • Suggests raising the implicit wait when a value assertion fails
  • Thinks the implicit wait retries getText until it changes
  • Believes an implicit wait prevents stale element reference errors
  • Assumes a found element is therefore visible and enabled
  • Says the implicit wait also covers page loads and scripts