Identifying xpath Selectors for Selenium – Basic and Advanced

Xpath is one of the most powerful selectors used for identifying elements for Selenium automation.  But as you start automating web applications extensively, you will find occasionally some trouble in finding unique selectors as multiple elements might have the same attributes. In those cases, you will need to use little complex selectors to traverse to the expected  html element

Through this post, i will show you how to find out simple and advanced selectors using xpath.

Below is a snippet of HTML code from Wikipedia page for ‘TEST’ and i will be using this html code to find all selectors for this post

HTML Selenium Xpath

Basic Rules of Xpath selectors 

  • Xpath always Starts with //
  • After the // follows the html tag names like //div //span //input //table
  • AS //div would give you all the div elements – specific element is selected using attributes which are mentioned in the square brackets [] –
  • Xpath attributes preceded ‘@’ symbol and then followed by attribute value

SAMPLE XPATH SELECTOR  – //TagName[@attributeName=’attributeValue’]

//div[@id='contentSub']
Below are some of the ways of identifying elements using Xpath selectors. I will start with the basic selector and then move to advanced xpath selectors.

  • When you dont want to use tag names, wild card symbol *  works like a charm to identify element with any of the tags

 //*[@id='contentSub'] will find all the elements with attribute id as 'contentSub'

  • Xpath can be also formed using text()

//div[text()='Test']

  • Xpath selectors can contain multiple levels of html tag seperated by a /

//tbody/td/tr[@class='mbox-image'] 

  • Using contains() function, you can find out elements without using the whole attribute value

//div[contains(text(),'te')] or //div[contains(@id='content')] contains partial values

  • Xpath can also be formed using ‘or’ & ‘and’ using multiple attributes

//div[contains(@id,'firstheading') and contains(@class,'firstheading')]

  • Using starts-with function, xpath can be written by having the first substring of an attribute

//div[starts-with(@id,'first')]

  • Xpath selector are case sensitive on the attributes for eg- //div[@id=’CONTENTSUB’] will not work as a selector as the html contains attribute as ‘contentSub’ but there is a function called Translate that you can use to make the selector case insensitive

//div[contains(translate(text(), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ').'CONTENTSUB')]

  • if there are more than one  same Tag element within a parent element, indexes can be used, however, using indexes is not recommended

//tr/td[2]   - this will pick the second td element within the parent tr

  • Xpath to find a parent element is written by using the syntax /..

//div[@class='jump-to-nav']/..  this will point to its parent element //div[@id='bodyContent']

  • Using ‘/’ after the ‘/..’ will select one of the childs of the parent using a given attribute value

//div[@class=’jump-to-nav’]/../div[@lang=’en’]

  • When multiple child nodes of same type are present, you can use the keyword preceding-sibling or following:sibling to find any of the siblings before or after a node

//td[contains(@id,'mbox-text')]/preceding-sibling::button[@id='mbox-image']

  • There is a possibility of having spaces in the text inside the html where the normal text() = ‘text’ will not work. There is a function called normalize-space which will be help you to write a xpath selector that would ignore any spaces before or after the text.

 test

test

//tr[normalize-space(text()) = 'test']

I am pretty sure this is all you would probably need to find any element using xpath. Either one of them or combination of them. But in case you find any issues with any element, please comment. I can help you out.

Advertisements

Selenium Automation : Waiting for a Page load and Ajax response

Waiting for a Page load or an ajax call is one of the important functions that an Automation Framework has to provide. There are multiple ways of waiting for a page load but not all of them are recommended.

Thread.Sleep(time in milliseconds) is probably the easiest and one of the worst ways to wait in a selenium or Non selenium based Automation framework because you are explicitly asking the driver to wait for, lets say 5 seconds, every time a function is called. Each page might have a different Page load time and your solution will have to be implemented in every page separately with a different time duration

Selenium provides you with Explicit and implicit Wait functions as well but again the logic is not dynamic enough to handle every page. Each page might have a different number of Ajax calls. Drivers implicit wait time will lead to the same problem that thread.sleep leads you to. Explicit wait is basically waiting till a condition is met for example an element being visible or element being present. So Explicit wait time will have to be used for each page separately.

The most efficient way to wait for an ajax response or a page load would be one that can be used for any of the Pages without modifying it.

IJavaScriptExecutor is  a powerful tool that selenium provides and it can do wonders, if one is strong in javascript and jQuery. Below is a function ( C#)  that waits for all the ajax calls to complete and  can be called for any of the pages that fires jquery ajax calls. The Timeout is basically optional, to make sure the function automatically finishes in 60 seconds and does not run for ever.

public void WaitForAjaxToComplete(int timeoutInSeconds = 60)
{
var endTime = DateTime.Now.AddSeconds(timeoutInSeconds);
while (DateTime.Now < endTime)
{

var isAjaxComplete =
(bool)((IJavaScriptExecutor)Driver).ExecuteScript(“return jQuery.active == 0”);

if (isAjaxComplete)
{
return;
}

}

}

Additionally, for pages with spinner, we can have an additional flag, that checks for the spinner to complete and finish because browser rendering can take a couple of extra seconds.

 

Hello ‘QA’ World!

Welcome to Explore QA – a guide to Quality Assurance.

Explore QA

I have been meaning to start a technical blog for couple of years now so this is indeed a proud moment for me because  I have finally got one. For years,  “Hello World” has been the first computer program, be it any language so i wanted to start with this “Hello QA world” post as i was little hesitant to break the old tradition.

Here you will find posts related to Quality Assurance i.e Software Testing, Test Automation and various technologies that are closely related to it. My attempt is to create a one stop place to share information on new technologies as i learn them, have healthy discussions on topics related to Software Testing and possibly anything related with Information Technology.