XPath in Selenium WebDriver: Complete Tutorial

In this post, we will discuss the XPath and different types and the expressions used to find elements like complex and dynamic elements in a DOM or a web page.

Every selenium automation test engineer should be comfortable locating the elements of a web page because it is the very basic thing in automation. If you cannot locate the elements in the DOM, the script will not work if you write the script. In our previous post, we discussed how we can find the elements by using different locators like ID, Name, TagName, ClassName, LinkText, and Partial Link text. But still, there are two other locating strategies available in selenium, which have powerful location strategies compared to the previously discussed strategies.

So it’s very important that an Automation engineer master the use of XPath and CSS Selector to easily locate the elements in such a situation as when ID or name is unavailable. Sometimes, a tag name also does not work in a scenario like when many elements have the same tag name. As we know, the link text will work only when the element has <a> tag, but if the application supports multi-language, then it will not work because the link text works as mentioned in the text, and if the text changes, it will not work.

I have noticed that most of the automation engineers do not pay much attention to different location strategies; they depend on the recording and playback option, but when they start any dynamic web page at that time, their scripts will fail. And some other testers are using browser plugins like Chropath and a few other plugins to retrieve the Xpath for an element. Still, those tools also have some limitations, and they do not provide the best XPath value for dynamic content. So, in this post, we will discuss XPath in detail, which will help you locate any elements on a webpage.

What is XPath?

XPath is a query language for selecting nodes from a web page using XML expressions, and also, by Using XPath, we can locate any element on a web page with an HTML Dom structure.

Syntax:

Selenium Xpath In Details
Selenium Xpath In Details

In the above Syntax

  • //: It is used to select the current node.
  • tagname: It is the name of the tag of a particular node.
  • @: It is used to select attributes.
  • Attribute: It is the name of the attribute of the node.
  • Value: It is the value of the attribute

Types of Xpath

Mainly, Xpath is categorized into 2 types:

  • Absolute Xpath
  • Relative XPath

Absolute XPath: In this type, the Xpath starts from the root of the HTML pages, but this type of Xpath is not recommended because these types are lengthier and not readable; in the meantime, if there are any small structural changes happen in the application then the Xpath will not work. So, Absolute XPath should be used when locating the element using the Relative XPath.

Example: /HTML/body/div[1]/div/div[2]/form/ div[2]/input

