Professional Documents
Culture Documents
Selenium test automation engineers must be very comfortable in locating elements in web
pages. XPath and CSS are very powerful location strategies used in Selenium as compared to
other location strategies (id, name, link, partialLinkText, tagName etc) .
Mastering XPath or CSS is essential for the Selenium test automation engineers to locate
dynamic web elements.
It is noted that new Selenium automation engineers do not pay much attention to master
location strategies. This leads to failure of test automation efforts when web pages with dynamic
contents are automated.
Most of the testers rely on extracting the XPaths from Firebug/Firepath like tools. The tools
cannot be used directly for dynamic web elements.
I have my own way of introducing (explaining) XPath to the trainees in my training sessions.
When A=B and B=C. I ask the students what can be derived from these expressions.
Immediately they reply with A=C.
Hence XPath can be used for locating elements in HTML pages/web pages.
Hence we may have to locate them differently than the static elements.
Locate elements with respective a known element
Locate elements with partial fixed attribute values
Locate element without attributes or without unique attributes
XPath can do bidirectional navigation (Going forward and backward)
XPath is one of most flexible and strongest location strategy
Types of XPath
Absolute XPath
Absolute XPaths starts with the root of the html pages.
Absolute XPaths are not advisable for most of the time due to following reasons
Absolute XPaths are lengthier and not readable
Absolute XPaths are brittle when minor structural changes are done to the web pages
Absolute XPaths shall be used only when a relative a XPath cannot be constructed. (highly
unlikely). Absolute XPaths tends to break as web pages/content is changed. Hence it not
recommended to use absolute XPath in Selenium.
Most of the beginners tend use absolute XPaths when they copy them from tools like
FireBug. These XPaths are tend to break (brittle) most of the time.
Example : /html/body/div[1]/div/div[2]/form/div[2]/input
Relative XPath
Relative XPaths is used for locating an element from a known element. The element of your
choice is referred relative to a known element.
Example : //div[@id='divUsername']/input
Examples :
To select the third input element : //form/input[3]
To select the last input element : //form/input[last()]
Unique
Descriptive
Unlikely to change
Sample HTML
Following simple HTML is used in most of the CSS examples in this document
<html><body>
<form id=login>
<input name=txtUserName id=txtUsername type=text class=userName >
<input name=txtPassword id=txtPassword type=password class=password >
<input name=submit id=btnLogin type=submit class=button>
</form>
</body></html>
//*[@attributeName=value]
Examples :
1. //*[@id='txtUsername']
2. //*[@name='txtUsername']
3. //*[@type='text']
Third XPath is not used even though it is a valid XPath. BUT It is not unique. There might
be many elements with attribute type=text.
//elementName[@attributeName=value]
Let's consider the username element again
Examples :
1. //input[@id='txtUsername']
2. //input[@name='txtUsername']
3. //input[@type='text']
Third option is valid but it is not unique. Hence it is discouraged to use in test scripts. There
could be many elements with type=text.
//elementName[text()=exact text] or
//*[text()=exact text]
Examples :
//a[text()='Pragmatic']
//*[text()='Pragmatic']
Warning : Locating by the visible text is not advisable if you are testing a multilingual application
and same text is appearing in more than one location.
Locating Elements when part of the visible text is known (partial match)
Examples :
//a[contains(text(),'Orange')]
//a[contains(.,'Orange')]
//*[contains(text(),'Orange')]
Ensure closing brackets are available.
//elementName[starts-with(text(),starting text)] ,
Example :
//a[starts-with(text(),'Orange')]
Example:
//a[contains(@href,'orangehrm.com')]
The ends-with function is part of xpath 2.0. Browsers generally only support 1.0 at the time
of this writing. Hence ends-with is not included.
//*[@attributeName=value]
Example:
//*[@id='txtUsername']
//*[attribute1=value1][attribute2=value2]...[attributeN=valueN]
Example :
//*[@id='txtUsername'][@name='txtUsername']
//elementName[attribute1=value1][attribute2=value2]...[attributeN=valueN]
Example :
//input[@class='button'][@type='submit'][@value='LOGIN'][@name='Submit']
We do this very well in our real life. We always give direction to a new location with respective
an already known location (a landmark). Giving direction to your home from a well know shop,
statue, railway station etc.
XPath has thirteen (13) different axes. We will look into a subset of useful axes in this
document.
When using those axis notations make sure to have a good understanding on the DOM
structure of your web page
//<knownXpath>/parent::* or
//<knownXpath>/parent::elementName
XPath of the known element : //div[@id='divUsername']
Now we can locate the parent form element with respect to the div element
//div[@id='divUsername']/parent::form
Also
//div[@id='divUsername']/parent::*
There can be only one parent to a context (known) element. Hence specifying the element
name is optional.
//<xpathOfKnownElement>/child::<elementName> or
//<xpathOfKnownElement>/child::*
Xpath of the known element //div[@id=divUsername]
Xpath to the child element is //div[@id='divUsername']/child::span
//<xpathOfKnownElement>/ancestor::<elementName>
or //<xpathOfKnownElement>/ancestor::*
Examples :
//input[@id='txtUsername']/ancestor::form
//input[@id=txtUsername]/ancestor::*
//<xpathOfKnownElement>/following::<elementName>
or //<xpathOfKnownElement>/following::*
//input[@id='txtUsername']/following::input
//<xpathOfKnownElement>/preceding::<elementName>
or //<xpathOfKnownElement>/preceding::*
Example :
//*[@id='txtPassword']/preceding::div[1]
: //<xpathOfKnownElement>/following-sibling::<elementName> or
//<xpathOfKnownElement>/following-sibling::*
Example :
//*[@id='txtUsername']/following-sibling::span
//<xpathOfKnownElement>/preceding-sibling::<elementName> or
//<xpathOfKnownElement>/preceding-sibling::*
Example :
//span[contains(text(),'Username')]/preceding-sibling::input
XPath1|Xpath2
If the first xpath is available first element is selected by Selenium for further actions. If both are
available first one is Selected.
Dont keep spaces between the pipe character and the XPaths.
Validating XPath
It is important to ensure XPath used in your automation script is valid before running the script.
There are number of tools available to validate the correctness of the XPaths.
Practice XPath
You can use XLab for practicing the XPath
1. Expressions
2. Axis
XPath or CSS
CSS and XPath are the most popular, widely used and powerful location strategies within the
Selenium test automation community.
CSS has gained wider acceptance from the test automation engineers due to following reasons.
(People in favour of CSS says)
Those who are in favour of XPath says about its ability to transverse around the page where
CSS cannot. XPath can traverse up and down the DOM. CSS can traverse only down the DOM.
These claims may be already outdated :-). Some research demonstrate that there is no
significant difference in speed.
Mastering both of them is a good idea for the Selenium test automation engineers who
wish to build their career around Selenium.
It is better to a use single location strategy for a project for number of reasons.
Some gurus advice hybrid approach. They use ID first and and moving to CSS. XPath is
used only when it is required.
Quick Reference
XPath Description
//*[attribute1=value1][attribute2=value2]...[attributeN=valueN]
//<knownXpath>/parent::*
//<knownXpath>/parent::elementName
//<xpathOfKnownElement>/ancestor::<elementName>
//<xpathOfKnownElement>/ancestor::*
//<xpathOfKnownElement>/following::<elementName>
//<xpathOfKnownElement>/following::*
//<xpathOfKnownElement>/preceding::<elementName>
//<xpathOfKnownElement>/preceding::*
//<xpathOfKnownElement>/following-sibling::<elementName>
//<xpathOfKnownElement>/following-sibling::*
//<xpathOfKnownElement>/preceding-
sibling::<elementName>
//<xpathOfKnownElement>/preceding-sibling::*
XPath1|Xpath2