CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-seleniumhq-selenium--selenium-support

Selenium WebDriver support utilities providing Page Object Model, waiting mechanisms, event handling, and UI utilities for robust test automation

Pending
Overview
Eval results
Files

utilities.mddocs/

Utilities and Helpers

The utilities package provides specialized helpers for common web interactions including dropdown selections, color handling, thread safety, and advanced element location strategies. These utilities simplify complex operations and provide additional safety and convenience features.

Select Class for Dropdowns

public class Select implements ISelect, WrapsElement {
    /**
     * Create Select helper for HTML select element
     * @throws UnexpectedTagNameException if element is not a SELECT tag
     */
    public Select(WebElement element);
    
    /**
     * Get the wrapped select element
     */
    public WebElement getWrappedElement();
    
    /**
     * Check if this select element supports multiple selections
     */
    public boolean isMultiple();
    
    /**
     * Get all option elements in the select
     */
    public List<WebElement> getOptions();
    
    /**
     * Get all currently selected options
     */
    public List<WebElement> getAllSelectedOptions();
    
    /**
     * Get the first selected option (or only selected option for single-select)
     */
    public WebElement getFirstSelectedOption();
    
    /**
     * Select option by visible text
     */
    public void selectByVisibleText(String text);
    
    /**
     * Select option by index (0-based)
     */
    public void selectByIndex(int index);
    
    /**
     * Select option by value attribute
     */
    public void selectByValue(String value);
    
    /**
     * Deselect all options (multi-select only)
     * @throws UnsupportedOperationException if not multi-select
     */
    public void deselectAll();
    
    /**
     * Deselect option by value (multi-select only)
     */
    public void deselectByValue(String value);
    
    /**
     * Deselect option by index (multi-select only)
     */
    public void deselectByIndex(int index);
    
    /**
     * Deselect option by visible text (multi-select only)
     */
    public void deselectByVisibleText(String text);
}

ISelect Interface

public interface ISelect {
    boolean isMultiple();
    List<WebElement> getOptions();
    List<WebElement> getAllSelectedOptions();
    WebElement getFirstSelectedOption();
    void selectByVisibleText(String text);
    void selectByIndex(int index);
    void selectByValue(String value);
    void deselectAll();
    void deselectByValue(String value);
    void deselectByIndex(int index);
    void deselectByVisibleText(String text);
}

Select Usage Examples

import org.openqa.selenium.support.ui.Select;

// Find select element and create Select helper
WebElement selectElement = driver.findElement(By.id("country"));
Select select = new Select(selectElement);

// Check if multiple selection is supported
if (select.isMultiple()) {
    System.out.println("Multi-select dropdown");
} else {
    System.out.println("Single-select dropdown");
}

// Select by visible text
select.selectByVisibleText("United States");

// Select by value attribute
select.selectByValue("US");

// Select by index (0-based)
select.selectByIndex(2);

// Get all options
List<WebElement> options = select.getOptions();
for (WebElement option : options) {
    System.out.println("Option: " + option.getText() + 
                      " (value=" + option.getAttribute("value") + ")");
}

// Get selected options
List<WebElement> selected = select.getAllSelectedOptions();
System.out.println("Selected options count: " + selected.size());

// For multi-select dropdowns
if (select.isMultiple()) {
    // Select multiple options
    select.selectByVisibleText("Option 1");
    select.selectByVisibleText("Option 2");
    
    // Deselect specific options
    select.deselectByVisibleText("Option 1");
    
    // Deselect all options
    select.deselectAll();
}

ThreadGuard Class

The ThreadGuard provides thread-safety verification for WebDriver instances, ensuring that WebDriver operations are only performed from the thread that created the driver instance.

public class ThreadGuard {
    /**
     * Wraps a WebDriver instance with thread-safety protection
     * @param actualWebDriver The WebDriver to protect
     * @return Protected WebDriver proxy that throws exception on cross-thread access  
     */
    public static WebDriver protect(WebDriver actualWebDriver);
}

ThreadGuard Usage Examples

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

// Protect WebDriver instance for multithreaded usage
WebDriver driver = ThreadGuard.protect(new ChromeDriver());

// This will work fine from the same thread
driver.get("https://example.com");

// Attempting to use from different thread will throw WebDriverException
// "Thread safety error; this instance of WebDriver was constructed on thread..."

LoadableComponent Classes

Provides abstractions for page objects and components that can be loaded, with automatic loading verification and timeout handling.

public abstract class LoadableComponent<T extends LoadableComponent<T>> {
    /**
     * Ensure that the component is currently loaded
     * @return The component instance
     * @throws Error when the component cannot be loaded
     */
    public T get();
    
