Locator Strategies in Selenium WebDriver

Introduction

Now a days Selenium is vastly used as web automation tool across industry. It has its own advantages whether it might be an open source tool or freedom of scripting language. Selenium WebDriver mimics the actual user operations, so it gives the actual user experience while execution.
Selenium have wide range of locators which helps to locate elements on a web page.
Today we will talk about them.

Selenium Locators

Selenium gives user options to locate elements in 9 different ways.
  • Id
  • Name
  • Linktext
  • Partial Linktext
  • Tag Name
  • Class Name
  • CSS (Cascaded Spread Sheets)
  • XPath (XML path)
  • DOM (Data object modeling) (Not supported by WebDriver)
The sequence of the operator shows how much your script is going to be efficient while execution. To elaborate this lets take one example.
We will try to locate field User ID by Id and XPath.
5
Locator by id : Id= txtUserName Locator by xpath : XPath= //input[@id=’txtUserName’]
(xpath might have different combination we will see them in xpath section.)
If we execute script using both locators, to locate the field using Id will take less time compared to Xpath. In this way we will able to increase the efficiency of script by reducing execution time.
Now we will see all locators in detail.

Selenium Locators: Locate element by Id

The most preferred, the easiest and efficient way to locate an element on a web page is By ID. Id will the attribute on the page which will be unique like you bank account number or employee id. Ids are the safest and fastest locator option and should always be the first choice even when there are multiple choices.
 Example 1:  <input id="txtUserName" type="text">
 Example 2:  <input id="txtUserName" name="userName" type="text">
In first example its straight forward we only have Id, but in second we have Id as well as Name as an attribute. We can write the script as
 WebElement Ele = driver.findElement(By.id("txtUserName "));
But in many cases we found that we have common Id or dynamic Ids (like in case of google, Gmail or the application using GWT). In that case we need to use different locators.

Selenium Locators: Locate element by Name

This is a fall back option when Id for element is not present. But mostly the names are used again and again, so make sure that the name is unique on the page before using it.
Example:
<input id="txtUserName" name="userName" type="text">
WebElement ele= driver.findElement(By.name("userName "));

Selenium Locators: Locate element by LinkText

Finding an element with link text is very simple. This locator is used in case you want to locate any hyperlink only. But make sure, there is only one unique link on the web page. If there are multiple links with the same link, in such cases Selenium will perform action on the first matching element with link on page.
Example:
2
In above image we have three hyperlinks. If we want to locate the Forgot Password? Link. The locator will be
<a href="#">Forgot Password? </a>
WebElement hyperlink = driver.findElement(By.linkText("Forgot Password?"));
We have 2 links with text Forgot Email. If we try to locate 2nd link with locator
LinkText=*Forgot Email. Selenium will locate 1st link.
3
In this case if we want to locate the 2nd link, we will need to use exact keyword with colon (exact:). The locator in that case will be
linkText= exact:*Forgot Email
<a style="background-color: transparent;" href="#">*Forgot Email</a>
WebElement hyperlink = driver.findElement(By.linkText("exact:*Forgot Email"));
4

Selenium Locators: Locate element by Partial LinkText

Partial LinkText works same as LinkText, only difference is you can use a part of the text from link.
Example:
<a href="#">Forgot Password? </a>
WebElement hyperlink = driver.findElement(By. PartialLinkText ("Password"));

Selenium Locators: Locate element by Tag Name

Tag Name we can use for the elements like drop downs, check boxed, radio buttons. Following html is for drop down with 3 values. To select that drop down we will use tagName locator.
Example:
<select name="selCity" id="selCity">
<option value="none">--Select--</option>
<option value="PUNE">Pune</option>
<option value="ADI">Ahmedabad</option>
</select>
WebDriver command:
Select select = new Select(driver.findElement(By.tagName("select")));
select.selectByVisibleText("Pune");
or
select.selectByValue("PUNE");

Selenium Locators: Locate element by Class Name

This locator we can use as a fall back option for either name or Id. But the same condition applied here Class name should be unique or selenium will locate the first element present on the page with the class name we have used to locate element.
Example:
<input id="txtName" class="textboxcss" tabindex="1" type="text">
WebElement classtest =driver.findElement(By.className(“textboxcss”));

Selenium Locators: Locate element by CSS selector using html tag attributes

This a fall back when all options fail, you can use parent child relation in tags, in case you need to use complex strategy to locate elements. CSS selectors are string representation of HTML tags, attributes, Id, Class. It’s somewhat complex strategy compared to the previous we seen. But we can locate the elements which don’t have even Id or name or class using CSS selectors.
We can use different combinations of attributes to locate an element using CSS selector.
  • Tag and ID
  • Tag and class
  • Tag and attribute
  • Tag, Id and attribute
  • Tag, class, and attribute
  • nth-child()
  • Inner text (Not supported by WebDriver)
