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-interaction.mddocs/

Element Interaction

Type-safe element selection, interaction, and assertion system with automatic synchronization and comprehensive action support for mobile UI testing.

Capabilities

Element Selection

Create element references using matcher-based selection with optional indexing for multiple matches.

/**
 * Create element reference from matcher
 * @param matcher - Element selector (by.id, by.text, etc.)
 * @returns Indexable element that can be refined with atIndex()
 */
function element(matcher: NativeMatcher): IndexableNativeElement;

interface IndexableNativeElement extends NativeElement {
  /**
   * Select specific element when multiple matches exist
   * @param index - Zero-based index of element to select
   * @returns Specific element instance
   */
  atIndex(index: number): NativeElement;
}

Usage Examples:

// Select single element
const loginButton = element(by.id('login_button'));

// Select from multiple matches
const secondProduct = element(by.type('ProductCard')).atIndex(1);

Basic Interactions

Core touch interactions for element manipulation.

/**
 * Tap element at center or specific point
 * @param point - Optional coordinates within element (defaults to center)
 */
async function tap(point?: Point2D): Promise<void>;

/**
 * Long press element with optional duration and point
 * @param point - Optional coordinates within element
 * @param duration - Optional press duration in milliseconds
 */
async function longPress(point?: Point2D, duration?: number): Promise<void>;

/**
 * Perform multiple taps on element
 * @param times - Number of taps to perform
 */
async function multiTap(times: number): Promise<void>;

/**
 * Long press and drag to target element (iOS only)
 * @param duration - Long press duration
 * @param normalizedPositionX - X position within source element (0-1)
 * @param normalizedPositionY - Y position within source element (0-1)
 * @param targetElement - Target element to drag to
 * @param normalizedTargetPositionX - X position within target element (0-1)
 * @param normalizedTargetPositionY - Y position within target element (0-1)
 * @param speed - Drag speed
 * @param holdDuration - Duration to hold at target
 */
async function longPressAndDrag(
  duration: number,
  normalizedPositionX: number,
  normalizedPositionY: number,
  targetElement: NativeElement,
  normalizedTargetPositionX: number,
  normalizedTargetPositionY: number,
  speed: Speed,
  holdDuration: number
): Promise<void>;

Usage Examples:

// Basic tap
await element(by.id('submit_button')).tap();

// Tap at specific point
await element(by.id('canvas')).tap({ x: 50, y: 75 });

// Long press with custom duration
await element(by.id('context_menu')).longPress({ x: 10, y: 10 }, 2000);

// Double tap
await element(by.id('photo')).multiTap(2);

Text Input

Text entry and manipulation for input fields and text areas.

/**
 * Type text using device keyboard
 * @param text - Text to type
 */
async function typeText(text: string): Promise<void>;

/**
 * Replace all text in field with new text
 * @param text - Replacement text
 */
async function replaceText(text: string): Promise<void>;

/**
 * Clear all text from field
 */
async function clearText(): Promise<void>;

/**
 * Tap backspace key on device keyboard
 */
async function tapBackspaceKey(): Promise<void>;

/**
 * Tap return/enter key on device keyboard
 */
async function tapReturnKey(): Promise<void>;

Usage Examples:

// Type in text field
await element(by.id('email_input')).typeText('user@example.com');

// Replace existing text
await element(by.id('name_input')).replaceText('New Name');

// Clear field
await element(by.id('search_input')).clearText();

// Use keyboard keys
await element(by.id('password_input')).tapBackspaceKey();
await element(by.id('message_input')).tapReturnKey();

Scrolling and Navigation

Scroll operations for lists, scroll views, and navigation.

/**
 * Scroll by pixel amount in specified direction
 * @param pixels - Distance to scroll in pixels
 * @param direction - Scroll direction
 * @param startPositionX - Starting X position (0-1 percentage, NaN for auto)
 * @param startPositionY - Starting Y position (0-1 percentage, NaN for auto)
 */
async function scroll(
  pixels: number,
  direction: Direction,
  startPositionX?: number,
  startPositionY?: number
): Promise<void>;

/**
 * Scroll to edge of scrollable content
 * @param edge - Target edge
 * @param startPositionX - Starting X position (0-1 percentage, NaN for auto)
 * @param startPositionY - Starting Y position (0-1 percentage, NaN for auto)
 */
async function scrollTo(
  edge: Direction,
  startPositionX?: number,
  startPositionY?: number
): Promise<void>;

/**
 * Scroll to specific index in list/collection
 * @param index - Target index
 */
async function scrollToIndex(index: number): Promise<void>;

type Direction = 'left' | 'right' | 'top' | 'bottom' | 'up' | 'down';

Usage Examples:

// Scroll down by 200 pixels
await element(by.id('scroll_view')).scroll(200, 'down');

// Scroll to bottom
await element(by.id('product_list')).scrollTo('bottom');

// Scroll to specific item
await element(by.id('message_list')).scrollToIndex(10);

// Scroll with custom start position
await element(by.id('horizontal_list')).scroll(100, 'right', 0.5, 0.8);

Swipe Gestures

Swipe interactions with configurable speed and distance.

/**
 * Swipe in specified direction
 * @param direction - Swipe direction
 * @param speed - Swipe speed (defaults to 'fast')
 * @param percentage - Screen percentage to swipe (0-1, defaults based on direction)
 * @param normalizedStartingPointX - Starting X position (0-1)
 * @param normalizedStartingPointY - Starting Y position (0-1)
 */
async function swipe(
  direction: Direction,
  speed?: Speed,
  percentage?: number,
  normalizedStartingPointX?: number,
  normalizedStartingPointY?: number
): Promise<void>;

type Speed = 'fast' | 'slow';

Usage Examples:

// Basic swipe
await element(by.id('card')).swipe('left');

// Slow swipe with custom distance
await element(by.id('gallery')).swipe('right', 'slow', 0.8);

// Swipe from specific starting point
await element(by.id('drawer')).swipe('up', 'fast', 0.5, 0.1, 0.9);

Specialized Input Controls

Interactions for specialized UI controls like sliders, pickers, and date selectors.

/**
 * Adjust slider to specific position
 * @param newPosition - Target position (0-1)
 */
async function adjustSliderToPosition(newPosition: number): Promise<void>;

/**
 * Set picker column to specific value (iOS only)
 * @param column - Column index (starts from 0)
 * @param value - Target value string
 */
async function setColumnToValue(column: number, value: string): Promise<void>;

/**
 * Set date picker to specific date
 * @param dateString - Date in specified format
 * @param dateFormat - Format specification ('ISO8601' or custom format)
 */
async function setDatePickerDate(dateString: string, dateFormat: string): Promise<void>;

Usage Examples:

// Set slider to 75%
await element(by.id('volume_slider')).adjustSliderToPosition(0.75);

// Set picker values
await element(by.type('UIPickerView')).setColumnToValue(0, 'January');
await element(by.type('UIPickerView')).setColumnToValue(1, '15');

// Set date picker
await element(by.id('date_picker')).setDatePickerDate('2024-01-15T00:00:00Z', 'ISO8601');
await element(by.id('date_picker')).setDatePickerDate('2024/01/15', 'yyyy/MM/dd');

Pinch and Zoom (iOS Only)

Multi-touch pinch gestures for zoom operations.

/**
 * Pinch with specified scale factor
 * @param scale - Scale factor (>1 for zoom in, <1 for zoom out)
 * @param speed - Pinch speed (defaults to 'fast')
 * @param angle - Rotation angle in radians (defaults to 0)
 */
async function pinch(scale: number, speed?: Speed, angle?: number): Promise<void>;

/**
 * @deprecated Use pinch() instead
 * Pinch with direction, speed, and angle
 */
async function pinchWithAngle(direction: PinchDirection, speed: Speed, angle: number): Promise<void>;

type PinchDirection = 'outward' | 'inward';

Usage Examples:

// Zoom in 2x
await element(by.id('map_view')).pinch(2.0);

// Zoom out to 50%
await element(by.id('image_view')).pinch(0.5);

// Pinch with rotation
await element(by.id('photo')).pinch(1.5, 'slow', Math.PI / 4);

Accessibility Actions

Trigger accessibility actions defined by the app.

/**
 * Perform accessibility action on element
 * @param actionName - Name of accessibility action to trigger
 */
async function performAccessibilityAction(actionName: string): Promise<void>;

Usage Example:

// Trigger custom accessibility action
await element(by.id('custom_control')).performAccessibilityAction('activate');

Element Inspection

Retrieve element attributes and properties for validation and debugging.

/**
 * Get element attributes and properties
 * @returns Element attributes object or array for multiple elements
 */
async function getAttributes(): Promise<
  IosElementAttributes | 
  AndroidElementAttributes | 
  { elements: IosElementAttributes[] } | 
  { elements: AndroidElementAttributes[] }
>;

/**
 * Take screenshot of specific element
 * @param name - Name for screenshot artifact
 * @returns Temporary path to screenshot file
 */
async function takeScreenshot(name: string): Promise<string>;

// Platform-specific attribute interfaces
interface ElementAttributes {
  enabled: boolean;
  identifier: string;
  visible: boolean;
  text?: string;
  label?: string;
  placeholder?: string;
  value?: unknown;
}

interface IosElementAttributes extends ElementAttributes {
  activationPoint: Point2D;
  hittable: boolean;
  frame: ElementFrame;
  // ... additional iOS-specific properties
}

interface AndroidElementAttributes extends ElementAttributes {
  visibility: 'visible' | 'invisible' | 'gone';
  width: number;
  height: number;
  focused: boolean;
  // ... additional Android-specific properties
}

Usage Examples:

// Get element attributes
const attributes = await element(by.id('status_label')).getAttributes();
console.log('Element is visible:', attributes.visible);
console.log('Element text:', attributes.text);

// Take element screenshot
const imagePath = await element(by.id('chart')).takeScreenshot('chart_state');

// Handle multiple elements
const multipleAttributes = await element(by.type('ListItem')).getAttributes();
if ('elements' in multipleAttributes) {
  console.log('Found', multipleAttributes.elements.length, 'list items');
}

Advanced Interactions

Coordinate-Based Actions

Direct coordinate manipulation for complex gestures.

/**
 * @deprecated Use tap() with point parameter instead
 * Tap at specific point within element
 */
async function tapAtPoint(point: Point2D): Promise<void>;

Error Handling

Common error scenarios and handling patterns:

// Element not found
try {
  await element(by.id('missing_element')).tap();
} catch (error) {
  console.log('Element not found:', error.message);
}

// Multiple elements without index
try {
  await element(by.type('Button')).tap(); // May fail if multiple buttons exist
} catch (error) {
  // Use atIndex() to specify which button
  await element(by.type('Button')).atIndex(0).tap();
}

// Element not visible
await waitFor(element(by.id('delayed_element')))
  .toBeVisible()
  .withTimeout(5000);
await element(by.id('delayed_element')).tap();

Types

interface Point2D {
  x: number;
  y: number;
}

interface ElementFrame {
  x: number;
  y: number;
  width: number;
  height: number;
}

interface NativeElement {
  // All the methods documented above
}