In this tutorial, we are going to learn the most important topic XPath in Selenium WebDriver which is asked by the interviewer in any company interview. Basically, when we write any test script, we generally prefer to use general Selenium locators such as id, name, className, etc. But sometimes it is difficult to find any of them in the DOM (Document Object Model). In this case, we will have to use XPath to locate an element on the webpage.

So, let's learn what is XPath and what are different ways to choose the most effective Xpath to find complex or dynamic elements whose attributes change dynamically on refresh or any other operations.

XPath In Selenium

XPath stands for XML (Extensible Markup Language) Path language. It is a query language which is used to search and select nodes in an XML document. All major web browser supports XPath. Selenium WebDriver supports XPath to find the location of any element on a webpage using XML path expression. The basic syntax of XPath is explained below with screenshot.
The path of element at a webpage is selected by XML path syntax. Standard syntax to create XPath is given below:
   // ➨ It select current node.
   tagname ➨ It is the name of tag of particular node. For example: input, div, img, etc. 
   @ ➨ It selects attribute like id, name, className, etc.
   Attribute ➨ It is the attribute name of the node. For example: type, class, name, id, etc.
   value ➨ It is value of attribute.
XPath in Selenium
For example:
     XPath = //input[@id='user-message']
How to Find XPath in Chrome Browser

Types of XPath in Selenium

There are two types of XPath in selenium.
1. Absolute XPath
2. Relative XPath

Absolute XPath in Selenium

Absolute XPath begins with a single forward-slash (/) which select element from the root HTML node. It is the easiest and direct way to find element but if any changes happen in the path of element, this XPath gets failed. So, this is the main disadvantage of using absolute XPath.
The example of an absolute XPath expression of the element is shown below.
Absolute XPath: /html/body/div/div/form/input.
     /html: This is the root HTML element node. You will have noticed in absolute XPath expression that a slash (/) is used in the beginning which represents an absolute xpath.

Finding Elements with an Absolute Path

Absolute path refers to a very specific location of the element which depends on the structure or hierarchy of elements on a webpage. Here is an example where the username is located using absolute path. So, we can search element using absolute path like this.
   WebElement username=driver.findElement(By.xpath("/html/body/div/div/form/input"));

Advantage & Disadvantage of Absolute XPath:

➲ Advantage of using absolute XPath is that it identifies an element very fast.
➲ Disadvantage is that if anything goes wrong or some other tag is added in between, this path will no longer work.
For example:
If we define a path as html/head/body/table/tbody/tr/th. But when we add a tag between body and table, the path will be changed like this html/head/body/form/table/tbody/tr/th. In this case, the first path will not work as 'form' tag has been added in between.

Relative XPath in Selenium