Relative XPath: In relative XPath, the path will start from the middle of the dom structure and always starts with a double forward slash (//).

Example: //div[@id=’divUsername’]/input

Difference between single ‘/’ or double ‘//’

A single slash at the start of Xpath instructs the XPath engine to look for elements starting from the root node. A double slash at the start of Xpath instructs the XPath engine to search for matching elements anywhere in the XML document.

But you have to select the Xpath in such a way that:

  • It should uniquely identify the element
  • You should prepare the Xpath so that you can use the same Xpath in different and subsequent releases.
  • The XPath should be selected so that if there are any minor changes in the structure, your XPath should locate the element without failing the script.
  • The Xpath should be in a readable format.

NOTE: Absolute XPaths are faster than the relative XPaths

Locate Element using Known Attribute

Sometimes elements are mentioned in the DOM or web page with some known attributes like name or ID, So here we are trying to learn how to locate such types of elements with the help of those known attributes. But before writing the Xpath, remember that the attribute value is unique and not changed.

Syntax:

//*[@attributeName=’value’]

Let’s take a Scenario:

Locate the search box on the SoftwareTestingo homepage search box. If you have the HTML code of that search box, that is:

<input class="search-form-input" type="search" itemprop="query-input" name="s" id="search for-2" placeholder="Search this website">

If you have marked the above HTML, then you can find 3 known attribute, which is ClassName, Id, and name; based on those values, we can locate the element

Examples:

//*[@id=searchform-2]
//*[@name=’s’]
//*[@type=’search’]
//*[@class=’search-form-input’]

NOTE: Third, XPath shall not be used even though it is valid. Because It will not be a unique XPath, there might be many elements with attribute type=’text’. Hence, Selenium will not be able to locate the element uniquely.

Single quotations should be used to enclose the values. //*[@name=’s’]

If there are multiple elements for an XPath?

If with an Xpath, multiple elements are identified, then in that case, if you run your script with that xpath_details, selenium always selects the first element. In that case, to locate a specific element, you can use the sequence number or predefined methods like last().

Suppose the table code:

<table id="customers">
<tbody>
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germany</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td>Mexico</td>
</tr>
<tr>
<td>Ernst Handel</td>
<td>Roland Mendel</td>
<td>Austria</td>
</tr>
<tr>
<td>Island Trading</td>
<td>Helen Bennett</td>
<td>UK</td>
</tr>
<tr>
<td>Laughing Bacchus Winecellars</td>
<td>Yoshi Tannamuri</td>
<td>Canada</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti</td>
<td>Giovanni Rovelli</td>
<td>Italy</td>
</tr>
</tbody>
</table>

From the above table, if you want to select the first row and last row, then you can use the below Xpath:

CompanyContactCountry
Alfreds FutterkisteMaria AndersGermany
Centro commercial MoctezumaFrancisco ChangMexico
Ernst HandelRoland MendelAustria
Island TradingHelen BennettUK
Laughing Bacchus WinecellarsYoshi TannamuriCanada
Magazzini Alimentari RiunitiGiovanni RovelliItaly

Examples :

To select the first row: //tr[1]
To select the last row: //tr[last()]

Locating Elements with Known Elements and Attributes

If you can locate an element using attributes like Name, id, or some other attributes, then you can write the Xpath for an element by following the below syntax:

elementName[@attributeName=’value’]

Suppose there is an element on a webpage, and the attributes are below.

Anatomy Of an Element
Anatomy Of an Element

Then you can prepare the XPath to locate the element uniquely by the below example

//input[@id=’txtUsername’]
//input[@name=’txtUsername’]

XPath Functions

As we have mentioned above, if you can locate the elements using the attributes, then it’s a good sign to locate the elements, but with those attributes details, if multiple elements are identified, then you can use some predefined XPath function that can help you to locate the elements uniquely.

Types of XPath Functions

There are so many methods defined in selenium to locate elements on a webpage, but we are going to discuss only a few of them that are widely used while writing the automation script; those are:

  • Contains()
  • starts-with()
  • text()
  • Position()
  • last()
  • concat()

Let’s start with how to use the above methods in our automation script individually, so let’s start with the Contains() method Of XPath.

Contains()

You can use this method in your automation script when the value of any attributes changes dynamically. For example, there are elements with an attribute id and value abc-123. However, the numeric value changes whenever you visit the application. At that time, you can use the contains() method to locate the elements easily, and it will not fail your script for the dynamic value change.

Note: If the value matches the details of the elements, then it will be able to locate the elements in the DOM.

Syntax for Contains():

Syntax: //tag[contains(@attribute, ‘value‘)]

Example: //input[contains(@id, ‘er-messa’)]

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class Xpath_Contains_Method 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/table-example-for-xpath.html");
      Thread.sleep(10000);
      
      WebElement Ele1=driver.findElement(By.xpath("//td[contains(text(),'Alfreds')]"));
      String text=Ele1.getText();
      
      System.out.println("The Full Text: "+text);
      driver.close();
   }
}

With the above example, I hope you can understand how to use the contains() method with the XPath. Let’s move further and other Xpath functions.

Starts-with()

Like the contains() method, it also searches the specified value on the DOM, but the main difference between contains() and starts-with() is that starts-with() checks the starting text of an attribute, whereas contains() will check the value in throughout the attribute.

So it’s very helpful to know that starting values are not changed in your element, but after a few characters, the value changes randomly. In this case, you can use this method for non-changing attribute values.

Syntax: //tag[starts-with(@attribute, ‘value‘)]
Example: //input[starts-with(@id, ‘user’)]

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class Xpath_StartsWith_Method 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/table-example-for-xpath.html");
      Thread.sleep(10000);
      
      WebElement Ele1=driver.findElement(By.xpath("//td[starts-with(text(),'Francisco')]"));
      String text=Ele1.getText();
      
      System.out.println("The Full Text: "+text);
      driver.close();
   }
}

Now let’s jump to another function text()

Text()

