Selenium 4 offers a new way of locating elements by using natural language terms such as “above”, “below”, “left of”, “right of”, and “near”. This article describes how to use the new Relative Locators.
Selenium 4 offers a new way of locating elements by using natural language terms such as “above”, “below”, “left of”, “right of”, and “near”. This article describes how to use the new Relative Locators.
This functionality brings a new way to locate elements to help you find the ones that are nearby other elements. The available locators are:
above
below
toLeftOf
toRightOf
near
The concept behind this method is to allow you to find elements based on how one would describe them on a page. It is more natural to say: “find the element that is below the image”, rather than “find the INPUT inside the DIV with the ‘id’ of ‘main’”. In general, you could think about them as a way to locate elements based on the visual placement on the page.
For additional examples, including chaining relative locators in these languages, look at our Selenium 4 Documentation.
We will use the following login form to understand how Relative Locators work:
We would like to find the email address field, which is above the password field. To do that, we find the password field through its id, and then we use the above relative locator.
Java
import static org.openqa.selenium.support.locators.RelativeLocator.with;
WebElement password = driver.findElement(By.id("password"));
WebElement email = driver.findElement(with(By.tagName("input")).above(passwordField));
Python
from selenium.webdriver.common.by import By
from selenium.webdriver.support.relative_locator import locate_with
passwordField = driver.find_element(By.ID, "password")
emailAddressField = driver.find_element(locate_with(By.TAG_NAME, "input").above(passwordField))
C#
using static OpenQA.Selenium.RelativeBy;
IWebElement passwordField = driver.FindElement(By.Id("password"));
IWebElement emailAddressField = driver.FindElement(RelativeBy(By.TagName("input")).Above(passwordField));
Ruby
password_field= driver.find_element(:id, "password")
email_address_field = driver.find_element(relative: {tag_name: "input", above:password_field})
JavaScript
let passwordField = driver.findElement(By.id('password'));
let emailAddressField = await driver.findElement(locateWith(By.tagName('input')).above(passwordField));
Going the other way around, let's find the password field, which is below the email address field.
Java
import static org.openqa.selenium.support.locators.RelativeLocator.with;
WebElement emailAddressField = driver.findElement(By.id("email"));
WebElement passwordField = driver.findElement(with(By.tagName("input"))
.below(emailAddressField));
Python
from selenium.webdriver.common.by import By
from selenium.webdriver.support.relative_locator import locate_with
emailAddressField = driver.find_element(By.ID, "email")
passwordField = driver.find_element(locate_with(By.TAG_NAME, "input").below(emailAddressField))
C#
using static OpenQA.Selenium.RelativeBy;
IWebElement emailAddressField = driver.FindElement(By.Id("email"));
IWebElement passwordField =
driver.FindElement(RelativeBy(By.TagName("input")).Below(emailAddressField));
Ruby
email_address_field = driver.find_element(:id, "email")
password_field = driver.find_element(relative: {tag_name: "input", below: email_address_field})
JavaScript
let emailAddressField = driver.findElement(By.id('email'));
let passwordField = await driver.findElement(locateWith(By.tagName('input')).below(emailAddressField));
Let’s consider the case where we want to find the element on the left side of the “Submit” button.
Java
import static org.openqa.selenium.support.locators.RelativeLocator.with;
WebElement submitButton = driver.findElement(By.id("submit"));
WebElement cancelButton = driver.findElement(with(By.tagName("button"))
.toLeftOf(submitButton));
Python
from selenium.webdriver.common.by import By
from selenium.webdriver.support.relative_locator import locate_with
submitButton = driver.find_element(By.ID, "submit")
cancelButton = driver.find_element(locate_with(By.TAG_NAME, "button").
to_left_of(submitButton))
C#
using static OpenQA.Selenium.RelativeBy;
IWebElement emailAddressField = driver.FindElement(By.Id("email"));
IWebElement passwordField =
driver.FindElement(RelativeBy(By.TagName("input")).Below(emailAddressField));
Ruby
submit_button= driver.find_element(:id, "submit")
cancel_button = driver.find_element(relative: {tag_name: 'button', left:submit_button})
JavaScript
let submitButton = driver.findElement(By.id('submit'));
let cancelButton = await driver.findElement(locateWith(By.tagName('button')).toLeftOf(submitButton));
Now we'll consider the opposite case, where we want to find the element on the right side of the “Cancel” button.
Java
import static org.openqa.selenium.support.locators.RelativeLocator.with;
WebElement cancelButton = driver.findElement(By.id("cancel"));
WebElement submitButton = driver.findElement(with(By.tagName("button")).toRightOf(cancelButton));
Python
from selenium.webdriver.common.by import By
from selenium.webdriver.support.relative_locator import locate_with
cancelButton = driver.find_element(By.ID, "cancel")
submitButton = driver.find_element(locate_with(By.TAG_NAME, "button").
to_right_of(cancelButton))
C#
using static OpenQA.Selenium.RelativeBy;
IWebElement cancelButton = driver.FindElement(By.Id("cancel"));
IWebElement submitButton = driver.FindElement(RelativeBy(By.TagName("button")).RightOf(cancelButton));
Ruby
cancel_button = driver.find_element(:id, "cancel")
submit_button = driver.find_element(relative: {tag_name: 'button', right:cancel_button})
JavaScript
let cancelButton = driver.findElement(By.id('cancel'));
let submitButton = await driver.findElement(locateWith(By.tagName('button')).toRightOf(cancelButton));
near
is helpful when we need to find an element that is at most 50px away from the specified element. In this case, we would like to find the email address field by first finding the label of that field.
Java
import static org.openqa.selenium.support.locators.RelativeLocator.with;
WebElement emailAddressLabel = driver.findElement(By.id("lbl-email"));
WebElement emailAddressField = driver.findElement(with(By.tagName("input")).near(emailAddressLabel));
Python
from selenium.webdriver.common.by import By
from selenium.webdriver.support.relative_locator import locate_with
emailAddressLabel = driver.find_element(By.ID, "lbl-email")
emailAddressField = driver.find_element(locate_with(By.TAG_NAME, "input").
near(emailAddressLabel))
C#
using static OpenQA.Selenium.RelativeBy;
IWebElement emailAddressLabel = driver.FindElement(By.Id("lbl-email"));
IWebElement emailAddressField = driver.FindElement(RelativeBy(By.TagName("input")).Near(emailAddressLabel));
Ruby
email_address_label = driver.find_element(:id, "lbl-email")
email_address_field = driver.find_element(relative: {tag_name: 'input', near: email_address_label})
JavaScript
let emailAddressLabel = driver.findElement(By.id("lbl-email"));
let emailAddressField = await driver.findElement(with(By.tagName("input")).near(emailAddressLabel));
An updated set of methods, utilities and examples can be found at the official documentation.
Check out our comprehensive guide to Selenium 4 for more information.