XPath Selenium tactics will help you to write effective selenium find by statements especially for locating dynamic web elements in selenium webdriver projects. Generally, test automation engineers struggle to write dynamic XPath at the beginning of their test automation journeys. To address this pain, I prepared this tutorial for writing effective XPath in Selenium.
I shared all my tactics such as XPath contains text, sibling, ancestor, child, preceding, descendant, parent, and so on. I hope this article will help you to write smart and non-brittle selenium find by statements in your projects. Let’s start!
Table Of Contents
Dynamic Web Elements
In our test automation codes, we generally prefer to use id, name, class, etc. these kinds of locators. However, sometimes we could not find any of them in the DOM and also sometimes locators of some elements change dynamically in the DOM. In these kinds of situations, we need to use smart locators. These locators must be capable to locate complex and dynamically changing web elements. In below sections, I will share with you 15 tactics to write effective XPath locators.
XPath Selenium Selectors
We can find the location of any element on a web page using XML path expressions. The basic syntax for XPath is shown below:
Syntax = //tagname[@attribute=’Value‘]
Example = //input[@id=’user-message‘]
You can also use class, name, link text, and the other attributes to locate an element with XPath as shown above.
Absolute and Relative XPath
Generally, in some test automation engineer interviews, I asked the difference between absolute and relative XPath. Actually, it is the answer is very easy.
Absolute XPath
- It is a direct way to locate an element.
- It is very brittle.
- Starts with single slash “/” that means starting to search from the root.
Example: /html/body/div[2]/div/div[2]/div[1]/div[2]/form/div/input
Relative XPath
- Starts from the middle of the HTML DOM.
- Starts with a double slash “//” that means it can start to search anywhere in the DOM structure.
- Shorter than Absolute XPath.
- Less fragile.
Example: //div[@class=’form-group’]//input[@id=’user-message’]
Example: //*[@class=’panel-body’]//li[contains(text(),’entered in input field’)]
Writing Smart XPaths for Complex and Dynamic Elements
Tag – Attribute – Value Trio
Syntax: //tag[@attribute=’value‘]
Example: //input[@id, ‘user-message’]
Examples:
1 2 3 4 5 6 7 8 9 10 11 12 | //input[@type='send text'] //label[@id='clkBtn'] //input[@value='SEND'] //*[@class='swtestacademy'] --> "*" means, search "swtestacademy" class for all tags. //a[@href='http://www.swtestacademy.com/'] //img[@src='cdn.medianova.com/images/img_59c4334feaa6d.png'] |
Contains
It is very handy XPath Selenium locator and sometimes it saves the life of a test automation engineer. When an attribute of an element is dynamic, then you can use contains() for the constant part of the web element but also you can use contains() in any condition when you need.
Syntax: //tag[contains(@attribute, ‘value‘)]
Example: //input[contains(@id, ‘er-messa’)]
Examples:
1 2 3 4 5 6 7 8 | //*[contains(@name,'btnClk')] --> It searches "btnClk" for all name attributes in the DOM. //*[contains(text(),'here')] --> It searches the text "here" in the DOM. //*[contains(@href,'swtestacademy.com')] --> It searches "swtestacademy.com" link in the DOM. |
Starts-with
This method checks the starting text of an attribute. It is very handy to use when the attribute value changes dynamically but also you can use this method for non-changing attribute values.
Syntax: //tag[starts-with(@attribute, ‘value‘)]
Example: //input[starts-with(@id, ‘user’)]
Chained Declarations
We can chain multiple relative XPath declarations with “//” double slash to find an element location as shown below.
Example: //div[@class=’form-group’]//input[@id=’user-message’]
Operator “or”
In this method, we use two interrogation conditions such as A and B and return a result-set as shown below:
A | B | Result |
False | False | No Element |
True | False | Returns A |
False | True | Returns B |
True | True | Returns Both |
“or” is case-sensitive, you should not use capital “OR”.
Syntax: //tag[XPath Statement-1 or XPath Statement-2]
Example: //*[@id=’user-message’ or @class=’form-control’]
Operator “and”
In this method, we use two interrogation conditions such as A and B and return a result-set as shown below:
A | B | Result |
False | False | No Element |
True | False | No Element |
False | True | No Element |
True | True | Returns Both |
“and” is case-sensitive, you should not use capital “AND”.
Syntax: //tag[XPath Statement-1 and XPath Statement-2]
Example: //*[@id=’user-message’ and @class=’form-control’]
Text
We can find an element with its exact text.
Syntax: //tag[text()=’text value‘]
Example: .//label[text()=’Enter message’]
Ancestor
It finds the element before the ancestor statement and set it as a top node and then starts to find the elements in that node. In below example,
1- First, it finds the class which id is “container-fluid”
2- Then, starts to find div elements in that node.
Example: //*[@class=’container-fluid’]//ancestor::div
You can select specific div groups by changing div depths as shown below.
.//*[@class=’container-fluid’]//ancestor::div[1] – Returns 13 nodes
.//*[@class=’container-fluid’]//ancestor::div[2] – Returns 7 nodes
.//*[@class=’container-fluid’]//ancestor::div[3] – Returns 5 nodes
.//*[@class=’container-fluid’]//ancestor::div[4] – Returns 3 nodes
.//*[@class=’container-fluid’]//ancestor::div[5] – Returns 1 node
Following
Starts to locate elements after the given parent node. It finds the element before the following statement and set as the top node and then starts to find all elements after that node. In below example,
1- First, it finds the form which id is “gettotal”
2- Then, starts to find all input elements after that node.
Example: .//form[@id=’gettotal’]//following::input
Child
Selects all children elements of the current node.
Example: //nav[@class=’fusion-main-menu’]//ul[@id=’menu-main’]/child::li
You can also select the required “li” element by using li[1], li[2], li[3], etc. syntax as shown below.
Preceding
Select all nodes that come before the current node. I give an example on swtestacademy. We will find all “li” elements in the homepage. First, we will locate the bottom element, then use preceding with “li” to find all “li” elements as shown below.
Example: //img[contains(@src,’cs.mailmunch.co’)]//preceding::li
Also, you can use [1], [2], etc. to select a specific element in the preceding element list.
Following-sibling
Select the following siblings of the context node.
Example: //*[@class=’col-md-6 text-left’]/child::div[2]//*[@class=’panel-body’]//following-sibling::li
Descendant
Identifies and returns all the element descendants to current element which means traverse down under the current element’s node. Below, the XPath returns all “li” elements under the “menu-main”.
Example: //nav[@class=’fusion-main-menu’]//*[@id=’menu-main’]//descendant::li
Returns the parent of the current node as shown in the below example.
Example: .//*[@id=’get-input’]/button//parent::form
Locate an Element inside Array of Elements
In Trivago website, lets search “Antalya” keyword. Then, find the first Odamax hotel with XPath.
First, we can find all Odamax hotels by using its text with below XPath:
//span[contains(text(),’odamax’)]
Above XPath returns many Odamax hotel’s, we can select the first one with below XPath expression:
(//span[contains(text(),’odamax’)])[1]
You can also continue to search and find the related hotel’s price element with below XPath:
(//span[contains(text(),’odamax’)])[1]/following-sibling::strong[@class=’deals__price’]
Also, you can learn how to write effective Selenium CSS locators in below article.
Selenium CSS Selector Complete Reference – All Tactics Explained!
I also suggest to save and always use the below reference.
See you!
Onur
This is by far the best tutorial on using xpath. It clearly explains the structure of an xpath expression; it then describes the variety of usage, clearly and with great graphics.
Great work and thanks.
Kgething.
You are welcome Kelvin. I am glad that you liked the article. 🙂
Very clear and easily digestible tutorial.
Thank you.
You are welcome Aleksandar.
I agree. By far the best xpath tut I’ve seen.
I kind of panicked when I couldn’t find my bookmark anymore (turned out it was on another computer XD)
:)))
As others have commented, this is a great xpath tutorial. Thank you 🙂
Thanks for your kind comment. 🙂 That makes me so happy. I am glad that it helps.
I’ve done Robot Framework tests with xpath now about 6 months. Now I learned much more after reading this tutorial. Thank a lot 🙂
Welcome, Marko. Happy to hear your kind feedback.
superb tutorial keep updating about all the concepts
Thank you so much. 🙂
Fantastic effort to put this up for everyone to use. Thanks a lot
Welcome Ram 🙂 Your comment makes my day. Thank you so much.
Hi Onur, please do you think you could write a tutorial that explains the difference between dot and text? I found this post but to be honest I’m more confused now than before reading it. Link: https://stackoverflow.com/questions/38240763/xpath-difference-between-dot-and-text
thanks
Hi Andrea, I did not use that but I will also check and try to add an section about this. Thank you for pointing out this topic.
Thanks for the answer Onur. I loved your tutorial and I hope to see more coming !
Awesome!
I appreciate this very much.
Welcome, Luke. Enjoy it 😉 Happy Testing! 🙂
Excellent effort,very helpful thanks for sharing.
Thank you so much Katt. I am so happy to hear this lovely comment.
I’ve been looking something like this. Thank you for your hard work.
Thanks Murat.
Hi Onur
It is really a very nice explanation of XPath with different real time examples.
Thanks for all your efforts for preparing and sharing the concepts with examples.:)
Best Regards,
Sudhakara
Hi Sudhakara,
Thank you so much for your kind feedback.
Best Regards.
Onur
Thanks for the clear examples, I have been an automation engineer for 1 year+ and as I have a lot of project examples I always reverse engineer the xpaths.
Now I started a new project from scratch and found this, its a good damn time to learn how to create an xpaths for everything.
I’m doing xpath angular apps with selenium and with this I’m able to create them.
Thanks, keep the good work.
Welcome Jose, thank you so much for your positive feedback.
thankyou so much its very helpfull
Thank you so much, Onur. Excellent work.
Welcome.
The best tutorial I’ve ever read. So many contents that I had to bookmark it to get the whole thing processed 😉
Welcome, Felipe. Happy to hear that. 🙂
Hi Onur,
What is url you have used to test this xpath??
I just tried on selenium easy website.