ID, Name, and Class Locators
Master the most common and reliable element locators: ID, Name, and Class Name attributes.
The ID, Name, and Class Name locators are the simplest and often most reliable ways to find elements. Understanding when to use each is fundamental to writing stable tests.
Locating by ID
The id attribute is the most reliable locator because IDs should be unique on a page.
import org.openqa.selenium.By;import org.openqa.selenium.WebElement;
// HTML: <input id="username" type="text">WebElement usernameField = driver.findElement(By.id("username"));usernameField.sendKeys("testuser");
// HTML: <button id="submit-btn">Submit</button>WebElement submitButton = driver.findElement(By.id("submit-btn"));submitButton.click();
// HTML: <div id="error-message" class="alert">Error!</div>WebElement errorMessage = driver.findElement(By.id("error-message"));String text = errorMessage.getText();from selenium.webdriver.common.by import By
# HTML: <input id="username" type="text">username_field = driver.find_element(By.ID, "username")username_field.send_keys("testuser")
# HTML: <button id="submit-btn">Submit</button>submit_button = driver.find_element(By.ID, "submit-btn")submit_button.click()
# HTML: <div id="error-message" class="alert">Error!</div>error_message = driver.find_element(By.ID, "error-message")text = error_message.textconst { By } = require('selenium-webdriver');
// HTML: <input id="username" type="text">const usernameField = await driver.findElement(By.id('username'));await usernameField.sendKeys('testuser');
// HTML: <button id="submit-btn">Submit</button>const submitButton = await driver.findElement(By.id('submit-btn'));await submitButton.click();
// HTML: <div id="error-message" class="alert">Error!</div>const errorMessage = await driver.findElement(By.id('error-message'));const text = await errorMessage.getText();using OpenQA.Selenium;
// HTML: <input id="username" type="text">IWebElement usernameField = driver.FindElement(By.Id("username"));usernameField.SendKeys("testuser");
// HTML: <button id="submit-btn">Submit</button>IWebElement submitButton = driver.FindElement(By.Id("submit-btn"));submitButton.Click();
// HTML: <div id="error-message" class="alert">Error!</div>IWebElement errorMessage = driver.FindElement(By.Id("error-message"));string text = errorMessage.Text;When to Use ID
| Pros | Cons |
|---|---|
| Fastest lookup | Not all elements have IDs |
| Should be unique | Dynamic IDs break tests |
| Simple syntax | Framework-generated IDs are unstable |
Warning: Avoid IDs that look auto-generated like
j_idt45:usernameorember123. These change between builds and sessions.
Locating by Name
The name attribute is commonly used for form elements and is often more stable than class names.
// HTML: <input name="email" type="email">WebElement emailField = driver.findElement(By.name("email"));emailField.sendKeys("test@example.com");
// HTML: <input name="password" type="password">WebElement passwordField = driver.findElement(By.name("password"));passwordField.sendKeys("secretpass");
// HTML: <select name="country">WebElement countryDropdown = driver.findElement(By.name("country"));
// HTML: <input name="agree" type="checkbox">WebElement checkbox = driver.findElement(By.name("agree"));if (!checkbox.isSelected()) { checkbox.click();}# HTML: <input name="email" type="email">email_field = driver.find_element(By.NAME, "email")email_field.send_keys("test@example.com")
# HTML: <input name="password" type="password">password_field = driver.find_element(By.NAME, "password")password_field.send_keys("secretpass")
# HTML: <select name="country">country_dropdown = driver.find_element(By.NAME, "country")
# HTML: <input name="agree" type="checkbox">checkbox = driver.find_element(By.NAME, "agree")if not checkbox.is_selected(): checkbox.click()// HTML: <input name="email" type="email">const emailField = await driver.findElement(By.name('email'));await emailField.sendKeys('test@example.com');
// HTML: <input name="password" type="password">const passwordField = await driver.findElement(By.name('password'));await passwordField.sendKeys('secretpass');
// HTML: <select name="country">const countryDropdown = await driver.findElement(By.name('country'));
// HTML: <input name="agree" type="checkbox">const checkbox = await driver.findElement(By.name('agree'));if (!(await checkbox.isSelected())) { await checkbox.click();}// HTML: <input name="email" type="email">IWebElement emailField = driver.FindElement(By.Name("email"));emailField.SendKeys("test@example.com");
// HTML: <input name="password" type="password">IWebElement passwordField = driver.FindElement(By.Name("password"));passwordField.SendKeys("secretpass");
// HTML: <select name="country">IWebElement countryDropdown = driver.FindElement(By.Name("country"));
// HTML: <input name="agree" type="checkbox">IWebElement checkbox = driver.FindElement(By.Name("agree"));if (!checkbox.Selected){ checkbox.Click();}Handling Duplicate Names
Sometimes multiple elements share the same name (like radio buttons):
// HTML:// <input name="gender" value="male" type="radio"> Male// <input name="gender" value="female" type="radio"> Female// <input name="gender" value="other" type="radio"> Other
// Get all radio buttonsList<WebElement> genderOptions = driver.findElements(By.name("gender"));System.out.println("Found " + genderOptions.size() + " options");
// Select specific option by valuefor (WebElement option : genderOptions) { if (option.getAttribute("value").equals("female")) { option.click(); break; }}# HTML:# <input name="gender" value="male" type="radio"> Male# <input name="gender" value="female" type="radio"> Female# <input name="gender" value="other" type="radio"> Other
# Get all radio buttonsgender_options = driver.find_elements(By.NAME, "gender")print(f"Found {len(gender_options)} options")
# Select specific option by valuefor option in gender_options: if option.get_attribute("value") == "female": option.click() break// HTML:// <input name="gender" value="male" type="radio"> Male// <input name="gender" value="female" type="radio"> Female// <input name="gender" value="other" type="radio"> Other
// Get all radio buttonsconst genderOptions = await driver.findElements(By.name('gender'));console.log(`Found ${genderOptions.length} options`);
// Select specific option by valuefor (const option of genderOptions) { if (await option.getAttribute('value') === 'female') { await option.click(); break; }}// HTML:// <input name="gender" value="male" type="radio"> Male// <input name="gender" value="female" type="radio"> Female// <input name="gender" value="other" type="radio"> Other
// Get all radio buttonsIList<IWebElement> genderOptions = driver.FindElements(By.Name("gender"));Console.WriteLine($"Found {genderOptions.Count} options");
// Select specific option by valueforeach (IWebElement option in genderOptions){ if (option.GetAttribute("value") == "female") { option.Click(); break; }}Locating by Class Name
Class names are used for styling and can locate elements, but use them carefully as they’re often not unique.
// HTML: <button class="btn-primary">Save</button>// Note: This only works if there's ONE element with this classWebElement saveButton = driver.findElement(By.className("btn-primary"));saveButton.click();
// HTML: <span class="error-text">Invalid input</span>WebElement errorSpan = driver.findElement(By.className("error-text"));String errorMessage = errorSpan.getText();
// Finding all elements with a class// HTML: <div class="product-card">...</div> (multiple)List<WebElement> productCards = driver.findElements(By.className("product-card"));System.out.println("Found " + productCards.size() + " products");# HTML: <button class="btn-primary">Save</button># Note: This only works if there's ONE element with this classsave_button = driver.find_element(By.CLASS_NAME, "btn-primary")save_button.click()
# HTML: <span class="error-text">Invalid input</span>error_span = driver.find_element(By.CLASS_NAME, "error-text")error_message = error_span.text
# Finding all elements with a class# HTML: <div class="product-card">...</div> (multiple)product_cards = driver.find_elements(By.CLASS_NAME, "product-card")print(f"Found {len(product_cards)} products")// HTML: <button class="btn-primary">Save</button>// Note: This only works if there's ONE element with this classconst saveButton = await driver.findElement(By.className('btn-primary'));await saveButton.click();
// HTML: <span class="error-text">Invalid input</span>const errorSpan = await driver.findElement(By.className('error-text'));const errorMessage = await errorSpan.getText();
// Finding all elements with a class// HTML: <div class="product-card">...</div> (multiple)const productCards = await driver.findElements(By.className('product-card'));console.log(`Found ${productCards.length} products`);// HTML: <button class="btn-primary">Save</button>// Note: This only works if there's ONE element with this classIWebElement saveButton = driver.FindElement(By.ClassName("btn-primary"));saveButton.Click();
// HTML: <span class="error-text">Invalid input</span>IWebElement errorSpan = driver.FindElement(By.ClassName("error-text"));string errorMessage = errorSpan.Text;
// Finding all elements with a class// HTML: <div class="product-card">...</div> (multiple)IList<IWebElement> productCards = driver.FindElements(By.ClassName("product-card"));Console.WriteLine($"Found {productCards.Count} products");Important: Single Class Only
By.className() only accepts a single class name:
// HTML: <div class="card featured product">...</div>
// WRONG - This will throw an error!// WebElement element = driver.findElement(By.className("card featured"));
// CORRECT - Use only one classWebElement element = driver.findElement(By.className("featured"));
// BETTER - Use CSS selector for multiple classesWebElement element = driver.findElement( By.cssSelector(".card.featured.product"));# HTML: <div class="card featured product">...</div>
# WRONG - This will throw an error!# element = driver.find_element(By.CLASS_NAME, "card featured")
# CORRECT - Use only one classelement = driver.find_element(By.CLASS_NAME, "featured")
# BETTER - Use CSS selector for multiple classeselement = driver.find_element( By.CSS_SELECTOR, ".card.featured.product")// HTML: <div class="card featured product">...</div>
// WRONG - This will throw an error!// const element = await driver.findElement(By.className('card featured'));
// CORRECT - Use only one classconst element = await driver.findElement(By.className('featured'));
// BETTER - Use CSS selector for multiple classesconst betterElement = await driver.findElement( By.css('.card.featured.product'));// HTML: <div class="card featured product">...</div>
// WRONG - This will throw an error!// IWebElement element = driver.FindElement(By.ClassName("card featured"));
// CORRECT - Use only one classIWebElement element = driver.FindElement(By.ClassName("featured"));
// BETTER - Use CSS selector for multiple classesIWebElement betterElement = driver.FindElement( By.CssSelector(".card.featured.product"));Comparison Table
| Locator | Speed | Uniqueness | Best For |
|---|---|---|---|
| ID | Fastest | Should be unique | Primary choice when available |
| Name | Fast | Often unique for forms | Form inputs, especially in legacy apps |
| Class | Fast | Rarely unique | Finding groups of similar elements |
Best Practices
- Prefer ID when available and stable
- Use Name for form elements without good IDs
- Avoid Class as primary locator unless it’s genuinely unique
- Combine with CSS when you need multiple classes
- Add data-testid attributes to your application for reliable automation
Working with data-testid
Modern best practice is to add dedicated test attributes:
// HTML: <button data-testid="submit-form">Submit</button>WebElement submitBtn = driver.findElement( By.cssSelector("[data-testid='submit-form']"));
// HTML: <input data-testid="email-input" type="email">WebElement emailInput = driver.findElement( By.cssSelector("[data-testid='email-input']"));# HTML: <button data-testid="submit-form">Submit</button>submit_btn = driver.find_element( By.CSS_SELECTOR, "[data-testid='submit-form']")
# HTML: <input data-testid="email-input" type="email">email_input = driver.find_element( By.CSS_SELECTOR, "[data-testid='email-input']")// HTML: <button data-testid="submit-form">Submit</button>const submitBtn = await driver.findElement( By.css("[data-testid='submit-form']"));
// HTML: <input data-testid="email-input" type="email">const emailInput = await driver.findElement( By.css("[data-testid='email-input']"));// HTML: <button data-testid="submit-form">Submit</button>IWebElement submitBtn = driver.FindElement( By.CssSelector("[data-testid='submit-form']"));
// HTML: <input data-testid="email-input" type="email">IWebElement emailInput = driver.FindElement( By.CssSelector("[data-testid='email-input']"));Next Steps
- CSS Selectors - More powerful selection syntax
- XPath Basics - Navigate the DOM tree
- Relative Locators - Find elements by position