skip to content

Implicit Timeouts

An implicit wait tells the remote end to keep retrying element lookup for a fixed duration, and it applies to nothing else. Interviewers ask because most flaky suites misread that sentence.

on this pageshow

explore

questions

4

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%

answer

  1. the loop only reacts to emptiness
  2. no exception comes back at all
  3. negative checks pay the full price
  4. an empty list after the whole timeout
  5. set Duration.ZERO around an absence check

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.

solid answer

~40 s

The call takes the full ten seconds and hands back an empty `List<WebElement>`; nothing is thrown. The driver's search routine loops while the collection is empty and the timer has not fired, and an assertion that nothing matches keeps the collection empty by definition, so the loop runs to the end. `findElement` shares the same routine and differs only in the ending: an empty collection becomes a `no such element` error, surfaced as `NoSuchElementException`. The practical consequence is that every negative check in a suite pays the implicit wait in full, silently. The usual remedy is to set `Duration.ZERO` around a deliberate absence assertion and restore the previous value in a `finally` block.

code

java · 19 lines
java
import java.time.Duration;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public final class BerthAbsence {

  public static boolean noOverdueBerths(WebDriver driver) {
    Duration previous = driver.manage().timeouts().getImplicitWaitTimeout();
    driver.manage().timeouts().implicitlyWait(Duration.ZERO);
    try {
      List<WebElement> overdue = driver.findElements(By.cssSelector("#berth-grid tr.overdue"));
      return overdue.isEmpty();
    } finally {
      driver.manage().timeouts().implicitlyWait(previous);
    }
  }
}

go deeper

for a junior

Remember the two shapes: a search for one element throws when it finds nothing, and a search for many returns an empty list instead. Neither returns early when the answer is nothing.

for a middle

Explain why the timeout is spent in full: the driver loops while the collection is empty, and a correct negative assertion keeps it empty. Be able to state what is returned as well as how long it takes.

for a senior

Show that you can quantify the cost across a suite and locate it from timing data, and that you know how to bound a deliberate absence check without changing the session's timeout for everything else.

for a principal

Own the trade the number represents: a value chosen to protect racy positive lookups is a per-assertion tax on every negative one, so decide whether the harness exposes a way to scope it at all.

## What actually happens on a no-match Set a ten-second implicit wait and call `driver.findElements(By.cssSelector("#berth-grid tr.overdue"))` on a marina berth allocation grid where no berth is overdue. The call **returns after roughly ten seconds**, and it returns an **empty `List<WebElement>`**. It does not throw. There is no `NoSuchElementException`, no `TimeoutException`, no warning — only a test step that quietly cost ten seconds and found nothing, which is exactly what you asked it to prove. ## Why the whole timeout is spent The remote end's search routine loops on one condition: *keep going while the result collection is empty and the timer has not fired*. It has no way to know that the page has finished rendering and that no berth will ever be overdue. Emptiness is the only signal it reacts to, and emptiness is precisely the state a correct negative assertion sits in. So the loop runs until the timer fires, and only then does it stop. The asymmetry is worth stating plainly: - A **positive** search — something will eventually match — costs roughly the time until the element appears. A generous implicit wait is nearly free here, because the loop exits early. - A **negative** search — nothing will ever match — costs the **full** timeout, every single time, and no amount of the page being fast can shorten it. ## `findElement` and `findElements` after the timer fires Both commands share the same search routine; they differ only in what they do with the collection it produces. | Call | Timing on a no-match | Result on a no-match | |---|---|---| | `findElement(By)` | the full implicit wait | throws `NoSuchElementException` | | `findElements(By)` | the full implicit wait | returns an empty list, no exception | The specification spells this out: find element returns the `no such element` error when the collection is empty, and find elements returns success with whatever the collection holds, empty included. Element-scoped searches behave the same way — `berthRow.findElements(...)` on a row with no matching children also burns the whole timeout before handing back an empty list. ## The one that surprises people: partial collections The loop stops as soon as the collection is **non-empty**, not when it stops growing. If the berth grid streams rows in as an API pages through them, a `findElements(By.cssSelector("#berth-grid tr"))` issued mid-render can return the four rows that exist at that instant. Your assertion then reads 4 where the finished grid shows 40, and the failure looks random because it depends on where the render happened to be. The implicit wait did nothing wrong — "at least one match" is its whole contract. ## What this costs a suite Work the arithmetic once and the effect stops being abstract: 1. A suite has 60 assertions of the shape "this berth is not in the grid" or "no conflict banner is showing". 2. The team sets a global implicit wait of ten seconds because a few positive lookups were racy. 3. Each of those 60 assertions now blocks for ten seconds by design, adding ten minutes of pure waiting to a run in which nothing was actually wrong. Nothing fails, nothing logs, and the run time climbs. The tell is a suite whose duration tracks the implicit wait value rather than the application's speed — and a profile in which the slowest steps are the ones that passed. ## Practical shape of a negative check Because the implicit wait is session state you can change at any point, the usual move is to drop it to `Duration.ZERO` around a deliberate absence assertion and restore it afterwards, so the check costs one round trip instead of the whole timeout: - Read the current value first with `getImplicitWaitTimeout()` if the harness might have set something you do not know about. - Set `Duration.ZERO`, run the `findElements` call, and assert the returned list is empty. - Restore the previous `Duration` so the rest of the test behaves as its author expected. - Do the restore in a `finally` block, since an assertion failure in between would otherwise leave the session at zero for every later test that reuses the driver. The point to carry into an interview is the pair of facts, not the workaround: **an implicit wait makes a failed search slow rather than impossible, and `findElements` reports that failure as an empty list rather than an exception.** A candidate who says `findElements` "returns immediately" or "throws when nothing matches" has never watched a negative check drag a suite out.

  • Why can findElements return fewer rows than the finished page shows, even with a generous implicit wait?
    The driver's loop stops as soon as the collection is non-empty, not when it stops growing. If rows arrive progressively, a search issued mid-render returns whatever existed at that instant. The implicit wait guarantees at least one match, never a complete match set.
  • Does the same full-timeout cost apply to a search scoped to an element rather than the whole document?
    Yes. An element-scoped `findElements` runs the same search routine on a different start node, so if no child matches it also loops until the timer fires and then returns an empty list. Scoping narrows what is searched, not how long a fruitless search takes.
  • How would you spot this cost in a suite without reading every test?
    Compare the run duration against the implicit wait value: if halving the timeout roughly halves the run, the suite is dominated by fruitless searches. Then look at per-step timings and pick out the steps that passed slowly, since a slow passing step is the signature of a negative check.

It is like ringing a doorbell over and over for ten seconds before concluding nobody is home. The answer is right, but the certainty costs the full ten seconds every single time.

saying these in an interview costs you the question

  • Says findElements throws NoSuchElementException when nothing matches
  • Thinks findElements returns immediately once the page is loaded
  • Assumes the returned list always holds every matching row
  • Believes an implicit wait costs nothing when the page is fast
  • Uses findElement inside a try-catch to assert absence
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, 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