Type-safe element selection, interaction, and assertion system with automatic synchronization and comprehensive action support for mobile UI testing.
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);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 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();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 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);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');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);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');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');
}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>;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();interface Point2D {
x: number;
y: number;
}
interface ElementFrame {
x: number;
y: number;
width: number;
height: number;
}
interface NativeElement {
// All the methods documented above
}