Reference - XPath and Locators
Jump to navigation
Jump to search
|
What can we help you find? |
Random | ||||||||||||||||
| Home | Testing | Automation | AI | IoT | OS | RF | Data | Development | References | Tools | Wisdom | Inspiration | Investing | History | Fun | POC | Help |
XPath Locator Fundamentals
The following are Best Practice XPath models to be used in object location for automated testing. A few fundamental rules to apply when setting up object locators.
- Tune XPath locators using Chrome browser and Developer Tools. Craft minimum number of attributes necessary to reliably locate an object, typically 1 HTML Tag and 1 Attribute Tag are all that’s needed.
- Locators should typically begin with an HTML Tag followed by an Attribute Tag such as ID or Name.
- Error on the side of data-testid, id or Name attributes as these tend not to change as often when an application goes through look-and-feel changes.
- Avoid using Class or other look-and-feel attributes in XPath locators as these are most likely to change over time.
| Most to Least Desirable Locator Attributes | |||
|---|---|---|---|
| Multi | Description | XPath | HTML Sample |
data-testid
|
{xpath: "//input[@data-testid='TransferAmount']"}
|
||
id
|
{xpath: "//button[@id='ChangePasswordForm_save']"}
|
||
value
|
{xpath: "//input[@value='Get the Free Guide!']"}
|
||
class
|
{xpath: "//button[@class='ResetBudget']"}
|
||
type
|
{xpath: "//input[@type='password']"}
|
||
contains(text)
|
{xpath: "//div[contains(text(), 'Transactions')]"}
|
||
name()
|
{xpath: "//*[name()='svg' and @class='ct-chart-line']"}
|
||
| XPath Best Practice Examples | |||
|---|---|---|---|
| Multi | Description | XPath | HTML Sample |
Page containing Text
|
{xpath: "//*[text()='Start free trial']"}
|
||
Page containing Text with escaped apostrophe
|
{xpath: "//*[text()='Don\'t remember it? No problem,']"}
|
||
Header containing Text
|
{xpath: "//h1[contains(text(),'Dashboard')]"}
|
||
Header containing Text (normalized)
|
{xpath: "//h6[normalize-space()='My Timesheets']"}
|
| |
Anchor containing Text
|
{xpath: "//a[contains(text(),'Remove')]"}
|
<a href="www.someurl.com">Remove</a>
| |
Anchor containing href
|
{xpath: "//a[contains(@href,'/report/admin/advisors/')]"}
|
<a href="/report/admin/advisor">5417 QA</a>
| |
Anchor with class
|
{xpath: "//a[@class='AppBadges']"}
|
<a class="AppBadges" href="https://itunes.apple.com">
| |
Button with ID
|
{xpath: "//button[@id='company_advisor']"}
|
<button id="company_advisor">Add Advisor</button>
| |
Button containing Text
|
{xpath: "//button[contains(text(),'Create My Account')]"}
|
<button type="button">Create My Account</button>
| |
Span containing Text
|
{xpath: "//span[contains(text(),'Next')]"}
|
||
Input with Name
|
{xpath: "//input[@name='firstName']"}
|
||
Input with Value, Indexed
|
{xpath: "(//input[@value='View Details'])[2]"}
|
||
Select with Name
|
{xpath: "//select[@name='country']"}
|
<select name="country">
| |
Select with ID
|
{xpath: "//select[@id='salesforce_web_lead']"}
|
<select id="salesforce_web_lead">
| |
Textarea with ID
|
{xpath: "//textarea[@id='salesforce_web_lead_description']"}
|
||
Span with Class containing specific text
|
{xpath: "//span[@class='card-title'][contains(text(),'Income')]"}
|
<span class="card-title">Income</span>
| |
Named element with class
|
{xpath: "//*[name()='svg' and @class='ct-chart-line']"}
|
<svg xmlns:ct="http://www.github.com/chartist-js/ct" class="ct-chart-line"></svg>
| |
Named element with attribute
|
line = //*[name()='line' and @y1='213']
|
<line y1="213" y2="213" x1="50" x2="544.453125" class="ct-grid ct-vertical"></line>
| |
*
|
Section with class name & Span containing text
|
{xpath: "//section[@class='HeroRow']//span[contains(text(),'Live')]"}
|
<section class="HeroRow">
|
*
|
Sibling and value
|
{xpath: "//h2[contains(text(),'Profit')]/following-sibling::progress[@value='100']"}
|
<h2 class="gzl-Heading">Profit</h2>
|
*
|
Element and value
|
{xpath: "//h3[(@class='desserts') and (contains(text(),'Cookie'))]"}
|
<h3 class="desserts">Cookie</h3>
|
iFrame containing text
|
{xpath: "//iframe[contains(@src,'cardNumber')]"}
|
<iframe src="https://js.stripe.com/card.html[color]=%23CFD7E0;componentName=cardNumber;"></iframe>
| |
| XPath Brittle Examples | |||
|---|---|---|---|
| Multi | Description | XPath | HTML Sample |
The XPath will match any input on the page containing the word Save and is not precise enough.
|
{xpath: "//input[@value='Save']"}
|
Matches any input containing "Save"
| |
This XPath provides no clues to what it actually references. The nesting of 3 div tags, anchor tags and a span make this extremely unintuitive and brittle.
|
{xpath: ".//*[@id='main']/section/div[3]/a/span"}
|
Brittle and unintuitive
| |
Another overly nested XPath that provides no clue to what it actually references.
|
{xpath: ".//*[@id='main']/section/div[2]/div[2]/a/span"}
|
Brittle and unintuitive
| |
Another overly nested XPath that provides no clue to what it actually references.
|
{xpath: ".//*[@id='main_navigation']/ol[2]/li[2]/a"}
|
Brittle and unintuitive
| |
Another overly nested XPath that provides no clue to what it actually references.
|
{xpath: "//table[@id=':if']//tbody[1]//tr[1]"}
|
Brittle and unintuitive
| |
The XPath must match this entire string to pass. Unless this exact string is required, this text should be trimmed down to a much smaller sample.
|
{xpath: "//*[text()='Your email is already in use. Simply enter your existing password below.']"}
|
Excessively long and brittle
| |
This XPath should probably only contain the H2 tag and ID which would be queried to determine if "Firms" existed within it.
|
{xpath: "//h2[@id='page_title'][contains(text(), "Firms")]"}
|
Excessive locators
| |
The iFrame should be referenced by name or ID if possible. This may be acceptable in certain scenarios. Talk to Dev about adding naming to make this better testable.
|
{xpath: "//iframe[@tabindex='-1']"}
|
Exclusively referenced by Index
| |
| XPath Special Examples | |||
|---|---|---|---|
| Multi | Description | XPath | HTML Sample |
Entire HTML Source Code
|
{xpath: "/html"}
|
||
HTML Body Source Code
|
{xpath: "/html/body"}
|
||
All Links
|
{xpath: "//a"}
|
||
All Images
|
{xpath: "//img"}
|
||
All JPG Images
|
{xpath: "//img[contains(@src,'.jpg')]"}
|
||
All JPG Images (alt 1)
|
{xpath: "//*[contains(@src,'.jpg')]"}
|
||
All GIF Images
|
{xpath: "//img[contains(@src,'.gif')]"}
|
||
All PNG Images
|
{xpath: "//img[contains(@src,'.png')]"}
|
||
All SVG Images
|
{xpath: "//img[contains(@src,'.svg')]"}
|
<img src="https://cdn.paskalfamily.com/footer-logo.svg">
| |
All JPG or PNG Images
|
{xpath: "//img[contains(@src,'.jpg') or contains(@src,'.png')]"}
|
||
| Locator Naming Convention and Abbreviations | ||
|---|---|---|
| Description | Abbreviation | Example |
Button
|
BUT
|
LO_BUT_SEARCH = { xpath: "//input[@value='Search']" }.freeze
|
Checkbox
|
CBX
|
LO_CBX_TERMS_AND_CONDITIONS = { xpath: "//input[@id='termsAccepted']" }.freeze
|
Dialog Box
|
DIA
|
LO_DIA_ORDER_CONFIRMED
|
Dropdown List
|
DPD
|
LO_DPD_STATE = { xpath: "//select[@id='state']" }.freeze
|
Edit Box
|
EDT
|
LO_EDT_WEIGHT = { xpath: "//input[@name='weight']" }.freeze
|
Edit Textarea
|
ETX
|
LO_ETX_DETAILS
|
iFrame
|
IFRAME
|
LO_IFRAME_STRIPE = { xpath: "//iframe[contains(@data-src, 'stripe')]" }.freeze
|
Image
|
IMG
|
LO_IMG_GOOGLE = { xpath: "//img[@id='hplogo']" }.freeze
|
Hyperlink
|
LNK
|
LO_LNK_AMAZON = { xpath: "//a[@id='amazonOrder']" }.freeze
|
Menu
|
MNU
|
LO_MNU_MAIN
|
Menu Item
|
MUI
|
LO_MUI_PRIN
|
Radio Button
|
RDO
|
LO_RDO_SHIPPING = { xpath: "//label[@for='shipping_ups']" }.freeze
|
Text
|
TXT
|
LO_TXT_DESCRIPTION = { xpath: "//h2[contains(text(), 'This Texas BBQ is one of the best')]" }.freeze
|
Toolbar
|
BAR
|
LO_BAR_TOOLS
|
Window
|
WIN
|
LO_WIN_SETTINGS
|
XPath Learning and References:
XPath Tutorial - https://www.w3schools.com/xml/xpath_intro.asp
XPath Syntax Details - https://www.w3schools.com/xml/xpath_syntax.asp
Online XPath Experimentation Tool - http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm
Another xPath Cheatsheet - https://devhints.io/xpath