Skip to content
Latchkey

Selenium "TimeoutException" waiting for an element in CI

WebDriverWait polls an expected condition until it is true or the timeout elapses. When the condition never holds in time, Selenium raises TimeoutException. In CI this often means the page or its API responded slower than the wait allowed.

What this error means

A test fails with "selenium.common.exceptions.TimeoutException: Message:" (often with an empty message) at a WebDriverWait line. The same wait passes locally with a faster app.

selenium
selenium.common.exceptions.TimeoutException: Message:
  File "tests/test_login.py", line 22, in test_login
    WebDriverWait(driver, 10).until(EC.url_contains("/dashboard"))

Common causes

The app responded slower than the timeout

A contended CI runner or a cold backend made the navigation or render exceed the (often default 10s) wait.

The condition can never become true

A wrong selector or a URL that never matches means the condition is unsatisfiable, so it always times out regardless of duration.

How to fix it

Wait on the right condition with a sane timeout

  1. Confirm the condition (URL, visibility, text) actually occurs in the flow.
  2. Raise the timeout for CI where the backend is slower than local.
  3. Re-run and verify the wait now resolves instead of timing out.
python
WebDriverWait(driver, 30).until(
    EC.visibility_of_element_located((By.CSS_SELECTOR, "[data-test=welcome]")))

Stabilize the backend the test depends on

If the timeout traces to a slow or cold service, warm it or wait for a health endpoint before driving the UI so the condition is reachable.

.github/workflows/ci.yml
- run: curl --retry 10 --retry-connrefused http://localhost:3000/healthz

How to prevent it

  • Set CI wait timeouts higher than local to absorb runner slowness.
  • Wait on stable conditions, not transient animation states.
  • Health-check the app before the UI test starts.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →