Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:SeleniumHQ Selenium WebElement Interaction API

From Leeroopedia
Knowledge Sources
Domains Test_Design, Design_Patterns, Browser_Automation
Last Updated 2026-02-11 00:00 GMT

Overview

Concrete tool for interacting with DOM elements within Page Objects provided by the WebElement interface and ThreadGuard utility.

Description

The WebElement interface (in package org.openqa.selenium) extends SearchContext and TakesScreenshot, providing the core interaction methods used within Page Object method implementations. All method calls perform a freshness check to verify the element is still attached to the DOM; if not, a StaleElementReferenceException is thrown. The interface includes action methods (click(), submit(), sendKeys(), clear()), query methods (getText(), getAttribute(), getDomAttribute(), getDomProperty(), getTagName(), getCssValue(), getAriaRole(), getAccessibleName()), state methods (isDisplayed(), isEnabled(), isSelected()), geometry methods (getLocation(), getSize(), getRect()), and search methods inherited from SearchContext (findElement(), findElements()). It also provides getShadowRoot() for accessing shadow DOM.

ThreadGuard.protect() wraps a WebDriver in a JDK dynamic proxy (via java.lang.reflect.Proxy) that validates all method calls come from the thread that created the guard. The WebDriverInvocationHandler stores the creating thread's ID and name, and on every invocation checks Thread.currentThread().getId() against the stored ID. If they differ, a WebDriverException is thrown with a descriptive message identifying both threads.

Usage

Use WebElement methods within Page Object method implementations. Use ThreadGuard when running tests in parallel with shared driver instances to catch accidental cross-thread access early.

Code Reference

Source Location

  • Repository: Selenium
  • File: java/src/org/openqa/selenium/WebElement.java (L32-335)
  • File: java/src/org/openqa/selenium/support/ThreadGuard.java (L42-102)

Signature

public interface WebElement extends SearchContext, TakesScreenshot {
    // Action methods
    void click();
    void submit();
    void sendKeys(CharSequence... keysToSend);
    void clear();

    // Query methods
    String getTagName();
    @Nullable String getAttribute(String name);
    default @Nullable String getDomAttribute(String name);
    default @Nullable String getDomProperty(String name);
    String getText();
    String getCssValue(String propertyName);
    default @Nullable String getAriaRole();
    default @Nullable String getAccessibleName();

    // State methods
    boolean isSelected();
    boolean isEnabled();
    boolean isDisplayed();

    // Geometry methods
    Point getLocation();
    Dimension getSize();
    Rectangle getRect();

    // Search methods (inherited from SearchContext)
    WebElement findElement(By by);
    List<WebElement> findElements(By by);

    // Shadow DOM
    default SearchContext getShadowRoot();
}

public class ThreadGuard {
    public static WebDriver protect(WebDriver actualWebDriver);
    // Returns proxy that throws WebDriverException if called from wrong thread
}

Import

import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ThreadGuard;

I/O Contract

Inputs

Name Type Required Description
keysToSend CharSequence... Yes (for sendKeys) Text to type or Keys enum values; throws IllegalArgumentException if null
name String Yes (for getAttribute/getDomAttribute/getDomProperty) Attribute or property name to retrieve
propertyName String Yes (for getCssValue) CSS property name (use longhand, not shorthand)
by By Yes (for findElement/findElements) Locator strategy for sub-element search
actualWebDriver WebDriver Yes (for ThreadGuard.protect) WebDriver instance to wrap with thread-safety proxy

Outputs

Name Type Description
getText() String Visible text of the element (not hidden by CSS), including sub-elements
getAttribute() String or null Value of attribute/property; returns null if not set
getDomAttribute() String or null Value of the DOM attribute only (not JavaScript property)
getDomProperty() String or null Value of the DOM property only (not HTML attribute)
getTagName() String HTML tag name (e.g., "input", "div", "button")
getCssValue() String Computed CSS value (e.g., "rgba(0, 255, 0, 1)")
isDisplayed() boolean Whether element is visible on the page
isEnabled() boolean Whether element is interactable (not disabled)
isSelected() boolean Whether checkbox/radio/option is selected
getLocation() Point Top-left corner coordinates
getSize() Dimension Width and height
getRect() Rectangle Combined location and size
ThreadGuard.protect() WebDriver Proxied WebDriver with thread-safety enforcement

Exceptions

Exception Condition
StaleElementReferenceException Element is no longer attached to the DOM
NoSuchElementException Element not found (for findElement) or form not found (for submit)
IllegalArgumentException keysToSend is null (for sendKeys)
WebDriverException ThreadGuard detects cross-thread access

Usage Examples

Page Object with Interaction Methods

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

public class LoginPage {
    private WebDriver driver;

    @FindBy(id = "username")
    private WebElement usernameInput;

    @FindBy(id = "password")
    private WebElement passwordInput;

    @FindBy(css = "button[type='submit']")
    private WebElement submitButton;

    @FindBy(css = ".error-message")
    private WebElement errorMessage;

    public LoginPage(WebDriver driver) {
        this.driver = driver;
        PageFactory.initElements(driver, this);
    }

    // Domain-specific method returning another Page Object
    public DashboardPage login(String username, String password) {
        usernameInput.clear();
        usernameInput.sendKeys(username);
        passwordInput.clear();
        passwordInput.sendKeys(password);
        submitButton.click();
        return new DashboardPage(driver);
    }

    // Query method returning data for test assertions
    public String getErrorMessage() {
        return errorMessage.getText();
    }

    // State query method
    public boolean isSubmitEnabled() {
        return submitButton.isEnabled();
    }
}

ThreadGuard for Parallel Tests

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ThreadGuard;

// Wrap driver creation with ThreadGuard
WebDriver driver = ThreadGuard.protect(new ChromeDriver());

// Any call from a different thread will throw WebDriverException:
// "Thread safety error; this instance of WebDriver was constructed on
//  thread main (id 1) and is being accessed by thread Thread-2 (id 15)
//  This is not permitted and *will* cause undefined behaviour"

Returning Page Objects for Navigation Flow

public class CartPage {
    private WebDriver driver;

    @FindBy(id = "checkout-btn")
    private WebElement checkoutButton;

    @FindBy(css = ".cart-item")
    private List<WebElement> cartItems;

    public CartPage(WebDriver driver) {
        this.driver = driver;
        PageFactory.initElements(driver, this);
    }

    public CheckoutPage proceedToCheckout() {
        checkoutButton.click();
        return new CheckoutPage(driver);
    }

    public int getItemCount() {
        return cartItems.size();
    }

    public String getItemName(int index) {
        return cartItems.get(index).getText();
    }
}

Related Pages

Implements Principle

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment