What is XPath

Xpath is nothing but XML path, develeoper used xpath to validate XML files. HTML also follows same structures as XML, so we can apply xpath to HTML pages as well along with selenium webdriver.

Hope reader is familiar with TryXpath and develpper tools of browser which we use for inspecting elements and verify out xpaths

Xpath is nothing but sting expression which used to find the element(s) along with Selenium Webdriver, and other automation tools

We should give last priority to XPath among locators because Xpath is little slow compared with other locators, if we are not able to find the element with id, name, linktext, css then only we should go for xpath

Selenium supports xpath 1.0 and xpath 2.0, 3.0 are not compatible with selenium

In this tutorial we are going to learn how to build xpaths and verify xpaths

Syntax of XPath

Xpath follows very simple syntax, please find below image for the xpath syntax


Xpath Syntax
xpath-selenium-selenide
HTML code Syntax
html-code-xpath-selenium

HTML code can have n-number of attributes, Text and closing tag is not mandatory for few elements


There are two kind of xpaths
  1. Absolute xpath
  2. Relative xpath

Absolute Xpath
absolute-xpath-selenium-selenide / - point to first node on the html document, it is html tag
Note: we are not going to focus on absolute xpath.

Relative Xpath
relative-xpath-selenium-webdriver-selenide // - points to the any node in the webpage

tagName - tag name is nothing but the name which is present after the < (angular bracket)

attribute - whatever is present inside < and > baracket except tagname is attribute, any number of attributes can present in html code

attribute's value - it is corresponding value to the attribute, sometime for boolean attribute developers may not specify any value, in those cases html takes 'true' as defaut value.

Text - text is the value present inside > and <

Now let form the xpath for the above html code.
//a[@class='idle']

Xpath with Tagname

We can write Xpath based on the Tagname, which is very simple.


							Syntax for Xpath with Tagname : //tagName
							

							<html>
								<body>
									<div id="pancakes">
										<button type="button">Blueberry</button><br><br>
									</div>
								</body>
							</html>
							
In above code there is button present under div. we can write the xpath with tagname : //button

Xpath with Index

We may not see unique elements in the webpage, other than on login page.

Please save the below html file as composite-xpath.html on you local machine


							<html>
								<body>
									<div id="pancakes">
										<button type="button">Blueberry</button><br><br>
										<button type="button">Banana</button><br><br>
										<button type="button">Strawberry</button><br><br>
									</div>
								</body>
							</html>
							

Open above html file in chrome, and press F12 or right click on element and choose Inspect Element or Press Ctrl+Shift+I

It may look like below image once you open the chrome developer tool

composite-xpath-selenium

Press Ctrl+F to verify Xpath, and write the xpath based on the xpath syntax.

Xpath based on the Tagname : //button 3-matches-composite-xpath

When you try the xpath with tagname it shows three matches, so we cannot proceed as we want to find only one match. We must write a xpath expression which should hav only one match. When we have matching element only under one parent(this case), we should add index to the xpath


							Syntax for Xpath with Index : //tagName[index]
							


index must be covered with square('[',']') brackets. Index starts from 1 in xpath index-xpath-selenium Xpath for the elements :
  Bluberry button- //button[1]
  Banana button - //button[2]
  Strawberry button -//button[3]

Xpath with Attribute

We can use index type xpath with webdriver when we have more matches under one parent, index might not work if there are more parent

Store below html in local system and open it with chrome


							<html>
								<body>
									<div id="pancakes">
										<button type="button">Blueberry</button><br><br>
										<button type="button" name='banana' >Banana</button><br><br>
										<button type="button">Strawberry</button><br><br>
									</div>
									<div id="pancakes">
										<button type="button">Apple</button><br><br>
										<button type="button">Orange</button><br><br>
										<button type="button">Grape</button><br><br>
									</div>
								</body>
							</html>
							

Let's try to write xpath for Banana button, Xpath based on index is //button[2] but it has two matches 1. Banana, 2.Orange.

With index we may not be able to solve this issue.

Let's consider other properties of the html element, banana has attribute name, Now we have to form the xpath based on the attribute.


							Xpath with Attribute ://tagName[@attribute='attribute value']
							

Xpath based on the Attribute is : //button[@name='banana'] , this xpath shows only one match which is Banana button

You can add n number attributes in one xpath itself

							Xpath with multiple Attributes://tagName[@attrib='attrib value'][@attrib2='attrib2 value']...
							

Can I use index along with attribute: yes , you can use, but index will be usefull only when matches are under single parent


							Xpath with Attribute and Index://tagName[@attribute='attribute value'][index]
							

Xpath With Parent Reference