Relative XPath starts from double forward-slash (//) and select element from anywhere on the webpage. It is the best practice to find element through relative XPath because it helps us to reduce chance of "ElementNotFoundException".

2. With a relative XPath, we can locate an element directly irrespective of its location in the DOM. Below is the example of a relative XPath expression of an element. It is a general format used to find out element through a relative XPath.
     Relative XPath: //input[@id='email']
Other example of Relative XPath: .//*[@id='username']

1. .(dot): Dot at starting represents current node. It tells that the processing will start from the current node.
2. . .(double dot): It will select the parent of current node. For example, //table/. . will return div element because div is the parent of table element.

3. '*': is used to select all the element nodes descending from the current node.
For example:
   /table/*:  It will select all child elements of a table element.
   //*: It will select all elements in the document.
   //*[@id='username']: It will select any element in document which has an attribute named "id" with the specified value "username".

4. @:  It represents an attribute which selects id, name, className, etc.
For example:
    @id: It will select all elements that are defined with the id attribute in the document. No matter where it is defined in the document.
    //img/@alt: It will select all the img elements that are defined with the @alt attribute.
    //td[@*]: It will select all td elements with any attribute.

Finding Elements using Attributes values in XPath

We can also search for elements using their attribute values in the XPath. Let's see an example where we will identify username field using the ID attribute.
     WebElement username=driver.findElement(By.xpath("//input[@id='username']"));
Let's take another example where image is located using alt attribute.
      WebElement nextbutton=driver.findElement(By.xpath("//img[@alt='next']"));

Advantage & Disadvantage of Relative XPath:

➲ Advantage of using relative XPath is that you don't have to create the long XPath. You can also start from the middle.
➲ Disadvantage of using relative XPath is that it takes more time in identifying the element as we specify the partial path, not the exact path.

Difference between "/" and "//" in XPath

There are mainly three differences between single slash and double slash.
1. Single slash is used to create absolute XPath whereas Double slash is used to create relative XPath.
2. Single slash selects an element from the root node. For example, /html will select the root HTML element.
Double slash search element from anywhere on the web page. For example, //table will select all the table elements from anywhere on the web page.

3. Single slash (/) defines ancestor and descendant relationships if used in the middle. For example, //div/table returns the div which contains a table object.
If double slash (//) is used in middle, it defines a descendant relationship. For example, /html//title returns title element which is descendant of html element. 

XPath Axes in Selenium

XPath axes are methods to identify those dynamic elements which are not possible to find by normal XPath method such as ID, Classname, Name, etc. Axes are so named because they tell about the axis on which elements are lying relative to an element.

Dynamic web elements are those elements on the webpage whose attributes dynamically change on refresh or any other operations.

The commonly useful XPath axes methods used in Selenium WebDriver are child, parent, ancestor, sibling, preceding, self, etc.  XPath axes help to find elements based on the element's relationship with another element in a document. We will elaborate on all methods of XPath axes in the next tutorial.

How to handle Complex and Dynamic Elements in Selenium using XPath?

There are following ways by which we can handle complex and dynamic element in selenium. They are as follows:

1. Basic XPath:

Basic XPath expression select nodes or list of nodes on the basis of attribute like ID, Name, Classname, etc from XML document.
For example:
          input ➡ tagname
          name ➡ attribute
          user-message ➡ value Let's find XPath of different elements on facebook for practice. Open the facebook page and find the XPath of email and password elements. We hope that you know the technique of finding XPath in chrome browser. If not, go to below link first to learn:
1. Right-click on email box and go to inspect option. Now press ctrl+F. Write XPath by following basic syntax and on the basis of the below screenshot. We will start to write XPath with //, followed by input tag, then we will use the select attribute, followed by its attribute name like name, id, etc, and then we will choose a value of attribute in single quotes.
How to handle Complex and Dynamic Elements in Selenium using XPath
XPath(email): //input[@id='email'] (1 of 1 matched)
Here, (1 of 1) means exact match. It indicates that there is only one element available for this XPath. If it is showing (1 of 2) or (1 of 3) and so on. In this case, you don't need to choose this XPath because there are multiple elements available with the same XPath.

Key points: 
If you find more than one elements matching the same XPath, do not choose that XPath. Try to write another XPath for that element and find one matched only (i.e. 1 of 1).

2. Contains()

Contains() is a method which is used to find the value of those attribute which changes dynamically. For example, login information. It has the following general form which is given below:
      //tagname[contains(@attribute, 'value')]
For example:
Let's try to find XPath of "Sign up button" on the facebook webpage for demo. Open facebook page, right-click on sign up button, and go to inspect option. Now write XPath in the panel like this.
         XPath(Sign Up): //button[contains(@name, 'websubmit')]

Key points:
1. The main feature of contains() method is that it can find element with partial text. For example, let's find the same XPath for sign up button with partial text.
         XPath(Sign Up): //button[contains(@name, 'web')]
In this expression, we have taken "name" as attribute and "web" as partial text in the place of websubmit.
2. Contains() method can be used in any condition when you need to find XPath.
     XPath(Female Radio button): //input[contains(@id, 'u_0_8')]
     XPath(New password): //input[contains(@id, 'u_0_13')]

3. starts-with():

starts-with() is a method which finds those elements whose attribute value changes on refresh on the webpage. This method checks the starting text of an attribute and find elements whose attribute changes dynamically. We can also use this method to find elements whose attribute value is static (not changing). The syntax for starts-with() method is given below:
     XPath: //tagname[starts-with(@attribute, 'value')] For example: Let's find XPath of search button using starts-with() method on webpage
1. XPath(Search button): //span[starts-with(@class, 'field-submit-text')]
2. XPath(Keyword): //input[starts-with(@name, 'keyword')]

4. ends-with():

ends-with() method checks the ending text of an attribute and find elements whose attribute changes dynamically on refresh. It has the following syntax which is given below.
      XPath: //tagname[ends-with(@attribute, 'value')]
For example, if the ID of an element is a_1_password, it will find and return elements with _password at the end of ID.

5. Using "OR" Statement:

In OR expression, two conditions are used and anyone condition either 1st condition or 2nd condition should be true to find element. It has the following general form.
     XPath: //tagname[XPath statement-1 or XPath statement-2]
For example: Let's find the XPath of login button of facebook page.
     XPath(login button): //input[@value='Log In' or @type='submit'] // Both XPath statements are true.

6. Using "AND" Statement:

In AND expression, two conditions are used and both conditions must be true to find element. If anyone condition is false then XPath will be failed to find element. It has the following general form.
     XPath: //tagname[XPath statement-1 and XPath statement-2]
For example: let us find XPath of sign up button on facebook page.
     XPath(Sign Up button): //button[@type='submit' and @id='u_0_19'] (1 of 1 matched).

7. Text():

The text() method is used to find elements with an exact match. The syntax for the text() method is given below:
      XPath: //tagname[text()='text_value']
For example, we will create XPath of text "Create a new account" of facebook page using text() method.
       XPath(Create a new account): //div[text()='Create a new account'] where div is tagname.
Similarly,  XPath(Recent logins): //div[text()='Recent logins']

How to Create XPath of Links in Selenium?

We can easily determine XPath of any link in Selenium using text() method. For example, open the webpage In this webpage, we will create XPath of Gmail link. When you will inspect it, you will see like this <a class="gb_e" data-pid="23" href=";ogbl">Gmail</a>. Here, Gmail is text. So, let's find XPath for this link.
          XPath(Gmail): //a[text()='Gmail']

We can also write the same XPath using contains() method like this:
          XPath(Gmail): //a[contains(text(), 'Gmail')] (1 of 1 matched).
Similarly, XPath(Images): //a[contains(text(), 'Images')] (1 of 1 matched).

Final words: 
Hope that this tutorial has covered almost all important points related to XPath in Selenium WebDriver with example. I hope that you will have understood this topic and practiced them. In the next tutorial, we will learn XPath axes methods in detail.
Thanks for reading!