Selenium interview question
Implicit vs explicit vs fluent waits in Selenium, and why not to mix them
Short answer
An implicit wait makes every findElement poll for presence up to a timeout. Explicit waits (WebDriverWait) wait for a specific condition such as visibility or clickability. FluentWait is the configurable base with polling interval and ignored exceptions. Mixing implicit and explicit waits causes unpredictable timeouts.
Answer
Selenium executes each command immediately against the current DOM. Modern apps render asynchronously, so tests need to wait for the right state. There are three mechanisms, plus the one you should avoid.
Implicit wait
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
This is a session-wide setting. Every findElement call polls the DOM until the element is present or the timeout elapses. It does nothing for visibility, clickability, text changes or an element disappearing. findElements (plural) also waits the full timeout before returning an empty list, which slows down “assert element is absent” checks.
Explicit wait
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement button = wait.until(ExpectedConditions.elementToBeClickable(By.id("submit")));
button.click();
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector(".spinner")));
wait.until(ExpectedConditions.textToBePresentInElementLocated(By.id("status"), "Paid"));
An explicit wait polls a specific condition for a specific step. It is precise, self-documenting and the right default. You can pass any lambda, not just ExpectedConditions:
wait.until(d -> d.findElements(By.cssSelector(".row")).size() == 20);
Fluent wait
WebDriverWait is actually a subclass of FluentWait<WebDriver>. Use FluentWait directly when you need to tune polling or ignore extra exceptions, or wait on something other than the driver:
Wait<WebDriver> fluent = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofMillis(500))
.ignoring(NoSuchElementException.class)
.ignoring(StaleElementReferenceException.class);
WebElement report = fluent.until(d -> d.findElement(By.id("report-ready")));
Why not to mix them
The Selenium documentation explicitly warns against mixing implicit and explicit waits. The implicit wait is applied inside the driver on every find, while the explicit wait polls from the client. When an explicit wait’s condition calls findElement, each poll can block for the full implicit timeout, so a 10 second explicit wait with a 15 second implicit wait might time out after 15, 20 or more seconds depending on driver and condition. Conditions that expect an element to be absent become painfully slow. The behaviour is hard to reason about and varies between drivers.
My rule: set the implicit wait to zero (the default) and use explicit waits everywhere, wrapped in small helper methods or Page Object methods so tests read cleanly.
What about Thread.sleep?
A fixed sleep either wastes time (the page was ready sooner) or is too short on a slow CI agent, causing flakiness. It is acceptable only for a deliberate delay that is part of the behaviour under test, and even then a condition is usually better.
What interviewers look for
- Clear distinction: implicit is global presence-only; explicit is per-condition.
- Knowing
WebDriverWaitextendsFluentWaitand usesDurationin Selenium 4. - A firm stance on not mixing waits, with the reason.
Common mistakes
- Using the deprecated
new WebDriverWait(driver, 10)long-based constructor, which was deprecated in Selenium 4 in favour ofDuration. - Raising the implicit wait to “fix” flakiness, which hides the real synchronisation problem and slows every negative check.
A strong answer covers
- Implicit wait is global and only covers element presence on find
- Explicit wait waits for a specific condition
- Fluent wait configures polling interval and ignored exceptions
- Mixing them gives unpredictable/compounded timeouts
- Avoid Thread.sleep