We cannot expect a HTML element to have different or uniques properties all the time, sometime there is a chance that every element may have same kind of attributes, In those cases we cannot use Xpath with Attribute in selenium webdriver

To handle such kind of cases we may need to take help of the parent element to find our actual element

Store the below code in html file and open it in chrome


								<html>
									<body>
										<div id="berry">
											<button type="button">Blueberry</button><br><br>
											<button type="button">Banana</button><br><br>
											<button type="button">Strawberry</button><br><br>
										</div>
										<div id="fruit">
											<button type="button">Apple</button><br><br>
											<button type="button">Orange</button><br><br>
											<button type="button">Grape</button><br><br>
										</div>
									</body>
								</html>
								

Let's write xpath for Orange, using parent and child concept


Syntax for Xpath with parent and child
parent-child-xpath

For Orange element we have to refet]r it parent div which has id attribute as fruit Xpath for the Orange: //div[@id='fruit']/button[2] parent-child-xpath-selenium We have only one match for the xpath we have written.

Explanation for Xpath : //div[@id='fruit']/button[2]
// - look for any node which has 'div' as tagname and id as fruit, look for immediate child(/) node which has tagname as button and at the index of 2.

Xpath with Group Index

Sometimes we may have to handle th elements with xpath index but index may give more than one match, which are under different parents, in these situations index might not help you. We may have to use Group index in these kind of scenarios

