Choosing the Best Locator

Priority Order

  1. id (if it is unique and not auto-generated like input-4821)
  2. name or a dedicated test attribute: data-testid="add-to-cart"
  3. CSS selector (short and readable)
  4. XPath (when you need text or to move up/sideways in the DOM)
  5. linkText for links, className / tagName for lists

Tip: Ask developers to add data-testid attributes. They do not change when the design changes, so tests stop breaking.

Good and Bad Locators

LocatorVerdictWhy
By.id("add-to-cart")goodunique, meaningful
By.cssSelector("[data-testid='cart-count']")goodmade for tests
By.id("ember1423")badgenerated, changes every load
By.xpath("/html/body/div[2]/div[3]/form/button")badbreaks if any div is added
By.className("col-md-4")badlayout class, matches many elements

Scoring Locators

Example

A small program that flags risky locators, using the rules above:

import java.util.*;

public class Main {
    static String review(String type, String value) {
        if (type.equals("id") && value.matches(".*[0-9]{3,}.*")) return "RISKY: looks auto-generated";
        if (type.equals("xpath") && value.startsWith("/html")) return "RISKY: absolute XPath";
        if (type.equals("className") && value.startsWith("col-")) return "RISKY: layout class";
        return "OK";
    }

    public static void main(String[] args) {
        String[][] locators = {
            {"id", "add-to-cart"}, {"id", "ember1423"},
            {"xpath", "/html/body/div[2]/form/button"}, {"xpath", "//button[text()='Login']"},
            {"className", "col-md-4"}, {"cssSelector", "#cart-count"}
        };
        for (String[] l : locators) {
            System.out.printf("%-12s %-32s %s%n", l[0], l[1], review(l[0], l[1]));
        }
    }
}

Output

id           add-to-cart                      OK
id           ember1423                        RISKY: looks auto-generated
xpath        /html/body/div[2]/form/button    RISKY: absolute XPath
xpath        //button[text()='Login']         OK
className    col-md-4                         RISKY: layout class
cssSelector  #cart-count                      OK