Nitun Pachauri

How to write awesome XPaths for Test Automation in Selenium

As a beginner in Test Automation, you have just started to write selenium scripts and test cases are getting automated like anything. You feel happy because of this sublime technical tool that you have just learned.

But there may be few roadblocks on your stupendous ride-
1. The elements are not selected or detected as you would expect them to when the script executes.
2. Your relative XPath solution that ‘Firepath’ Add-on provides is not so efficient.
3. A small change in the HTML page massacres all the locators.
4. Your most basic necessity- the ‘id’ attribute- is not provided for all elements!

You must have started to wonder what to do here and how to avoid all this hassle? So without further ado, let’s just dive into the good stuff.

selenium

Nothing works better than a live example. I’ve taken an element from the Flipkart website. Below is the HTML code of the target element along with a picture to help you get the picture (pun intended).

HTML Code

<input class=”LM6RPg” type=”text” data-reactid=”Flipkart-search-sddxcf3446″ placeholder=”Search for Products, Brands and More” autocomplete=”off” name=”q” title=”Search for Products, Brands and More” value=””/>

Suppose that you have been using XPaths in somewhat like this fashion:
‘.//*[@id=’container’]/div/header/div[1]/div[2]/div/div/div[2]/form/div/div[1]/div/input’

Let’s change that right away.

Firstly, you can use the exact type of element in the XPath. In this case, it is ‘input’. So we will use that instead of using ‘*’, which represents all types of elements.

New XPath so far – //input

You must know this by now that ‘//’ is responsible for traversing through the DOM to look for your element anywhere within the document. This is straightforward so we will keep it that way.

Secondly, we can use the ‘class’ attribute since we don’t have ‘id’, as usual.
New XPath so far – //input[@class=’LM6RPg’]

So it works as [attribute = value] pair. Nothing too complex, right? We can use any other attribute in place of ‘class’ as long as we are sure that it will bring uniqueness to the XPath and hence shorten the time to catch the element at runtime. That’s why we can also write it as:

//input[@data-reactid=’Flipkart-search-sddxcf3446′],
//input[@placeholder=’Search for Products, Brands and More’],
//input[@name=’q’], etc.

Lastly, if we have different attributes then they can be clubbed to get a faster and reliable match.

New XPath so far

//input[@data-reactid=’Flipkart-search-sddxcf3446′ AND @placeholder=’Search for Products, Brands and More’ AND @name=’q’]

You can use ‘OR’ instead of ‘AND’ if some of the attributes don’t stay associated all the time and might not appear for a particular element.

Now your job is done here and all you need to do is use this XPath instead of that crappy, old one in you test script and it will work like a charm.

So the next question that arises is- what if you don’t have the exact ‘value’ of an ‘attribute’? Maybe the ‘value’ for some attributes is getting generated at runtime, where part of the value is a constant String that doesn’t change, like ,’Flipkart-search-’ in our example code. And the rest of the ‘value’ is getting a random String, which gets generated at the runtime. Let’s assume that it is the ‘data-reactid’ attribute in our example.

In that case, the constant part of the ‘value’ will help us write the XPath like:
XPath – //input[contains(@data-reactid,’Flipkart-search-‘)]

Also, what if there is not much to go within the HTML document? Consider the following code for your target element:

HTML Code

<span value=” class=”> Electronics </span>

We can call the text of the element to the rescue here:
XPath – //span[text()=’Electronics’]

It’s always better to choose ‘id’ as your object locator but XPaths like these will definitely do the trick if there is no ‘id’ at all. I guess all of this new info might come in handy to some of you soon, till then Happy Automating!

 

Related Articles

#Tech

NHibernate, Linq and Lazy Collections

For the past few months we have been busy building a services framework for one of our clients so that they can build all of their enterprise web services without ever having to worry about the cross cutting concerns and... Read more
#Tech

Page Redirects using Spring.NET

Who is responsible for page redirects in ASPNET MVP – The View or the Presenter None of the above, it is you :) On a serious note, it is the View as one shouldn’t pollute the Presenter with the page navigation... Read more