    /**
     * Override to check if the component is loaded
     * @throws Error if not loaded
     */
    protected abstract void isLoaded() throws Error;
    
    /**
     * Override to perform loading actions
     */
    protected abstract void load();
}

public abstract class SlowLoadableComponent<T extends LoadableComponent<T>> 
    extends LoadableComponent<T> {
    /**
     * Create component with timeout for loading
     * @param clock Clock for timing
     * @param timeOutInSeconds Maximum time to wait for loading
     */
    public SlowLoadableComponent(Clock clock, int timeOutInSeconds);
    
    /**
     * Get component, waiting up to timeout for it to load
     */
    @Override
    public T get();
}

LoadableComponent Usage Examples

import org.openqa.selenium.support.ui.LoadableComponent;

public class LoginPage extends LoadableComponent<LoginPage> {
    private WebDriver driver;
    
    public LoginPage(WebDriver driver) {
        this.driver = driver;
    }
    
    @Override
    protected void load() {
        driver.get("/login");
    }
    
    @Override
    protected void isLoaded() throws Error {
        if (!driver.getCurrentUrl().contains("/login")) {
            throw new Error("Login page not loaded");
        }
    }
    
    public void login(String user, String pass) {
        // Will automatically load if not already loaded
        get();
        // ... login logic
    }
}

Color Utilities

Color Class

public class Color {
    /**
     * Create Color with RGB values and alpha
     * @param red Red component (0-255)
     * @param green Green component (0-255)
     * @param blue Blue component (0-255)
     * @param alpha Alpha channel (0.0-1.0)
     */
    public Color(int red, int green, int blue, double alpha);
    
    /**
     * Parse color from string in various formats:
     * - Hex: #ffffff, #fff
     * - RGB: rgb(255, 255, 255)
     * - RGBA: rgba(255, 255, 255, 1.0)
     * - HSL: hsl(0, 100%, 50%)
     * - Named colors: red, blue, etc.
     */
    public static Color fromString(String value);
    
    /**
     * Set opacity/alpha channel
     */
    public void setOpacity(double alpha);
    
    /**
     * Convert to CSS rgb() format
     */
    public String asRgb();
    
    /**
     * Convert to CSS rgba() format
     */
    public String asRgba();
    
    /**
     * Convert to hex format (#rrggbb)
     */
    public String asHex();
    
    /**
     * Convert to Java AWT Color
     */
    public java.awt.Color getColor();
    
    public String toString();
    public boolean equals(Object other);
    public int hashCode();
}

Colors Enum

public enum Colors {
    TRANSPARENT, ALICEBLUE, ANTIQUEWHITE, AQUA, AQUAMARINE, AZURE, BEIGE, 
    BISQUE, BLACK, BLANCHEDALMOND, BLUE, BLUEVIOLET, BROWN, BURLYWOOD, 
    CADETBLUE, CHARTREUSE, CHOCOLATE, CORAL, CORNFLOWERBLUE, CORNSILK, 
    CRIMSON, CYAN, DARKBLUE, DARKCYAN, DARKGOLDENROD, DARKGRAY, DARKGREEN, 
    DARKGREY, DARKKHAKI, DARKMAGENTA, DARKOLIVEGREEN, DARKORANGE, DARKORCHID, 
    DARKRED, DARKSALMON, DARKSEAGREEN, DARKSLATEBLUE, DARKSLATEGRAY, 
    DARKSLATEGREY, DARKTURQUOISE, DARKVIOLET, DEEPPINK, DEEPSKYBLUE, 
    DIMGRAY, DIMGREY, DODGERBLUE, FIREBRICK, FLORALWHITE, FORESTGREEN, 
    FUCHSIA, GAINSBORO, GHOSTWHITE, GOLD, GOLDENROD, GRAY, GREY, GREEN, 
    GREENYELLOW, HONEYDEW, HOTPINK, INDIANRED, INDIGO, IVORY, KHAKI, 
    LAVENDER, LAVENDERBLUSH, LAWNGREEN, LEMONCHIFFON, LIGHTBLUE, LIGHTCORAL, 
    LIGHTCYAN, LIGHTGOLDENRODYELLOW, LIGHTGRAY, LIGHTGREEN, LIGHTGREY, 
    LIGHTPINK, LIGHTSALMON, LIGHTSEAGREEN, LIGHTSKYBLUE, LIGHTSLATEGRAY, 
    LIGHTSLATEGREY, LIGHTSTEELBLUE, LIGHTYELLOW, LIME, LIMEGREEN, LINEN, 
    MAGENTA, MAROON, MEDIUMAQUAMARINE, MEDIUMBLUE, MEDIUMORCHID, MEDIUMPURPLE, 
    MEDIUMSEAGREEN, MEDIUMSLATEBLUE, MEDIUMSPRINGGREEN, MEDIUMTURQUOISE, 
    MEDIUMVIOLETRED, MIDNIGHTBLUE, MINTCREAM, MISTYROSE, MOCCASIN, 
    NAVAJOWHITE, NAVY, OLDLACE, OLIVE, OLIVEDRAB, ORANGE, ORANGERED, 
    ORCHID, PALEGOLDENROD, PALEGREEN, PALETURQUOISE, PALEVIOLETRED, 
    PAPAYAWHIP, PEACHPUFF, PERU, PINK, PLUM, POWDERBLUE, PURPLE, 
    REBECCAPURPLE, RED, ROSYBROWN, ROYALBLUE, SADDLEBROWN, SALMON, 
    SANDYBROWN, SEAGREEN, SEASHELL, SIENNA, SILVER, SKYBLUE, SLATEBLUE, 
    SLATEGRAY, SLATEGREY, SNOW, SPRINGGREEN, STEELBLUE, TAN, TEAL, 
    THISTLE, TOMATO, TURQUOISE, VIOLET, WHEAT, WHITE, WHITESMOKE, 
    YELLOW, YELLOWGREEN;
    
