or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

advanced-interactions.mdbidi-protocol.mdbrowser-automation.mdbrowser-options.mddriver-management.mdelement-location.mderror-handling.mdindex.mdwait-conditions.md
tile.json

element-location.mddocs/

Element Location

Comprehensive element location strategies for finding elements on web pages using various locator types including CSS selectors, XPath, and relative positioning.

Capabilities

By Class

The By class provides static methods for creating element locators using different strategies.

/**
 * Element location strategies
 */
class By {
  /** Locate element by ID attribute */
  static id(id: string): By;
  
  /** Locate element by CSS selector */
  static css(selector: string): By;
  
  /** Locate element by XPath expression */
  static xpath(xpath: string): By;
  
  /** Locate element by name attribute */
  static name(name: string): By;
  
  /** Locate element by CSS class name */
  static className(name: string): By;
  
  /** Locate link by exact text content */
  static linkText(text: string): By;
  
  /** Locate link by partial text content */
  static partialLinkText(text: string): By;
  
  /** Locate element by tag name */
  static tagName(name: string): By;
  
  /** Locate element using JavaScript function */
  static js(script: string | Function, ...args: any[]): By;
}

Usage Examples:

const { By } = require('selenium-webdriver');

// Basic locators
let elementById = await driver.findElement(By.id('submit-button'));
let elementByClass = await driver.findElement(By.className('btn-primary'));
let elementByName = await driver.findElement(By.name('username'));
let elementByTag = await driver.findElement(By.tagName('input'));

// CSS selectors
let elementByCss = await driver.findElement(By.css('.form-control[type="email"]'));
let nestedElement = await driver.findElement(By.css('#content .article > h2'));

// XPath
let elementByXPath = await driver.findElement(By.xpath('//input[@type="password"]'));
let complexXPath = await driver.findElement(By.xpath('//div[contains(@class, "result")][2]//a'));

// Link text
let linkByText = await driver.findElement(By.linkText('Click Here'));
let linkByPartialText = await driver.findElement(By.partialLinkText('Download'));

// JavaScript locator
let elementByJs = await driver.findElement(By.js('return document.querySelector(".dynamic-content")'));

RelativeBy Class

Modern relative locator strategies for finding elements based on their spatial relationship to other elements.

/**
 * Relative element location based on spatial relationships
 */
class RelativeBy extends By {
  /** Create relative locator with base tag name */
  static withTagName(tagName: string): RelativeBy;
  
  /** Element above the reference element */
  above(element: WebElement | By): RelativeBy;
  
  /** Element below the reference element */
  below(element: WebElement | By): RelativeBy;
  
  /** Element to the left of the reference element */
  toLeftOf(element: WebElement | By): RelativeBy;
  
  /** Element to the right of the reference element */
  toRightOf(element: WebElement | By): RelativeBy;
  
  /** Element near the reference element (within 50 pixels) */
  near(element: WebElement | By): RelativeBy;
}

/** Create relative locator starting with tag name */
function locateWith(tagName: string): RelativeBy;

/** Alias for locateWith */
function withTagName(tagName: string): RelativeBy;

Usage Examples:

const { By, locateWith } = require('selenium-webdriver');

// Find elements relative to other elements
let passwordField = await driver.findElement(By.id('password'));

// Find submit button below password field
let submitButton = await driver.findElement(
  locateWith(By.tagName('button')).below(passwordField)
);

// Find label to the left of an input
let inputField = await driver.findElement(By.name('email'));
let label = await driver.findElement(
  locateWith(By.tagName('label')).toLeftOf(inputField)
);

// Chain relative locators
let cancelButton = await driver.findElement(
  locateWith(By.tagName('button'))
    .below(By.id('form'))
    .toLeftOf(By.id('submit'))
);

// Find element near another element
let helpIcon = await driver.findElement(
  locateWith(By.tagName('img')).near(By.id('username'))
);

Locator Validation

Utility functions for validating and working with locators.

/**
 * Check if an object is a valid locator
 * @param locator - Object to validate
 * @returns True if valid locator
 */
function isValidLocator(locator: any): boolean;

/**
 * Validate and return a checked locator
 * @param locator - Locator to validate
 * @returns Validated locator
 * @throws Error if invalid locator
 */
function checkedLocator(locator: By): By;

Usage Examples:

