XPath is an important Web application UI Elements Identifier mostly used in test automation. It is one of the widely used identification strategies in open source tools. In this article, we will learn about XPath and different XPath expressions to identify complex or dynamic elements whose attributes change dynamically in web applications.
Notes:
- Throughout the article, I have used a sample application to illustrate examples. Here is the application link – OrangeHRM Demo.
- To write Xpath expressions, I have used TestProject’s free Smart Test Recorder and utilized their smart element inspector to easily do so.
For Selenium test automation, if elements are not identified by general locators such as ID, Class, Name, etc., XPath is used to locate an element on the web pages.
Overview
- What is XPath?
- The Syntax for XPath
- Types of XPath
- XPath Axes
- Handle Dynamic and Complex Elements in Selenium
- Summary
What is XPath?
XPath is defined as an XML path. It is a syntax or a language used to locate UI elements on the web page using an XML path expression. XPath is used to locate any UI elements on a webpage using the HTML DOM structure. The basic example of XPath is explained in the image below:
The Syntax for XPath
XPath contains the path of the UI element present on the web page.
The standard syntax for an XPath is as below:
There are different types of locators to find a web element on the webpages accurately:
Locators | Types of identification |
ID | To find the element by the ID of the element |
ClassName | To find the element by ClassName of the element |
Name | To find the element by ClassName of the element |
Link Text | To find the element by the text of the link |
XPath | XPath required for finding the dynamic element and traverse between various elements of the web page |
CSS Path | CSS path also locates elements having no name, class or ID |
Types of XPath
There are two types of XPath:
- Absolute XPath
- Relative XPath
Absolute XPath
It uses the full path from the root element to the desired UI element. The disadvantage is that if anything changes between the path, such as some other tag is added or removed, then this path will no longer work. For example:
/html[1]/body[1]/div[1]/div[1]/div[3]/div[2]/div[2]/form[1]/div[5]/input[1]
Relative Xpath
You can begin by referencing the component from the middle of the HTML DOM structure and go from there. It starts with the double forward-slash (//). Below is an example of the relative XPath expression of the same UI element shown in the image below. This is the popular format used to locate the item in a relative XPath:
//input[@id='btnLogin']
XPath Axes
The paths define the location of a node using absolute or relative paths. An axis represents a relationship to the context (current) node and is used to locate nodes relative to that node on the tree. XPath Axes are used to identify elements by their relationship: Parent, child, sibling, etc. Axes refer to the axis on which elements are lying relative to an element. There are few axes methods commonly used in Selenium Webdriver, such as: child, parent, ancestor, sibling, preceding, self, etc.
Here is a list of various Axis values:
Axes | Description |
ancestor | It specifies the ancestors of the current nodes which include the parents up to the root node. Example:
Xpath=//*[text()='<Text Element>']//ancestor::div |
ancestor-or-self | It specifies the current node and its ancestors. Example:
Xpath=//*[text()='<Text Element>']/ancestor-or-self::* |
child | It specifies the children of the current node. Example:
Xpath=//*[@id='<id attribute of an Element>']/child::li |
descendant | It specifies the descendants of the current node. i.e. the node’s children up to the leaf node (no more children). Example:
Xpath=//*[@id='<id attribute of an Element>']//descendant::a |
descendant-or-self | It specifies the current node and its descendants. Example:
Xpath=//*[@id='<id attribute of an Element>']//descendant-or-self::* |
following | It specifies all the nodes that come after the current node. Example:
Xpath=//*[@type=<Text Element>]//following::input[1] |
following-sibling | It specifies the following siblings of the context node. Siblings are at the same level as the current node and share its parent. Example:
Xpath=//*[@type='submit']//following-sibling::input |
namespace | It specifies the namespace of the current node. |
parent | It specifies the parent of the current node. Example:
Xpath=//*[@id='<id attribute of an Element>']//parent::div |
preceding | It specifies all nodes that come before the current node (i.e. before its opening tag). Example:
Xpath=//*[@type=”<Type attribute of an Element>”//preceding::input |
self | It specifies the node of itself. Example:
Xpath =//*[@type=”<Type attribute of an Element>”]//self::input |
How to Handle Dynamic and Complex Elements in Selenium
There are a few functions you can use to handle dynamic and complex elements in Selenium:
1. Basic XPath
Xpath selects the node or list of nodes based on the node attributes references like ID, Name, Class, Value, etc. XPath using an ID attribute would look as follows:
//input[@id='txtUsername']
The same element can be found using other types of attributes as well, as seen in the examples below:
//input[@name='txtUsername'] (//div/input)[2] //*[id='txtUsername']
Below are examples of other UI elements on the login page with other nodes and attributes combinations:
//input[@class='button'] //form[@action=''/index.php/auth/validateCredentials] //input[@value='LOGIN'
2. Contains()
Contains is one of the functions in XPath expressions. It can be used when the UI element attribute values are changing dynamically, for example: Dates, login successful/error messages, etc. Contains method can be used when we know about the partial value of an attribute or partial text associated with the web element, for example:
//span[contains(text(),'cannot be empty')]
More examples:
//span[contains(text(),'( Username : Admin | Password : admin123 )')] //a[contains(text(),'password?')] //span[@class='form-hint'][contains(text(),'Username')]
3. Starts-with()
Starts-with function can be used when we know the starting partial attribute value or starting partial text associated with the web element. It can also be used to locate web elements that consist of both the static(initial) and dynamic(trailing) values. Example:
//div[starts-with(@id,'forgot')]
More examples:
//h1[starts-with(text(),'Forgot')] //label[starts-with(text(),'Employee')] //div[starts-with(@class,'input')]
4. And/OR
OR expression can be used when we want to combine two conditions together, and based on whether they are true or false – Identify a UI element on the web page. That means, at least one condition should be true to find the UI element. Example:
//input[@name='txtusername' or @id='txtUsername']
More examples:
//input[@name='Submit' or @id='btnLogin'] //input[@name='Submit' or @value='Login']
AND expression can be used when we want to combine two conditions, and both of the conditions should be true in order to find the element. If anyone of these conditions is not matched – we will fail to find an element on the web page. Example:
//input[@type='submit' and @id='btnLogin']
5. Text()
Text() function can be used to find the element with the exact text match as shown below:
//span[text()='( Username : Admin | Password : admin123 )']
Summary
We’ve understood what is XPath and what are its various types of axes. In addition, we learned how to effectively use XPath patterns to identify web page UI elements. There are many ways to learn how to make XPaths more efficient when dealing with complex UI elements, and there are various levels of expertise. If you’d like me to elaborate on any of these subjects any further, please comment below – I’d be pleased to expand this post with advanced concepts 😎