    /**
     * Get Color instance for this color constant
     */
    public Color getColorValue();
}

Color Usage Examples

import org.openqa.selenium.support.Color;
import org.openqa.selenium.support.Colors;

// Parse colors from various formats
Color color1 = Color.fromString("#ff0000");           // Hex
Color color2 = Color.fromString("rgb(255, 0, 0)");   // RGB
Color color3 = Color.fromString("rgba(255, 0, 0, 0.5)"); // RGBA
Color color4 = Color.fromString("red");               // Named color

// Create color programmatically
Color customColor = new Color(255, 128, 0, 1.0); // Orange

// Convert between formats
String hex = customColor.asHex();        // #ff8000
String rgb = customColor.asRgb();        // rgb(255, 128, 0)
String rgba = customColor.asRgba();      // rgba(255, 128, 0, 1)

// Use predefined color constants
Color blue = Colors.BLUE.getColorValue();
Color transparent = Colors.TRANSPARENT.getColorValue();

// Validate element colors
WebElement element = driver.findElement(By.id("coloredElement"));
String elementColor = element.getCssValue("background-color");
Color actualColor = Color.fromString(elementColor);
Color expectedColor = Colors.RED.getColorValue();

if (actualColor.equals(expectedColor)) {
    System.out.println("Element has correct color");
}

// Work with transparency
Color semiTransparent = new Color(255, 0, 0, 0.5);
semiTransparent.setOpacity(0.8); // Change alpha to 0.8

Thread Safety

ThreadGuard

public class ThreadGuard {
    /**
     * Wrap WebDriver with thread safety protection
     * Ensures WebDriver instance is only used from the thread that created it
     */
    public static WebDriver protect(WebDriver actualWebDriver);
}

ThreadGuard Usage

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

// Create WebDriver and protect it with ThreadGuard
WebDriver driver = new ChromeDriver();
WebDriver protectedDriver = ThreadGuard.protect(driver);

// This will work fine (same thread)
protectedDriver.get("https://example.com");

// This would throw an exception if called from different thread
// because WebDriver instances are not thread-safe
new Thread(() -> {
    try {
        protectedDriver.get("https://another-url.com"); // Will throw exception
    } catch (Exception e) {
        System.err.println("Thread safety violation: " + e.getMessage());
    }
}).start();

Advanced Locator Strategies

ByIdOrName

public class ByIdOrName extends By {
    /**
     * Locator that searches by id first, then by name if id not found
     */
    public ByIdOrName(String idOrName);
    
    public WebElement findElement(SearchContext context);
    public List<WebElement> findElements(SearchContext context);
    public String toString();
}

ByIdOrName Usage

import org.openqa.selenium.support.ByIdOrName;

// Create locator that tries id first, then name
By locator = new ByIdOrName("username");

// This will find element with id="username" or name="username"
WebElement element = driver.findElement(locator);

// Useful for forms where fields might have either id or name attributes
WebElement emailField = driver.findElement(new ByIdOrName("email"));
WebElement passwordField = driver.findElement(new ByIdOrName("password"));

Utility Classes and Helpers

Quotes Utility

public class Quotes {
    /**
     * Escape quotes in strings for safe use in XPath expressions
     * Handles both single and double quotes by creating concat() expressions
     */
    public static String escape(String toEscape);
}

Quotes Usage

import org.openqa.selenium.support.ui.Quotes;

// Escape text for XPath usage
String problematicText = "It's a \"quoted\" string";
String escaped = Quotes.escape(problematicText);

// Use in XPath expression
String xpath = "//div[text()=" + escaped + "]";
WebElement element = driver.findElement(By.xpath(xpath));

// Example with form validation message containing quotes
String errorMessage = "Please enter a valid \"email address\"";
String escapedMessage = Quotes.escape(errorMessage);
By errorLocator = By.xpath("//span[@class='error' and text()=" + escapedMessage + "]");

LoadableComponent Pattern

public abstract class LoadableComponent<T> {
    /**
     * Ensure the component is loaded, loading it if necessary
     */
    public T get();
    
    /**
     * Load the component (implement page navigation/setup)
     */
    protected abstract void load();
    
    /**
     * Check if component is loaded (implement verification logic)
     * @throws Error if component is not in expected state
     */
    protected abstract void isLoaded() throws Error;
}

SlowLoadableComponent

public abstract class SlowLoadableComponent<T> extends LoadableComponent<T> {
    /**
     * Loadable component that waits for loading with timeout
     */
    public SlowLoadableComponent(Clock clock, int timeOutInSeconds);
    
    public T get();
    
    /**
     * Check for error conditions during loading
     */
    protected void isError() throws Error;
    
    /**
     * Sleep duration between load checks
     */
    protected long sleepFor();
}

LoadableComponent Usage Example

public class HomePage extends LoadableComponent<HomePage> {
    private final WebDriver driver;
    private final String url;
    
    public HomePage(WebDriver driver, String url) {
        this.driver = driver;
        this.url = url;
    }
    
    @Override
    protected void load() {
        driver.get(url);
    }
    
    @Override
    protected void isLoaded() throws Error {
        String currentUrl = driver.getCurrentUrl();
        if (!currentUrl.contains("home")) {
            throw new Error("Not on home page. Current URL: " + currentUrl);
        }
        
        // Check that key elements are present
        try {
            driver.findElement(By.id("main-navigation"));
            driver.findElement(By.className("welcome-message"));
        } catch (NoSuchElementException e) {
            throw new Error("Home page not fully loaded: " + e.getMessage());
        }
    }
    
    // Page-specific methods
    public void clickMenuItem(String menuText) {
        WebElement menuItem = driver.findElement(
            By.xpath("//nav[@id='main-navigation']//a[text()='" + menuText + "']")
        );
        menuItem.click();
    }
}

// Usage
HomePage homePage = new HomePage(driver, "https://example.com/home");
homePage.get(); // Will load page if not already loaded and verify state
homePage.clickMenuItem("Products");

SlowLoadableComponent Example

public class DashboardPage extends SlowLoadableComponent<DashboardPage> {
    private final WebDriver driver;
    
    public DashboardPage(WebDriver driver) {
        super(Clock.systemDefaultZone(), 30); // 30 second timeout
        this.driver = driver;
    }
    
    @Override
    protected void load() {
        driver.get("/dashboard");
    }
    
    @Override
    protected void isLoaded() throws Error {
        // Check URL
        if (!driver.getCurrentUrl().contains("dashboard")) {
            throw new Error("Not on dashboard page");
        }
        
        // Check that dashboard content is loaded (AJAX content)
        try {
            WebElement dashboardContent = driver.findElement(By.id("dashboard-content"));
            if (!dashboardContent.isDisplayed()) {
                throw new Error("Dashboard content not visible");
            }
            
            // Verify data has loaded
            List<WebElement> dataItems = driver.findElements(By.className("data-item"));
            if (dataItems.isEmpty()) {
                throw new Error("Dashboard data not loaded");
            }
        } catch (NoSuchElementException e) {
            throw new Error("Dashboard elements not found");
        }
    }
    
    @Override
    protected void isError() throws Error {
        // Check for error messages
        List<WebElement> errors = driver.findElements(By.className("error-message"));
        if (!errors.isEmpty()) {
            throw new Error("Error loading dashboard: " + errors.get(0).getText());
        }
    }
    
    @Override
    protected long sleepFor() {
        return 1000; // Check every second
    }
}

Exception Classes

UnexpectedTagNameException

public class UnexpectedTagNameException extends WebDriverException {
    /**
     * Exception thrown when an element has an unexpected tag name
     */
    public UnexpectedTagNameException(String expectedTagName, String actualTagName);
}

Exception Usage

// This is typically thrown by Select class constructor
try {
    WebElement element = driver.findElement(By.id("not-a-select"));
    Select select = new Select(element); // May throw UnexpectedTagNameException
} catch (UnexpectedTagNameException e) {
    System.err.println("Element is not a SELECT tag: " + e.getMessage());
}

Install with Tessl CLI

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

docs

events.md

index.md

pagefactory.md

utilities.md

waiting.md

tile.json