Wednesday, 28 September 2016

How to create your own XPath

I am writing this blog to share my personal experience with Xpath. Most of the guys in automation testing fear of writing Xpath, therefore they rely mostly on Firepath and Firebug. But most of the times those xpath are too long and impact the performance of the code.

So in this blog I will try to simplify the way of writing your own xpath. I hope after reading the arcticle writing Xpath will be a fun.

What is an XPath ?
XPath is used to navigate through elements and attributes in an XML document. That's it !

Types of Xpath:

Location path specifies the location of node in XML document. This path can be absolute or relative. 


ABSOLUTE XPATH


If location path starts with root node or with '/'(single slash) then it is an absolute path. Following are few of the example locating the elements using absolute path.

RELATIVE XPATH

If location path starts with the node that we've selected then it is a relative path. It starts with //(double slash).


Let's start writing xpath now.


Here we are taking example of www.wikipedia.org, press F12 to open the console. Here we are using chrome so that we do not take help from firebug/firepath.








Right click on the searchbox, select inspect. Below image should appear:






Press the Esc key to open the console where we will write the xpath.


General Syntax of Xpath

//tagname[@attribute='value of the attribute']


Here in chrome we will write xpath as $x("//tagname[@attribute='value of the attribute']"). However in our scripts we will use the general format only. So don't get confused of $x.

Step1


$x("//input[@id='searchInput']")


Here we can write the xpath based on id or name as well.
As we have written the correct format in first line it has given us the result, however if the xpath is incorrect it will show nothing as shown in the second xpath.


Step 2


Let's say 'id' is common across various elements. Or let's say name is common. Then we can write the xpath in the following format using two attributes:




$x("//input[@id='searchInput'][@name='search']") 

Step 3

There are situations when we see element id/name are not entirely constant. A part would be constant but the remaining part will remain changing. In that case we can identify the element using starts-with expression.


Let's take above example. Assume id=searchInput is not constant, only the starting part(search) is constant.


$x("//input[starts-with(@id, 'search')]")


Here we have generated the xpath based on starting characters of the attribute. Here we are assuming the later characters are changing with every application refresh.

Step 4

Let's move forward. Let's say if we want to get xpath using attribute whose value is a String and we want to fetch xpath from x character to y character. From example it will be more clear. Here we will use function substring.


Here we will try to find "earch" from id attribute.


$x("//input[substring(@id, 2,5)= 'earch']")


Step 5

At times there can be unwanted spaces in a String. If the spaces are too much and we cannot count the number of spaces, we need to trim the spaces. Let's see how it is done. Here we will take the example of google.com. It will be more clear from the example below:

We have input 'selenium' in google searchbox, pressed enter and using text() method we tried finding xpath of title title of the page.

Note: text() method can be used to get the inner text of the element.






Now let's introduce a lot of spaces before/after typing selenium and press enter. As, we will not be sure about the spaces, this is how our xpath will be using normalize-space.





$x("//title[normalize-space(text())='selenium - Google Search']")


Step 6

Xpath can also be identified using contains method. Here we can take example of wikipedia.org where id='searchInput'. Let's try to find out the element which contains "chInp"(taken from searchInput)


$x("//input[contains(@id,'chInp')]")


Step 7

We might come across a situation where id/name/class keeps on changing and we are unable to write xpath for that particular element using the above methods. We can use xpath axis at that time.

Xpath has a feature of navigating forward and backward. We will use this feature to locate those elements.


Let's take help of an example to understand this functionality:



Assume we have constant attributes for div tag and attributes for button tag keeps on changing.


In that case we will use following-sibling
$x("//div[contains(@class,'h-inp')]/following-sibling::button")

Secondly, assume if there are five button tags following the div tag and we want to jump on to the second one.
$x("//div[contains(@class,'h-inp')]/following-sibling::button[2]")

This is really interesting and easy ! Isn't it ?



Let's say if we want to find the parent of the div sibling. This is how it is done.


$x("//div[contains(@class,'h-inp')]/parent::fieldset") or $x("//div[contains(@class,'h-inp')]/..")

If we want to navigate to parent of parent then $x("//div[contains(@class,'h-inp')]/../..") can be used.


Navigating back using the preceding-sibling


Now let's assume vice-versa. Now attributes of button tag are constant and attributes for div is not constant.




$x("//button[contains(@class,'pure')]/preceding-sibling::div")

This is all about xpath. Now you can easily write and find xpath of any element. I hope this article will be useful for you. If there are any queries kindly write in the comment section below.


Thank You