Advanced Chapter 11 · 9 min read

Parallelism, Projects & Retries

Run tests on multiple devices at once, target iOS and Android from one config with projects, and retry flaky tests automatically.

Workers = Devices

Mobilewright runs tests in parallel using workers — independent processes that each hold a connection to one device or simulator. Two workers means two devices running two tests at the same time. To actually use multiple devices you need both a higher worker count and fullyParallel: true (without it, all tests in one file stay on the same worker):

mobilewright.config.ts
import { defineConfig } from 'mobilewright';

export default defineConfig({
  // Two devices running tests at the same time
  workers: 2,

  // Required: lets tests from the same file spread across workers
  fullyParallel: true,
});
mobilewright.config.js
const { defineConfig } = require('mobilewright');

module.exports = defineConfig({
  // Two devices running tests at the same time
  workers: 2,

  // Required: lets tests from the same file spread across workers
  fullyParallel: true,
});
Tip: Requesting more workers than you have devices does not fail — extra workers simply wait until a device is free. Devices are allocated lazily and reused between tests.

Serial Mode for Dependent Tests

Some flows must run in order — sign in, add to cart, check out. Mark the group serial so the tests share one device and run sequentially. If one fails, the rest are skipped, and the whole group retries together:

checkout.test.ts
import { test, expect } from '@mobilewright/test';

// These tests run in order on the same device
test.describe.configure({ mode: 'serial' });

test('sign in', async ({ screen }) => { /* ... */ });
test('add to cart', async ({ screen }) => { /* ... */ });
test('complete purchase', async ({ screen }) => { /* ... */ });
checkout.test.js
const { test, expect } = require('@mobilewright/test');

// These tests run in order on the same device
test.describe.configure({ mode: 'serial' });

test('sign in', async ({ screen }) => { /* ... */ });
test('add to cart', async ({ screen }) => { /* ... */ });
test('complete purchase', async ({ screen }) => { /* ... */ });

Projects: iOS and Android in One Config

A project is a named group of tests with its own configuration. The classic use-case: run your whole suite on both platforms from a single config file. Running npx mobilewright test then executes every test twice — once per project:

mobilewright.config.ts
import { defineConfig } from 'mobilewright';

export default defineConfig({
  bundleId: 'com.example.myapp',
  timeout: 120_000,
  workers: 2,
  projects: [
    {
      name: 'ios',
      use: { platform: 'ios', installApps: 'ios/MyApp.zip' },
    },
    {
      name: 'android',
      use: { platform: 'android', installApps: 'android/MyApp.apk' },
    },
  ],
});
mobilewright.config.js
const { defineConfig } = require('mobilewright');

module.exports = defineConfig({
  bundleId: 'com.example.myapp',
  timeout: 120_000,
  workers: 2,
  projects: [
    {
      name: 'ios',
      use: { platform: 'ios', installApps: 'ios/MyApp.zip' },
    },
    {
      name: 'android',
      use: { platform: 'android', installApps: 'android/MyApp.apk' },
    },
  ],
});

Target one platform with npx mobilewright test --project=android.

Retries: Taming Flaky Tests

Mobile tests can be flaky — network, timing, device state. With retries configured, a failing test is automatically re-run: the app is terminated and relaunched on the same device (fast — no re-allocation), and the test gets another chance. A test that passes on a retry is reported as flaky, not failed:

mobilewright.config.ts
import { defineConfig } from 'mobilewright';

export default defineConfig({
  // Retry twice in CI, never locally
  retries: process.env.CI ? 2 : 0,
});
mobilewright.config.js
const { defineConfig } = require('mobilewright');

module.exports = defineConfig({
  // Retry twice in CI, never locally
  retries: process.env.CI ? 2 : 0,
});

A common pattern is retries in CI only, keeping local feedback fast — and you can check testInfo.retry inside a test to clear leftover state before a re-run.


Mobilewright Advanced Parallel Projects Retries

Written by PV

© 2026 All Rights Reserved