CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-detox

Gray box end-to-end testing and automation framework for mobile applications with advanced synchronization capabilities

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

device-management.mddocs/

Device Management

Comprehensive device control including app lifecycle management, hardware simulation, permissions, and platform-specific features for both iOS and Android testing environments.

Capabilities

Device Properties

Core device identification and metadata properties.

/**
 * Device properties available on the device object
 */
interface Device {
  /** Environment-unique ID of the device (e.g., emulator-5554, simulator UDID) */
  id: string;
  /** Descriptive name of the device (e.g., "emulator-5554 (Pixel_API_29)") */
  name: string;
  /** Launch arguments manager for configuring app startup parameters */
  appLaunchArgs: AppLaunchArgs;
}

App Lifecycle Management

Control app installation, launching, termination, and background/foreground transitions.

/**
 * Launch the app with optional configuration
 * @param config - Launch configuration options
 */
async function launchApp(config?: DeviceLaunchAppConfig): Promise<void>;

/**
 * Terminate the app
 * @param bundle - Optional bundle ID to terminate specific app (defaults to current app)
 */
async function terminateApp(bundle?: string): Promise<void>;

/**
 * Send app to background by bringing system home screen to foreground
 */
async function sendToHome(): Promise<void>;

/**
 * Reload React Native JS bundle (faster than full app relaunch)
 */
async function reloadReactNative(): Promise<void>;

/**
 * Relaunch app with fresh instance (convenience method)
 * @param config - Launch configuration options (same as launchApp)
 */
async function relaunchApp(config?: DeviceLaunchAppConfig): Promise<void>;

/**
 * Install app from file path
 * @param path - Path to app file (defaults to current configuration)
 */
async function installApp(path?: string): Promise<void>;

/**	
 * Uninstall app by bundle ID
 * @param bundle - Bundle ID to uninstall (defaults to current app)
 */
async function uninstallApp(bundle?: string): Promise<void>;

/**
 * Select current app in multi-app configurations
 * @param app - App name as defined in configuration
 */
async function selectApp(app: string): Promise<void>;

interface DeviceLaunchAppConfig {
  /** Restart app (terminate and launch new instance) */
  newInstance?: boolean;
  /** Grant or deny runtime permissions */
  permissions?: DevicePermissions;
  /** Mock opening from URL for deep link testing */
  url?: string;
  /** Source app bundle ID for URL opening (iOS only) */
  sourceApp?: string;
  /** Launch with user notification */
  userNotification?: any;
  /** Launch with user activity */
  userActivity?: any;
  /** Launch into fresh installation (uninstall and reinstall) */
  delete?: boolean;
  /** Arguments to pass to app */
  launchArgs?: Record<string, any>;
  /** Language and locale configuration */
  languageAndLocale?: LanguageAndLocale;
}

Usage Examples:

// Basic app launch
await device.launchApp();

// Launch with permissions
await device.launchApp({
  permissions: { camera: 'YES', notifications: 'YES' }
});

// Launch from URL (deep linking)
await device.launchApp({
  url: 'myapp://product/123'
});

// Fresh installation
await device.launchApp({
  delete: true,
  newInstance: true
});

// Relaunch app (convenience method)
await device.relaunchApp({
  permissions: { camera: 'YES' }
});

Hardware Simulation

Simulate hardware interactions and device state changes.

/**
 * Set device orientation
 * @param orientation - Target orientation
 */
async function setOrientation(orientation: Orientation): Promise<void>;

/**
 * Set device location coordinates
 * @param lat - Latitude
 * @param lon - Longitude
 */
async function setLocation(lat: number, lon: number): Promise<void>;

/**
 * Shake device (iOS only)
 */
async function shake(): Promise<void>;

/**
 * Perform tap at arbitrary screen coordinates
 * @param point - Coordinates (defaults to {x: 100, y: 100})
 * @param shouldIgnoreStatusBar - Start measuring from under status bar (Android only)
 */
async function tap(point?: Point2D, shouldIgnoreStatusBar?: boolean): Promise<void>;

/**
 * Perform long press at arbitrary screen coordinates
 * @param point - Coordinates (defaults to {x: 100, y: 100})
 * @param duration - Press duration in milliseconds
 * @param shouldIgnoreStatusBar - Start measuring from under status bar (Android only)
 */
async function longPress(point?: Point2D, duration?: number, shouldIgnoreStatusBar?: boolean): Promise<void>;

type Orientation = 'portrait' | 'landscape';

Platform Detection

Determine the current platform for conditional test logic.

/**
 * Get current platform
 * @returns Platform identifier
 */
function getPlatform(): 'ios' | 'android';

Usage Example:

if (device.getPlatform() === 'ios') {
  await device.shake();
} else {
  await device.pressBack();
}

Biometric Authentication (iOS Only)

Control biometric authentication features like TouchID and FaceID.

/**
 * Toggle biometric enrollment (TouchID/FaceID)
 * @param enabled - Enable or disable biometric enrollment
 */
async function setBiometricEnrollment(enabled: boolean): Promise<void>;

/**
 * Simulate successful Face ID match
 */
async function matchFace(): Promise<void>;

/**
 * Simulate failed Face ID match
 */
async function unmatchFace(): Promise<void>;

/**
 * Simulate successful Touch ID match
 */
async function matchFinger(): Promise<void>;

/**
 * Simulate failed Touch ID match
 */
async function unmatchFinger(): Promise<void>;

/**
 * Clear simulator keychain
 */
async function clearKeychain(): Promise<void>;

