Handling Waits (Implicit, Explicit, Fluent)
Wait handling is the most critical skill in Selenium automation. The #1 cause of flaky tests is improper waits — either tests fail because elements haven't loaded yet, or they waste time with excessive hardcoded sleeps. Professional SDETs use explicit waits with expected conditions to create tests that are both fast and reliable.
Three Types of Waits
- Implicit Wait: Global wait applied to ALL find_element calls. Sets how long WebDriver polls for an element before throwing NoSuchElementException. Set once, applies everywhere.
- Explicit Wait: Targeted wait for a SPECIFIC condition on a SPECIFIC element. Most flexible and recommended for production tests.
- Fluent Wait: Advanced explicit wait with custom polling interval and ignored exceptions. Used for complex scenarios like animations.
- Thread.sleep() / time.sleep(): NEVER USE in test code. Wastes time unconditionally. Makes tests slow and still flaky.
All Wait Types with Best Practice Examples
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
import time
driver = webdriver.Chrome()
# ── IMPLICIT WAIT (set once, global) ─────────────────────────
driver.implicitly_wait(10) # 10 seconds max wait for all find_element calls
# Good for: simple apps, getting started, fallback
# Bad for: dynamic content, SPAs, elements that appear/disappear
# ── EXPLICIT WAIT (recommended — targeted and fast) ──────────
wait = WebDriverWait(driver, timeout=15) # Create wait object
# Wait for element to be VISIBLE (in DOM and visible to user)
email_field = wait.until(EC.visibility_of_element_located((By.ID, "email")))
# Wait for element to be CLICKABLE (visible AND enabled)
submit_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '[data-testid="submit"]')))
# Wait for text to appear in element
wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR, ".status"), "Order confirmed"))
# Wait for URL to change (after redirect)
wait.until(EC.url_contains("/dashboard"))
# Wait for element to DISAPPEAR (spinner/loader gone)
wait.until(EC.invisibility_of_element_located((By.CSS_SELECTOR, ".loading-spinner")))
# Wait for number of elements to be greater than N
wait.until(EC.number_of_windows_to_be(2))
# ── FLUENT WAIT (custom polling interval + exception ignoring) ─
from selenium.common.exceptions import NoSuchElementException
fluent_wait = WebDriverWait(
driver,
timeout=30, # Max wait: 30 seconds
poll_frequency=0.5, # Check every 500ms (not every 500ms default)
ignored_exceptions=[NoSuchElementException] # Ignore while waiting
)
# Good for: animations that take variable time, slow API responses
slowly_loading_element = fluent_wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, ".data-table tr"))
)
# ── WHAT NOT TO DO ────────────────────────────────────────────
# ❌ NEVER DO THIS:
time.sleep(5) # Wastes 5 seconds even if element loads in 0.1s
# AND still fails if element takes 6 seconds
# ❌ BAD: implicit + explicit mixed (doubles wait time):
driver.implicitly_wait(10)
wait = WebDriverWait(driver, 15)
# When element doesn't exist: waits 10s (implicit) + 15s (explicit) = 25s!Common Mistakes
- Using time.sleep() — the cardinal sin of test automation; use explicit waits that return as soon as the condition is met
- Mixing implicit and explicit waits — they interact unpredictably and can double your wait times; choose one strategy
- Waiting for presence, not visibility — an element can be in the DOM but invisible (display:none); always wait for visibility_of_element_located for interactive elements
- Same timeout for all waits — a page load might need 30s; a button click response needs 2s; use context-appropriate timeouts
Tip
Tip
Practice Handling Waits Implicit Explicit Fluent in small, isolated examples before integrating into larger projects. Breaking concepts into small experiments builds genuine understanding faster than reading alone.
Testing pyramid: many unit tests, fewer integration, fewest E2E
Practice Task
Note
Practice Task — (1) Write a working example of Handling Waits Implicit Explicit Fluent from scratch without looking at notes. (2) Modify it to handle an edge case (empty input, null value, or error state). (3) Share your solution in the Priygop community for feedback.
Quick Quiz
Common Mistake
Warning
A common mistake with Handling Waits Implicit Explicit Fluent is skipping edge case testing — empty inputs, null values, and unexpected data types. Always validate boundary conditions to write robust, production-ready software testing code.
Key Takeaways
- Wait handling is the most critical skill in Selenium automation.
- Implicit Wait: Global wait applied to ALL find_element calls. Sets how long WebDriver polls for an element before throwing NoSuchElementException. Set once, applies everywhere.
- Explicit Wait: Targeted wait for a SPECIFIC condition on a SPECIFIC element. Most flexible and recommended for production tests.
- Fluent Wait: Advanced explicit wait with custom polling interval and ignored exceptions. Used for complex scenarios like animations.