lecture 10 of 200 completed

Implicit waits, and why you should not use them

Every legacy suite has them. You need to recognise them, understand the bug they cause, and know what to write instead.

You will meet implicit waits in the first Selenium codebase you join, and you need to understand them well enough to remove them safely.

What they are. One setting that tells the driver: whenever an element is not found, keep retrying for up to this long before giving up.

await driver.manage().setTimeouts({ implicit: 10000 });

One line, applies to every findElement for the whole session. It looks like the perfect fix for timing problems, which is exactly why it is everywhere.

Why it is a trap.

It only waits for existence, not for readiness. The element can be in the DOM while invisible, still animating, or disabled. findElement returns it, your click fails, and the implicit wait did not help.

It slows failures down. A test that should fail instantly because a selector is wrong now takes ten seconds to say so. Twenty such tests is over three minutes of waiting for information you already had.

You cannot wait for anything else. Text changing, an element disappearing, a button becoming enabled: an implicit wait covers none of these. It has exactly one trigger.

And then the real problem, the one that produces bug reports nobody can explain.

⚠️ Never mix implicit and explicit waits.

When both are set, their behaviour combines in ways the documentation itself warns about. A wait you expected to last 5 seconds can take 15, or return at unpredictable times. The Selenium project's own advice is to pick one.

Since explicit waits do everything implicit waits do and much more, the choice is straightforward: use explicit waits, and set the implicit timeout to zero.

What to write instead. An explicit wait names the condition you actually care about:

const { until, By } = require('selenium-webdriver');

// wait for it to exist
await driver.wait(until.elementLocated(By.css('[data-testid="toast"]')), 5000);

// wait for it to be visible and ready
const el = await driver.wait(
  until.elementIsVisible(driver.findElement(By.css('[data-testid="toast"]'))),
  5000,
);

// wait for specific text
await driver.wait(until.elementTextIs(badge, '1'), 5000);

Longer to write, and it says what you mean. It waits for the right thing, fails fast when the thing is wrong, and does not interact badly with anything else.

If you inherit a suite full of implicit waits, do not remove the setting in one commit. Tests will start failing that were silently relying on it. Convert one file at a time: add explicit waits, then remove the implicit setting for that suite once it is green.

Remember this: implicit waits wait for the wrong thing and conflict with explicit ones. Use explicit waits everywhere.

Reference: Waits.