Finding elements reliably

Choosing a locator strategy that survives the next release of the application, and avoiding the ones that do not.

A locator copied out of the browser’s developer tools works today and breaks the first time a designer moves a div. Tests then fail for reasons that have nothing to do with the behaviour they were written to check, and the suite stops being trusted.

Prefer locators that describe what an element is over locators that describe where it happens to sit in the document, roughly in this order:

  1. id, when the page has stable, unique ids. This is the fastest and most readable choice.
  2. name, for form fields, which tend to keep their names because the server depends on them.
  3. CSS selector, for everything else. A short selector anchored on an id, a data attribute, or a meaningful class is both fast and expressive.
  4. Relative locators, when the target has no stable attributes of its own but a nearby element does: find the input below a given label, or the button to the right of a field.

Avoid absolute XPath (/html/body/div[3]/...). It encodes the entire structure of the page, so any change above the element breaks it, and it is slow in some browsers. XPath itself is fine when you need it, for example to match on text content, but keep the expression short and anchored.

If the application does not expose stable attributes, ask for them. A data-test attribute costs the developers nothing and removes an entire class of failures.

Locate the first matching element:

    driver.get(LOCATORS_PAGE);
    WebElement firstInput = driver.findElement(By.className("information"));
    driver.get(LOCATORS_PAGE)
    first_input = driver.find_element(By.CLASS_NAME, "information")
            driver.Url = LocatorsPage;
            IWebElement firstInput = driver.FindElement(By.ClassName("information"));
    driver.navigate.to locators_page
    first_input = driver.find_element(class: 'information')
    await driver.get(LOCATORS_PAGE);
    const firstInput = await driver.findElement(By.className('information'));
        driver.get(locatorsPage)
        val firstInput = driver.findElement(By.className("information"))

Locate by id, the preferred strategy when one is available:

        WebElement element = driver.findElement(By.id("lname"));
    element = driver.find_element(By.ID, "lname")
    driver.find_element(id: 'lname')
    const element = await driver.findElement(By.id('lname'));

Locate relative to another element:

      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})

Common errors

Reference