Beginner Chapter 4 · 12 min read

Locators & Finding Elements

Master all Selenium locator strategies — ID, name, className, tagName, CSS selectors, XPath, linkText, and Selenium 4 relative locators.

Finding Elements on the Page

Locators are the most critical skill in Selenium. Every interaction — clicking, typing, reading — starts with finding the right element. Selenium offers 8 built-in locator strategies plus Selenium 4's relative locators.

Locator Strategies (Best to Worst)

  1. By.id — Fastest and most reliable (when IDs exist and are unique)
  2. By.name — Good for form elements
  3. By.cssSelector — Powerful, flexible, and performant
  4. By.xpath — Most flexible, handles complex scenarios, but slower
  5. By.linkText / partialLinkText — For anchor tags only
  6. By.className — Risky if classes change frequently
  7. By.tagName — Rarely unique enough

Selenium 4 Relative Locators

New in Selenium 4 — find elements based on their position relative to other elements: above(), below(), toLeftOf(), toRightOf(), and near(). This is invaluable when elements lack good attributes.

LocatorsTest.java
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.locators.RelativeLocator;
import org.testng.Assert;
import org.testng.annotations.*;
import java.util.List;

public class LocatorsTest {

    WebDriver driver;

    @BeforeMethod
    public void setup() {
        driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(
            java.time.Duration.ofSeconds(10));
        driver.get("https://www.selenium.dev/selenium/web/web-form.html");
    }

    @Test
    public void testById() {
        WebElement element = driver.findElement(By.id("my-text-id"));
        Assert.assertTrue(element.isDisplayed());
    }

    @Test
    public void testByName() {
        WebElement input = driver.findElement(By.name("my-text"));
        input.sendKeys("Hello Selenium!");
        Assert.assertEquals(input.getAttribute("value"), "Hello Selenium!");
    }

    @Test
    public void testByCssSelector() {
        // Attribute selector
        WebElement el = driver.findElement(
            By.cssSelector("input[name='my-text']"));

        // Class selector
        WebElement form = driver.findElement(By.cssSelector(".container"));

        // Combination
        WebElement specific = driver.findElement(
            By.cssSelector("form .row input[type='password']"));

        Assert.assertNotNull(specific);
    }

    @Test
    public void testByXPath() {
        // Absolute path (fragile — avoid)
        // WebElement el = driver.findElement(By.xpath("/html/body/..."));

        // Relative XPath (preferred)
        WebElement input = driver.findElement(
            By.xpath("//input[@name='my-text']"));

        // Text-based
        WebElement label = driver.findElement(
            By.xpath("//label[text()='Text input']"));

        // Contains
        WebElement partial = driver.findElement(
            By.xpath("//input[contains(@name, 'text')]"));

        Assert.assertTrue(input.isDisplayed());
    }

    @Test
    public void testByLinkText() {
        WebElement link = driver.findElement(
            By.linkText("Return to index"));
        Assert.assertTrue(link.isDisplayed());

        WebElement partial = driver.findElement(
            By.partialLinkText("Return"));
        Assert.assertTrue(partial.isDisplayed());
    }

    @Test
    public void testFindMultipleElements() {
        List<WebElement> inputs = driver.findElements(By.tagName("input"));
        System.out.println("Found " + inputs.size() + " input elements");
        Assert.assertTrue(inputs.size() > 0);
    }

    @Test
    public void testRelativeLocators_Selenium4() {
        // Find the password field below the text input
        WebElement textInput = driver.findElement(By.name("my-text"));

        WebElement passwordField = driver.findElement(
            RelativeLocator.with(By.tagName("input"))
                .below(textInput));

        Assert.assertEquals(passwordField.getAttribute("type"), "password");

        // Find element near another element
        WebElement label = driver.findElement(
            RelativeLocator.with(By.tagName("label"))
                .near(textInput));
        Assert.assertNotNull(label);
    }

    @AfterMethod
    public void teardown() { if (driver != null) driver.quit(); }
}
test_locators.py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.relative_locator import locate_with
import pytest

@pytest.fixture
def driver():
    d = webdriver.Chrome()
    d.implicitly_wait(10)
    d.get("https://www.selenium.dev/selenium/web/web-form.html")
    yield d
    d.quit()


def test_by_id(driver):
    element = driver.find_element(By.ID, "my-text-id")
    assert element.is_displayed()


def test_by_name(driver):
    input_el = driver.find_element(By.NAME, "my-text")
    input_el.send_keys("Hello Selenium!")
    assert input_el.get_attribute("value") == "Hello Selenium!"


def test_by_css_selector(driver):
    # Attribute selector
    el = driver.find_element(By.CSS_SELECTOR, "input[name='my-text']")

    # Class selector
    form = driver.find_element(By.CSS_SELECTOR, ".container")

    # Combination
    specific = driver.find_element(
        By.CSS_SELECTOR, "form .row input[type='password']")
    assert specific is not None


def test_by_xpath(driver):
    # Relative XPath
    input_el = driver.find_element(By.XPATH, "//input[@name='my-text']")

    # Text-based
    label = driver.find_element(By.XPATH, "//label[text()='Text input']")

    # Contains
    partial = driver.find_element(
        By.XPATH, "//input[contains(@name, 'text')]")
    assert input_el.is_displayed()


def test_by_link_text(driver):
    link = driver.find_element(By.LINK_TEXT, "Return to index")
    assert link.is_displayed()

    partial = driver.find_element(By.PARTIAL_LINK_TEXT, "Return")
    assert partial.is_displayed()


def test_find_multiple_elements(driver):
    inputs = driver.find_elements(By.TAG_NAME, "input")
    print(f"Found {len(inputs)} input elements")
    assert len(inputs) > 0


def test_relative_locators_selenium4(driver):
    """Selenium 4 relative locators"""
    text_input = driver.find_element(By.NAME, "my-text")

    # Find element below
    password = driver.find_element(
        locate_with(By.TAG_NAME, "input").below(text_input))
    assert password.get_attribute("type") == "password"

    # Find element near
    label = driver.find_element(
        locate_with(By.TAG_NAME, "label").near(text_input))
    assert label is not None

Selenium Beginner Locators & Finding Elements

Written by PV

© 2026 All Rights Reserved