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 Constant | Example Value | Notes |
|---|---|---|
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_NAMEdoes not accept multiple classes. UseBy.CSS_SELECTORwith".class-a.class-b"instead.
XPath indexing is 1-based, not 0-based:
(//li)[1]is the first item.
find_elementraisesNoSuchElementExceptionimmediately if the element is absent. Use an explicit wait or atry/exceptblock 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.