Selenium 4 Relative Locators | Friendly Locators

Selenium 4 Alpha comes with a new feature which is called “Relative Locators” before it is called “Friendly Locators“. We generally write tests by using CSS and XPath locators and also of course selenium find by methods such as find by id, name, link text, etc. We also covered these functionalities in the below articles.

Selenium Xpath: https://www.swtestacademy.com/xpath-selenium/

Selenium CSS: https://www.swtestacademy.com/css-selenium/

Selenium FindBy: https://www.swtestacademy.com/selenium-find-element/

In this article, we will introduce you to a new feature that comes with Selenium 4 Alpha. By using this new feature we will easily locate elements that are close to other ones. You can also find comprehensive information about the relative locators on the Angie Jones’s blog.

We have several methods to find a close-by (relative) element. These are:

  • toLeftOf(): Element located to the left of specified element.
  • toRightOf(): Element located to the right of the specified element.
  • above(): Element located above with respect to the specified element.
  • below(): Element located below with respect to the specified element.
  • near(): Element is at most 50 pixels far away from the specified element. The pixel value can be modified.

The methods which are represented above are overloaded accept a By or a WebElement.

Let’s do a quick example of this new feature. The scenario is, we will find the first article then, we will use toRightOf() and below() functions to print out and highlight right and below articles to the first article. This feature is still in the development phase (Alpha version) and it is not working sometimes as expected but we will be ready how to use this new locator strategy and when it will be stable, our codes will be ready for this. :)

In the below code snippet, you can find the details. I commented above() and toLeftOf() functions because for the first article there are no left and above articles.

public class RelativeLocatorTest {
    private WebDriver driver;
    private WebDriverWait wait;
    private JavascriptExecutor javascriptExecutor;
    final private String URL = "https://www.swtestacademy.com";
    @BeforeTest
    public void setupTest() {
        this.driver = new ChromeDriver();
        this.wait = new WebDriverWait(driver, ofSeconds(10));
        this.javascriptExecutor = (JavascriptExecutor) driver;
        driver.manage().window().maximize();
    }
    @AfterTest
    public void tearDown() {
        this.driver.quit();
    }
    @Test
    public void T01_getURLExample() throws InterruptedException {
        driver.get(URL);
        WebElement firstArticle = driver.findElement(By.xpath("(//article)[1]"));
        System.out.println("First Article Name: " + firstArticle.findElement(By.cssSelector(".entry-title")).getText());
        highlightElement(firstArticle);
        WebElement rightOfFirstArticle = driver.findElement(withTagName("article").toRightOf(By.xpath("(//article)[1]")));
        System.out.println("Right Of First Article Name: " + rightOfFirstArticle.findElement(By.cssSelector(".entry-title")).getText());
        highlightElement(rightOfFirstArticle);
        WebElement belowOfFirstArticle = driver.findElement(withTagName("article").below(firstArticle));
        System.out.println("Below Of First Article Name: " + belowOfFirstArticle.findElement(By.cssSelector(".entry-title")).getText());
        highlightElement(belowOfFirstArticle);
//     WebElement leftOfFirstArticle = driver.findElement(withTagName("article").toLeftOf(firstArticle));
//     System.out.println(leftOfFirstArticle.findElement(By.cssSelector(".entry-title")).getText());
//     highlightElement(leftOfFirstArticle);
//
//     WebElement aboveOfFirstArticle = driver.findElement(withTagName("article").above(firstArticle));
//     System.out.println("Above Of First Article Name: " + aboveOfFirstArticle.findElement(By.cssSelector(".entry-title")).getText());
//     highlightElement(aboveOfFirstArticle);
    }
    private WebElement highlightElement(WebElement element) {
        javascriptExecutor.executeScript("arguments[0].style.border='3px solid red'", element);
        return element;
    }
}

GitHub Project

https://github.com/swtestacademy/selenium4relativelocators

Thanks.
Onur

3 thoughts on “Selenium 4 Relative Locators | Friendly Locators”

    • To use relative locators with PageFactory, you can annotate your WebElement fields in the Page Object with the @FindBy annotation and provide the relative locator expression as the value of the using parameter.

      public class LoginPage {
      @FindBy(id = “username”)
      private WebElement usernameField;

      @FindBy(using = “following-sibling::input”, relativeTo = “usernameField”)
      private WebElement passwordField;

      public LoginPage() {
      FieldDecorator decorator = new DefaultElementLocatorFactory(driver)
      .createDecorator(this);
      PageFactory.initElements(decorator, this);
      }

      // rest of the page object methods
      }

      In this example, the usernameField WebElement is located using the traditional id locator. The passwordField WebElement is located using a relative locator expression that specifies that the element should be located as a sibling that follows the usernameField element.

      Note that you need to use the RelativeLocator class to create the relative locator expression and provide the name of the target WebElement as the value of the relativeTo parameter. Also, ensure you initialize your Page Object using the PageFactory.initElements() method with a FieldDecorator that supports relative locators, such as the DefaultElementLocatorFactory.

      Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.