Our Thoughts
Sonam Chaturvedi
10 August, 2021
4 MIN READ

Selenium 4 - Relative Locators

Selenium has always been the most preferred tool suite for automated testing of web applications. Selenium 4 beta comes along with a lot of new features and functionalities. In this blog, we will be exploring Selenium 4’s feature known as Relative Locators (formerly known as Friendly Locators). Relative locators help locate WebElements based on the location relative to other DOM elements.

There are five relative locators:

  • above()
  • below()
  • toLeftOf()
  • toRightOf()
  • near()

All of these methods are overloaded to accept a By or a WebElement.

 

Why Relative Locators?

In Selenium 3, when elements were not uniquely identifiable using any of the locator strategies, we used to loop the web elements based on certain conditions and select that required web element. For such scenarios, we can now use relative locators to identify a web element in relation to other web elements.

 

How to use Relative Locators?

Selenium 4 Alpha

WebDriver::findElement accepts a new method withTagname(). withTagName() is a static method which internally creates a new instance of RelativeBy class and returns the same RelativeLocator.RelativeBy object.

Syntax:

driver.findElements(withTagName('input').above(password));

Selenium 4 Beta.3

With Selenium 4 beta.3, Java bindings support with(By) instead of withTagName() allowing users to pick a locator of their choice like By.id, By.cssSelector, etc.

Selenium 4

Syntax:

driver.findElement(with(By.tagName('input')).above(password));


How do Relative Locators work?

To find the location of the element, Selenium leverages the JavaScript function getBoundingClientRect(). This function returns properties of an element like left, right, top and bottom.

There have been changes made to Relative Locator in Selenium 4 beta 3. Elements are first sorted by proximity and then DOM insertion order, to make the result more accurate and deterministic. Proximity is determined using distance from center points of each element’s bounding client rect.

Let us understand each relative locator with an example of a login form.

Selenium 4

Selenium 4

above()

Searches and returns the WebElement, which is above the specified element.

The ‘Email Address’ input element is above the ‘Password’ input element in the login form. So, we can use it as below:

public void setEmailAddress() {		
	WebElement txtEmail = driver.findElement(with(By.tagName('input'))
                .above(By.id('inputPassword')));
	txtEmail.sendKeys('[email protected]');
}

below()

Searches and returns the WebElement, which is below the specified element.

public void setPassword() {		
	WebElement txtPassword = driver.findElement(with(By.tagName('input'))
                .below(By.id('inputEmail')));
	txtPassword.sendKeys('[email protected]');
}

toLeftOf()

Searches and returns the WebElement, which is to the left of the specified element. The ‘Login’ button is to the left of the ‘Forgot Password’ button, so we can use it as below:

public void clickLogin() {		
	WebElement btnForgotPwd = driver.findElement(with(By.tagName('input'))
                .toLeftOf(By.linkText('Forgot Password?')));
	btnForgotPwd.click();
}

toRightOf()

Searches and returns the WebElement, which is to the right of the specified element.

public void clickForgotPwd() {		
	WebElement btnLogin = driver.findElement(with(By.tagName('a'))
                .toRightOf(By.id('login')));
	btnLogin.click();
}

near()

Searches and returns the WebElement, which is at most 50px near to the specified element.

public void nearElement() {		
	WebElement emailAddrField = driver.findElement(By.id('inputEmail'));
	WebElement emailAddrLabel = driver.findElement(with(By.tagName('label'))
				.near(emailAddrField));
		
	Assert.assertEquals(emailAddrLabel.getText(), 'Email Address');
}


Multiple Relative Locators To Find A WebElement

We could come across a scenario where finding an element using only one relative locator is not sufficient. So, we can use multiple relative locators to find a fixed web element. Consider, we need to locate the 'Remember Me' checkbox in the login form. This checkbox is below the 'Password' field and above the ‘Google ReCaptcha’ field. Here, we can use below() and above() locators as:

public void multiRelativeLocator() {		
	WebElement chkboxRememberMe = driver.findElement(with(By.tagName('input'))
				.below(By.id('inputPassword'))
				.above(By.id('google-recaptcha-domainchecker1')));
	chkboxRememberMe.click();
}

Looking at the below screenshot, we can notice that 'Username', 'Password' and 'Remember Me' web elements have the same position on the x-axis. Therefore, we need to use both below() and above() relative locators to find the 'Remember Me' checkbox.

Selenium 4

Note: Selenium 4 Relative Locator methods do not work with overlapping elements.

The sample codes are available at the Github repository here.

 

Conclusion

Relative Locator is an interesting locator strategy added in Selenium 4, using which testers can access web elements with fewer lines of code. Incorporate relative locators in your Selenium automation testing and share your thoughts with us.

Happy Testing!

Sonam Chaturvedi