Selenium Cheatsheet

Waits

Use this Selenium reference while you build software engineering projects, review code, or refresh the syntax you reach for most.

Wait Types Overview

TypeModuleWhen to Use
Implicit waitdriver.implicitly_wait(n)Simple projects; sets a global timeout for find_element
Explicit waitWebDriverWait + expected_conditionsProduction; wait for a specific condition
Fluent waitWebDriverWait with poll_frequency + ignored_exceptionsCustom polling, ignore transient errors
time.sleep()stdlibLast resort / debugging only

Never mix implicit and explicit waits — implicit wait shifts the timeout baseline and makes explicit waits behave unpredictably.

Implicit Wait

driver.implicitly_wait(10)  # seconds; applied globally to every find_element call

Set once after creating the driver. Polls the DOM up to the timeout before raising NoSuchElementException.

Explicit Wait

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

wait = WebDriverWait(driver, timeout=10)

# Wait until element is present in DOM
el = wait.until(EC.presence_of_element_located((By.ID, "result")))

# Wait until element is visible AND interactable
el = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.submit")))

# Wait until element disappears
wait.until(EC.invisibility_of_element_located((By.CLASS_NAME, "spinner")))

Expected Conditions Reference

ConditionDescription
presence_of_element_located(locator)Element in DOM (may be hidden)
visibility_of_element_located(locator)Element visible and has size
visibility_of(element)Existing element becomes visible
element_to_be_clickable(locator)Visible + enabled
invisibility_of_element_located(locator)Not visible or not in DOM
element_to_be_selected(element)Checkbox/radio is selected
element_located_to_be_selected(locator)Locator resolves to selected element
presence_of_all_elements_located(locator)At least one element present
visibility_of_all_elements_located(locator)All elements visible
text_to_be_present_in_element(locator, text)Element's text contains text
text_to_be_present_in_element_value(locator, text)Element's value attr contains text
title_is(title)Page title equals string
title_contains(title)Page title contains string
url_contains(url)Current URL contains string
url_matches(pattern)Current URL matches regex
url_to_be(url)Current URL equals string
url_changes(url)Current URL differs from given
frame_to_be_available_and_switch_to_it(locator)Frame ready; switches into it
alert_is_present()Alert/confirm/prompt dialog is open
staleness_of(element)Element no longer attached to DOM
number_of_windows_to_be(num)Given number of windows/tabs open
new_window_is_opened(handles)A new window opened vs prior handles

Full Explicit Wait Examples

wait = WebDriverWait(driver, 15)

# Title
wait.until(EC.title_contains("Dashboard"))

# URL
wait.until(EC.url_contains("/dashboard"))

# Text in element
wait.until(EC.text_to_be_present_in_element((By.ID, "status"), "Complete"))

# All elements
rows = wait.until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "tr.data-row")))

# Alert
wait.until(EC.alert_is_present())

# Stale element gone (e.g. after page reload)
wait.until(EC.staleness_of(old_element))

Fluent Wait

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException

wait = WebDriverWait(
    driver,
    timeout=20,
    poll_frequency=0.5,                             # check every 0.5s (default 0.5)
    ignored_exceptions=[NoSuchElementException, StaleElementReferenceException]
)

el = wait.until(EC.element_to_be_clickable((By.ID, "dynamic-btn")))

Custom Wait Condition (Lambda)

# Wait until a custom condition is truthy
wait.until(lambda d: d.find_element(By.ID, "counter").text == "10")

# Wait until count of elements equals N
wait.until(lambda d: len(d.find_elements(By.CLASS_NAME, "item")) == 5)

# Wait for attribute value
wait.until(lambda d: "active" in d.find_element(By.ID, "tab").get_attribute("class"))

Custom Wait Condition (Class)

class element_has_css_class:
    def __init__(self, locator, css_class):
        self.locator = locator
        self.css_class = css_class

    def __call__(self, driver):
        el = driver.find_element(*self.locator)
        return self.css_class in el.get_attribute("class")

wait.until(element_has_css_class((By.ID, "panel"), "expanded"))

wait.until_not

# Wait until condition is FALSE
wait.until_not(EC.visibility_of_element_located((By.ID, "loading-overlay")))
wait.until_not(lambda d: "disabled" in d.find_element(By.ID, "btn").get_attribute("class"))

Timeout Handling

from selenium.common.exceptions import TimeoutException

try:
    wait.until(EC.element_to_be_clickable((By.ID, "submit")))
except TimeoutException:
    print("Element never became clickable within timeout")

Gotchas

element_to_be_clickable does not guarantee a click will succeed if an overlay appears between the wait resolving and your click. Retry logic may be needed.

presence_of_element_located does not mean the element is visible. Use visibility_of_element_located to confirm it is rendered on screen.

Stale element references occur when the DOM refreshes after you located the element. Re-locate the element after any navigation or dynamic DOM update.