This method can locate the element with an exact text match. This method will help when you observe that the attribute value changes dynamically with no substantial part of the attribute value that can be used via Starts-with or Contains. in that case, you can use the text() to locate and operate on that element.

For locating the element Free Sign Up, you can use the below XPath, with text(), and by combining the contain() and text() methods.

Xpath= //button[text()=’Free Sign Up’]
Xpath=//button[contains(text(), ‘Signup’ )]

If you see our two above examples, in one example, we are trying to use the text() method to identify the element. In the other example, we are trying to locate the same element with the partially matched text with the contains().

Example Program:

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class Xpath_Contains_Text_Method 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/table-example-for-xpath.html");
      Thread.sleep(10000);
      
      WebElement Ele1=driver.findElement(By.xpath("//td[contains(text(),'Alfreds')]"));
      String text=Ele1.getText();
      
      System.out.println("The Full Text: "+text);
      driver.close();
   }
}

Position()

When using Xpath, if multiple elements are located with an Xpath, then if you know the index, you can use the Position() function to locate the elements in the web page, and XPath looks like below.

xpath=(//input[@type='checkbox'])[position()=3]

Below, we are trying to locate the element of the second-row first-cell value.

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class Xpath_Contains_Position_Method 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/table-example-for-xpath.html");
      Thread.sleep(10000);
      
      WebElement Ele1=driver.findElement(By.xpath("//tr[position()=2]/td[1]"));
      String text=Ele1.getText();
      
      System.out.println("The Second Row First Cell Text: "+text);
      driver.close();
   }
}

Suppose we want to locate all the paragraph elements except the paragraph element that is in the first position using the position( ) function; we’ve to use position( ) > 1 in the XPath Statement. you can also use the less-than symbol with position() function like this position( )<3.

Note: The index is counted from top to bottom of the page, and the index starts from 1.

Last()

If you don’t know the element’s index but it’s the last element out of the selected elements, then you can use the last() function to select the last element, and the syntax looks like the one below.

xpath=(//input[@type='checkbox'])[last()]
package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class Xpath_Contains_Last_Method 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/table-example-for-xpath.html");
      Thread.sleep(10000);
      
      WebElement Ele1=driver.findElement(By.xpath("//tr[last()]/td[last()]"));
      String text=Ele1.getText();
      
      System.out.println("The Last Row Last Cell Text: "+text);
      driver.close();
   }
}

You can also use the minus operator (-) with the last() function to locate the elements like those below

xpath=(//input[@type='checkbox'])[last()-1]

in this example, we will find the last row’s last element, Italy, using the last method.

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class Xpath_Contains_Last_Method 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/table-example-for-xpath.html");
      Thread.sleep(10000);
      
      WebElement Ele1=driver.findElement(By.xpath("//tr[last()]/td[last()-2]"));
      String text=Ele1.getText();
      
      System.out.println("The Last Row First Cell Text: "+text);
      driver.close();
   }
}

Concat()

From the above examples, we have noticed that Xpath is more helpful when writing the selenium tests. Even though there are so many Selenium selectors doing a tremendous job, experts can express things that the other selectors cannot do.

But we must be slightly careful when dealing with the strings in Selenium. As though We have a special method like text(), contains(), and starts-with() to deal with the strings.

Because strings are very limited in Xpath, to deal with the strings and to prepare a custom XPath, we have a separate method, which is Concat().

Where should you use the Concat() Method?

when we are dealing with those string which does not have single quotes (‘) or Double quotes (“) to locate the element, you can use methods like contains(), text(), and starts-with(). But if a string has single quotes and double quotes in it, then in that case, we will get an InvalidSelectorException.

When you execute the below piece of code at that time, you will get InvalidSelectorException. The normal way of writing XPath will not work because of enclosing quotes, and you can not escape it. If we keep the text within single or double quotes, we get another within the text that can not be escaped.

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class Xpath_Concat_Method_Ex2 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/invalidselectorexception-in-selenium.html");
      Thread.sleep(10000);
      
      String quotetext=driver.findElement(By.xpath("//p[text()='Hi User. Thanks for Your's love & Supoport']")).getText();	
      System.out.println("The Full Text: "+quotetext);
      
      driver.close();
   }
}