These are commonly used combinations, for more combinations you can refer this
URL: http://www.w3schools.com/cssref/css_selectors.asp
But you need to check first that the combination you are going to use is supported by Selenium WebDriver.

Tag and ID

In this case you need to follow this syntax css=tag#id. For Id we need to use sign before id value.
Example:
<input id="txtName" class="textboxcss" tabindex="1" type="text">
css=input#txtName
WebElement cssele = driver.findElements(By.cssSelector("input#txtName"));
Here input is tag name and Id is txtName with # sign.

Tag and Class

In this case you need to follow this syntax css=tag.classname. For class we need to use dotbefore class value. If there is space between classname like classname you need to use dot in between space.
Example 1:
<input id="txtName" class="textboxcss" tabindex="1" type="text">
css=input.textboxcss
WebElement cssele = driver.findElements(By.cssSelector("input.textboxcss"));
Example 2:
<input id="txtName" class="textboxcss top" tabindex="1" type="text">
css=input.textboxcss.top
WebElement cssele = driver.findElements(By.cssSelector("input.textboxcss.top"));
Here input is tag name followed by dot and class name textboxcss. In example 2 class name is
textboxcss<space>top in that case we put dot in between textboxcss and top.

Tag and Attribute

In this case when we don’t have both Id or class name we go for html attributes given in tags.
Syntax for this combination is css=tag[attribute=’value’]. We need to use square brackets to specify the attribute and its value. Put the value between single quotes when you are writing script in Java.
Example:
<input value="Reading" type="checkbox">
 css=input[type=’checkbox’]
or
 css=input[value=’Reading’]
Here in first case type is attribute and checkbox is its value, in other case value is an attribute and its value is Reading.

Tag, ID and Attribute

In this case when we have common id but other attributes are different, we go with this combination. Syntax for this combination is css=tag#id[attribute=’value’].
Example:
<input id="txtName" class="textboxcss" tabindex="1" name="taComment" type="text">
<input id="txtName" class="textboxcss" tabindex="1" name="tbComment" type="text">
css=input#txtName[name=’taComment’]
WebElement cssele = driver.findElements(By.cssSelector("input#txtName[name=’taComment’]"));
Here for both textboxes id is same ever class name is also same, only name is different for both. So if we want to locate first text box we will go with locator given in above example. For second text box we need to change value of name attribute in same combination.

Tag, Class and Attribute

In this case when we have id but we have class name which is common around other elements but other attributes are different, we go with this combination. Syntax for this combination is css=tag.classname[attribute=’value’].
Example:
<input class="textboxcss" tabindex="1" name="taComment" type="text">
<input class="textboxcss" tabindex="1" name="tbComment" type="text">
css=input.textboxcss [name=’taComment’]
WebElement cssele = driver.findElements(By.cssSelector("input.textboxcss [name=’taComment’]"));

nth-chilld()

In this case we have same Id or class name and other attributes for different elements, we can go with nth-child().
Syntax for this combination is css=tag:nth-child(n). Here in syntax we can use any combination discussed above. With that we need to use: nth-child(n). n represent child number.
Example:
<ul>
<li>C</li>
<li>C++</li>
<li>C#</li>
<li>Java</li>
<li>Python</li>
<li>Ruby</li>
</ul>
 css= li:nth-child(n)
WebElement cssele = driver.findElements(By.cssSelector("li:nth-child(n)"));
Here if we can see the ul li parent child structure. We have only tag names which are common to everyone. Here if we want to locate sat Java we will put n=4 in above command.
6

Inner text

This is right now not supported by WebDriver in case of CSS, but most probably will support in upcoming Selenium 3 or 4.
Syntax: css= tag:contains(‘inner text’), Here in syntax we can use any combination discussed above. With that we need to use (:) contains(inner text).
Example:
<span>Upload you pic :</span>
  css= span:contains(‘Upload you pic ‘)
WebElement cssele = driver.findElements(By.cssSelector("span:contains(‘Upload you pic‘)"));

Absolute and Relative Path

The Examples we have seen till now are related to only single tag and its attribute. But when we require to build path using parent child relation we need to give its either absolute or relative path.
Example:
<div>
<ul>
<li>C</li>
<li>C++</li>
<li>Python</li>
</ul>
</div>
Consider here we want to locate Python using parent child relation. In that case relative path will be
Relative path: css=div<space>ul<space>li:nth-child(3) or css=div<space>li:nth-child(3). In second combination we have removed ul. Space denotes it’s a Relative path. Here WebDriver will search 3rd li inside given div and ul.
And if we want Absolute path for same, it will be
Absolute path: css= div>ul >li:nth-child(3) or css=ul> li:nth-child(3). Here angular bracket denotes Absolute path. It’s an exact path for given element.
To know the difference between both let’s consider the example.
Someone asked you where is your office? Most common answer is Hinjewadi. But if a courier boy asked you the address you will tell full and exact address of your office. 1st one is relative path to your office but 2nd is absolute one.