/**
 * Reset iOS status bar to default state (iOS only)
 */
async function resetStatusBar(): Promise<void>;

Android-Specific Features

Features specific to Android platform testing.

/**
 * Press back button (Android only)
 */
async function pressBack(): Promise<void>;

/**
 * Get UiAutomator UiDevice API access (Android only)
 * @returns UiDevice instance for low-level Android automation
 */
function getUiDevice(): any;

/**
 * Enable TCP port forwarding for network requests (Android only)
 * @param port - Port number to forward
 */
async function reverseTcpPort(port: number): Promise<void>;

/**
 * Disable TCP port forwarding (Android only)
 * @param port - Port number to stop forwarding
 */
async function unreverseTcpPort(port: number): Promise<void>;

iOS-Specific Features

Features specific to iOS platform testing.

/**
 * Override iOS simulator status bar (iOS only)
 * @param config - Status bar configuration
 */
async function setStatusBar(config: {
  time?: string;
  dataNetwork?: 'hide' | 'wifi' | '3g' | '4g' | 'lte' | '5g';
  wifiMode?: 'searching' | 'failed' | 'active';
  wifiBars?: '0' | '1' | '2' | '3';
  cellularMode?: 'notSupported' | 'searching' | 'failed' | 'active';
  cellularBars?: '0' | '1' | '2' | '3' | '4';
  operatorName?: string;
  batteryState?: 'charging' | 'charged' | 'discharging';
  batteryLevel?: string; // 0-100
}): Promise<void>;

/**
 * Capture iOS view hierarchy snapshot (iOS only)
 * @param name - Name for the artifact
 * @returns Temporary path to .viewhierarchy file
 */
async function captureViewHierarchy(name?: string): Promise<string>;

Debug and Artifacts

Generate debugging artifacts and inspect app state.

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

/**
 * Generate XML view hierarchy
 * @param shouldInjectTestIds - Inject test IDs when missing (changes app state)
 * @returns XML string representation of view hierarchy
 */
async function generateViewHierarchyXml(shouldInjectTestIds?: boolean): Promise<string>;

/**
 * Reset device to clean state (iOS Simulator only)
 */
async function resetContentAndSettings(): Promise<void>;

Synchronization Control

Control Detox's automatic synchronization behavior.

/**
 * Disable automatic synchronization with app
 * Use with caution - may require manual sleep() calls
 */
async function disableSynchronization(): Promise<void>;

/**
 * Re-enable automatic synchronization with app
 * Only call when app can become idle again
 */
async function enableSynchronization(): Promise<void>;

/**
 * Set URL blacklist for synchronization
 * @param urls - Array of URL patterns to ignore during sync
 */
async function setURLBlacklist(urls: string[]): Promise<void>;

Launch Arguments Management

Configure and modify app launch arguments dynamically.

interface AppLaunchArgs {
  /** Shared arguments across all apps */
  shared: ScopedAppLaunchArgs;
  
  /**
   * Modify app-specific launch arguments
   * @param modifier - Object with argument modifications
   */
  modify(modifier: object): this;
  
  /** Reset app-specific launch arguments */
  reset(): this;
  
  /** Get all current launch arguments */
  get(): object;
}

interface ScopedAppLaunchArgs {
  modify(modifier: object): this;
  reset(): this;
  get(): object;
}

Usage Example:

// Set shared launch arguments
device.appLaunchArgs.shared.modify({
  mockServer: 'https://staging.api.com'
});

// Set app-specific launch arguments
device.appLaunchArgs.modify({
  debugMode: true,
  userId: '12345'
});

// Launch app with all configured arguments
await device.launchApp();

Notification and URL Handling

Simulate external app triggers and deep linking scenarios.

/**
 * Mock opening app from URL
 * @param config - URL configuration
 */
async function openURL(config: {
  url: string;
  sourceApp?: string; // iOS only
}): Promise<void>;

/**
 * Mock received user notification when app is in foreground
 * @param params - Notification parameters
 */
async function sendUserNotification(...params: any[]): Promise<void>;

/**
 * Mock received user activity when app is in foreground  
 * @param params - User activity parameters
 */
async function sendUserActivity(...params: any[]): Promise<void>;

Types

interface DevicePermissions {
  location?: 'always' | 'inuse' | 'never' | 'unset';
  notifications?: 'YES' | 'NO' | 'unset';
  calendar?: 'YES' | 'NO' | 'unset';
  camera?: 'YES' | 'NO' | 'unset';
  contacts?: 'YES' | 'NO' | 'unset' | 'limited';
  photos?: 'YES' | 'NO' | 'unset' | 'limited';
  microphone?: 'YES' | 'NO' | 'unset';
  health?: 'YES' | 'NO' | 'unset';
  homekit?: 'YES' | 'NO' | 'unset';
  medialibrary?: 'YES' | 'NO' | 'unset';
  motion?: 'YES' | 'NO' | 'unset';
  reminders?: 'YES' | 'NO' | 'unset';
  siri?: 'YES' | 'NO' | 'unset';
  speech?: 'YES' | 'NO' | 'unset';
  faceid?: 'YES' | 'NO' | 'unset';
  userTracking?: 'YES' | 'NO' | 'unset';
}

interface LanguageAndLocale {
  language?: string;
  locale?: string;
}

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

Install with Tessl CLI

npx tessl i tessl/npm-detox

docs

assertions.md

configuration.md

device-management.md

element-interaction.md

element-selection.md

index.md

synchronization.md

web-view-testing.md

tile.json