Next-gen browser and mobile automation test framework for Node.js
—
Complete mobile automation support through Appium integration, including touch gestures, app management, context switching, and mobile-specific interactions.
Mobile-specific touch interactions and gestures.
/**
* Perform touch action sequences on mobile devices
* @param action - Touch action configuration or sequence
* @returns Promise that resolves when touch action is complete
*/
touchAction(action: object): Promise<void>;
/**
* Perform swipe gesture across the screen
* @param xStart - Starting X coordinate
* @param yStart - Starting Y coordinate
* @param xEnd - Ending X coordinate
* @param yEnd - Ending Y coordinate
* @returns Promise that resolves when swipe is complete
*/
swipe(xStart: number, yStart: number, xEnd: number, yEnd: number): Promise<void>;
/**
* Tap on specific coordinates or element
* @param x - X coordinate or element reference
* @param y - Y coordinate (if x is coordinate)
* @returns Promise that resolves when tap is complete
*/
tap(x: number | WebdriverIO.Element, y?: number): Promise<void>;Usage Examples:
// Simple tap gesture
await browser.touchAction('tap');
// Complex touch sequence
await browser.touchAction([
{ action: 'press', x: 100, y: 200 },
{ action: 'wait', duration: 500 },
{ action: 'moveTo', x: 300, y: 200 },
{ action: 'release' }
]);
// Swipe gestures
await browser.swipe(100, 500, 100, 100); // Swipe up
await browser.swipe(300, 200, 100, 200); // Swipe left
// Tap on coordinates
await browser.tap(150, 300);
// Tap on element
const button = await browser.$('~mobile-button');
await browser.tap(button);Touch gestures specific to mobile elements.
/**
* Perform touch action on a specific element
* @param action - Touch action configuration
* @returns Promise that resolves when touch action is complete
*/
element.touchAction(action: object): Promise<void>;
/**
* Long press on an element
* @param duration - Duration of the long press in milliseconds
* @returns Promise that resolves when long press is complete
*/
element.longPress(duration?: number): Promise<void>;
/**
* Drag and drop for mobile elements
* @param target - Target element or coordinates
* @returns Promise that resolves when drag and drop is complete
*/
element.dragAndDrop(target: WebdriverIO.Element | {x: number, y: number}): Promise<void>;
/**
* Tap on a mobile element
* @returns Promise that resolves when tap is complete
*/
element.tap(): Promise<void>;
/**
* Pinch gesture on an element (zoom out)
* @param scale - Scale factor for pinch
* @returns Promise that resolves when pinch is complete
*/
element.pinch(scale: number): Promise<void>;
/**
* Zoom gesture on an element (zoom in)
* @param scale - Scale factor for zoom
* @returns Promise that resolves when zoom is complete
*/
element.zoom(scale: number): Promise<void>;Usage Examples:
const image = await browser.$('~image-view');
// Long press on element
await image.longPress(1000);
// Pinch to zoom out
await image.pinch(0.5);
// Zoom in
await image.zoom(2.0);
// Tap element
await image.tap();
// Complex touch action on element
await image.touchAction([
{ action: 'press' },
{ action: 'wait', duration: 100 },
{ action: 'moveTo', x: 50, y: 0 },
{ action: 'release' }
]);Manage mobile app contexts and switch between native and web views.
/**
* Get the current context (NATIVE_APP or WEBVIEW)
* @returns Promise resolving to the current context name
*/
getContext(): Promise<string>;
/**
* Get all available contexts
* @returns Promise resolving to array of available context names
*/
getContexts(): Promise<string[]>;
/**
* Switch to a specific context
* @param context - Context name to switch to (e.g., 'NATIVE_APP', 'WEBVIEW_1')
* @returns Promise that resolves when context switch is complete
*/
switchContext(context: string): Promise<void>;Usage Examples:
// Get current context
const currentContext = await browser.getContext();
console.log('Current context:', currentContext);
// Get all available contexts
const contexts = await browser.getContexts();
console.log('Available contexts:', contexts);
// Output: ['NATIVE_APP', 'WEBVIEW_chrome']
// Switch to native app context
await browser.switchContext('NATIVE_APP');
// Switch to web view context
await browser.switchContext('WEBVIEW_chrome');
// Switch back to native
await browser.switchContext('NATIVE_APP');Control mobile application lifecycle and state.
/**
* Relaunch the currently active application
* @returns Promise that resolves when app is relaunched
*/
relaunchActiveApp(): Promise<void>;
/**
* Handle deep links and URL schemes
* @param url - Deep link URL to open
* @returns Promise that resolves when deep link is handled
*/
deepLink(url: string): Promise<void>;
/**
* Get current app state
* @returns Promise resolving to app state information
*/
getAppState(): Promise<object>;
/**
* Launch a specific app by bundle ID or package name
* @param bundleId - App bundle identifier
* @returns Promise that resolves when app is launched
*/
launchApp(bundleId: string): Promise<void>;
/**
* Close/terminate a specific app
* @param bundleId - App bundle identifier
* @returns Promise that resolves when app is terminated
*/
terminateApp(bundleId: string): Promise<void>;Usage Examples:
// Relaunch current app
await browser.relaunchActiveApp();
// Handle deep links
await browser.deepLink('myapp://profile/123');
await browser.deepLink('https://example.com/app-link');
// App lifecycle management
await browser.launchApp('com.example.myapp');
await browser.terminateApp('com.example.myapp');
// Get app state
const appState = await browser.getAppState();
console.log('App state:', appState);Interact with device-specific features and hardware.
/**
* Simulate device orientation change
* @param orientation - Device orientation ('PORTRAIT' or 'LANDSCAPE')
* @returns Promise that resolves when orientation change is complete
*/
setOrientation(orientation: 'PORTRAIT' | 'LANDSCAPE'): Promise<void>;
/**
* Get current device orientation
* @returns Promise resolving to current orientation
*/
getOrientation(): Promise<string>;
/**
* Simulate device shake gesture
* @returns Promise that resolves when shake is complete
*/
shake(): Promise<void>;
/**
* Lock device orientation
* @param orientation - Orientation to lock to
* @returns Promise that resolves when orientation is locked
*/
lock(orientation: string): Promise<void>;
/**
* Unlock device orientation
* @returns Promise that resolves when orientation is unlocked
*/
unlock(): Promise<void>;Usage Examples:
// Change device orientation
await browser.setOrientation('LANDSCAPE');
await browser.setOrientation('PORTRAIT');
// Check current orientation
const orientation = await browser.getOrientation();
console.log('Current orientation:', orientation);
// Device gestures
await browser.shake();
// Lock/unlock orientation
await browser.lock('PORTRAIT');
await browser.unlock();Mobile-specific element interaction patterns.
/**
* Scroll to an element in a scrollable view
* @param element - Element to scroll to
* @param options - Scroll options
* @returns Promise that resolves when scrolling is complete
*/
scrollToElement(element: WebdriverIO.Element, options?: object): Promise<void>;
/**
* Find element by accessibility ID (mobile-specific selector)
* @param accessibilityId - Accessibility identifier
* @returns Promise resolving to the element
*/
$accessibility(accessibilityId: string): Promise<WebdriverIO.Element>;
/**
* Find elements by accessibility ID
* @param accessibilityId - Accessibility identifier
* @returns Promise resolving to array of elements
*/
$$accessibility(accessibilityId: string): Promise<WebdriverIO.Element[]>;Usage Examples:
// Mobile-specific selectors
const button = await browser.$accessibility('submit-button');
const allButtons = await browser.$$accessibility('button');
// iOS-specific selectors
const iosElement = await browser.$('-ios predicate string:name == "Login"');
const iosElements = await browser.$$('-ios class chain:**/XCUIElementTypeButton[`name == "Login"`]');
// Android-specific selectors
const androidElement = await browser.$('android=new UiSelector().text("Login")');
const androidElements = await browser.$$('android=new UiSelector().className("android.widget.Button")');
// Scroll to element
const targetElement = await browser.$accessibility('target-element');
await browser.scrollToElement(targetElement, {
direction: 'down',
maxSwipes: 5
});Features specific to iOS and Android platforms.
// iOS-specific capabilities
/**
* iOS-specific element selection using predicate strings
* @param predicate - iOS predicate string
* @returns Promise resolving to matching element
*/
$ios(predicate: string): Promise<WebdriverIO.Element>;
// Android-specific capabilities
/**
* Android-specific element selection using UiSelector
* @param selector - Android UiSelector string
* @returns Promise resolving to matching element
*/
$android(selector: string): Promise<WebdriverIO.Element>;
/**
* Android back button press
* @returns Promise that resolves when back button is pressed
*/
back(): Promise<void>;
/**
* Android home button press
* @returns Promise that resolves when home button is pressed
*/
home(): Promise<void>;
/**
* Android menu button press
* @returns Promise that resolves when menu button is pressed
*/
menu(): Promise<void>;Usage Examples:
// iOS predicate strings
const iOSButton = await browser.$ios('name == "Submit" AND visible == 1');
const iOSInput = await browser.$ios('type == "XCUIElementTypeTextField"');
// Android UiSelector
const androidButton = await browser.$android('new UiSelector().text("Submit")');
const androidInput = await browser.$android('new UiSelector().className("android.widget.EditText")');
// Android hardware buttons
await browser.back(); // Press back button
await browser.home(); // Press home button
await browser.menu(); // Press menu buttonMobile-specific waiting and synchronization patterns.
/**
* Wait for element to be stable (not moving/animating)
* @param options - Wait options including timeout
* @returns Promise that resolves when element is stable
*/
element.waitForStable(options?: object): Promise<boolean>;
/**
* Wait for app to reach a specific state
* @param state - Expected app state
* @param timeout - Maximum wait time
* @returns Promise that resolves when state is reached
*/
waitForAppState(state: string, timeout?: number): Promise<void>;Usage Examples:
// Wait for element to stop animating
const animatedElement = await browser.$accessibility('animated-view');
await animatedElement.waitForStable({ timeout: 5000 });
// Wait for app state changes
await browser.waitForAppState('RUNNING_IN_FOREGROUND', 10000);
// Mobile-specific wait patterns
await browser.waitUntil(async () => {
const contexts = await browser.getContexts();
return contexts.includes('WEBVIEW_chrome');
}, {
timeout: 15000,
timeoutMsg: 'WebView context never became available'
});Install with Tessl CLI
npx tessl i tessl/npm-webdriverio