Selenium Cheatsheet

Locators

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

Locator Strategy Overview

All locators live in selenium.webdriver.common.by.By.

By ConstantExample ValueNotes
By.ID"submit-btn"Fastest; IDs must be unique
By.NAME"username"Matches name attribute
By.CLASS_NAME"nav-link"Single class only (no spaces)
By.TAG_NAME"input"Returns all matching tags
By.LINK_TEXT"Sign in"Exact text of an <a>
By.PARTIAL_LINK_TEXT"Sign"Substring match on <a> text
By.CSS_SELECTOR"div.card > a"Flexible; near-universal support
By.XPATH"//button[@type='submit']"Most powerful; can be fragile

find_element vs find_elements

from selenium.webdriver.common.by import By

# Single element — raises NoSuchElementException if not found
el = driver.find_element(By.ID, "username")

# All matching elements — returns empty list if none found
els = driver.find_elements(By.CLASS_NAME, "item")

Locator Examples

# By ID
driver.find_element(By.ID, "main-nav")

# By Name
driver.find_element(By.NAME, "q")

# By Class (single class only)
driver.find_element(By.CLASS_NAME, "btn-primary")

# By Tag
inputs = driver.find_elements(By.TAG_NAME, "input")

# By Link Text (exact)
driver.find_element(By.LINK_TEXT, "Forgot Password?")

# By Partial Link Text
driver.find_element(By.PARTIAL_LINK_TEXT, "Forgot")

CSS Selectors

# Basic
driver.find_element(By.CSS_SELECTOR, "#login-form")         # by id
driver.find_element(By.CSS_SELECTOR, ".error-msg")          # by class
driver.find_element(By.CSS_SELECTOR, "input[type='email']") # by attribute
driver.find_element(By.CSS_SELECTOR, "div > p.lead")        # child combinator

# Multiple classes
driver.find_element(By.CSS_SELECTOR, "button.btn.btn-lg")

# nth-child
driver.find_element(By.CSS_SELECTOR, "ul.menu li:nth-child(2)")

# Attribute contains
driver.find_element(By.CSS_SELECTOR, "[href*='dashboard']")

# Attribute starts with
driver.find_element(By.CSS_SELECTOR, "[id^='row-']")

# Attribute ends with
driver.find_element(By.CSS_SELECTOR, "[id$='-btn']")

# Sibling
driver.find_element(By.CSS_SELECTOR, "label + input")

XPath

# Absolute (fragile — avoid)
driver.find_element(By.XPATH, "/html/body/div[2]/form/input[1]")

# Relative (preferred)
driver.find_element(By.XPATH, "//input[@id='username']")
driver.find_element(By.XPATH, "//button[@type='submit']")
driver.find_element(By.XPATH, "//a[text()='Login']")
driver.find_element(By.XPATH, "//a[contains(text(),'Login')]")
driver.find_element(By.XPATH, "//div[contains(@class,'card')]")
driver.find_element(By.XPATH, "//input[@name='email' and @required]")

# Navigate axes
driver.find_element(By.XPATH, "//label[text()='Email']/following-sibling::input")
driver.find_element(By.XPATH, "//input[@id='pw']/ancestor::form")
driver.find_element(By.XPATH, "//ul[@class='menu']/child::li[3]")
driver.find_element(By.XPATH, "//td[text()='Alice']/../td[2]")  # sibling cell

# XPath functions
driver.find_element(By.XPATH, "//button[starts-with(@id,'btn-')]")
driver.find_element(By.XPATH, "(//input[@type='text'])[2]")     # 2nd match
driver.find_element(By.XPATH, "//p[normalize-space(text())='Hello']")

Scoped Lookups (element as root)

container = driver.find_element(By.ID, "product-list")
items = container.find_elements(By.CLASS_NAME, "product-card")
first_title = items[0].find_element(By.CSS_SELECTOR, "h2.title")

Relative Locators (Selenium 4+)

from selenium.webdriver.support.relative_locator import locate_with

email_input = driver.find_element(By.ID, "email")

# Locate password field BELOW the email field
pwd = driver.find_element(
    locate_with(By.TAG_NAME, "input").below(email_input)
)

# Other relative directions
driver.find_element(locate_with(By.TAG_NAME, "button").to_right_of(email_input))
driver.find_element(locate_with(By.TAG_NAME, "label").above(email_input))
driver.find_element(locate_with(By.TAG_NAME, "div").to_left_of(email_input))
driver.find_element(locate_with(By.TAG_NAME, "p").near(email_input))  # within 50px

Storing Locators as Tuples

# Best practice: store (By, value) tuples for reuse
LOGIN_BTN  = (By.ID, "login-btn")
EMAIL_FIELD = (By.NAME, "email")

driver.find_element(*LOGIN_BTN).click()
driver.find_element(*EMAIL_FIELD).send_keys("user@example.com")

Gotchas

By.CLASS_NAME does not accept multiple classes. Use By.CSS_SELECTOR with ".class-a.class-b" instead.

XPath indexing is 1-based, not 0-based: (//li)[1] is the first item.

find_element raises NoSuchElementException immediately if the element is absent. Use an explicit wait or a try/except block when the element may not be present yet.

Avoid absolute XPaths — they break on any DOM restructure. Always anchor to a stable id or attribute.