Implicit Wait in Selenium: How It Works and Why to Avoid It (2026)
Implicit wait in Selenium sets a global timeout applied to every find_element call: driver.implicitly_wait(10). The driver retries finding the element for up to 10 seconds before throwing NoSuchElementException. The problem: mixing implicit and explicit waits causes unpredictable behavior. Use explicit waits exclusively — set driver.implicitly_wait(0) and use WebDriverWait per element instead.
Key Takeaways
Implicit wait is global — it applies to every find_element call. Set once, applies everywhere. This sounds convenient but creates hidden timing side effects across your entire test suite.
Never mix implicit and explicit waits. When both are set, wait times can compound unpredictably. The Selenium WebDriver spec explicitly warns against this. Always disable implicit wait (driver.implicitly_wait(0)) if you use explicit waits.
Implicit wait only handles NoSuchElementException. It retries when the element isn't found yet. It does NOT wait for visibility, clickability, or specific conditions — you still get ElementNotInteractableException on hidden elements.
Use explicit wait instead. WebDriverWait(driver, 10).until(EC.element_to_be_clickable(...)) gives you condition-specific waits per element. More precise, more reliable, easier to debug.
time.sleep() is always wrong. Never use fixed sleeps. They waste time when elements load fast and still fail when the network is slow.
What is Implicit Wait in Selenium?
Implicit wait tells the Selenium WebDriver to poll the DOM for a specified amount of time when trying to find an element.
from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(10) # Wait up to 10 seconds globally
After this single line, every subsequent find_element call will:
- Try to find the element immediately
- If not found, retry every 500ms (approximately)
- Continue retrying until the element appears or 10 seconds elapse
- Raise
NoSuchElementExceptionif the element never appears
driver.implicitly_wait(10)
# These all use the 10-second implicit wait automatically
username = driver.find_element(By.ID, "username") # Retries up to 10s
password = driver.find_element(By.NAME, "password") # Retries up to 10s
submit = driver.find_element(By.CSS_SELECTOR, "#submit") # Retries up to 10s
Implicit Wait vs Explicit Wait vs Fluent Wait
| Feature | Implicit Wait | Explicit Wait | Fluent Wait |
|---|---|---|---|
| Scope | Global (all find_element) | Per-element | Per-element |
| Condition | Element exists in DOM | Any condition | Any condition |
| Poll frequency | ~500ms (browser default) | Configurable | Configurable |
| Handles visibility | ❌ No | ✅ Yes | ✅ Yes |
| Handles clickability | ❌ No | ✅ Yes | ✅ Yes |
| Mix safely with others | ❌ No | ✅ Yes | ✅ Yes |
| Recommended | ❌ Avoid | ✅ Use this | ✅ For complex cases |
How to Set Implicit Wait
from selenium import webdriver
driver = webdriver.Chrome()
# Set implicit wait (seconds)
driver.implicitly_wait(10)
# Navigate and find elements
driver.get("https://example.com/login")
username = driver.find_element(By.ID, "username")
username.send_keys("testuser")
To disable implicit wait:
driver.implicitly_wait(0) # Disable — set back to zero
What Implicit Wait Does NOT Handle
This is where most developers get burned. Implicit wait only catches NoSuchElementException. It does not wait for:
Visibility
driver.implicitly_wait(10)
# The element is in the DOM but hidden (display: none)
button = driver.find_element(By.ID, "hidden-button") # Succeeds immediately!
button.click() # ❌ ElementNotInteractableException — element is hidden
Clickability
driver.implicitly_wait(10)
# Element exists and is visible, but disabled
submit = driver.find_element(By.ID, "submit-btn") # Succeeds immediately!
submit.click() # ❌ ElementClickInterceptedException if button is disabled
AJAX Content
driver.implicitly_wait(10)
driver.find_element(By.ID, "load-more").click()
# Tries to find .new-item, but if the DOM element is removed and re-added
# during loading, implicit wait may find a stale reference
items = driver.find_elements(By.CSS_SELECTOR, ".new-item")
# May return stale elements or miss new ones
The Core Problem: Mixing Implicit and Explicit Waits
The most dangerous mistake in Selenium is setting both:
# ❌ Never do this
driver.implicitly_wait(10) # Global 10-second wait
wait = WebDriverWait(driver, 5) # Explicit 5-second wait
# What actually happens?
element = wait.until(EC.visibility_of_element_located((By.ID, "element")))
# Behavior is UNDEFINED — waits can compound, overlap, or interact
# You might wait 10s + 5s = 15s, or 5s, or something else
From the Selenium documentation:
"Warning: Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times."
The WebDriver spec marks this as a known issue. Different browsers implement the interaction differently, making cross-browser tests even more unpredictable.
Why Explicit Wait is Better
Explicit wait gives you condition-specific, per-element control:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
# Disable implicit wait
driver.implicitly_wait(0)
wait = WebDriverWait(driver, 10)
# Wait for element to EXIST (in DOM, may be hidden)
element = wait.until(EC.presence_of_element_located((By.ID, "element")))
# Wait for element to be VISIBLE
element = wait.until(EC.visibility_of_element_located((By.ID, "element")))
# Wait for element to be CLICKABLE (visible + enabled)
element = wait.until(EC.element_to_be_clickable((By.ID, "submit-btn")))
# Wait for specific TEXT to appear
wait.until(EC.text_to_be_present_in_element((By.ID, "status"), "Done"))
# Wait for element to DISAPPEAR
wait.until(EC.invisibility_of_element_located((By.CSS_SELECTOR, ".spinner")))
Each wait is precise. You know exactly what you're waiting for. When a test fails, you know exactly why.
When Implicit Wait Seems Acceptable
There are narrow cases where implicit wait appears useful:
Simple Scripted Tests
# Quick script, not a test suite
driver.implicitly_wait(5)
driver.get("https://example.com")
driver.find_element(By.ID, "login").click()
driver.find_element(By.ID, "username").send_keys("user")
# etc.
For one-off automation scripts (not maintained test suites), implicit wait reduces boilerplate. But even here, explicit waits are more reliable.
Legacy Codebases
If you're inheriting a codebase that uses implicit waits throughout, ripping them all out at once is risky. In this case:
- Keep
driver.implicitly_wait()as-is - Never add
WebDriverWaitalongside it - Gradually refactor to explicit waits module by module
Correct Pattern: Explicit Waits Only
Here's the production-ready pattern:
import pytest
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
@pytest.fixture
def driver():
driver = webdriver.Chrome()
driver.implicitly_wait(0) # Explicitly disabled
yield driver
driver.quit()
def test_login(driver):
wait = WebDriverWait(driver, 10)
driver.get("https://example.com/login")
# Each wait is specific to what we need
username = wait.until(EC.visibility_of_element_located((By.ID, "username")))
username.send_keys("testuser@example.com")
password = driver.find_element(By.ID, "password") # After first element loads, others are present
password.send_keys("password123")
submit = wait.until(EC.element_to_be_clickable((By.ID, "submit-btn")))
submit.click()
# Wait for navigation
wait.until(EC.url_contains("/dashboard"))
# Verify dashboard loaded
welcome = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".welcome-message")))
assert "testuser" in welcome.text.lower()
Checking if Implicit Wait is Set
There's no direct getter in Selenium Python for the current implicit wait value. Track it yourself:
class BrowserDriver:
def __init__(self):
self._driver = webdriver.Chrome()
self._implicit_wait = 0
self._driver.implicitly_wait(self._implicit_wait)
def set_implicit_wait(self, seconds: int):
self._implicit_wait = seconds
self._driver.implicitly_wait(seconds)
def disable_implicit_wait(self):
self.set_implicit_wait(0)
Implicit Wait in Selenium Java
The same rules apply in Java:
// Set implicit wait
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
// Disable implicit wait
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(0));
// ❌ Never mix with explicit wait
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
// Unpredictable behavior when both are set
Implicit Wait in Selenium JavaScript (WebDriverJS)
// Set implicit wait
await driver.manage().setTimeouts({ implicit: 10000 }); // milliseconds
// Disable
await driver.manage().setTimeouts({ implicit: 0 });
// ✅ Use explicit wait instead
const { until, By } = require('selenium-webdriver');
await driver.wait(until.elementLocated(By.id('element')), 10000);
await driver.wait(until.elementIsVisible(element), 10000);
Migration: From Implicit to Explicit Waits
If you're refactoring away from implicit waits:
Before (implicit wait):
driver.implicitly_wait(10)
driver.get("https://example.com/products")
product = driver.find_element(By.CSS_SELECTOR, ".product-card")
product.click()
add_to_cart = driver.find_element(By.ID, "add-to-cart")
add_to_cart.click()
cart_count = driver.find_element(By.ID, "cart-count")
assert cart_count.text == "1"
After (explicit wait):
driver.implicitly_wait(0)
wait = WebDriverWait(driver, 10)
driver.get("https://example.com/products")
product = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".product-card")))
product.click()
add_to_cart = wait.until(EC.element_to_be_clickable((By.ID, "add-to-cart")))
add_to_cart.click()
cart_count = wait.until(EC.text_to_be_present_in_element((By.ID, "cart-count"), "1"))
The explicit version catches more failures (hidden elements, disabled buttons) and gives clearer error messages when things go wrong.
The Alternative: AI Handles All Waits
Selenium requires you to choose between implicit and explicit waits — both have trade-offs. HelpMeTest eliminates the choice entirely:
Go to https://example.com/login
Type "testuser@example.com" in the email field
Type "password123" in the password field
Click the "Sign In" button
Verify the dashboard page loads
The AI waits for each element to be ready before interacting — no implicitly_wait, no WebDriverWait, no time.sleep. It behaves like a human: it sees the page and waits until elements are actually interactable.
Implicit/explicit waits matter when:
- Maintaining existing Selenium test suites
- Working in teams with mixed testing backgrounds
- Migrating from legacy test infrastructure
When to reconsider:
- New test projects without legacy constraints
- Non-technical team members need to write tests
- Test maintenance is consuming more time than feature development
Summary
Implicit wait in Selenium:
# Set (applies globally to all find_element calls)
driver.implicitly_wait(10)
# Disable (required before using explicit waits)
driver.implicitly_wait(0)
Rules:
- Never mix implicit and explicit waits — behavior is undefined
- Implicit wait only handles
NoSuchElementException, not visibility/clickability - Use
WebDriverWait+expected_conditionsfor reliable, precise waits - Set
driver.implicitly_wait(0)in your test fixture if using explicit waits time.sleep()is always wrong — never use fixed sleeps in tests