Group index puts all matches into a list and gives indexes them. So here we will not have any duplicates matches


							Syntax : (//tagName)[index]
							

We have to use paranthesis to make a xpath into group xpath after it index the xpath

Store below HTML code in to html file :

							<html>
							<body>
								<div id="fruit"><br><br><br>
									<button type="button">Blueberry</button><br><br>
									<button type="button"  >Banana</button><br><br>
									<button type="button">Strawberry</button><br><br>
								</div>
								<div id="fruit">
									<button type="button">Apple</button><br><br>
									<button type="button" >Orange</button><br><br>
									<button type="button">Grape</button><br><br>
								</div>
							</body>
						</html>
							

Let's write xpath for Orange : (//button)[5]

group-index-xpath-selenium-webdriver

text() function in Xpath

There will be situations, where you may not able to use any html property ther than text present in the element

text() function helps us to find the element based on the text present in the element, text() funnction is case sensitive


								<button type="button">Blueberry</button><br><br>
								

In above code the text is Blueberry, and we can write xpath using text() like below


								xpath with text : //button[text()='Bluberry']
								

Note: we use @ sign for attributes, functions does not need @ sign

We can also match element(s) which have text in them with below xpath

								xpath with text ://button[text()]
								                 ://button/text()
								

Wild card Character with Xpath in Selenium webdriver

* -is the one of most used wild card character with xpath in selenium webdriver, we can use it instead of tag name and attribute

//* - matches all the elements present in the html (including html)

//div/* - matches all the immediate element(s) inside the div tag

//input[@*] - matches all the element(s) with input tag and have atleast one attribute, attribute value may or maynot present

//*[@*] - matches all the element(s) which have atleast one attribute.

Dependent and Independent Xpath

We may face scenarios where the give element may change it's position everytime, so handle such kind of scenarios we have to go for dependent and independet xpaths

For example : Take any ecommerce website, search for a specific product and write xpath for that particular product, take rest for few days and then go and search for the same product, there could be change in position of the product, to handle this we should use dependent and independent concept

Scenario : Select the check box which is present in the same row as Protractor

Select Tool Language
Selenium Java
Protractor Typescript
Selenium Bindings Python
QTP VB

Steps to solve the scenario:
1. Donot write the xpath for the checkbox, beacuse checkboxes might change its position.

2. Based on the text present in the Protarctor field we have to write the xpath

2.1 we have to find the common parent for Protractor and Checkbox

3. Xpath to find the protractor : //td[text()='Protractor']

4. Now we should find the parent of Protractor element

5. We can find the parent of an elemen using /.. like in unix

6. Xpath for parent of Protractor : //td[text()='Protractor']/..

7. Check Protractor's parent is common parent for Protractor and checkbox.

8. Yes, Protractor parent is common parent for Protractor and checkbox

9. Now try to navigate to checkbox using checkbox properties

10. Checkbox has tagname as inpu : //td[text()='Protractor']/..//input

11. try the above xpath it will highlight the checkbox related to Protractor field

Here Protractor is independent and checkbox is dependent
Independent: It doesnot depend on any other element
Depenedent : We have to find this based on the other element(Independent)

contains() function in Xpath

contains() function helps user to fins the element with partial values, or dynamically chaning values, contains verifies matches with portion of the value


							contains function ://xpath[contains(@attribute, 'attribute value')]
													//xpath[contains(@text(), 'attribute value')]
							
Example of below html:

							<html>
							<body>
								<div id="fruit"><br><br><br><br><br><br><br><br><br><br><br>
									<button type="button">Blue berry1234</button><br><br>
									<button type="button" >Banana</button><br><br>
									<button type="button">Straw</button><br><br>
									<button type="button">berry</button><br><br>
									<button type="button">Straw berry</button><br><br>
									</div>
								</body>
							</html>
							


Xpath for the Blueberry : //button[contains(text(),'Blue')]
Xpath for the Banana : //button[contains(text(),'Ban')]

More Complex items:
In same way if you try to find xpath for Straw berry with //button[contains(text(),'Straw')] it find the element with text Straw as well.

If you try with berry you may get 'berry' element. So how to find teh Straw berry button.

We can combne more than one contains functions like : //xpath[contains(text(), 'text1')][contains(text(), 'text2')]
Xpath for Strawberry is : //button[contains(text(),'Straw')][contains(text(), 'berry')]

Not only for text you can apply contains function for other properties as well Eg : //button[contains(@type,'but')]

Normalize Space in Xpath

Normalize space matches the element ignoring starting and ending spaces


							syntax ://xpath[normalize-space(property)='value']
							

							<button type="button">   Strawberry   </button><br><br>
							

Xpath for the Strawberry element : //button[normalize-space(text())= 'Strawberry']

starts-with function xpath

Starts-with function matches the elements which property starting value


							syntax ://xpath[starts-with(@attribute,'starting value')]
							

							<button type="button">Straw berry</button><br><br>
							
Xpath for the Strawberry element : //button[starts-with(text(), 'Straw')]

ends-with func xpath

Ends-with function matches the elements properties ending value


							syntax ://xpath[ends-with(@attribute,'ending value')]
							

							<button type="button">Straw berry</button><br><br>
							

Xpath for the Strawberry element : //button[ends-with(text(), 'berry')]

Last() function in Xpath

By default automation tools takes first instance of the match, also if we want to achieve the first element we can use index [1].But in some pages we may not be able to see how may matches are present when page is loading or on dynamic page.

last() function in Xpath helps user to find the last match of the element.


							last function : //xpath[last()]
							
take example of below html code

							<html>
							<body>
								<div id="fruit"><br><br><br>
									<button type="button">Blueberry</button><br><br>
									<button type="button"  >Banana</button><br><br>
									<button type="button">Strawberry</button><br><br>
								</div>
							</body>
						</html>
							

In above if we want to write xpath for last element it is easy we can say use index [3] , but if application is very large or dynamic, we cannot say how may elements are gonna present.

So let's use last funtion in xpath : //button[last()] - points to the Strawberry button.

last-xpath-selenium

Position function in Xpath

Position function help the user to get the match at particular index, using position we can get element which are less than the postion or greater than the position as well.


								position function ://xpath[position()=2]
														://xpath[position()<2]
														 ://xpath[position()>2]
														 ://xpath[position()=<2]]  ...
								
								
Example : //button[position()=2] position-xpath-selenium

CaSe in-sensitive Xpath in selenium webdriver

Sometimes we may have a situation where we have find the element based on the attribute. We can use @ method for attribute but if the atrribute values changes every time lower to upper case or mix case value when page refreshes, in this @ method may not help us.

During such kind of situations we must ignore the case(UPPER/lower). Below is the syntax to match the elements by ignoring case, translate method helps us to perform this .


								Syntax :// tagname[text(), 'sourceCaseContent', 'targetCaseContent'), 'value']
								


tagname - is the html tag used to for the element like label,a, span, div..

text() - text() value present in the element.

sourceCaseContent - We have to pass the Letter(s) which all we want to convert 'ABCD' so on, we can also give only few letter like 'agk' (sourceCaseContent could be UPPER/lower case)

targetCaseContent - We have to pass the Letter(s) to which we want to convert the SourceCaseContent, it could be in any case

value - the target value which we want to compare it could be any value but it should be in target case (if target case is UPPER then the value also should be in upper


								Html code : <label id="aBcK" name='p'>SEleNiuM</label>
								Xpath ://label[contains(translate(text(),'CDEILMNSU','cdeilmnsu'),'selenium')]
								
Attribute value's Length xpath in Slenium

We can find the element based on the attribute value/text lenght in selenium, string-length() method helps us to form the xpath based on the element's attribute length.


								Syntax :// tagname[string-length(@attibute's name/text)= expectedLength]
								


tagname - is the html tag used to for the element like label,a, span, div..

@attibute's name - any attribute present in the element like id, name, src, href... text() - text() value present in the element.

expectedLength - numeric expected lenght of the attibute value or text value


								Html code : <label id="twinkie" name='p'>selenium</label>
								Xpath ://label[string-length(@id) = 7]
								Xpath ://label[string-length(text()) = 8]
								
								twinkie - 7 letters
								selenium - 8 letters
								
Relational value Xpath in selenium webdriver

We can form xpath based on the numeric attribute value / text present in the element with relational operators. For example we can find the elements which have numeric text greater than 40 or less than 70 like so


								Syntax :// tagname[@atrribute/function > expectedValue]
								


@atrribute/function - sshould result in numeric value

expectedValue - Must be numeric value


								Html code : <label id="50" name='p'>30</label>
								Xpath 1 ://label[text()>20]
								Xpath 2 ://label[@id()<70]
								Xpath 3 ://label[@id()<70][text()>20]
								

Axes in Xpath in selenium webdriver

XPath axes are used to identify elements which periodically change or refreshes it attributes by their relationship like parent, child, sibling, based on the independent element, whose properties doesnot change.

Axes refers to node on which elements are lying relative to an independent element. We could traverse in both forward and reverse directions.

Forward Axis :

self
attribute
child
descendant
descendant-or-self
following-sibling
following

Reverse Axis :
parent
ancestor
preceding-sibling
preceding
ancestor-or-self
Save below code as html file

								<html>
									<head></head>
									<body>
										<div name='username'>
											<label id="user">Username</label>
											<input id="username" type="text">
										</div>
										<div name='password'>
											<label id="pass">Password</label>
											<input id="username" type="password">
										</div>
									</body>
								</html>
								

Forward Axes

Forward axis in xpath helps to find the element/node after the current or reference element (helps to find element in the code which is below the current element in html file).

We can narrow down the matches by adding more details about the html element like tagnames, attributes

forward-reverse-axis-xpath-selenium-webdriver

self : It specifies the current element

self-axes-xpath-selenium-webdriver

attribute : It specifies the attributes of the current element.

all-attribute-axes-xpath-selenium-webdriver

Now let's narrow down to the element(s), which have attribute id
attribute-axes-xpath-selenium-webdriver

child : It specifies all child elements of the current element.

child-axes-xpath-selenium-webdriver

We can match the element with particular tag or ids, below one matches the child element(s) which have input as tag
input-child-axes-xpath-selenium-webdriver

descendant : It specifies all the children and grand children elements

descendant-axes-xpath-selenium-webdriver

Narrow down to the decendent which has input as tag
input-descendant-axes-xpath-selenium-webdriver

descendant-or-self : It specifies current or all the children and grand children elements

descendant-or-self-axes-xpath-selenium-webdriver

Narrow down to the child which has input as tag, if the current element has input tag then this xpath matches that as well.
input-descendant-or-self-axes-xpath-selenium-webdriver

following-sibling : It specifies the following siblings of the current element. Siblings are at the same level as the current element and share it's parent.

following-sibling-axes-xpath-selenium-webdriver

following : It specifies all elements that come after the current element which includes elements of other div's as well.

following-axes-xpath-selenium-webdriver

Reverse Axes

Reverse axis in xpath helps to find the element/node before the current or reference element (helps to find element in the code which is above the current element in html file)

We can narrow down the matches by adding more details about the html element like tagnames, attributes

parent : It specifies the parent of the current element.

parent-axes-xpath-selenium-webdriver

ancestor : It specifies the ancestors of the current element/nodes which include the parents up to the root html.

ancestor-axes-xpath-selenium-webdriver

Narrow the matches to the element(s) which has div as html tag by navigating to ancestors div-ancestor-axes-xpath-selenium-webdriver

ancestor-or-self : It specifies current element or all elements that come before the current element

ancestor-or-self-axes-xpath-selenium-webdriver

Let's narrow down our search to the element which has tag as body from current element by navigating reverse axis, if current element is body then it matches with current element itself.
body-ancestor-or-self-axes-xpath-selenium-webdriver

preceding-sibling : It specifies element that come before the current element

preceding-sibling-axes-xpath-selenium-webdriver

preceding : It specifies all elements that come before the current element (i.e. before it's opening tag).

preceding-axes-xpath-selenium-webdriver

About Author

Myself KarthiQ, I am the author of this blog, I know ways to write a good article but some how I donot have the skills to make it to reach people, would you like help me to reach more people By sharing this Article in the social media.

Share this Article Facebook
You can also share knowledge by Adding a topic here


Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions

Recent Addition

new tutorial Registrations for Selenium Online Training is Over.

Below are the training details:
Meeting link : https://zoom.us/j/737840591
Starting Time : 9:00PM 18th DEC 2018
 
Join My Facebook Group
Join Group