Selenium Cheatsheet

Locators

Use this Selenium reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

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.