or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

assertions.mdconfiguration.mddevice-management.mdelement-interaction.mdelement-selection.mdindex.mdsynchronization.mdweb-view-testing.md
tile.json

element-selection.mddocs/

Element Selection

Flexible and powerful element selection system supporting multiple matcher types, combination strategies, and hierarchical relationships for precise UI element targeting.

Capabilities

Basic Matchers

Core element selection methods using common element properties.

/**
 * Select element by test ID or accessibility identifier
 * @param id - Test ID string or regular expression pattern
 * @returns Matcher for elements with matching test ID
 */
function id(id: string | RegExp): NativeMatcher;

/**
 * Select element by visible text content
 * @param text - Text string or regular expression pattern
 * @returns Matcher for elements containing matching text
 */
function text(text: string | RegExp): NativeMatcher;

/**
 * Select element by accessibility label or content description
 * @param label - Label string or regular expression pattern
 * @returns Matcher for elements with matching accessibility label
 */
function label(label: string | RegExp): NativeMatcher;

/**
 * Select element by native view type/class name
 * @param nativeViewType - Native view type (e.g., 'RCTImageView', 'Button')
 * @returns Matcher for elements of specified type
 */
function type(nativeViewType: string): NativeMatcher;

/**
 * Select element by accessibility traits (iOS only)
 * @param traits - Array of accessibility trait strings
 * @returns Matcher for elements with specified traits
 */
function traits(traits: string[]): NativeMatcher;

/**
 * Select element by value attribute
 * @param value - Value string to match
 * @returns Matcher for elements with matching value
 */
function value(value: string): NativeMatcher;

/**
 * Alias for label() - select element by accessibility label
 * @param label - Accessibility label string
 * @returns Matcher for elements with matching accessibility label
 */
function accessibilityLabel(label: string): NativeMatcher;

Usage Examples:

// Select by test ID
await element(by.id('login_button')).tap();
await element(by.id(/submit_.*_button/)).tap(); // Regex pattern

// Select by text content
await element(by.text('Sign In')).tap();
await element(by.text(/^Welcome/)).tap(); // Text starting with "Welcome"

// Select by accessibility label
await element(by.label('Close dialog')).tap();
await element(by.label(/.*menu$/)).tap(); // Label ending with "menu"

// Select by view type
await element(by.type('RCTImageView')).tap();
await element(by.type('android.widget.Button')).tap();

// Select by accessibility traits (iOS)
await element(by.traits(['button', 'selected'])).tap();

// Select by value attribute
await element(by.value('submit')).tap();

// Select by accessibility label (alias for by.label)
await element(by.accessibilityLabel('Close button')).tap();

Matcher Combination

Combine multiple matchers to create more specific element selection criteria.

interface NativeMatcher {
  /**
   * Combine with another matcher using logical AND
   * @param matcher - Additional matcher to combine
   * @returns Combined matcher requiring both conditions
   */
  and(matcher: NativeMatcher): NativeMatcher;
  
  /**
   * Find element with specified ancestor in hierarchy
   * @param parentMatcher - Matcher for ancestor element
   * @returns Matcher for elements with matching ancestor
   */
  withAncestor(parentMatcher: NativeMatcher): NativeMatcher;
  
  /**
   * Find element with specified descendant in hierarchy
   * @param childMatcher - Matcher for descendant element
   * @returns Matcher for elements with matching descendant
   */
  withDescendant(childMatcher: NativeMatcher): NativeMatcher;
}

Usage Examples:

// Combine multiple conditions
await element(
  by.text('Submit').and(by.type('Button'))
).tap();

// Find button inside specific container
await element(
  by.id('confirm_button').withAncestor(by.id('dialog_container'))
).tap();

// Find container that has specific child element
await element(
  by.type('ScrollView').withDescendant(by.text('Load More'))
).scroll(200, 'down');

// Complex hierarchy selection
await element(
  by.id('product_card')
    .withDescendant(by.text('iPhone'))
    .withAncestor(by.id('products_list'))
).tap();

Web Element Selection

Specialized matchers for elements within web views using DOM-based selection.

/**
 * Web element matchers for DOM-based selection
 */
interface ByWebFacade {
  /**
   * Select by DOM element ID
   * @param id - DOM element ID
   */
  id(id: string): WebMatcher;
  
  /**
   * Select by CSS class name
   * @param className - CSS class name
   */
  className(className: string): WebMatcher;
  
  /**
   * Select by CSS selector
   * @param cssSelector - Valid CSS selector string
   */
  cssSelector(cssSelector: string): WebMatcher;
  
  /**
   * Select by name attribute
   * @param name - Element name attribute value
   */
  name(name: string): WebMatcher;
  
  /**
   * Select by XPath expression
   * @param xpath - XPath selector string
   */
  xpath(xpath: string): WebMatcher;
  
  /**
   * Select link by href attribute
   * @param linkText - Complete href value
   */
  href(linkText: string): WebMatcher;
  
  /**
   * Select link by partial href match
   * @param linkTextFragment - Partial href value
   */
  hrefContains(linkTextFragment: string): WebMatcher;
  
  /**
   * Select by HTML tag name
   * @param tagName - HTML tag name
   */
  tag(tagName: string): WebMatcher;
  
  /**
   * Select by element value (iOS only)
   * @param value - Element value
   */
  value(value: string): WebMatcher;
  
  /**
   * Select by accessibility label (iOS only)
   * @param text - Accessibility label text
   */
  label(text: string): MaybeSecuredWebMatcher;
  
  /**
   * Select secured element by type (iOS only)
   * @param type - Element type for secured web elements
   */
  type(type: string): SecuredWebMatcher;
}

// Access via by.web
const webMatcher = by.web.id('submit_form');

Usage Examples:

// Select web elements by different attributes
await element(web().element(by.web.id('username'))).typeText('user@example.com');
await element(web().element(by.web.className('submit-btn'))).tap();
await element(web().element(by.web.cssSelector('#form .required'))).tap();
await element(web().element(by.web.name('email_field'))).typeText('test@test.com');
await element(web().element(by.web.xpath('//button[@type="submit"]'))).tap();

// Link selection
await element(web().element(by.web.href('https://example.com'))).tap();
await element(web().element(by.web.hrefContains('github.com'))).tap();

// Tag-based selection
await element(web().element(by.web.tag('input'))).typeText('search query');

// iOS secured web elements
await element(web().element(by.web.label('Login').asSecured())).tap();
await element(web().element(by.web.type('textField').asSecured())).typeText('password');

System-Level Selection

Matchers for system-level UI elements outside the app (permissions dialogs, system alerts, etc.).

/**
 * System-level element matchers for OS dialogs and alerts
 */
interface BySystemFacade {
  /**
   * Select system element by label text
   * @param text - System element label
   */
  label(text: string): SystemMatcher;
  
  /**
   * Select system element by type
   * @param type - System element type
   */
  type(type: string): SystemMatcher;
}

// Access via by.system
const systemMatcher = by.system.label('Allow');

Usage Examples:

// Handle permission dialogs
await element(system.element(by.system.label('Allow'))).tap();
await element(system.element(by.system.label('Don\'t Allow'))).tap();

// Interact with system alerts
await element(system.element(by.system.type('button'))).atIndex(1).tap();

Selection Best Practices

Recommendations for reliable element selection:

Preference Order

  1. Test IDs (Recommended): Most reliable and performance-optimized
// Best: Explicit test IDs
await element(by.id('login_submit_button')).tap();
  1. Accessibility Labels: Good for user-facing elements
// Good: Semantic accessibility labels
await element(by.label('Sign in to your account')).tap();
  1. Text Content: Suitable for static text, but fragile for internationalization
// Caution: May break with text changes or localization
await element(by.text('Submit')).tap();
  1. View Types: Use sparingly, better combined with other matchers
// Less reliable: Too generic alone
await element(by.type('Button').and(by.label('Submit'))).tap();

Hierarchical Selection

Use ancestor/descendant relationships for complex UI structures:

// Select specific button within a form
await element(
  by.id('submit_button')
    .withAncestor(by.id('registration_form'))
).tap();

// Select list item containing specific text
await element(
  by.type('ListItem')
    .withDescendant(by.text('John Doe'))
).tap();

Regular Expression Patterns

Use regex patterns for flexible matching:

// Match elements with dynamic IDs
await element(by.id(/^product_\d+_buy_button$/)).tap();

// Match text with variations
await element(by.text(/^Welcome,?\s+\w+/)).tap(); // "Welcome John" or "Welcome, Jane"

// Match partial labels
await element(by.label(/.*Settings$/)).tap(); // Any label ending with "Settings"

Error Prevention

Handle common selection issues:

// Multiple matches - use index or more specific matcher
try {
  await element(by.type('Button')).tap();
} catch (error) {
  // More specific selection
  await element(by.type('Button').and(by.label('Submit'))).tap();
  // Or select by index
  await element(by.type('Button')).atIndex(0).tap();
}

// Element not found - wait or verify matcher
await waitFor(element(by.id('dynamic_element')))
  .toExist()
  .withTimeout(5000);

// Case sensitivity issues
await element(by.text('SUBMIT', { caseSensitive: false })).tap(); // If supported
// Or use regex with case-insensitive flag
await element(by.text(/submit/i)).tap();

Types

interface NativeMatcher {
  and(matcher: NativeMatcher): NativeMatcher;
  withAncestor(parentMatcher: NativeMatcher): NativeMatcher;
  withDescendant(childMatcher: NativeMatcher): NativeMatcher;
}

interface WebMatcher {
  __web__: any; // Internal marker
}

interface SecuredWebMatcher {
  __web__: any; // Internal marker
}

interface MaybeSecuredWebMatcher {
  __web__: any; // Internal marker
}

interface SystemMatcher {
  __system__: any; // Internal marker
}