Selenium WebDriver Locators: Examples and Guide
Learn Selenium’s locator strategies, choose stable selectors, and use runnable Java examples for finding one or many elements.
Selenium WebDriver locators identify elements in a page’s DOM so your code can read, click, type into, or otherwise interact with them. Selenium documents eight traditional strategies: ID, CSS selector, name, class name, link text, partial link text, tag name, and XPath. In Selenium 4, relative locators can also find elements by their position in relation to another element.
Prefer a unique, stable ID when one is available. If there is no suitable unique ID, Selenium’s guidance prefers a well-written CSS selector. Use XPath when the target is best described through its attributes or DOM relationships, and use link-text strategies only for links. Always decide whether you expect one match or several.
1. Set up a runnable Java example
This guide uses Java with Selenium 4. The example opens a page, locates an email field by ID, enters a value, and closes the browser. It uses Selenium Manager, which can manage the browser driver for current Selenium releases.
<!-- Add to pom.xml -->
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.27.0</version>
</dependency>
</dependencies>
Use the current Selenium release approved for your project; check the official installation guidance for current setup details. Save this as LocatorExample.java:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class LocatorExample {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
try {
driver.get("https://www.selenium.dev/selenium/web/web-form.html");
WebElement textBox = driver.findElement(By.name("my-text"));
textBox.sendKeys("Selenium locator example");
System.out.println("Field located: " + textBox.getAttribute("name"));
} finally {
driver.quit();
}
}
}
The dependency version above is an example; use the version managed by your project and verify it against the official Selenium getting-started guide. Selenium’s locator reference is at Selenium WebDriver locators.
2. The eight traditional locator strategies
| Strategy | Java example | Use it when | Watch for |
|---|---|---|---|
| ID | By.id("email") |
The element has a unique, stable ID. | IDs generated per render or duplicated in invalid markup may be unstable or ambiguous. |
| CSS selector | By.cssSelector("form#login input[name='email']") |
You can express the target through IDs, classes, attributes, or ancestry. | Keep it focused on meaningful attributes; long chains tied to layout are brittle. |
| Name | By.name("newsletter") |
A form element has a useful, stable name attribute. |
Names may be shared by repeated controls. |
| Class name | By.className("information") |
A single class identifies the intended elements. | Class names often repeat. A compound value such as "btn primary" is not valid for By.className; use a CSS selector such as .btn.primary. |
| Link text | By.linkText("Account settings") |
The target is an anchor and its visible text is an exact, useful identifier. | Text changes, localization, or whitespace can make this fragile. |
| Partial link text | By.partialLinkText("Account") |
The target is a link and a meaningful text fragment identifies it. | If several links contain the fragment, a singular lookup selects the first match; use a collection and filter when you need a specific one. |
| Tag name | By.tagName("button") |
You intend to inspect or act on elements by tag, often as a collection. | Usually broad when used alone. |
| XPath | By.xpath("//input[@value='f']") |
You need attribute predicates or relationships that are clearer in XPath. | Absolute paths and implementation-specific nesting are easy to break. Selenium notes browser vendors typically do not performance-test XPath selectors, so avoid assuming a universal speed ranking. |
Selenium’s published locator advice says to prefer a unique ID; when unique IDs are unavailable, it recommends a well-written CSS selector. This is guidance, not a claim that CSS is always faster or better for every target.
3. Runnable locator examples
The following methods can be placed inside a Java class with a configured WebDriver. Each locator should describe the intended element, not merely happen to match it in the current page.
ID, CSS, name, and XPath
WebElement firstName = driver.findElement(By.id("fname"));
WebElement sameField = driver.findElement(By.cssSelector("#fname"));
WebElement newsletter = driver.findElement(By.name("newsletter"));
WebElement femaleOption = driver.findElement(By.xpath("//input[@value='f']"));
Class and tag lookups
// One class token only. This may match multiple elements.
List<WebElement> informationBlocks =
driver.findElements(By.className("information"));
// Tag-name lookups are often broad, so collect and inspect them.
List<WebElement> buttons = driver.findElements(By.tagName("button"));
System.out.println("Button count: " + buttons.size());
Add import java.util.List; for collection examples.
Link text
WebElement exactLink = driver.findElement(By.linkText("Selenium Official Page"));
WebElement linkContainingText =
driver.findElement(By.partialLinkText("Official Page"));
These strategies target links. If several links could match, explicitly inspect the collection rather than relying on the first result.
4. One match versus many
findElement returns one element: the first matching element, or throws NoSuchElementException if none matches at the time of lookup. findElements returns a list: it can contain one or more matches, and is empty when none match.
// Assert the page has exactly one submit button before acting.
List<WebElement> submitButtons =
driver.findElements(By.cssSelector("button[type='submit']"));
if (submitButtons.size() != 1) {
throw new IllegalStateException(
"Expected one submit button, found " + submitButtons.size());
}
submitButtons.get(0).click();
// For repeated rows, scope the next lookup to the intended row.
WebElement row = driver.findElement(
By.cssSelector("tr[data-order-id='A-104']"));
WebElement cancel = row.findElement(By.cssSelector("button.cancel"));
cancel.click();
Scoping a child lookup to a specific container often makes intent clearer than writing a broad page-wide selector. Do not silently use the first result when uniqueness matters: a changed page could make the test interact with the wrong control.
5. Choosing a reliable locator
- Identify the target and expected count. Is it one control, every row action, or a group of links?
- Prefer stable application attributes. Use a unique ID where available, or a well-written CSS selector based on stable attributes.
- Use visible text for meaningful links. Link text can make a test readable, but it couples the test to wording and language.
- Use XPath for a clear relationship. For example, it can describe a node relative to another node when that relationship is the requirement.
- Keep the locator focused. Avoid long absolute DOM paths and selectors tied to incidental layout wrappers.
- Check the match count. Use singular lookup only when one match is intended, and use plural lookup for collections.
These choices improve maintainability. The Selenium documentation does not provide a universal quantified ranking for locator speed, and speed can depend on the browser, page, and selector.
6. Relative locators in Selenium 4
Relative locators find an element using spatial relationships such as above, below, left, right, or near. They are useful when a target is hard to identify directly but its position relative to a known element is the useful clue. Selenium determines element dimensions and positions using the browser’s getBoundingClientRect().
import static org.openqa.selenium.support.locators.RelativeLocator.with;
WebElement password = driver.findElement(By.id("password"));
WebElement emailAbovePassword = driver.findElement(
with(By.tagName("input")).above(password));
WebElement label = driver.findElement(By.id("delivery-address-label"));
WebElement inputNearLabel = driver.findElement(
with(By.tagName("input")).near(label));
Other relationships include below, leftOf, and rightOf; conditions can be chained. A spatial relationship can change when responsive layout, content, or viewport changes, so use it only when position is genuinely part of the page’s meaning. Prefer a direct semantic locator where one is available.
7. Waiting for elements and dynamic pages
A correct locator can still fail if the page has not rendered the target yet. For asynchronous pages, wait for the specific condition instead of adding a fixed sleep. This Java example waits until a button is clickable:
import java.time.Duration;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement save = wait.until(ExpectedConditions.elementToBeClickable(
By.cssSelector("button[data-action='save']")));
save.click();
Choose a timeout appropriate to your application and environment. A wait does not repair an incorrect locator; first confirm the selector matches the intended element after the page is ready.
8. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
NoSuchElementException |
The locator is wrong, the element is not rendered yet, or it is in a different browsing context. | Inspect the live DOM, verify attributes and spelling, wait for the element, and switch to the correct frame or window when applicable. |
findElements returns an empty list |
No element matches at lookup time; plural lookup reports this as an empty list rather than an exception. | Check selector syntax and page state; wait for the expected content before examining the collection. |
| More than one element matches | A class, name, tag, text fragment, or broad CSS/XPath expression is shared. | Narrow using a stable attribute or scope the lookup to a unique container. If the intended target is a collection, handle each result explicitly. |
| Invalid selector exception | Malformed CSS/XPath, or a compound class name passed to By.className. |
Validate selector grammar; for multiple class tokens use CSS such as .primary.action. |
| Link lookup misses visible text | The target is not an anchor, or exact link text differs because of whitespace, punctuation, or localization. | Confirm it is an <a> element and inspect its rendered text; consider a stable attribute selector if text is not the contract. |
| Element is found but click fails | The element may be covered, disabled, outside the viewport, stale after a re-render, or not yet interactable. | Wait for clickability, scroll or dismiss the overlay if appropriate, and re-find an element after the page replaces it. |
| Relative locator selects a different element | Layout or viewport changes affected spatial relationships. | Use a stable direct locator or make the viewport and page state explicit for the test. |
9. Performance, reliability, and maintenance
Locator selection should first make the test identify the right element consistently. Selenium cautions that XPath may be slower because browser vendors typically do not performance-test XPath selectors; this does not establish a universal performance ranking. Avoid premature optimization based on selector folklore. If locator performance matters in a real suite, measure the relevant workflow in its own browser and page conditions.
Reliability usually improves when the application exposes stable identifiers, the selector expresses the intended control, and the test waits for the required state. A brittle selector can fail after harmless markup changes; a text locator can fail after copy or localization changes; a relative locator can fail after layout changes. Use the form of identity your application can maintain.
10. Or skip the browser setup
If your goal is a screenshot for documentation, review, or an AI workflow rather than interacting with an element, ScreenshotNeo provides a website screenshot API and MCP server. It is not a replacement for Selenium interaction tests; it can handle the screenshot capture step directly.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for options and setup. Cookie banners, newsletter popups, and chat widgets are removed before the shot; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. Its MCP server lets Claude, Cursor, and other MCP clients use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots. Sign up for 1,000 free screenshots a month, no card required.
11. FAQ
Can a locator use more than one attribute?
Yes. A CSS selector or XPath expression can combine attributes when that makes the target more specific and remains readable.
Does a locator automatically wait for an element?
A lookup checks the current page state. Use an explicit wait when the element appears asynchronously.
Are relative locators a replacement for CSS and XPath?
No. They are another option for spatial relationships. Direct locators are usually clearer when the target has a stable identity or attribute.
Should I use link text for buttons?
No. Selenium’s link-text strategies apply to anchor elements. For buttons, use an appropriate ID, CSS selector, or XPath locator.


