CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-wd

WebDriver/Selenium 2 Node.js client for browser automation and testing

Pending
Overview
Eval results
Files

mobile-testing.mddocs/

Mobile Testing

Comprehensive mobile testing support through Appium integration with device-specific actions, app management, and mobile-optimized interactions.

Capabilities

Device Actions

Control physical device functions and hardware features.

/**
 * Shake the device
 * @param cb - Callback receiving (err)
 */
shakeDevice(cb?: callback): void;
shake(cb?: callback): void; // Alias

/**
 * Lock device for specified duration
 * @param seconds - Lock duration in seconds
 * @param cb - Callback receiving (err)
 */
lockDevice(seconds?: number, cb?: callback): void;
lock(seconds?: number, cb?: callback): void; // Alias

/**
 * Unlock the device
 * @param cb - Callback receiving (err)
 */
unlockDevice(cb?: callback): void;
unlock(cb?: callback): void; // Alias

/**
 * Check if device is locked
 * @param cb - Callback receiving (err, isLocked)
 */
isLocked(cb?: callback): boolean;

/**
 * Rotate device orientation
 * @param x - X-axis rotation
 * @param y - Y-axis rotation
 * @param z - Z-axis rotation
 * @param cb - Callback receiving (err)
 */
rotateDevice(x: number, y: number, z: number, cb?: callback): void;
rotate(x: number, y: number, z: number, cb?: callback): void; // Alias

Usage Examples:

// Shake device to trigger refresh
browser.shakeDevice(function(err) {
  console.log('Device shaken');
});

// Lock device and verify
browser.lockDevice(5, function(err) {
  browser.isLocked(function(err, locked) {
    console.log('Device is locked:', locked);
    
    setTimeout(() => {
      browser.unlockDevice();
    }, 2000);
  });
});

// Rotate device for landscape testing
browser.rotateDevice(0, 0, 90, function(err) {
  console.log('Device rotated to landscape');
});

// Promise chain device control
browser
  .lockDevice(3)
  .sleep(1000)
  .unlockDevice()
  .isLocked()
  .then(locked => console.log('Still locked:', locked));

Screen Orientation

Manage device screen orientation for responsive testing.

/**
 * Get current screen orientation
 * @param cb - Callback receiving (err, orientation)
 */
getOrientation(cb?: callback): string;

/**
 * Set screen orientation
 * @param orientation - 'PORTRAIT', 'LANDSCAPE', 'UIA_DEVICE_ORIENTATION_PORTRAIT', etc.
 * @param cb - Callback receiving (err)
 */
setOrientation(orientation: string, cb?: callback): void;

Usage Examples:

// Get current orientation
browser.getOrientation(function(err, orientation) {
  console.log('Current orientation:', orientation);
});

// Set to landscape mode
browser.setOrientation('LANDSCAPE', function(err) {
  console.log('Switched to landscape');
  
  // Test responsive layout
  browser.elementByCss('.responsive-menu', function(err, menu) {
    menu.isDisplayed(function(err, visible) {
      console.log('Landscape menu visible:', visible);
    });
  });
});

// Portrait mode testing
browser.setOrientation('PORTRAIT', function(err) {
  browser.takeScreenshot('portrait-view.png');
});

App Management

Install, launch, and manage mobile applications.

/**
 * Get current activity (Android)
 * @param cb - Callback receiving (err, activity)
 */
getCurrentDeviceActivity(cb?: callback): string;
getCurrentActivity(cb?: callback): string; // Alias

/**
 * Get current package name (Android)
 * @param cb - Callback receiving (err, package)
 */
getCurrentPackage(cb?: callback): string;

/**
 * Install app on device
 * @param appPath - Path to app file
 * @param cb - Callback receiving (err)
 */
installAppOnDevice(appPath: string, cb?: callback): void;
installApp(appPath: string, cb?: callback): void; // Alias

/**
 * Activate app by bundle ID
 * @param bundleId - App bundle identifier
 * @param cb - Callback receiving (err)
 */
activateApp(bundleId: string, cb?: callback): void;

/**
 * Remove app from device
 * @param bundleId - App bundle identifier
 * @param cb - Callback receiving (err)
 */
removeAppFromDevice(bundleId: string, cb?: callback): void;
removeApp(bundleId: string, cb?: callback): void; // Alias

/**
 * Check if app is installed
 * @param bundleId - App bundle identifier
 * @param cb - Callback receiving (err, isInstalled)
 */
