Skip to content

Selenium - Locators

Locators are the core mechanism Selenium uses to find elements on a web page. Selecting the right locator strategy is crucial for creating stable and maintainable automated tests. Selenium WebDriver provides several locator strategies via the By class.

The primary methods for finding elements are:

  • driver.findElement(By locator): Returns the first WebElement object matching the specified locator strategy. If no element is found, it throws a NoSuchElementException.
  • driver.findElements(By locator): Returns a List<WebElement> containing all elements matching the locator strategy. If no elements are found, it returns an empty list.

Here are the common locator strategies available in WebDriver, along with usage tips:

StrategyJava Syntax ExampleDescription & Best Practice
By IDdriver.findElement(By.id("userId"))Locates an element using its unique id attribute. Preferred: IDs are typically unique and less likely to change, making tests more robust.
By Namedriver.findElement(By.name("username"))Locates an element using the name attribute. Useful for form elements, but ensure the name is stable.
By CSS Selectordriver.findElement(By.cssSelector("input[type='submit']"))Locates an element using CSS selector syntax. Highly Recommended: Powerful, concise, and generally faster than XPath. Good for complex selections and locating elements based on attributes or relationships.
By XPathdriver.findElement(By.xpath("//button[contains(text(),'Login')]"))Locates an element using XPath (XML Path Language). Powerful but use judiciously: Very flexible, can navigate the DOM in complex ways (e.g., finding parent/sibling elements). Can be slower than CSS and brittle if based on absolute paths or indices. Prefer relative XPath expressions.
By Link Textdriver.findElement(By.linkText("Forgot Password"))Locates an anchor element (<a>) by its exact visible text. Use only when the link text is unique and static.
By Partial Link Textdriver.findElement(By.partialLinkText("Forgot"))Locates an anchor element (<a>) by a partial match of its visible text. Useful if parts of the link text are dynamic, but can lead to incorrect matches if multiple links share the partial text.
By Class Namedriver.findElement(By.className("btn-primary"))Locates elements using the class attribute. Often returns multiple elements (findElements). Use cautiously as class names might not be unique or might change frequently for styling purposes.
By Tag Namedriver.findElements(By.tagName("img"))Locates elements by their HTML tag name (e.g., div, a, input). Usually used with findElements to get collections of elements.

Aim for locators that are:

  • Unique: Identify only the intended element.
  • Stable: Less likely to change due to UI redesigns or dynamic content.
  • Descriptive: Easy to understand which element the locator refers to.
  • Concise: Shorter locators (like ID or good CSS selectors) are often preferred.

Order of preference generally is: ID > Name > CSS Selector > XPath > Link Text > Partial Link Text > Class Name > Tag Name. However, the best choice depends on the specific HTML structure.

Forget outdated plugins like Firebug/FirePath. Modern browsers (Chrome, Firefox, Edge) have excellent built-in Developer Tools (usually accessed by pressing F12). Use the ‘Inspect Element’ feature (often an arrow icon) to select an element on the page. The tools will show you the HTML structure, attributes (like ID, name, class), and often suggest CSS Selectors or XPath.

Imagine you want to find a login button with the HTML: <button id="loginBtn" class="submit primary" type="submit">Log In</button>

Possible locators:

// Preferred:
WebElement loginButtonById = driver.findElement(By.id("loginBtn"));
// Also good:
WebElement loginButtonByCss = driver.findElement(By.cssSelector("button#loginBtn")); // Using ID
WebElement loginButtonByCssType = driver.findElement(By.cssSelector("button[type='submit']")); // Using attribute
// Okay, but potentially less robust if text changes:
WebElement loginButtonByXpath = driver.findElement(By.xpath("//button[text()='Log In']"));
// Less ideal if class names change or are not unique:
WebElement loginButtonByClass = driver.findElement(By.className("submit")); // Might find other elements

Experiment with different strategies in your browser’s developer console to find the most reliable option for your specific application.