Selenium 4 is out with a lot of cool and interesting things. The motivation behind this new makeover of features and functionalities was to upgrade the quality and efficiency of the automation testing process. This new release came out with enhanced SeleniumGrid architecture, W3C standardized protocol, updated IDE, relative locators, and few others. Our main focus here will be on Relative Locators originally known as Friendly Locators. Before we dive deeper into Relative Locators, let’s refresh with some basics.
So, what is Selenium?
What are Locators in Selenium?
Every web page can consist of multiple web elements, also known as GUI (Graphical User Interface) elements. Depending on the complexity of the web page, typical elements can be seen in the form of radio buttons, checkboxes, text boxes, drop-downs, inputs, images, and etc. So, to perform some action on web elements we need to identify these elements first, that is where locators are coming into the game of automation.
Locators are a way of identifying web elements on a web page. Where prerequisite for creating any successful automation script lies in uniquely identification of web elements. Selenium supports various kinds of locators which we all are familiar with, such as ID, CSS Selector, XPath, Link, Text etc. You can learn more about Selenium Locators here.
What are Relative Locators in Selenium 4?
Selenium 4 brings a new handy way for locating web elements. The concept behind this way of locating web elements is to use natural language in describing position of elements on a web page. In other words, they allow us to locate the web element based on their position with respect to the other web elements. Using this new selenium feature we can easily locate elements that are close to other ones.
There are several methods which can be used to find relative elements, they can be combined with any selector not just tag-name.
|above()||web element to be searched appears above the specified element|
|below()||web element to be searched appears below the specified element|
|toLeftOf()||web element to be searched appears to the left of the specified element|
|toRightOf()||web element to be searched appears to the right of the specified element|
|near()||web element to be searched is at most 50 pixels away from the specified element|
How does it all work?
How can we use it?
Let’s see how it all works with the help of an example page. For the purpose of demonstration, we will focus on the bottom section of the page, on input fields, buttons and their labels.
Imagine a scenario where we want to locate an element on the right side of the input name field. This can be done by using toRightOf() relative locator. As we can see the “Contact us” is placed on the right side of the ‘Your name’ input field and that is how we are going to locate it.
First we will find inputName field and then use findElement() method which accepts withTagName() method to which we will pass searched tag value and from there we can use relative locator to find our element and grab there attribute value and verify it.
let inputName = driver.findElement(By.xpath(inputNameXpathLocator)) let contactUsButton = await driver.findElement(withTagName("input") .toRightOf(inputName)); let contactUsButtonValue = await contactUsButton.getAttribute("value"); assert.equal(contactUsButtonValue, "Contact us");
Relative Locators can be used not only as standalone methods. We can combine relative locators depending on the position of the searched element. From time to time we may find ourselves in a position where using only one relative locator is not sufficient and where mixing them is quite beneficial.
Consider the scenario where we want to grab the label name which is above the input Name field but on the right side of the Email field. This can be done by combining the above() method to tell that our element is above the inputName field and adding toRightOf() method to tell that our element is positioned on the right side of the inputMail field.
let inputMail = driver.findElement(By.xpath(inputMailXpathLocator)) let inputName = driver.findElement(By.xpath(inputNameXpathLocator)) let inputLabel = await driver.findElement(withTagName("label") .above(inputName) .toRightOf(inputMail)); let inputLabelText = await inputLabel.getText(); assert.equal(inputLabelText, "Your name:")
To locate this element we could not just use the above() method whose main purpose is to locate elements which are positioned above the specified element. The reason is if we take a close look at driver.findElement() which will locate the searched element starting from the top of the web page. Considering that top element, that would be found first would be the element with <label> tag whose value is “Your message:” and not “Your name: “.
Similarly, to the samples of the code the rest of the methods can be used in a same way.
Be aware of, what?
Using relative Locators requires extra caution when it comes to size of the window on which tests are running. Resizing the window elements would not be in the same position, they may overlap which can cause our elements to not be found. Taking into account the previous example and resizing the window it would look something like this.
Looking at the properties of these elements we can see that all elements have a common x axis and they actually overlap. It shows us that the position of the elements has changed. This is the case where our visual view matches to properties of elements which does not have to be the case all the time. All of this is just one thing that needs to be considered while using relative locators.
Relative locators are a very interesting feature which is added in Selenium 4. It is a way of locating web elements based on the visual placement on the web page. They are very beneficial for unstable applications, elements with dynamic values and elements without unique attributes values. They should be used wisely.
For more information about examples of Relative Locators can be seen on this page.