In this practical guide we will not go thru the very beginning or explaining what is Xpath. This is fully practical tutorial to increase your effectiveness and speed in writing Xpath in difficult cases and for dynamically generated locators on your page.
Disassembling the element
Just picking some subject element to have a closer look at the parts it's built from.
I will use https://material.angular.io/ page as i think it's pretty good for the examples of difficult to find elements.
We will need Chrome Developer Tools (or similar in another browser, but i will use this one)
We need to hit an element inspection tool and then click on element we want to inspect (to see this element in HTML page with all it's properties and where it's located in the page)
Now let's have a closer look to element we selected.
Here's the copy of this element in html format
<a _ngcontent-ity-c49="" mat-button="" routerlink="guides" class="mat-focus-indicator docs-navbar-hide-small docs-button mat-button mat-button-base" tabindex="0" aria-disabled="false" href="/guides">
The parts from which element is built from :
Tag name (the very first text value in our element is a tag name - here it's a)
Attribute name (name of the attribute is some text value, it might be separate or in format attribute="some value". For example in this element href)
Attribute value (the value of attribute,in Chrome dev tools comes orange colored, comes after = sign, in "" marks. Here attribute href has the value "/guides")
Attributes might come without values (like _ngcontent in this example)
<text ... - Tag Name
NAME = "VALUE" or NAME - attributes
Just remember simple rule - always start from //
Next after // we need to tell what kind of element to search by writing a Tag Name of element, like that //a or we can set to search all element with //*
Our element is a , so first part of our Xpath is //a
After //a we can make search more accurate, by telling which attributes should our element contain with opening [ ] .
Remember the href attribute? Attribute in xpath should start with @
But we can make it even more accurate, providing a value of attribute
By the way it is almost the same as //*[@href='/guides']
After one element we can look into child element from this one.. or parent
Just remember the syntax :
Parent element of selected element
//a[@href='/guides']//parent::and here everything repeats from beginning - tag name, attribute..
Child element of selected element
For child it looks more compact
//a[@href='/guides']//span[text()='Guides'] - with text() we can search for text value instead of attribute
Order of same elements
You have few similar elements but need to pick exact one of them?
(//a) - for exact order | (//a)[last()] - for the last element | (//a)[last()-2] - expressions
Dynamic ID or CLASSNAME
You have an id with some dynamic part in it which always changes?
Let's say you have an id or class that looks like id="user.name-13"
We can cut a part from this id with contains expression
Like this //*[contains(@id,'user.name')]
Difference between Mobile and Web elements
Text - in Web, text locator is text() in Mobile - @text
For id in Android we use - @resource-id in Web just - @id