Skip to content

Device Matrix ​

By default every flow in an upload runs on one device, set by the --ios-device, --ios-version, --android-device and --android-api-level flags on dcd cloud.

A device matrix runs your whole suite against several devices from a single dcd cloud invocation. Every flow runs once per device, all under one upload with one console entry.

Usage ​

Pass --ios-device-matrix <device>:<version> (or --android-device-matrix <device>:<apiLevel>) once per device you want. Supported devices and operating systems are listed here.

iOS ​

bash
dcd cloud --app-binary-id <id> ./flows \
  --ios-device-matrix iphone-16:18 \
  --ios-device-matrix iphone-17:26 \
  --ios-device-matrix iphone-18-pro:27
# one upload, 3 devices x N flows

Android ​

bash
dcd cloud --app-binary-id <id> ./flows \
  --android-device-matrix pixel-8:34 \
  --android-device-matrix pixel-10:36

Append :play to run a cell against a Google Play device. Google Play is available as pixel-8:34, pixel-10:36, pixel-10:37 and pixel-7:34 (deprecated, and not on the m1 runner type) (see Google Play APIs):

bash
dcd cloud --app-binary-id <id> ./flows \
  --android-device-matrix pixel-8:34 \
  --android-device-matrix pixel-8:34:play

Every --ios-device-matrix / --android-device-matrix names exactly one device. There is no cross-product: the flags are not combined with each other, or with --ios-device / --ios-version.

bash
# runs exactly these two, and nothing else
dcd cloud [...] --ios-device-matrix iphone-14:18 --ios-device-matrix iphone-air:26

This is deliberate as not every device supports every OS. Naming each device explicitly means you always get exactly what you asked for.

Cost ​

A matrix runs one test per (flow x device), so a 4-device matrix over 10 flows is 40 flows, not 10. Before submitting, the CLI prints the number of flows and what they will cost:

⏺ Device matrix
  ⎿ cells       4
    est. cost   $0.36
    Pixel 8 · API 34   2 flows · $0.18
    Pixel 10 · API 36   2 flows · $0.18

Rates are per device — iPad, iPhone Duo, Generic Tablet, Pixel 10 Pro Fold and Google Play flows are charged at the advanced rate, as per our pricing.

Results ​

Each device gets its own result, grouped together in the console so you can compare a flow across devices at a glance.

Under --json, every entry in tests[] carries a device object, so the same flow run on two devices is unambiguous:

json
{
  "uploadId": "...",
  "tests": [
    { "name": "login.yaml", "status": "PASSED", "device": { "name": "Pixel 8", "osVersion": "34", "googlePlay": false } },
    { "name": "login.yaml", "status": "FAILED", "device": { "name": "Pixel 10", "osVersion": "36", "googlePlay": false } }
  ]
}

Without --async the run waits for every device and exits 0 only if all of them passed. Retrying a single failed result re-runs just that one flow on that one device and not the entire matrix.

Rules ​

  • Every device and OS must be a supported combination, including Google Play if applicable. An unsupported one is rejected before anything runs so you never get a partial submission. Some runner types support fewer devices, see Runner Type.

  • One platform per upload. An upload runs one app binary, so --ios-device-matrix and --android-device-matrix cannot be combined in the same run.

  • A flow that names its own device wins. If a flow targets a device in its YAML via per-flow devices, it runs once on that device and is excluded from the matrix. Ten flows across four devices with one targeted flow is 37 runs, not 40.

  • A flow that sets its own runner type is not excluded. It still runs on every device in the matrix, on that runner type.