Selenium · Intermediate

Selenium Wait and Stale Element Interview Questions

Explicit versus implicit waits, stale references, page objects and session management.

20 questions, each with the answer and the reason every other option is wrong. You can read them here, then sit the timed session to find out what you actually remember.

1. A project sets an implicit wait of 10 seconds and also uses explicit waits. What is the effect?

Answer

The waits can multiply, making timeouts much longer and less predictable than either setting suggests

Correct. Each poll inside the explicit wait goes through the implicit wait. Mixing them is a well-known source of very slow, confusing failures.

Pick explicit waits and leave the implicit wait at zero. Mixing them is the classic Selenium performance bug.

Why the other answers are wrong

  • The larger of the two values is used. They interact rather than one overriding the other.
  • The implicit wait is ignored once an explicit wait is used. It stays active for every lookup, including those inside the explicit wait.
  • Nothing; they are independent. They are not independent, which is why the documentation warns against mixing them.

2. What does StaleElementReferenceException actually mean?

Answer

You are using a reference to an element that was removed or replaced when the page re-rendered

Correct. The fix is to find the element again after the action that changed the page, not to add waits.

Find elements late, use them immediately, and re-find after anything that rebuilds part of the page.

Why the other answers are wrong

  • The element is taking too long to appear. That is a timeout. Staleness is about a reference that used to be valid.
  • The selector is wrong. A wrong selector gives NoSuchElementException at lookup time.
  • The browser session expired. Session problems produce different errors.

3. Why is this loop dangerous? const rows = await driver.findElements(By.css('.row')); for (const row of rows) { await row.click(); await driver.navigate().back(); }

Answer

Navigating rebuilds the page, so every remaining row reference becomes stale

Correct. Re-find the rows inside the loop, or work by index and look them up each time.

Any action that changes the page invalidates the element references you are holding.

Why the other answers are wrong

  • findElements cannot be used in a loop. It can. The problem is holding references across a navigation.
  • click() is not allowed on a list item. It is allowed; the staleness is the issue.
  • The loop runs in parallel. It runs sequentially, and it still breaks.

4. In a Page Object, should you store By locators or the found WebElements?

Answer

Store the By locators and find the element when you use it

Correct. Elements found in the constructor go stale as soon as the page changes. Locators do not.

Locators are descriptions and stay valid. Elements are references and expire.

Why the other answers are wrong

  • Store found WebElements for speed. That is exactly how page objects start throwing stale element errors.
  • Either is fine. One of them breaks on any re-render, so it is not equivalent.
  • Store CSS strings and use eval. Storing By objects is the normal, type-safe approach.

5. What is the correct order for logging in by setting a session cookie directly?

Answer

Visit the domain, add the cookie, then refresh

Correct. The browser cannot store a cookie before it knows the site, and the app must reload to read it.

Visit, add cookie, refresh. This order catches almost everyone the first time.

Why the other answers are wrong

  • Add the cookie, then visit the domain. Setting a cookie before any navigation fails, because there is no domain context yet.
  • Add the cookie and continue without reloading. The already-loaded page will not pick it up.
  • Cookies cannot be set through Selenium. driver.manage().addCookie() exists for this.

6. Why create test data through an HTTP request instead of the UI form?

Answer

It takes milliseconds instead of seconds and does not break when the form changes

Correct. Selenium has no built-in HTTP client, so use a normal library like axios or fetch in your setup.

Set up through the API and spend the test's time on the behaviour you are actually checking.

Why the other answers are wrong

  • It tests more of the application. It tests less. Speed and stability are the reasons.
  • Selenium cannot fill forms reliably. It fills forms fine. This is about cost.
  • It removes the need for waits. You may still wait for the UI to show the data.

7. Two tests both create a contact named 'Dana Fox'. What happens?

Answer

They pass alone and fail together, and the failure moves around once the suite is split across machines

Correct. Shared data is the classic cause of failures nobody can reproduce. Add a unique value to the name.

Give each test data no other test uses, for example by appending Date.now() to the name.

Why the other answers are wrong

  • Nothing; each test has its own database. Tests usually share an environment.
  • Both fail immediately. They pass alone, which is what makes this hard to diagnose.
  • Selenium prevents duplicate data. Selenium knows nothing about your application data.

8. What is the safest default for browser sessions across a suite?

Answer

A fresh browser per test, created in beforeEach and quit in afterEach

Correct. It is slower, but no test can inherit cookies, login state or leftovers from another.

Fresh session per test is the safe default. Optimise elsewhere before you share browsers.

Why the other answers are wrong

  • One browser shared by all tests for speed. That reintroduces every dependency problem and makes single tests unrunnable.
  • One browser per file, shared inside it. Better than one for everything, but tests inside the file can still affect each other.
  • It does not matter. It decides whether your tests are independent.

9. A custom wait needs to return the rows only when exactly one remains. How do you write it?

Answer

Pass a function to driver.wait that returns the rows when the count is right and null otherwise

Correct. Returning null (or false) keeps polling; returning a value ends the wait and yields it.

Return null to keep waiting, a value to finish. This pattern solves most Selenium waiting problems.

Why the other answers are wrong

  • Use driver.sleep until the count settles. A sleep is a guess and does not adapt to a slow run.
  • Loop with findElements and no timeout. An unbounded loop can hang forever and hammers the driver.
  • Custom conditions are not supported. driver.wait accepts any function, which is one of its best features.

10. Where should assertions live when using Page Objects?

Answer

In the test, not in the page object

Correct. Page objects hold locators and actions. Assertions inside them hide what a test proves.

If you cannot see what a test proves without opening another file, the split has gone too far.