const { By, isValidLocator, checkedLocator } = require('selenium-webdriver');

// Validate locators
let locator = By.id('submit');
if (isValidLocator(locator)) {
  let element = await driver.findElement(locator);
}

// Use checked locator for safety
try {
  let validatedLocator = checkedLocator(By.css('.invalid-css['));
  let element = await driver.findElement(validatedLocator);
} catch (error) {
  console.log('Invalid locator:', error.message);
}

Element Finding Methods

WebDriver methods for finding single or multiple elements using locators.

/**
 * WebDriver element finding methods
 */
interface WebDriver {
  /** Find single element */
  findElement(locator: By): Promise<WebElement>;
  
  /** Find multiple elements */
  findElements(locator: By): Promise<WebElement[]>;
}

/**
 * WebElement child element finding methods
 */
interface WebElement {
  /** Find child element */
  findElement(locator: By): Promise<WebElement>;
  
  /** Find child elements */
  findElements(locator: By): Promise<WebElement[]>;
}

Usage Examples:

// Find single element (throws if not found)
let singleElement = await driver.findElement(By.id('unique-id'));

// Find multiple elements (returns empty array if none found)
let multipleElements = await driver.findElements(By.className('item'));

// Check if element exists
let elements = await driver.findElements(By.id('optional-element'));
if (elements.length > 0) {
  // Element exists
  await elements[0].click();
}

// Find child elements
let parentElement = await driver.findElement(By.id('parent'));
let childElements = await parentElement.findElements(By.tagName('li'));

// Nested element finding
let form = await driver.findElement(By.id('login-form'));
let usernameField = await form.findElement(By.name('username'));
let submitButton = await form.findElement(By.css('button[type="submit"]'));

Advanced Locator Patterns

Complex locator strategies for challenging element selection scenarios.

CSS Selector Patterns:

// Attribute selectors
By.css('input[type="text"]')           // Exact attribute match
By.css('input[placeholder*="search"]') // Attribute contains
By.css('input[id^="field-"]')          // Attribute starts with
By.css('input[class$="-required"]')    // Attribute ends with

// Pseudo-selectors
By.css('tr:nth-child(2)')              // Nth child
By.css('input:not([disabled])')        // Not selector
By.css('option:checked')               // Checked elements
By.css('input:first-of-type')          // First of type

// Combinators
By.css('form > input')                 // Direct child
By.css('div + p')                      // Adjacent sibling
By.css('h2 ~ p')                       // General sibling
By.css('article p')                    // Descendant

XPath Patterns:

// Axis navigation
By.xpath('//input/following-sibling::button')     // Following sibling
By.xpath('//td/preceding-sibling::td')            // Preceding sibling
By.xpath('//div/parent::section')                 // Parent element
By.xpath('//li/ancestor::ul')                     // Ancestor element

// Text-based selection
By.xpath('//button[text()="Submit"]')             // Exact text
By.xpath('//a[contains(text(), "Download")]')     // Contains text
By.xpath('//span[normalize-space()="  Text  "]')  // Normalized text
By.xpath('//label[starts-with(text(), "Name")]')  // Starts with text

// Position-based selection
By.xpath('(//input[@type="radio"])[2]')           // Second element
By.xpath('//tr[position()>1]')                    // All but first
By.xpath('//option[last()]')                      // Last element
By.xpath('//li[last()-1]')                        // Second to last

// Complex conditions
By.xpath('//div[@class and @id]')                 // Has both attributes
By.xpath('//input[@type="text" or @type="email"]') // Multiple conditions
By.xpath('//a[@href and normalize-space()]')      // Has href and text

Usage Examples:

// Dynamic element selection
let currentDate = new Date().toISOString().split('T')[0];
let dateSpecificElement = await driver.findElement(
  By.css(`[data-date="${currentDate}"]`)
);

// Table navigation
let headerCell = await driver.findElement(By.xpath('//th[text()="Price"]'));
let columnIndex = await headerCell.getAttribute('data-column');
let priceValues = await driver.findElements(
  By.xpath(`//td[position()=${columnIndex}]`)
);

// Form validation
let requiredFields = await driver.findElements(
  By.css('input[required], select[required], textarea[required]')
);

let invalidFields = await driver.findElements(
  By.css('input:invalid, select:invalid, textarea:invalid')
);