CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-seleniumhq-selenium--selenium-api

Selenium WebDriver core API for automating web browsers across different platforms and programming languages.

Pending
Overview
Eval results
Files

locators.mddocs/

Element Location Strategies

The By class provides various strategies for locating elements in the DOM, including ID-based, CSS selector, XPath, and text-based searches.

Capabilities

By Class

Abstract factory class providing static methods for creating element locator strategies.

/**
 * By abstract class for element location strategies
 * Provides static factory methods for different locator types
 */
abstract class By {
    /**
     * Locate element by ID attribute
     * @param id - Element ID value
     * @return By locator for ID-based search
     */
    static By id(String id);
    
    /**
     * Locate element by name attribute
     * @param name - Element name value
     * @return By locator for name-based search
     */
    static By name(String name);
    
    /**
     * Locate element by CSS class name
     * @param className - CSS class name (single class only)
     * @return By locator for class-based search
     */
    static By className(String className);
    
    /**
     * Locate element by HTML tag name
     * @param tagName - HTML tag name (e.g., "div", "input", "button")
     * @return By locator for tag-based search
     */
    static By tagName(String tagName);
    
    /**
     * Locate element by XPath expression
     * @param xpathExpression - XPath query string
     * @return By locator for XPath-based search
     */
    static By xpath(String xpathExpression);
    
    /**
     * Locate element by CSS selector
     * @param cssSelector - CSS selector string
     * @return By locator for CSS selector-based search
     */
    static By cssSelector(String cssSelector);
    
    /**
     * Locate link element by exact link text
     * @param linkText - Exact text content of the link
     * @return By locator for link text search
     */
    static By linkText(String linkText);
    
    /**
     * Locate link element by partial link text
     * @param partialLinkText - Partial text content of the link
     * @return By locator for partial link text search
     */
    static By partialLinkText(String partialLinkText);
}

Locator Strategy Examples

ID-Based Location

Most reliable and fastest locator strategy when unique IDs are available.

// Locate by ID attribute
WebElement loginButton = driver.findElement(By.id("loginBtn"));
WebElement usernameField = driver.findElement(By.id("username"));
WebElement errorMessage = driver.findElement(By.id("error-msg"));

// Multiple elements (rare with ID, but possible with invalid HTML)
List<WebElement> elementsWithSameId = driver.findElements(By.id("duplicateId"));

Name-Based Location

Useful for form elements with name attributes.

// Form elements by name
WebElement emailField = driver.findElement(By.name("email"));
WebElement passwordField = driver.findElement(By.name("password"));
WebElement newsletterCheckbox = driver.findElement(By.name("newsletter"));

// Radio button groups
List<WebElement> genderOptions = driver.findElements(By.name("gender"));
for (WebElement option : genderOptions) {
    if (option.getAttribute("value").equals("female")) {
        option.click();
        break;
    }
}

CSS Class-Based Location

Locate elements by CSS class name (single class only).

// Single class name
WebElement submitButton = driver.findElement(By.className("btn-primary"));
WebElement errorDiv = driver.findElement(By.className("error-message"));

// Find multiple elements with same class
List<WebElement> menuItems = driver.findElements(By.className("nav-item"));
List<WebElement> productCards = driver.findElements(By.className("product-card"));

Tag Name-Based Location

Locate elements by HTML tag name, useful for finding all elements of a type.

// Find elements by tag
List<WebElement> allInputs = driver.findElements(By.tagName("input"));
List<WebElement> allLinks = driver.findElements(By.tagName("a"));
List<WebElement> allImages = driver.findElements(By.tagName("img"));
WebElement firstHeading = driver.findElement(By.tagName("h1"));

// Within a specific parent
WebElement form = driver.findElement(By.id("contactForm"));
List<WebElement> formInputs = form.findElements(By.tagName("input"));

XPath-Based Location

Powerful but potentially slow locator using XPath expressions.

// Simple XPath
WebElement button = driver.findElement(By.xpath("//button[@type='submit']"));
WebElement input = driver.findElement(By.xpath("//input[@name='username']"));

// XPath with text content
WebElement link = driver.findElement(By.xpath("//a[text()='Click Here']"));
WebElement header = driver.findElement(By.xpath("//h1[contains(text(), 'Welcome')]"));

// XPath with parent/child relationships
WebElement tableCell = driver.findElement(By.xpath("//table[@id='data']/tbody/tr[2]/td[3]"));
WebElement lastListItem = driver.findElement(By.xpath("//ul[@class='menu']/li[last()]"));

// XPath with multiple conditions
WebElement complexElement = driver.findElement(
    By.xpath("//div[@class='product' and @data-price > '100']//button[text()='Buy Now']")
);