Why the other answers are wrong

  • In the page object, so they can be reused. Reuse is not worth losing the ability to read a test and see what it checks.
  • In the base page class. That hides the checks even further from the test.
  • In afterEach. Checks belong where the behaviour is exercised.

11. A test fails on the build server but never locally. What should you add first?

Answer

A screenshot saved on failure in afterEach

Correct. Selenium records nothing by itself. Without evidence, a CI failure is a stack trace and a guess.

Make failures leave evidence first. Screenshots and browser logs answer most CI mysteries.

Why the other answers are wrong

  • A longer timeout everywhere. That hides the symptom and slows every run.
  • More retries. Retries make the failure invisible without fixing it.
  • A sleep before the failing step. A guess, and it will fail again on a slower day.

12. How do you read JavaScript errors from the page in Selenium?

Answer

driver.manage().logs().get('browser')

Correct. Some test failures are caused by an app error that never appears in the UI.

Browser logs often explain a failure that the screenshot only hints at.

Why the other answers are wrong

  • driver.getPageSource(). That gives HTML, not console output.
  • Selenium cannot access browser logs. It can, and it is useful when a page silently breaks.
  • By taking a screenshot. A screenshot shows the result, not the error message.

13. What is the difference between until.elementLocated and until.elementIsVisible?

Answer

Located means it exists in the DOM; visible means the user can actually see it

Correct. An element can exist while hidden, so choose the condition that matches your claim.

Wait for existence when you need the node, visibility when the user must see it.

Why the other answers are wrong

  • They are the same. Existence and visibility are different states.
  • elementIsVisible also scrolls to the element. Wait conditions do not act on the page.
  • elementLocated only works with CSS. Both accept any locator strategy.

14. Which check proves a search narrowed a table, rather than that one row exists?

Answer

Counting the rows with findElements and asserting the count dropped to 1

Correct. If the filter is ignored, the matching row is still visible, so presence proves nothing.

A filter is defined by what it removes. Assert the size of the result.

Why the other answers are wrong

  • Asserting the matching row is displayed. That passes when the filter did nothing at all.
  • Asserting the search box contains your text. That checks what you typed, not what happened.
  • Asserting the table exists. It exists either way.

15. How do you assert that an element is NOT present?

Answer

findElements and check that the returned list has length 0

Correct. findElements returns an empty list instead of throwing, which makes absence a simple length check.

findElements + length 0 is the standard absence assertion in Selenium.

Why the other answers are wrong

  • findElement inside try/catch and pass when it throws. It works, but it is noisy and easy to get wrong. The list check is cleaner.
  • isDisplayed() on the element. You cannot call a method on an element you could not find.
  • Absence cannot be checked in Selenium. findElements makes it straightforward.

16. A shared base class contains driver setup used by every test. What is the main risk?

Answer

Hidden global settings, like an implicit wait, that affect every test and are hard to find

Correct. This is how a 30-second implicit wait can sit unnoticed for years and slow an entire suite.

Shared setup is useful, but audit it. Global timing settings hide there and affect everything.

Why the other answers are wrong

  • Base classes are not supported in test frameworks. They are common and often useful.
  • It makes tests run in parallel unsafely. That depends on what the class does, not on inheritance itself.
  • It prevents using page objects. The two work together fine.

17. What is the purpose of driver.wait returning the element it waited for?

Answer

You can use it immediately without a second lookup, which also avoids a stale reference in between

Correct. const toast = await driver.wait(until.elementLocated(...), 5000) gives you a fresh, usable element.

Wait and capture in one step. It reads well and avoids an extra lookup.

Why the other answers are wrong

  • It is returned only for logging. It is the element itself and is meant to be used.
  • It returns a boolean. Locator conditions return the element.
  • The return value must be ignored. Using it is the recommended pattern.

18. Your suite passes in one order and fails in another. What is the cause?

Answer

Tests depend on state another test created, such as data or a shared login

Correct. Give each test its own setup and its own data. Order should never matter.

Run a single test alone. If it fails, it was borrowing state from another test.

Why the other answers are wrong

  • The test runner has a bug. Order sensitivity is nearly always a dependency in the tests.
  • Selenium requires a fixed order. It does not, and relying on order breaks under parallel runs.
  • The browser cache. Possible in rare cases, but shared state is far more likely.

19. When is it acceptable to use driver.sleep?

Answer

Almost never; only when there is genuinely no observable condition to wait for

Correct. Such cases are rare, for example waiting out a fixed animation with no state change to detect.

Wait for a condition. Keep sleep for the rare case where nothing observable changes.

Why the other answers are wrong

  • Whenever a test is flaky. That is the case where a sleep does the most harm.
  • Before every assertion, as a safety measure. It slows every run and does not make anything reliable.
  • Instead of explicit waits, because it is simpler. Simplicity here costs stability and time.

20. Why does a test that only fails on Firefox often indicate a test problem rather than a browser bug?

Answer

Firefox often renders at a different speed, so tests with weak waits fail there first

Correct. A browser-specific failure is worth investigating, but timing assumptions are the more common cause.

Different speed exposes hidden timing assumptions. Check your waits before blaming the browser.

Why the other answers are wrong

  • Firefox does not support Selenium properly. It is fully supported.
  • Firefox ignores CSS selectors. It handles them normally.
  • Tests cannot run on Firefox in CI. They can and commonly do.

Now prove it in code

Knowing the answer and writing the test are different skills. These problems run your test against a working app, then against a copy with the behaviour broken on purpose, and tell you which behaviour your test missed.

More Selenium interview questions

Other frameworks