Console Log:

Exception in thread "main" org.openqa.selenium.InvalidSelectorException: invalid selector: Unable to locate an element with the xpath expression //p[text()='Hi User. Thanks for Your's love & Supoport'] because of the following error:
SyntaxError: Failed to execute 'evaluate' on 'Document': The string '//p[text()='Hi User. Thanks for Your's love & Supoport']' is not a valid XPath expression.
  (Session info: chrome=84.0.4147.125)
For documentation on this error, please visit: http://seleniumhq.org/exceptions/invalid_selector_exception.html
Build info: version: '3.9.0', revision: '698b3178f0', time: '2018-02-05T14:56:13.134Z'
System info: host: 'DESKTOP-QDIUJQH', ip: '172.20.10.3', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_231'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 84.0.4147.125, chrome: {chromedriverVersion: 84.0.4147.30 (48b3e868b4cc0..., userDataDir: C:\Users\SOFTWA~1\AppData\L...}, goog:chromeOptions: {debuggerAddress: localhost:59137}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: WINDOWS, platformName: WINDOWS, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:virtualAuthenticators: true}
Session ID: 6d37050b2f0ab95d890c29f99d14e34b
*** Element info: {Using=xpath, value=//p[text()='Hi User. Thanks for Your's love & Supoport']}
   at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
   at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
   at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
   at java.lang.reflect.Constructor.newInstance(Unknown Source)
   at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187)
   at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122)
   at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49)
   at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:160)
   at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
   at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:601)
   at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:371)
   at org.openqa.selenium.remote.RemoteWebDriver.findElementByXPath(RemoteWebDriver.java:473)
   at org.openqa.selenium.By$ByXPath.findElement(By.java:361)
   at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:363)
   at com.selenium.practice.locator.Xpath_Concat_Method_Ex2.main(Xpath_Concat_Method_Ex2.java:19)
InvalidSelectorException Console Log
InvalidSelectorException Console Log

To deal with such a scenario, you can use the contact method.

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class Xpath_Concat_Method_Ex3 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/invalidselectorexception-in-selenium.html");
      Thread.sleep(10000);
      
      String quotetext=driver.findElement(By.xpath("//p[text()=concat('Hi User. Thanks for Your',\"'s love\",' & Supoport')]")).getText();	
      System.out.println("The Full Text: "+quotetext);
      
      driver.close();
   }
}

If you have noticed the example, we have split the string in the presence of single quotes and used the escape sequence here.

  • First Section: Hi User. Thanks for Your
  • Second section: ‘s love & Support

Finally, we combine two separate strings with the contact() method. The syntax for the Concat method is:

concat(string1 ,string2 [,stringn]* )

Using ‘OR’ & ‘AND’

If you remember, you have read about this OR & AND, which are logical expressions. In OR logical expression, if there are two conditions, and out of that, if any condition is true or both are true, then you can locate the elements.

< input type=”email” placeholder=”Work Email*” name=”email” value=”” class=”form-control sign-up-input-2 ” >

Xpath= //input[@type= ‘email’ or @name= ‘email’]

When we are going to use, AND in that case, both the conditions should match and be true, then only the element will be located.

Xpath= //input[@type= ‘email’ and @name= ‘email’]

For Example:

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class Xpath_And_Or_Example 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/xpath-locators.html");
      Thread.sleep(10000);
      
      driver.findElement(By.xpath("//input[@type='email' and @name='email']")).sendKeys("Software Testingo");;
      Thread.sleep(5000);
      driver.close();
   }
}

Using Index

The index comes into the picture when you want to locate an element; for that, you know the tag details and index of the element. Then, in that case, you can use the index. In the real-time scenario, you can get such cases when dealing with the data in a table.

Xpath= //div[@class= ’ col-sm-12 google-sign-form’]/input[2]

Example:

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class Xpath_Index_Example 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/xpath-locators.html");
      Thread.sleep(10000);
      
      driver.findElement(By.xpath("//input[2]")).sendKeys("Software Testingo");
      Thread.sleep(5000);
      driver.close();
   }
}

Using Chained XPath In Selenium