// XPath with following/preceding siblings
WebElement nextSibling = driver.findElement(By.xpath("//label[text()='Email:']/following-sibling::input"));
WebElement previousElement = driver.findElement(By.xpath("//button[@id='submit']/preceding-sibling::input"));

// XPath with contains and attributes
List<WebElement> elements = driver.findElements(
    By.xpath("//div[contains(@class, 'product') and contains(@data-category, 'electronics')]")
);

CSS Selector-Based Location

Modern and efficient locator using CSS selector syntax.

// Basic CSS selectors
WebElement elementById = driver.findElement(By.cssSelector("#loginForm"));
WebElement elementByClass = driver.findElement(By.cssSelector(".btn-primary"));
WebElement elementByTag = driver.findElement(By.cssSelector("input"));

// Attribute selectors
WebElement inputByType = driver.findElement(By.cssSelector("input[type='email']"));
WebElement linkByHref = driver.findElement(By.cssSelector("a[href='https://example.com']"));
WebElement elementByDataAttr = driver.findElement(By.cssSelector("div[data-testid='user-profile']"));

// Descendant and child selectors
WebElement nestedElement = driver.findElement(By.cssSelector("form#login input[name='username']"));
WebElement directChild = driver.findElement(By.cssSelector("nav > ul > li:first-child"));

// Pseudo-selectors
WebElement firstChild = driver.findElement(By.cssSelector("ul li:first-child"));
WebElement lastChild = driver.findElement(By.cssSelector("ul li:last-child"));
WebElement nthChild = driver.findElement(By.cssSelector("tr:nth-child(3)"));
WebElement evenRows = driver.findElement(By.cssSelector("tr:nth-child(even)"));

// Partial attribute matching
WebElement partialClass = driver.findElement(By.cssSelector("div[class*='product']"));
WebElement startsWith = driver.findElement(By.cssSelector("input[id^='user']"));
WebElement endsWith = driver.findElement(By.cssSelector("img[src$='.png']"));

// Multiple selectors
List<WebElement> multipleSelectors = driver.findElements(
    By.cssSelector("input[type='text'], input[type='email'], textarea")
);

Link Text-Based Location

Specialized locators for anchor elements based on their text content.

// Exact link text
WebElement homeLink = driver.findElement(By.linkText("Home"));
WebElement loginLink = driver.findElement(By.linkText("Login"));
WebElement logoutLink = driver.findElement(By.linkText("Logout"));

// Partial link text (useful for dynamic or long link text)
WebElement downloadLink = driver.findElement(By.partialLinkText("Download"));
WebElement readMoreLink = driver.findElement(By.partialLinkText("Read More"));
WebElement productLink = driver.findElement(By.partialLinkText("iPhone"));

// Case sensitivity considerations
try {
    WebElement link1 = driver.findElement(By.linkText("CONTACT US"));
    WebElement link2 = driver.findElement(By.linkText("Contact Us"));
    // These may find different elements or throw NoSuchElementException
} catch (NoSuchElementException e) {
    // Handle case where exact text doesn't match
}

// Finding all links with partial text
List<WebElement> productLinks = driver.findElements(By.partialLinkText("Product"));

Best Practices and Strategy Selection

Locator Priority and Recommendations

// 1. ID - Most reliable and fastest (when available and unique)
WebElement element1 = driver.findElement(By.id("unique-id"));

// 2. Name - Good for form elements
WebElement element2 = driver.findElement(By.name("fieldName"));

// 3. CSS Selector - Modern, flexible, and readable
WebElement element3 = driver.findElement(By.cssSelector("input[data-testid='username']"));

// 4. Link Text - Good for navigation links
WebElement element4 = driver.findElement(By.linkText("Contact Us"));

// 5. Class Name - Use with caution (ensure uniqueness)
WebElement element5 = driver.findElement(By.className("unique-class"));

// 6. XPath - Powerful but can be fragile and slow
WebElement element6 = driver.findElement(By.xpath("//button[text()='Submit']"));

// 7. Tag Name - Usually for finding multiple elements
List<WebElement> elements7 = driver.findElements(By.tagName("input"));

Robust Locator Patterns

// Use data attributes for test automation
WebElement testElement = driver.findElement(By.cssSelector("[data-testid='submit-button']"));

// Combine multiple attributes for uniqueness
WebElement specificButton = driver.findElement(
    By.cssSelector("button[type='submit'][class*='primary']")
);

// Use partial matching for dynamic content
WebElement dynamicElement = driver.findElement(
    By.cssSelector("div[id^='generated-'][class$='-container']")
);

// Create reusable locator methods
public By buttonByText(String text) {
    return By.xpath("//button[normalize-space(text())='" + text + "']");
}

public By inputByPlaceholder(String placeholder) {
    return By.cssSelector("input[placeholder='" + placeholder + "']");
}

