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.
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).
<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:
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[@placeholder=’Search for Products, Brands and More’],
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:
<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!