By using the existing attributes and functions, if we cannot locate any element in the DOM at that time, we try to use multiple Xpaths in a chained form [ using more than one XPath]. For example

<ul class="nav navbar-nav navbar-right">
<li><a href="https://www.softwaretestingo.com/">Live</a></li>
<li><a href="https://www.softwaretestingo.com/">Automation</a></li> <li><a href="https://www.lambdatest.com/blog">Blog</a></li>
<li><a href="https://www.softwaretestingo.com/">Pricing</a></li>
<li><a href="https://www.softwaretestingo.com/">Support</a></li>
<li class="sign-in"><a href="https://www.softwaretestingo.com/">Login</a></li>
<li class="login"><a href="https://www.softwaretestingo.com/">Free Sign Up</a>
</li>
</ul>

In the below example, you can say that first, we try to locate the permanent element class for which we have used //ul[@class=’nav navbar-nav navbar-right’]. Later, we move to our required element, logging in. and all the operations we can do by using multiple Xpaths; I hope you can understand this example.

//ul[@class=’nav navbar-nav navbar-right’]//li[@class=’login’]

Example:

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class Chained_Xpath_Example 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/xpath-locators.html");
      Thread.sleep(10000);
      
      WebElement link=driver.findElement(By.xpath("//ul[@class='nav navbar-nav navbar-right']//li[@class='sign-in']"));
      String text=link.getText();
      Thread.sleep(10000);
      System.out.println("The Link Text Is: "+text);
      driver.close();
   }
}

XPath axes

When you are learning XPath, don’t miss the important concept of XPath, which is XPath axes, because this will help you locate the element with the help of writing your XPath, which is a help to locate dynamic elements. Sometimes, we may not find the unique attribute(s) or innerHTML when locating a specific element in the DOM. That time, you have to take the help of the known elements with unique attribute(s) or innerHTML.

Regular daily life; for example, if someone asks you about location details, we tell him about the first location or landmark like [shop, building, street, etc.], which he is aware of, and then from that place, we guide him so that he can easily reach to his required location

Similarly, when we try to locate or identify an element in DOM that time, if we are not able to find that element using the tagname or some attribute value, then, in that case, we can try to identify it by traversing the child/sibling or parent will be an easy approach. Some of the widely used XPath axes are:

  • Child
  • descendant
  • descendant-or-self
  • Ancestor
  • Parent
  • Ancestor-or-self
  • Preceding
  • Preceding-sibling
  • following
  • following-sibling

Ancestors

What is an Axes View?

Axes view represents the other node’s path or location concerning the current node.

So, the basic rule of axes view is to find a node in the hierarchy with the constant value for their attribute, mark that node as the current node, and calculate the XPath for other nodes based on that node.

Child Axes view

Suppose your requirement has located an element, but you cannot locate that element. In that case, you have to find the parent node or the node that you can find easily with some unique attributes. After that, you need to use the child keyword so that all the immediate child nodes will be selected in reference to the parent node.

Xpath= //div[@class=’ col-sm-12 google-sign-form’]/child::*

The above syntax will select all the immediate child nodes of that parent node.

Xpath= //div[@class=’ col-sm-12 google-sign-form’]/child::input

If you want to select only the input immediate child nodes of a specific parent node, you can use another filter with the child keyword to select a specific node.

descendant Axes View [Grand Child & Child Nodes]

When you go to the descendant keyword, it will select the current node’s immediate child and grandchild nodes. and the XPath will look something similar to the one below

Xpath= //div[@class=’ col-LG-3 col-MD-4 col-sm-6 sign-form’]//descendant:: *

After this, as per your requirement, you can use the filter to select some specific nodes like those below

Xpath= //div[@class=’ col-LG-3 col-MD-4 col-sm-6 sign-form’]//descendant:: input

descendant-or-self Axes view

In the above, we can see that when we use a descendant at that time, we can select the immediate child and grandchild nodes of the current node, but the current node is not selected. Still, when selecting the current node with the child and grandchild nodes, you have to use the descendant-or-self keyword.

Xpath= //div[@class=’ col-lg-3 col-md-4 col-sm-6 sign-form’]//descendant-or-self::*

