Quick Reference · Copy-Paste Ready
XPath Cheatsheet with Examples
Everything you need to write robust XPath and CSS selectors — axes, functions, real-world examples from TesterRank practice portals.
XPath Axes
Navigate the DOM tree relative to the current element.
| Axis | Example | Description |
|---|---|---|
| parent | //input[@id="email"]/parent::div | Select the direct parent element |
| child | //div[@class="form"]/child::input | Select direct children |
| ancestor | //input[@id="email"]/ancestor::form | Select any ancestor up the tree |
| descendant | //form/descendant::input | Select any descendant down the tree |
| following-sibling | //label/following-sibling::input | Select siblings after the current node |
| preceding-sibling | //input/preceding-sibling::label | Select siblings before the current node |
XPath Functions
Built-in functions for matching text, attributes, and position.
| Function | Example | Description |
|---|---|---|
| text() | //button[text()="Login"] | Exact text match |
| contains() | //button[contains(text(),"Log")] | Partial text match |
| starts-with() | //input[starts-with(@id,"user")] | Attribute starts with value |
| normalize-space() | //span[normalize-space()="Total"] | Trim whitespace before matching |
| position() | //table/tbody/tr[position()=1] | Select by position (1-indexed) |
| last() | //table/tbody/tr[last()] | Select the last element |
| not() | //input[not(@disabled)] | Negate a condition |
| and / or | //input[@type="text" and @required] | Combine multiple conditions |
XPath vs CSS Selectors
Side-by-side comparison — use CSS when you can, XPath when you need text matching or ancestor traversal.
| Target | CSS Selector | XPath |
|---|---|---|
| By ID | #loginBtn | //*[@id="loginBtn"] |
| By class | .btn-primary | //*[contains(@class,"btn-primary")] |
| By attribute | input[type="email"] | //input[@type="email"] |
| By data-testid | [data-testid="submit"] | //*[@data-testid="submit"] |
| Child element | form > input | //form/input |
| Descendant | form input | //form//input |
| Nth child | tr:nth-child(2) | //tr[2] |
| Text content | (not possible) | //button[text()="Submit"] |
Real Examples from TesterRank
These locators work on our practice portals — try them yourself.
| Portal | Element | XPath | CSS |
|---|---|---|---|
| Banking | Login button | //button[@id="loginBtn"] | #loginBtn |
| Banking | User ID input | //input[@id="userId"] | #userId |
| Shopping | Search box | //input[@data-testid="search-box"] | [data-testid="search-box"] |
| Shopping | Cart icon | //a[contains(@href,"/shopping/cart")] | a[href*="/shopping/cart"] |
| Insurance | Policy table row | //table[@id="policyTable"]//tbody/tr[1] | #policyTable tbody tr:first-child |
| Loan | EMI Calculator link | //a[@id="linkEmiCalc"] | #linkEmiCalc |
Common Mistakes
Using absolute XPath
Avoid
/html/body/div[1]/form/input[2]Better
Use relative XPath with attributes: //input[@id="email"]Matching text with extra whitespace
Avoid
//span[text()="Total Amount"]Better
Use normalize-space(): //span[normalize-space()="Total Amount"]Fragile class-based selectors
Avoid
//*[@class="btn btn-primary btn-lg"]Better
Use contains(): //*[contains(@class,"btn-primary")]Ignoring data-testid
Avoid
//div[3]/button[1]Better
Use data-testid: //button[@data-testid="submit"]Master locators in depth
Chapter 6 of our Selenium course covers locator strategies, dynamic elements, and real-world patterns.
Go to Locators Course