What is XPATH?
- It is xml path.
- It is one of the locator type in selenium.
- It uses path expression to navigate in XML document and to identify a node or number of nodes.
- XPATH is much more advance/powerful than any locators in selenium but xpath engine (e.g. Handling xpath: xpath calculate on IEBrowser may or may not work on Firefox browser) is different according to different browsers. It has number of build in functions.
- XPath are used to handle complex and dynamic xpath.
Types of XPATH in Selenium-
- Absolute XPath
- Relative XPath
What is Absolute XPath?
- Absolute path starts from <HTML> tag.
- It uses / ( forward slash ).
- It is used to identify any element direct way by consider all the tag starts from <HTML> tag.
- While considering a path to identify node/tag if new tags gets added in between then absolute path which was working earlier now it won't work as new tags gets added in path in between.
Example:
https://www.google.com/ Google
html/body/div/div/div/div/div/div/div/a => To identify Gmail link from right top corner.
If new tags lets
div gets added in DOM then above xpath may gets changed and absolute
xpath may be won't work.
- It is much more faster than "Relative xpath" as it holds the direct path to the target node/tag/element from start <Html> tag.
- But mostly we never going to use this one as it holds a long string path and it is difficult to maintain or handle it. It is not a shortend path.
What is Relative XPath?
- It uses // ("forward double slash") .
- It will consider any node/element/tag as a refernce point from where either we can traverse forard or reverse direction to identify target node/tag.
- Here reference point we consider is more stable tag/node where we could understand it never be going to remove or change in the DOM.
- It is not faster as compared to "Absolute XPath" as we are considering any tag/node in a DOM to traverse towards target element/tag. So searchng time is needed as we are not considering a path starts from <HTML> tag and succedding tags.
- It is mostly used as we are considering any node as a reference node (stable node) from a DOM.
Example:
Site: https://www.google.com/ Google
//a[contains(text(),'Gmail')] => To identify Gmail link from right top corner.
XPath Axes:
XPath axis represents the relationship between current node and other nodes those are used to locate current node.
- ancestor
- parent
- self
- attribute
- child
- descendant
- following
- following-sibling
- preceding
- preceding-sibling
To Test all above axes
Site we used is: https://www.facebook.com/r.php
1. Ancestor:
It will select parent, grand parent or grand-grand parent of the current node.
Site: https://www.facebook.com/r.php (
click here )
Example:
//input/ancestor::* => Find any parent/grand parent (any tag) of first input tag.
//input/ancestor::form => Find form tags which is the parent/grand parent of input tag.
Here we explicitly specified to find
form tag earlier we want
any tag so we used astrik (
*) .
//input//ancestor::div[@id='reg_box'] => Find the
div tag which will be parent or grad
parent (
ancestor ) of input tag.
2. parent:
It will select the parent of the current node. Current node specifies the node before the scope resolution operator.
If the specified node is node the exact and immediate parent then it will not return/find the parent node.
Site: https://www.facebook.com/r.php
Example:
//input[@id='u_0_n']/parent::* => we want to find parent any tag (*) of the current
node
(input tag) whose id is 'u_0_n' i.e. First Name
text box.
//input[@id='u_0_n']/parent::div => Find the immediate parent as "Div" tag of the current
node.
//input[@id='u_0_n']/parent::form => It will not find the form as parent for input tag
because it is not a immediate parent.
3. Self:
It will find/select the current node it self.
Example:
//input[@id='u_0_n']/self::* => Select the current node itself even by specifying
astrik.
//input[@id='u_0_n']/self::input => Select the current by specifying input tag.
//input[@id='u_0_n']/self::input[@id='u_0_n'] => Select the current tag by specifying tag
name with attribute value like id.
4. Attribute:
- It will select/find the tag by considering their attribute.
- For attribute selection we have to use @.
- we can consider any attribute those are available in tag like-id, name, text, class, value etc..
Example:
//*[@id='u_0_n'] => Select any tag (astrik) whose id=u_0_n.
i.e. First Name
//input[@id='u_0_n'] => Select any input tag whose id=u_0_n.
i.e First Name
//*[@name='firstname'] => Select the First Name text box whose name is
"firstname".
//*[@class='inputtext _58mg _5dba _2ph-'] => Find any tag whose class value is specified.
//input[@class='inputtext _58mg _5dba _2ph-']
=> Find any input tags whose class value is
specified.
//input[@id='u_0_n'][@class='inputtext _58mg _5dba _2ph-'] => Select input tag only whose id
and class specified match. So
here
AND condition is used if
we use multiple attribute.
//input[@id='u_0_n'][@name='firstname']
=> Select the input tag whose id & name value
specified is matched.
5. child:
Select all the child node of the current node. (Not grand child only immediate child)
.
Example:
//div[@id='reg_form_box']/child::* => Select/find all the childs (any tag) of a specified
div tag.
//div[@id='reg_form_box']/child::div => It will return all the div those are immediate child of
specified tag/current node/tag.
//select[@id='day']/child::* => It will return/find all the child (
option tags ) of a select tag.
//select[@id='day']/child::option[@value='21'] => It will select the child node (
option tag ) of a
select tag whose value is
'21'.
6. Descendant:
It will selects all the children, grand-children of the current node.
Example:
//form[@id='reg']/descendant::input => Select all the
input tag (child/grand child) of the
form
tag whose id is '
reg'.
//span[@id='u_0_10']/descendant::select => Select the
'select' tag which is the child of span.
//span[@id='u_0_10']/descendant::option => Select the
'option' tag which is the grand child of
span tag.
7. following:
Select the rest/all of the tags
after the closing of the current tag from the document.
Example:
//span[@id='u_0_10']/following::* => It will return all the tags after the closing of span tag.
//span[@id='u_0_10']/following::button[contains(text(),'Sign Up')] => To get the
Sign Up button
//span[@id='u_0_10']/following::input[@name='sex'] => To select all three genders.
8. following-sibling:
Select all the sibling nodes of the current node.
Example:
Site for Testing: https://www.facebook.com/
Below example will work on https://www.facebook.com where login form should be there.
Login Form (Email or phone , Passowrd, forgotten account, Log In these controls are placed
on Table
First TR- Indicates Email or phone and Password label
Second TR - Indicates Text boxes for email & Password and Login Button
Third TR- Indicates Forgotten account link
//table//tr/following-sibling::tr => It will return second TR (two textboxes and Log In button)
//table//tr/following-sibling::tr[2] => Select the third TR which is the sibling of first TR.
//table//tr[2]/td/following-sibling::td => Select the sibling
'td' (second/third TD) of the second
TR (Two text boxex and Log In Button)
Below example is to select the Mobile Number text box from
Create An Account Form.
//div[@id='reg_form_box']/div/following-sibling::div -> Select the Mobile Number Text box.
9. preceding:
It will selects all nodes/tags/element that appear before the current node in the document, except ancestors, attribute nodes and namespace nodes.
It will select all the node is upword direction except parent, ancestor (i.e. It will select all sibling tags/elements of direct parent or ancestor .)
Example:
//form/preceding::form => Select the first form (Log In form)
//form/preceding::form//table//input[@id='email']=> Select
Email or Phone Text Box from Log
In form.
//form/preceding::form//table//input[@id='pass']
=> Select
Password Text Box from Log In form.
10. preceding-sibling:
It will select the all the siblings(all are st same level ) nodes/tags/elements before the current node.
Example:
//table//tr[3]/preceding-sibling::tr => Select the second row(email,password textboxes) from
the Log In form
//table//tr[3]/preceding-sibling::tr [1]=> Select the first row(email or phone, Password label)
from Log In form.
//div[@id='u_0_12']/preceding-sibling::div[6] => Select the Mobile Number or email address
text box from create an account form.
OR
//div[@id='u_0_12']/preceding-sibling::div[@id='birthday_wrapper']=> Select the Mobile
Number or email address text box from create an account form.
XPath Methods:
1. Starts-with()
2. ends-with()
3. contains()
4. text()
All above methods are used to handle dynamic web controls/elements.
To Test all above methods
Site we used is: https://www.facebook.com/r.php
1. starts-with():
Starts-with function finds/handles the control whose value (some part of the value) changes frequently on any action on control/page or refresh
the page. So to find such kind of controls starts-with function is used. So on the basis of partial text/atribute value matched it will find the control.
Example:
//input[starts-with(@id,'ema')] => Find any input tag whose attribute id starts with value 'ema' i.e.
Email or Phone text box from Facebook Log In page.
//input[starts-with(@id,'pas')] => Find only input tag whose attribute starts with 'pas' i.e.
Password text box from Facebook Log In page.
//input[starts-with(@type,'sub')=> Find input tag whose sttribute type starts with 'sub' i.e.
Log
In button from Log In page
//*[starts-with(@name,'firstna')] => Find any tag whose attribute name starts with 'firstna' i.e.
First Name text box from create a new account page.
//*[starts-with(text(),'Forgotten')] => Find any tag (as *
is there
) whose text starts with
'Forgotten' so it will find the Forgotten account? link from
Log In page.
2. ends-with():
ends-with function finds/handles the control whose value (some
part of the value) changes frequently on any action on control/page or
refresh the page. So to find such kind of controls ends-with
function is used. So on the basis of partial text/atribute value matched
it will find the control.
If value of any attribute or text whose end part is constant then we can use ends-with function.
Example:
//input[ends-with(@id,'ail')]
=> Find any input tag whose attribute id starts with value 'ema'
i.e.
Email or Phone text box from Facebook Log In page.
OR
//input[contains(@id,'ail')]
//input[ends-with(@id,'ss')] => Find only input tag whose attribute starts with 'pas' i.e.
Password text box from Facebook Log In page.
OR
//input[contains(@id,'ss')]
//input[ends-with(@type,'bmit')]=> Find input tag whose sttribute type starts with 'sub' i.e.
Log
In button from Log In page
OR
//input[contains(@type,'mit')]
//*[starts-with(@name,'stname')] => Find any tag whose attribute name starts with 'firstna' i.e.
First Name text box from create a new account page.
OR
//*[contains(@name,'stname')]
//*[starts-with(text(),'account?')] => Find any tag (as *
is there
) whose text starts with
'Forgotten' so it will find the Forgotten account? link from
Log In page.
OR
//*[contains(text(),'account?')]
Note: The ends-with
function is part of XPath 2.0 but browsers generally only support 1.0.
So, We can use contains() & text() methods to find the tags/controls/webelements with specific pattern without using ends-with method.
3. Contains:
Contains method generally used if some portion of text or attribute value is static then contains method is used. But this method returns mostly multiple controls as it will check for contains particular text in attribute value.
Example:
//input[contains(@id,'ail')]
=> Find any input tag whose attribute id starts with value 'ema'
i.e.
Email or Phone text box from Facebook Log In page.
//input[contains(@id,'ss')] => Find only input tag whose attribute starts with 'pas' i.e.
Password text box from Facebook Log In page.
//input[contains(@type,'mit')]=> Find input tag whose attribute type starts with 'sub' i.e.
Log
In button from Log In page
//*[contains(@name,'stname')] => Find any tag whose attribute name starts with 'firstna'
i.e. First Name text box from create a new account page.
//*[contains(text(),'account?')] => Find any tag (as *
is there
) whose text starts with
'Forgotten' so it will find the Forgotten account? link from
Log In page.
//a[contains(text(),'stagr')] => Find anchor tag whose link text contains 'stagr' i.e.
Instagram
4. text():
This method is used with any other methods like starts-with, ends-with and contains method. This method find the text in between start and end of the tag.
ex:
<a href="/r.php" title="Sign up for Facebook">
Sign Up</a>
So, here text() method capture
Sign Up text from anchor <a> tag.
Example:
//*[contains(text(),'account?')] => Find any tag (as * is there) whose text starts with
'Forgotten' so it will find the Forgotten account? link from
Log In page.
//a[contains(text(),'stagr')] => Find anchor tag whose link text contains 'stagr' i.e.
Instagram
Site for Testing: https://www.facebook.com/r.php
XPath Wildcards:
1. * ( Matches any element node )
2. @* ( Matches any attribute node )
3. node() ( Matches any node of any kind )
For all above wildcards to test we used Site is: https://www.facebook.com/r.php
1. * :
It indicates any tag/node in DOM with matches condition.
Example:
//*[@id='email'] => Select any tag whose attribute id value is 'email'.
//table/* => Select any child of parent tag 'table'.
2. @* :
It indicates any attribute of a specified tag or any tag with matches specified value/condition.
Example:
//*[@*='email'] => Select any tag whose any attribute value is 'email'.
OR
//input[@*='email'] => Select only Input tag whose any attribute value is 'email'.
//*[@*='pass'] => Select any tag whose any attribute value is 'pass'.
OR
//input[@*='pass'] => Select only input tag whose any attribute values matches 'pass'.
//*[@*='firstname'] => Select any tag whose any attribute value matches with 'firstname'.
OR
//input[@*='firstname'] => Select only input tag whose any attribute value matches 'firstname'.
3. node() :
It will return any node/tag.
Example:
//node() => Select any node or all node from current DOM. Starting from HTML tag.
//node()//table => Select table from current DOM.
//table//node() => Select all the node (child node/grand child of table tag only ).
//table/node() => Select Immediate child (any immediate child ) tag i.e. tbody tag.
Path Expression:
1. / ( Selects from the root node )
2. // ( Selects nodes any where in the document from the current node )
3. . ( Select the current node/tag )
4. .. ( Select the parent node of the current Node/Tag )
5. @ ( Selects attribute like id, name, type, option etc... )
1. / :
This path expression is used to select/consider from the root node. Like Absolute Path where we need to find a node then we have to traverse from <HTML> tag to node to select.
Example:
Site: https://www.facebook.com/r.php
/html/body/....../till current node
2. // :
Select any node/tag any where in the document without considering from <HTML> tag (from start of the document ). We can consider any tag/node in document as a reference tag whose name or id property is fixed and the can traversed to expected/required node.
Example:
Site: https://www.facebook.com/r.php
//table//input[@id='email'] => Here in the document we have consider a "table" as a reference tag
and then we go drill down to node input whose @id='email'.
//form//input[@name='firstname'] => Find "form" tag anywhere in the current DOM and consider
as a reference node/tag then find any input tag whose
attribute @name='firstname'.
3. . (Single Dot )
Select the current node or a node itself.
Example:
//table/. => select "table" node/tag any where in the document and select it self ( /. ) .
//table//. => Select "table" node/tag any where in the document along with current node itself and
its childrens tags/nodes of table tag.
4. .. (Double Dot):
Select the parent of the current node (not ancestor , only parent).
Example:
Site: https://www.facebook.com/r.php
//table/.. => It will return the parent of table node here it will return "form" tag.
//form/.. => It will return the parent of form tag i.e. DIV in this case.
5. @
It is used
Example:
//@name => It will select all the attribute that are named as "name" here .
//@id => It will select all the attribute that are named as "id" here.
//@value => It will select all the attribute that are named as
"value" here.
Array in XPath or Predicates:
Predicates are used to find a specific value like array[index] or that contains a specific value.
predicates are always embedded in square brackets.
1. [index/value]
2. last()
3. position()
4. [@attribute]
5. [ @attribute='value']
6. [ attributename > attribute value ]
1. [index/value] :
we can select any child node and any node by providing specific index value (integer value).
Example:
Site: https://www.facebook.com Login page
//table/tr[3] => It will select the third row from log in form i.e. "Forgotten Password?" link row.
//select[@id='day']/option[22] => Select option value=21 from Birthday Day drop down.
//select[2] => Select 'select' tag in document with index=2. i.e Birthday Month Drop Down list.
2. last() :
Select the last element.
Example:
//select[@id='day']/option[last()] => Select the last option from day drop downlist i.e. 31.
//select[@id='month'/option[last()] => Select the last option from day drop downlist i.e. Dec.
//select[@id='year'/option[last()] => Select the last option from day drop downlist i.e. 1905.
//table//tr[last()] =>Select the any child as TR (Here third TR 'Forgotten Password?') from Table tag
//table//tr[last()-1] =>Select the any child as TR (Here third TR 'email/pass textbox') from Table tag
3. position()
It is used to select elements based on > (grater than ) or < (less than ) certain index value.
lets if a table <Table> tag has three <TR> child then if you want to select first Two <TR> then we can use //table/tr[position() < 3] .
Example:
//table//tr[position()<3] => Select only first two TR node/tag under the table tag.
//select[@id='month']/option[position()>5] => Select all other option whose position is greater than 5. Here text month=1, jan=2, feb=3, mar=4, APR=5 & so on . so here it will return all other option from May to Dec.from Month Drop Down List.
//select[@id='day']/option[position()>30] => It will return day option 30 & 31. as 0 indicates 'Day'
4. node[@attribute]:
It will select the tag/node that have an attribute name as @attribute.
Example:
//input[@id] => Select all input tag/node those have attribute 'Id'.
<input type="email" class="inputtext login_form_input_box" name="email" id="email" data-testid="royal_email">
//select[@title] => Select 'select' tag/node those have 'title' as a attribute.
//*[@title] => Select any tag/node those have 'title' as a attibute.
6. [ attributename > attribute value ]:
Select all the nodes/tags that have an attribute value is greate than or less than specified attribute value.
Example:
//select[@id='year']/option[text()>2000] => Select all the option from 'year' drop down list those are having text value greater than 2000. So the result is option from 2001 to option 2019.
//select[@id='day']/option[text()<5] => Select all the option those are having text value which is less than 5. So here the result conatins option value=1 to option value =4.
Operators in XPath:
1. and:
- Both the condition should be true to find the element.
- It is case sensitive (attribute values should be in same case).
- If you want to find an element based on multiple condition like by considering @id, @name, text(), @type or any attribute then AND Operator is used.
- If one of the condition if wrong then it won't identify an element.
Example:
//input[@id='u_0_n' and @name='firstname'] => Find the firstName element from create an account.
//input[@id='u_0_n' and @name='firstnamee'] => It won't find an element as value of attribute @name=firstnamee is not matched (expected @name='firstname' ).
//select[@id='day' and @name='birthday_day' and @title='Day'] => select the 'Birthday Day' drop downlist from create an account form using multiple attribute values with and condition.
another way is-
//input[@id='u_0_n'][@name='firstname'] => Here it will by default consider and. No need to
explicitly specify and over here.
//select[@id='day'][@name='birthday_day'][@title='Day'] => It will select Birthday Day drop down.
2. or:
- If one of the condition is then it will find an element.
- It is case sensitive (attribute values should be in same case).
- If
you want to find an element based on multiple condition like by
considering @id, @name, text(), @type or any attribute then OR Operator
is used.
- If one of the condition (attribute value is not matched ) is wrong or true(if one of the attribute values matched with DOM values) still it will identify an element.
- If all the conditions are wrong (attribute values are not matched in DOM values ) then it won't identify an element.
Example:
//input[@id='u_0_n' or @name='firstname'] => Find the firstName element from create an account.
//input[@id='u_0_n' or @name='firstnamee'] => It won't find an element as value of attribute @name=firstnamee is not matched (expected @name='firstname' ).
//input[@id='u_0_nn' or @name='firstnamee']=> If both attribute values are not matched then it will not identify an element. Expected values are //input[@id='u_0_n' or @name='firstname']
//select[@id='day' or @name='birthday_day' or @title='Day'] => select the
'Birthday Day' drop downlist from create an account form using multiple attribute values with
and condition.
References:
- https://www.w3schools.com/xml/xpath_intro.asp
- https://www.facebook.com/r.php