Here, you can also use the filter option to select some specific node; for example, if you want to select the parent node and input type elements, you can use

Xpath= //div[@class=’ col-lg-3 col-md-4 col-sm-6 sign-form’]//descendant::input

Note: It is better to use a descendant axes view when dealing with the child and grandchild.

XPath in Selenium WebDriver: Complete Tutorial 1

Parent Axes View

We now have different axes viewed as child, descendant, following, and preceding axes view, and now we will look at Ancestor Axces’ view. If you want to select the parent node of the current node at that time, you can use the parent keyword like below.

Xpath=//input[@name=’password’]//preceding::div/parent::*

Ancestor [Grandparent] Axes view

When you are going to use the ancestor keyword, it will be going to select all the parent and grandparent nodes of the current node. and the Xpath will look like below

Xpath= //input[@name=’email]//ancestor::*

If you want to filter out from all the select nodes, then you can use the filters with the ancestor keyword like below.

Xpath= //input[@name=’email]//ancestor::div[1]

Ancestor-or-self Axes view

In the view, you can select the parent and grandparent nodes with the current node, and the syntax looks like the one below.

Xpath= //input[@name=’email]//ancestor-or-self::*

Note: using the axes view, you can select any node in a web page or DOM, the only thing you need to find a reference node. So with the help of a reference node, you can able to select any node present anywhere on the web page. This is the main advantage of using the axes’ view.

Following Axes View

The following keyword will select all the nodes parallel to the current node and the child and grandchild nodes of the parallel node.

Xpath= //input[@name=’ organization_name’]//following::*

You can use the filter with the above node to select any specific node.

following-sibling Axes view

Still, now we have discussed that when we are going to deal with the child nodes, we need to use the descendant axes view, and whenever we are dealing with the nodes that are parallel to our current node, we will use the following axes view. That means the node and the current belong to the same parent.

Xpath= //li[@class=’sign-in’]//following-sibling::*

You can also use filters to locate specific elements.

Xpath= //li[@class=’sign-in’]//following-sibling::li

Preceding Axes view

as we have seen, when we use the following keyword, it only considers nodes at the same level as the current node but below the current node. But when we use the Preceding keyword, it will consider all those nodes at the same level as the current node but above the current node.

Xpath=//input[@name=’password’]//preceding::*;

preceding-sibling axes view

preceding-sibling we can use when we want to select all the nodes that are the same level but above the current node. and the XPath will look like the below:

Xpath=//input[@name=’password’]//preceding-sibling::*;
Xpath=//input[@name=’password’]//preceding::div

How do you locate an element using an XPath Locator example in Selenium?

package com.selenium.locator;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
public class Locator_Xpath 
{
   WebDriver driver=new FirefoxDriver();
   @BeforeTest
   public void openwebsite()
   {
      driver.manage().window().maximize();
      driver.manage().timeouts().implicitlyWait(5000, TimeUnit.SECONDS);
      driver.get("http://opensource.demo.orangehrmlive.com/index.php/auth/login");
   }
   @Test
   public void login()
   {
      driver.findElement(By.xpath(".//*[@id='txtUsername']")).sendKeys("Admin");
      driver.findElement(By.xpath("//input[contains(@id,'txtPassword')]")).sendKeys("admin");
      driver.findElement(By.xpath("//input[starts-with(@name,'Submit')]")).click();
   }
   @AfterTest
   public void close() throws InterruptedException
   {
      Thread.sleep(5000);
      driver.close();
   }
}

I love open-source technologies and am very passionate about software development. I like to share my knowledge with others, especially on technology that's why I have given all the examples as simple as possible to understand for beginners. All the code posted on my blog is developed, compiled, and tested in my development environment. If you find any mistakes or bugs, Please drop an email to softwaretestingo.com@gmail.com, or You can join me on Linkedin.

3 thoughts on “XPath in Selenium WebDriver: Complete Tutorial”

  1. Hi there
    First of all amazing work!
    I just want to know is this site repo available on git where we can send the PRs with changes or improvement suggestions?

    Thanks!

    Reply
    • Hi Mukul,

      Thanks for showing interest in contributing to the community; we will soon create a GIT Repo and will update

      Reply

Leave a Comment