isAppInstalledOnDevice(bundleId: string, cb?: callback): boolean;
isAppInstalled(bundleId: string, cb?: callback): boolean; // Alias

/**
 * Launch current app
 * @param cb - Callback receiving (err)
 */
launchApp(cb?: callback): void;

/**
 * Close current app
 * @param cb - Callback receiving (err)
 */
closeApp(cb?: callback): void;

/**
 * Reset app to clean state
 * @param cb - Callback receiving (err)
 */
resetApp(cb?: callback): void;

/**
 * Put app in background
 * @param seconds - Duration to background (0 = indefinitely)
 * @param cb - Callback receiving (err)
 */
backgroundApp(seconds: number, cb?: callback): void;

Usage Examples:

// Check current app state
browser.getCurrentActivity(function(err, activity) {
  console.log('Current activity:', activity);
});

browser.getCurrentPackage(function(err, package) {
  console.log('Current package:', package);
});

// Install and launch app
browser.installApp('/path/to/app.apk', function(err) {
  if (err) throw err;
  console.log('App installed');
  
  browser.launchApp(function(err) {
    console.log('App launched');
  });
});

// Check if app is installed
browser.isAppInstalled('com.example.myapp', function(err, installed) {
  if (!installed) {
    console.log('App not installed, installing...');
    browser.installApp('/path/to/myapp.apk');
  } else {
    browser.activateApp('com.example.myapp');
  }
});

// App lifecycle testing
browser
  .launchApp()
  .sleep(2000)
  .backgroundApp(5)  // Background for 5 seconds
  .sleep(6000)
  .activateApp('com.example.myapp')  // Bring back to foreground
  .getCurrentActivity()
  .then(activity => console.log('Resumed activity:', activity));

Keyboard Management

Handle virtual keyboard interactions on mobile devices.

/**
 * Check if keyboard is shown
 * @param cb - Callback receiving (err, isShown)
 */
isKeyboardShown(cb?: callback): boolean;

/**
 * Hide device keyboard
 * @param strategy - Hide strategy ('tap', 'press', 'swipe', etc.)
 * @param key - Key to press (for 'press' strategy)
 * @param cb - Callback receiving (err)
 */
hideDeviceKeyboard(strategy?: string, key?: string, cb?: callback): void;
hideKeyboard(strategy?: string, key?: string, cb?: callback): void; // Alias

Usage Examples:

// Check keyboard state and hide if shown
browser.isKeyboardShown(function(err, shown) {
  console.log('Keyboard visible:', shown);
  
  if (shown) {
    browser.hideKeyboard('tap', function(err) {
      console.log('Keyboard hidden');
    });
  }
});

// Different keyboard hiding strategies
browser.hideKeyboard('press', 'Done'); // Press Done button
browser.hideKeyboard('swipe');         // Swipe to hide
browser.hideKeyboard('tap');           // Tap outside

Hardware Key Events

Send hardware key events to mobile devices.

/**
 * Send device key event
 * @param keycode - Android keycode
 * @param metastate - Key meta state (optional)
 * @param cb - Callback receiving (err)
 */
deviceKeyEvent(keycode: number, metastate?: number, cb?: callback): void;
pressDeviceKey(keycode: number, metastate?: number, cb?: callback): void; // Alias

/**
 * Press keycode
 * @param keycode - Android keycode
 * @param metastate - Key meta state (optional)
 * @param cb - Callback receiving (err)
 */
pressKeycode(keycode: number, metastate?: number, cb?: callback): void;

/**
 * Long press keycode
 * @param keycode - Android keycode
 * @param metastate - Key meta state (optional)
 * @param cb - Callback receiving (err)
 */
longPressKeycode(keycode: number, metastate?: number, cb?: callback): void;

Usage Examples:

// Common Android keycodes
const KEYCODE_HOME = 3;
const KEYCODE_BACK = 4;
const KEYCODE_MENU = 82;
const KEYCODE_POWER = 26;
const KEYCODE_VOLUME_UP = 24;
const KEYCODE_VOLUME_DOWN = 25;

// Press hardware buttons
browser.pressKeycode(KEYCODE_BACK, function(err) {
  console.log('Back button pressed');
});

browser.pressKeycode(KEYCODE_HOME, function(err) {
  console.log('Home button pressed');
});

// Long press power button
browser.longPressKeycode(KEYCODE_POWER, function(err) {
  console.log('Power button long pressed');
});

// Volume control
browser.pressKeycode(KEYCODE_VOLUME_UP);
browser.pressKeycode(KEYCODE_VOLUME_DOWN);

Network and Connectivity

Control device network settings and connectivity features.

/**
 * Toggle airplane mode
 * @param cb - Callback receiving (err)
 */
toggleAirplaneModeOnDevice(cb?: callback): void;
toggleAirplaneMode(cb?: callback): void; // Alias
toggleFlightMode(cb?: callback): void;   // Alias

/**
 * Toggle WiFi
 * @param cb - Callback receiving (err)
 */
toggleWiFiOnDevice(cb?: callback): void;
toggleWiFi(cb?: callback): void; // Alias

/**
 * Toggle location services
 * @param cb - Callback receiving (err)
 */
toggleLocationServicesOnDevice(cb?: callback): void;
toggleLocationServices(cb?: callback): void; // Alias

/**
 * Toggle mobile data
 * @param cb - Callback receiving (err)
 */
toggleDataOnDevice(cb?: callback): void;
toggleData(cb?: callback): void; // Alias

/**
 * Set network connection type
 * @param type - Connection type bitmask
 * @param cb - Callback receiving (err)
 */
setNetworkConnection(type: number, cb?: callback): void;

/**
 * Get network connection type
 * @param cb - Callback receiving (err, connectionType)
 */
getNetworkConnection(cb?: callback): number;

Usage Examples:

// Network connection types
const CONNECTION_NONE = 0;
const CONNECTION_AIRPLANE_MODE = 1;
const CONNECTION_WIFI_ONLY = 2;
const CONNECTION_DATA_ONLY = 4;
const CONNECTION_ALL_NETWORK_ON = 6;

// Test offline scenarios
browser.setNetworkConnection(CONNECTION_NONE, function(err) {
  console.log('Network disabled');
  
  // Test app behavior offline
  browser.elementById('sync-button', function(err, button) {
    button.click();
    // Verify offline message appears
  });
  
  // Re-enable network
  browser.setNetworkConnection(CONNECTION_ALL_NETWORK_ON);
});

// Toggle connectivity features
browser.toggleAirplaneMode(function(err) {
  console.log('Airplane mode toggled');
});

browser.toggleWiFi(function(err) {
  console.log('WiFi toggled');
});

// Check current connection
browser.getNetworkConnection(function(err, connectionType) {
  console.log('Connection type:', connectionType);
  
  if (connectionType === CONNECTION_WIFI_ONLY) {
    console.log('Device connected via WiFi only');
  }
});

Context Switching

Switch between native and web contexts in hybrid apps.

/**
 * Get current context
 * @param cb - Callback receiving (err, context)
 */
currentContext(cb?: callback): string;

/**
 * Switch to context
 * @param contextRef - Context name
 * @param cb - Callback receiving (err)
 */
context(contextRef: string, cb?: callback): void;

/**
 * Get all available contexts
 * @param cb - Callback receiving (err, contexts)
 */
contexts(cb?: callback): string[];

Usage Examples:

// List available contexts
browser.contexts(function(err, contexts) {
  console.log('Available contexts:', contexts);
  // Example: ['NATIVE_APP', 'WEBVIEW_1', 'WEBVIEW_2']
});

// Switch to web context for hybrid app testing
browser.context('WEBVIEW_1', function(err) {
  console.log('Switched to web context');
  
  // Now can use web element selectors
  browser.elementByCss('.web-button', function(err, button) {
    button.click();
  });
});

// Switch back to native context
browser.context('NATIVE_APP', function(err) {
  console.log('Switched to native context');
  
  // Use native selectors
  browser.elementByAccessibilityId('native-button', function(err, button) {
    button.click();
  });
});

// Context switching workflow
browser
  .contexts()
  .then(contexts => {
    console.log('Contexts:', contexts);
    if (contexts.includes('WEBVIEW_1')) {
      return browser.context('WEBVIEW_1');
    }
  })
  .elementByCss('.login-form')
  .then(form => {
    // Interact with web elements
    return browser.context('NATIVE_APP');
  })
  .elementByAccessibilityId('native-menu')
  .click();

Install with Tessl CLI

npx tessl i tessl/npm-wd

docs

browser-sessions.md

configuration.md

element-location.md

index.md

javascript-execution.md

mobile-testing.md

navigation.md

touch-actions.md

user-input.md

waiting.md

window-management.md

tile.json