Skip to main content

Sauce Labs

Sauce Labs runs Mobilewright tests on real Android and iOS devices through the @saucelabs/mobilewright-driver package, maintained by Sauce Labs. Each test shows up on the Sauce Labs Test Results page with its video, screenshots and device logs, and no Sauce Labs-specific code is needed in your tests.

Requires mobilewright 0.0.67, Node.js ≥ 22.12, and Android 13 or later on Android devices.

The driver uses the Sauce Labs Real Device Access API, which is available on Enterprise plans only. Self-serve plans don't include it.

Setup​

1. Install the driver​

npm install --save-dev @saucelabs/mobilewright-driver

2. Set your credentials​

Find your username and access key in your Sauce Labs user settings and export them:

export SAUCE_USERNAME=...
export SAUCE_ACCESS_KEY=...

The driver also takes username and accessKey options directly, but keep credentials out of the repository.

3. Set the driver​

This example runs the Sauce Labs demo app on a Pixel and an iPhone:

// mobilewright.config.ts
import { defineConfig } from 'mobilewright';
import { sauceLabsDriver } from '@saucelabs/mobilewright-driver';

export default defineConfig({
testDir: './tests',
use: { actionTimeout: 30_000 },
expect: { timeout: 30_000 },
driver: sauceLabsDriver({ region: 'us-west-1', build: 'my-first-build' }),
projects: [
{
name: 'android',
use: {
platform: 'android',
deviceName: /Google_Pixel(?!.*Fold)/, // no foldables: apps can open on the hidden screen
osVersion: '>=13',
bundleId: 'com.saucelabs.mydemoapp.android',
installApps: 'https://github.com/saucelabs/my-demo-app-android/releases/download/2.3.0/mda-2.3.0-27.apk',
},
},
{
name: 'ios',
use: {
platform: 'ios',
deviceName: /iPhone/,
osVersion: '>=16.6',
bundleId: 'com.saucelabs.mydemo.app.ios',
installApps: 'https://github.com/saucelabs/my-demo-app-ios/releases/download/2.3.0/SauceLabs-Demo-App.ipa',
},
},
],
});

Device selection uses the standard config fields: platform, deviceName (regex) and osVersion (exact, or a range like ">=17 <19").

installApps takes an https:// URL (Sauce Labs downloads it), a file in App Storage (storage:<id> or storage:filename=<name>), or a local .apk, .ipa or .zip, which is uploaded once and then reused.

Mobilewright's 5-second default timeouts are meant for local devices. Use 30 seconds for actionTimeout and expect, as in the example above.

Driver options​

All options are optional.

OptionPurpose
username, accessKeyCredentials; default to the environment variables above
regionData center: us-west-1 (default), us-east-4, eu-central-1 or asia-south-2
build, tagsBuild name and tags shown on the Test Results page
reportTestsReport each test to the Test Results page (default true)
artifactsWhat Sauce Labs records per test: { video, screenshots, deviceLogs, networkCapture }
allocationTimeoutHow long to wait for a device (default 300s)
sessionDurationMaximum session length, e.g. PT1H
sauceConnectStart a Sauce Connect tunnel for the run (default false)
sauceConnectOptsTunnel options: any sc run flag, camelCased (e.g. tunnelDomains)
tunnelName, tunnelOwnerUse a tunnel that is already running, or one shared with you

Running tests​

Each worker uses one device. Set workers to your account's concurrency, and run Android and iOS in separate processes:

npx mobilewright test --project android
npx mobilewright test --project ios
DEBUG=mw:mobilewright-driver* npx mobilewright test # driver debug logging
SAUCE_LIVE_VIEW=1 npx mobilewright test # print a link to watch each device live

A retry shows up on Sauce Labs as … (retry 1). Each test in the HTML report links to its Sauce Labs job, where the video is.

Sauce Connect​

Use Sauce Connect when your app talks to a server on your machine or on a private network. The driver downloads it, starts the tunnel before the first test and stops it at the end:

driver: sauceLabsDriver({
sauceConnect: true,
sauceConnectOpts: { tunnelDomains: ['.*\\.internal'] }, // optional: only these hosts use the tunnel
}),

Devices don't send localhost or 127.0.0.1 through the tunnel, so use another host name for your server.

Switching between a local device and Sauce Labs​

Keep one config and pick the driver by environment: local (mobilecli) by default, Sauce Labs when credentials are present.

import { defineConfig, type MobilewrightConfig } from 'mobilewright';
import { sauceLabsDriver } from '@saucelabs/mobilewright-driver';

const config: MobilewrightConfig = { /* ...your existing config... */ };

if (process.env.SAUCE_USERNAME) {
config.driver = sauceLabsDriver();
}

export default defineConfig(config);
npx mobilewright test # local device
SAUCE_USERNAME=... SAUCE_ACCESS_KEY=... \
npx mobilewright test # the same suite on Sauce Labs

Learn more​

Public and private devices, web views, Sauce Connect details, troubleshooting and complete example projects are in the @saucelabs/mobilewright-driver repository.