Wednesday 16 August 2017

Selenium Webdriver Locating Strategies

There are various strategies to locate elements in a page. You can use the most appropriate one for your case. Selenium provides the following methods to locate elements in a page:
  • Id
  • Name
  • Xpath
  • Link Text
  • Partial Link Text
  • Tag Name
  • Class Name
  • Css selector
We will use below HTML page to learn each locating strategy.

<html>
 <body>
   <form id="loginForm" class="login-form">
    <input id="uname" name="username" type="text" />
    <input name="password" type="password" />
    <input name="continue" type="submit" value="Login" />
  </form>
  <a href="forgot-password.html">Forgot Password</a>
 </body>
<html>

Before getting to know how to locate an element with Webdriver, there is one thing you should know is WebElement and it's use.

WebElement:

It is an interface provided by Webdriver represents an HTML element. When we find an element using webdriver, that element should be assigned to a WebElement object.

Like,
WebElement element = driver.findElement(By.Id("someId"));

Generally, all interesting operations to do with interacting with a page will be performed through this interface. Like,
element.click();
element.sendKeys("some text"); //etc

All method calls will do a freshness check to ensure that the element reference is still valid.
This essentially determines whether or not the element is still attached to the DOM. If this test fails, then an StaleElementReferenceException is thrown, and all future calls to this instance will fail.


Locating by Id:

This is first preferred way of locating elements on the page. Use this when you know id attribute of an element. With this strategy, the first element with the id attribute value matching the location will be returned. If no element has a matching id attribute, a NoSuchElementException will be raised.

Use this approach for only static Ids, not fit for dynamic Ids where they are changing every time you load the page.

From above example HTML, if you want to locate the login form with Id, it can be located like this:

WebElement loginForm = driver.findElement(By.Id("loginForm"));


Locating by Name:

Use this when you know name attribute of an element. With this strategy, the first element with the name attribute value matching the location will be returned. If no element has a matching name attribute, a NoSuchElementException will be raised.

The username & password elements from above HTML page can be located like this:

WebElement username = driver.findElement(By.name("username"));
WebElement password = driver.findElement(By.name("password"));


Locating by XPath:

XPath is the language used for locating nodes in an XML document. As HTML can be an implementation of XML (XHTML), Selenium users can leverage this powerful language to target elements in their web applications. XPath extends beyond (as well as supporting) the simple methods of locating by id or name attributes, and opens up all sorts of new possibilities such as locating the third checkbox on the page.

One of the main reasons for using XPath is when you don’t have a suitable id or name attribute for the element you wish to locate. You can use XPath to either locate the element in absolute terms (not advised), or relative to an element that does have an id or name attribute. XPath locators can also be used to specify elements via attributes other than id and name.

Absolute XPaths contain the location of all elements from the root (html) and as a result are likely to fail with only the slightest adjustment to the application. By finding a nearby element with an id or name attribute (ideally a parent element) you can locate your target element based on the relationship. This is much less likely to change and can make your tests more robust.

The form elements can be located like this:

To locate login form with xpath instead Id,

WebElement loginForm = driver.findElement(By.xpath("//form[@id='loginForm']"));

The username element can be located like this:

First form element with an input child element with name attribute and it's value username,

WebElement userName = driver.findElement(By.xpath("//form[input/@name='username']"));

First input child element of the form element with id attribute and it's value loginForm,

WebElement userName = driver.findElement(By.xpath("//form[@id='loginForm']/input[1]"));

First input element with attribute named ‘name’ and the value username,

WebElement userName = driver.findElement(By.xpath("//input[@name='username']"));


Locating Hyperlinks by Link Text:

Use this when you know link text used within an anchor tag. With this strategy, the first element with the link text value matching the location will be returned. If no element has a matching link text attribute, a NoSuchElementException will be raised.

From above HTML page, if you want to click Forgot Password link,

The forgot-password.html link can be located like this:

WebElement userName = driver.findElement(By.xpath("//input[@name='username']"));

with partial link text, means it finds the link whichever the link text contains the given partial link text.

WebElement forgotPassLink = driver.findElement(By.partialLinkText("Forgot"));


Locating Elements by Tag Name:

Use this when you want to locate an element by tag name. With this strategy, the first element with the given tag name will be returned. If no element has a matching tag name, a NoSuchElementException will be raised.

From above HTML page, if you want to locate anchor element which is forgot password link with it's tag name 'a'.

WebElement forgotPassLink = driver.findElement(By.tagName("a"));


Locating Elements by Class Name:

Use this when you want to locate an element by class attribute name. With this strategy, the first element with the matching class attribute name will be returned. If no element has a matching class attribute name, a NoSuchElementException will be raised.

From above HTML page, if you want to locate form element with it's class name,

WebElement form = driver.findElement(By.className("login-form"));


Locating Elements by CSS Selectors:

Use this when you want to locate an element by CSS selector syntax. This is recommended after Id locator. Finding elements with CSS locators is faster than any other strategies. With this strategy, the first element with the matching CSS selector will be returned. If no element has a matching CSS selector, a NoSuchElementException will be raised.

consider the HTML page source above:

The form element can be located like this:

with class name as cssSelector,

WebElement form = driver.findElement(By.cssSelector(".login-form"));

or with Id as  cssSelector,


WebElement form = driver.findElement(By.cssSelector("#loginForm"));