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 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.