// Usage
WebElement submitBtn = driver.findElement(buttonByText("Submit"));
WebElement emailInput = driver.findElement(inputByPlaceholder("Enter your email"));

Error Handling and Fallback Strategies

// Try multiple locator strategies
public WebElement findElementWithFallback(WebDriver driver, String id, String className, String xpath) {
    try {
        return driver.findElement(By.id(id));
    } catch (NoSuchElementException e1) {
        try {
            return driver.findElement(By.className(className));
        } catch (NoSuchElementException e2) {
            return driver.findElement(By.xpath(xpath));
        }
    }
}

// Check element existence before interaction
public boolean isElementPresent(WebDriver driver, By locator) {
    try {
        driver.findElement(locator);
        return true;
    } catch (NoSuchElementException e) {
        return false;
    }
}

// Wait for element with multiple locators
public WebElement waitForAnyElement(WebDriver driver, Duration timeout, By... locators) {
    WebDriverWait wait = new WebDriverWait(driver, timeout);
    for (By locator : locators) {
        try {
            return wait.until(ExpectedConditions.presenceOfElementLocated(locator));
        } catch (TimeoutException e) {
            // Continue to next locator
        }
    }
    throw new NoSuchElementException("None of the provided locators found an element");
}

Relative Locators

Modern spatial locator strategy for finding elements relative to other elements.

/**
 * RelativeLocator class for spatial element location
 * Allows finding elements based on their position relative to other elements
 */
class RelativeLocator {
    /**
     * Create relative locator starting with a base locator
     * @param by - Base locator strategy
     * @return RelativeBy instance for chaining spatial relationships
     */
    static RelativeBy with(By by);
}

/**
 * RelativeBy class for chaining spatial relationships
 */
class RelativeBy extends By {
    /**
     * Find element above the reference element
     * @param element - Reference element
     * @return RelativeBy for further chaining
     */
    RelativeBy above(WebElement element);
    
    /**
     * Find element above the located reference element
     * @param locator - Locator for reference element
     * @return RelativeBy for further chaining
     */
    RelativeBy above(By locator);
    
    /**
     * Find element below the reference element
     * @param element - Reference element
     * @return RelativeBy for further chaining
     */
    RelativeBy below(WebElement element);
    
    /**
     * Find element below the located reference element
     * @param locator - Locator for reference element
     * @return RelativeBy for further chaining
     */
    RelativeBy below(By locator);
    
    /**
     * Find element to the left of the reference element
     * @param element - Reference element
     * @return RelativeBy for further chaining
     */
    RelativeBy toLeftOf(WebElement element);
    
    /**
     * Find element to the left of the located reference element
     * @param locator - Locator for reference element
     * @return RelativeBy for further chaining
     */
    RelativeBy toLeftOf(By locator);
    
    /**
     * Find element to the right of the reference element
     * @param element - Reference element
     * @return RelativeBy for further chaining
     */
    RelativeBy toRightOf(WebElement element);
    
    /**
     * Find element to the right of the located reference element
     * @param locator - Locator for reference element
     * @return RelativeBy for further chaining
     */
    RelativeBy toRightOf(By locator);
    
    /**
     * Find element near the reference element (within 50 pixels)
     * @param element - Reference element
     * @return RelativeBy for further chaining
     */
    RelativeBy near(WebElement element);
    
    /**
     * Find element near the located reference element
     * @param locator - Locator for reference element
     * @return RelativeBy for further chaining
     */
    RelativeBy near(By locator);
}

Usage Examples:

import static org.openqa.selenium.support.locators.RelativeLocator.with;

// Find element above another element
WebElement passwordField = driver.findElement(with(By.tagName("input"))
    .above(By.id("login-button")));

// Find element to the right of another element
WebElement submitButton = driver.findElement(with(By.tagName("button"))
    .toRightOf(By.id("cancel-button")));

// Find element below and to the right of another element (chaining)
WebElement errorMessage = driver.findElement(with(By.className("error"))
    .below(By.id("email-field"))
    .toRightOf(By.id("password-field")));

// Find element near another element
WebElement helpIcon = driver.findElement(with(By.className("help-icon"))
    .near(By.id("complex-field")));

// Multiple spatial relationships
WebElement specificElement = driver.findElement(with(By.tagName("span"))
    .above(driver.findElement(By.id("footer")))
    .below(driver.findElement(By.id("header")))
    .toRightOf(driver.findElement(By.className("sidebar"))));

Install with Tessl CLI

npx tessl i tessl/maven-org-seleniumhq-selenium--selenium-api

docs

alerts.md

configuration.md

drivers.md

elements.md

index.md

interactions.md

javascript.md

locators.md

page-objects.md

waits.md

webdriver.md

tile.json