Skip to main content

Maestro Test Options

When running Maestro tests on TestingBot, you can customize the test execution using various options. These options are passed when starting a test run via the API.

Options are organized into two categories:

  • maestroOptions: Options specific to Maestro execution (version, environment variables, flows, tags)
  • capabilities: Device and test configuration options (device, orientation, locale, network, etc.)

Moving an existing suite across? See migrate from Maestro Cloud for the full flag mapping.

Quick Reference

All available options at a glance:

Maestro Options

Option Type Description
version string Maestro CLI version to use (e.g., "2.0.10")
flows array Only run these flows, by path, file name or directory (e.g., ["login.yml", "checkout.yml"])
env object Environment variables to pass to flows
includeTags array Only run flows carrying at least one of these tags. Untagged flows are skipped
excludeTags array Skip flows carrying any of these tags. Untagged flows are kept
shardSplit number Split flows across N parallel sessions
showKeyboard boolean Show the soft keyboard on Android (default: false)
commitSha string Git commit SHA for CI/CD tracking
pullRequestId string Pull request ID for CI/CD tracking
repoName string Repository name (e.g., GitHub repo slug)
repoOwner string Repository owner (e.g., GitHub org or username)

Capability Options

Option Type Description
platformName string Platform: "Android" or "iOS" (required)
version string OS version (required)
deviceName string Device name (required)
name string Test name shown in dashboard
build string Build name for grouping tests
groups comma-separated strings Groups to which the test belongs, visible in the dashboard
orientation string "PORTRAIT" (default) or "LANDSCAPE"
locale string Device locale (e.g., "en_US", "de_DE")
timeZone string Device timezone (e.g., "America/New_York")
googlePlayStore boolean Use Google Play Store Android emulator.
throttle_network string Network preset: "Edge", "3G", "4G", "airplane"
testingbot.geoCountryCode string Route traffic through specific country (ISO code)

Set Maestro Version

Unless you pin one, TestingBot runs your flows with Maestro 2.6.0. This is a known-good default rather than the newest release, so pin a version explicitly if you need a specific one.

These versions can be pinned:

  • 2.10.0, 2.9.0, 2.8.0, 2.7.0
  • 2.6.1, 2.6.0 (default), 2.5.0, 2.4.0
  • 2.3.0, 2.0.10

Startup time. A few versions are pre-installed on our devices and start immediately. Any other version is fetched when the session starts, which adds to your startup time. If a run is slow to start after pinning a version, that is why.

testingbot maestro app.apk ./flows \
  --device "Pixel 8" \
  --deviceVersion "14" \
  --maestro-version "2.0.10"

If you need a specific version for compatibility, specify the version option in maestroOptions.

Option Type Example
maestroOptions.version string "2.0.10"
curl -u api_key:api_secret \
-X POST "https://api.testingbot.com/v1/app-automate/maestro/:id/run" \
-d '{
  "maestroOptions": {
    "version": "2.0.10"
  },
  "capabilities": [{
    "platformName": "Android",
    "version": "14",
    "deviceName": "Pixel 8"
  }]
}' \
-H "Content-Type: application/json"

Replace :id with your project ID from the app upload.

Select Specific Flows

By default, TestingBot runs every flow file in your zip archive, one device session per flow. To run only some of them, use the option below. Flows you filter out are not scheduled at all, so they do not consume a session.

Each entry is matched against the path of the flow inside your archive, and can be:

  • the full path, for example flows/smoke/login.yml
  • just the file name, for example login.yml
  • a directory, which selects every flow inside it, for example flows/smoke

Use Cases

  • Run a subset of flows for faster feedback during development
  • Execute specific test scenarios without modifying your test suite
  • Re-run failed flows without running the entire suite

With the CLI, you specify flows directly as arguments:

# Run specific flow files
testingbot maestro app.apk login.yml checkout.yml --device "Pixel 8"

# Run flows from a specific directory
testingbot maestro app.apk ./flows/smoke --device "Pixel 8"

# Mix directories and individual files
testingbot maestro app.apk ./flows/smoke login.yml --device "Pixel 8"
Option Type Example
maestroOptions.flows array of strings ["login.yml", "checkout.yml"]
curl -u api_key:api_secret \
-X POST "https://api.testingbot.com/v1/app-automate/maestro/:id/run" \
-d '{
  "maestroOptions": {
    "flows": ["login.yml", "checkout.yml"]
  },
  "capabilities": [{
    "platformName": "Android",
    "version": "14",
    "deviceName": "Pixel 8"
  }]
}' \
-H "Content-Type: application/json"

A filter that matches nothing is rejected. If flows, includeTags or excludeTags leave no flows to run, the run request comes back with a 400 listing the flows the project does have, and nothing is scheduled. Check the paths and tags against the archive you uploaded.

Environment Variables

Pass environment variables to your Maestro flows using the env option. This is useful for configuration that varies between environments (staging, production) or for sensitive data like API keys.

Use Cases

  • Environment-specific URLs: Point to staging or production backends
  • Test credentials: Pass login credentials securely via CI/CD
  • Feature flags: Enable or disable features during tests
  • App identifiers: Specify package names or bundle IDs dynamically

Use the -e or --env flag (can be repeated):

testingbot maestro app.apk ./flows --device "Pixel 8" \
  -e API_URL=https://staging.example.com \
  -e TEST_USER=testuser@example.com \
  -e TEST_PASSWORD=secret123
Option Type Example
maestroOptions.env object {"API_URL": "https://staging.example.com"}
curl -u api_key:api_secret \
-X POST "https://api.testingbot.com/v1/app-automate/maestro/:id/run" \
-d '{
  "maestroOptions": {
    "env": {
      "API_URL": "https://staging.example.com",
      "TEST_USER": "testuser@example.com",
      "TEST_PASSWORD": "secret123"
    }
  },
  "capabilities": [{
    "platformName": "Android",
    "version": "14",
    "deviceName": "Pixel 8"
  }]
}' \
-H "Content-Type: application/json"

Using Variables in Your Flows

Reference environment variables in your Maestro flow files using the ${VARIABLE_NAME} syntax:

appId: com.example.app
---
- launchApp
- inputText:
    text: "${TEST_USER}"
- tapOn: "Next"
- inputText:
    text: "${TEST_PASSWORD}"
- tapOn: "Login"

Best Practice: Never commit sensitive values like passwords or API keys to your repository. Pass them as environment variables through your CI/CD pipeline.

Include Tags

Run only flows that have specific tags. This is equivalent to Maestro's --include-tags option.

Untagged flows are skipped. When you set includeTags, a flow has to carry at least one of the tags you listed to run. Flows with no tags at all are left out, which is how Maestro's own --include-tags behaves. Tags are matched without regard to case.

Adding Tags to Flows

Add tags to your flow files using the tags property:

appId: com.example.app
tags:
  - smoke
  - login
---
- launchApp
- tapOn: "Login"

Use the --include-tags flag with comma-separated tags:

testingbot maestro app.apk ./flows --device "Pixel 8" \
  --include-tags "smoke,critical"
Option Type Example
maestroOptions.includeTags array of strings ["smoke", "critical"]
curl -u api_key:api_secret \
-X POST "https://api.testingbot.com/v1/app-automate/maestro/:id/run" \
-d '{
  "maestroOptions": {
    "includeTags": ["smoke", "critical"]
  },
  "capabilities": [{
    "platformName": "Android",
    "version": "14",
    "deviceName": "Pixel 8"
  }]
}' \
-H "Content-Type: application/json"

Exclude Tags

Skip flows that have specific tags. This is equivalent to Maestro's --exclude-tags option. Unlike includeTags, flows with no tags are kept.

You can combine the two. includeTags is applied first and excludeTags second, so a flow tagged both smoke and flaky is skipped by "includeTags": ["smoke"], "excludeTags": ["flaky"].

Use Cases

  • Skip slow tests during development for faster feedback
  • Exclude known flaky tests from CI pipelines
  • Skip platform-specific tests (e.g., exclude "ios-only" when running on Android)

Use the --exclude-tags flag with comma-separated tags:

testingbot maestro app.apk ./flows --device "Pixel 8" \
  --exclude-tags "slow,flaky"
Option Type Example
maestroOptions.excludeTags array of strings ["slow", "flaky"]
curl -u api_key:api_secret \
-X POST "https://api.testingbot.com/v1/app-automate/maestro/:id/run" \
-d '{
  "maestroOptions": {
    "excludeTags": ["slow", "flaky"]
  },
  "capabilities": [{
    "platformName": "Android",
    "version": "14",
    "deviceName": "Pixel 8"
  }]
}' \
-H "Content-Type: application/json"

IP Geolocation

Test your app from different geographic locations using TestingBot's GeoIP feature. Traffic from the device will route through an IP address in the specified country.

Use Cases

  • Test geo-restricted content or features
  • Verify location-based pricing or currency display
  • Test localized content delivery
testingbot maestro app.zip ./flows \
  --platform iOS \
  --device "iPhone 15" \
  --deviceVersion "17.2" \
  --geo-country-code "DE"
Option Type Example
testingbot.geoCountryCode string (ISO code) "DE", "US", "JP"
curl -u api_key:api_secret \
-X POST "https://api.testingbot.com/v1/app-automate/maestro/:id/run" \
-d '{
  "capabilities": [{
    "platformName": "iOS",
    "version": "17.2",
    "deviceName": "iPhone 15",
    "testingbot.geoCountryCode": "DE"
  }]
}' \
-H "Content-Type: application/json"

See the full list of available country codes.

Network Throttling

Simulate different network conditions to test how your app performs under various connectivity scenarios.

Option Type Example
throttle_network string "4G", "3G", "Edge", "airplane"

Network Presets

Preset Download Upload Latency Use Case
4G 18 Mbps 9 Mbps 100ms Standard mobile connection
3G 400 Kbps 100 Kbps 100ms Slower mobile network
Edge 250 Kbps 150 Kbps 300ms Poor connectivity areas
airplane 0 0 - No connectivity (offline mode)
disable - - - Restore full connectivity
testingbot maestro app.zip ./flows \
  --platform iOS \
  --device "iPhone 15" \
  --deviceVersion "17.2" \
  --throttle-network "3G"
curl -u api_key:api_secret \
-X POST "https://api.testingbot.com/v1/app-automate/maestro/:id/run" \
-d '{
  "capabilities": [{
    "platformName": "iOS",
    "version": "17.2",
    "deviceName": "iPhone 15",
    "throttle_network": "3G"
  }]
}' \
-H "Content-Type: application/json"

Test Name

Set a custom name for your test that appears in the TestingBot dashboard. This makes it easier to identify specific test runs.

Option Type Example
name string "Login Flow - Smoke Test"
testingbot maestro app.zip ./flows \
  --platform iOS \
  --device "iPhone 15" \
  --deviceVersion "17.2" \
  --name "Login Flow - Smoke Test"
curl -u api_key:api_secret \
-X POST "https://api.testingbot.com/v1/app-automate/maestro/:id/run" \
-d '{
  "capabilities": [{
    "platformName": "iOS",
    "version": "17.2",
    "deviceName": "iPhone 15",
    "name": "Login Flow - Smoke Test"
  }]
}' \
-H "Content-Type: application/json"

Build Grouping

Group multiple test runs under a single build name. This is useful for organizing tests that belong to the same CI/CD pipeline run or release version.

Option Type Example
build string "Release 2.5.0"

Benefits

  • View aggregated pass/fail statistics for all tests in a build
  • Track test results across different device configurations
  • Easily identify which builds introduced failures
# The Maestro CLI groups runs by the --name you pass; the API exposes this as the "build" field
testingbot maestro app.ipa ./flows \
  --platform iOS \
  --device "iPhone 17" \
  --real-device \
  --name "Release 2.5.0"
curl -u api_key:api_secret \
-X POST "https://api.testingbot.com/v1/app-automate/maestro/:id/run" \
-d '{
  "capabilities": [{
    "platformName": "iOS",
    "version": "26.0",
    "deviceName": "iPhone 17",
    "realDevice": true,
    "build": "Release 2.5.0"
  }]
}' \
-H "Content-Type: application/json"

Shard Split

Group your Maestro flows into chunks, which will run across multiple parallel sessions for faster execution. For example you have 3 parallel slots and 9 tests, but you want to split this test suite into 3 chunks of tests and run them in parallel on connected devices, then you would use shardSplit set to 3.

Option Type Example
shardSplit number 1
# Split flows across 3 parallel sessions - without this each flow would run in its own session
testingbot maestro app.apk ./flows \
  --device "Pixel 8" \
  --deviceVersion "14" \
  --shard-split 3
curl -u api_key:api_secret \
-X POST "https://api.testingbot.com/v1/app-automate/maestro/:id/run" \
-d '{
  "shardSplit": 3,
  "capabilities": [{
    "platformName": "Android",
    "version": "14",
    "deviceName": "Pixel 8"
  }]
}' \
-H "Content-Type: application/json"

Device Matrix

Run the same flows across several devices in one command with --device-matrix. Each cell names exactly one device as <device>[:<version>][:real]; cells are comma-separated or the flag is repeated. There is no cross-product, because not every device exists in every OS version.

testingbot maestro app.apk ./flows \
  --device-matrix "Pixel 9:14" \
  --device-matrix "Samsung Galaxy S24:14:real" \
  --device-matrix "Pixel 8"

Every flow runs once per device, so the cost is devices × flows; the CLI prints that summary before submitting. Each device becomes its own run with its own results, live table rows and dashboard link, --json lists the device per run, and --retry re-runs only the flow that failed on the device it failed on. If any cell is not a valid device and OS combination the whole request is rejected and nothing runs, so a matrix never partially submits.

--real-device, or an .ipa app which implies it, applies to every cell. --device and --deviceVersion cannot be combined with a matrix; list every device as a cell instead.

Reuse an Uploaded App

Every run prints its project ID after the app upload. Pass that ID to a later run with --app-binary-id and the upload is skipped; each run still gets its own project and results. testingbot upload uploads an app on its own and prints the ID, which is handy for pipelines that build once and run several suites.

testingbot upload app.apk
#   App ready: app.apk. Project ID: 4321
#   Run flows against it with: testingbot maestro --app-binary-id 4321 ./flows

testingbot maestro --app-binary-id 4321 ./flows/smoke
testingbot maestro --app-binary-id 4321 ./flows/regression --device "Pixel 9"

The platform is taken from the stored app unless --platform is given. Unchanged binaries are also deduplicated by checksum on every upload; pass --ignore-checksum-check to force a fresh upload.

Expo / EAS Build

eas build hands back a download URL rather than a local file, and for iOS simulator builds the artifact is a .tar.gz that contains the .app. Pass the URL with --app-url and the CLI downloads it, extracts the bundle when needed, and uploads it like any other app. Android EAS builds (.apk) and plain .zip / .ipa URLs work the same way, and a local .tar.gz can be passed as the app file directly.

# iOS simulator build
URL=$(eas build --platform ios --profile preview --json --non-interactive | jq -r '.[0].artifacts.buildUrl')
testingbot maestro --app-url "$URL" ./flows --device "iPhone 16"

# Android build
URL=$(eas build --platform android --profile preview --json --non-interactive | jq -r '.[0].artifacts.buildUrl')
testingbot maestro --app-url "$URL" ./flows --device "Pixel 9"

Inside an EAS Build or EAS Workflows job the run is tagged automatically with the EAS build id, profile and platform, and the job's commit hash is used as the commit SHA unless --commit-sha is given. EAS download links are signed and expire after about an hour; a rejected link is reported as such so you know to request a fresh one. testingbot upload <url> accepts URLs too, which is handy to upload once and reuse across several suites.

JSON Output and Exit Codes

--json prints one JSON document on stdout with the outcome, project ID, dashboard URL and every flow attempt per run, and moves all log lines to stderr. --json-file writes the same document to <projectId>_testingbot.json (or --json-file-name) while keeping the console output. Exit codes are 0 passed, 2 flows failed, 1 CLI or infrastructure error. Examples and the document layout are on the CI/CD page.

CI/CD Integration

Pass Git and repository metadata to associate test runs with specific commits and pull requests. This information appears in the TestingBot dashboard and can be used for tracking and debugging.

Option Type Description
commitSha string Git commit SHA associated with this test run
pullRequestId string Pull request ID this test run originated from
repoName string Repository name (e.g., GitHub repo slug)
repoOwner string Repository owner (e.g., GitHub organization or username)
# Pass Git metadata for CI/CD tracking
testingbot maestro app.apk ./flows \
  --device "Pixel 8" \
  --deviceVersion "14" \
  --commit-sha "abc123def456" \
  --pull-request-id "42" \
  --repo-owner "myorg" \
  --repo-name "myapp"

GitHub Actions Example

The TestingBot Maestro GitHub Action fills in the branch, commit, repository and pull request from the workflow context, so no metadata flags are needed:

- uses: testingbot/maestro-action@v1
  with:
    api-key: ${{ secrets.TB_KEY }}
    api-secret: ${{ secrets.TB_SECRET }}
    app-file: app.apk
    workspace: ./flows
    device: Pixel 8

See GitHub Actions for the full workflow and the action's outputs.

curl -u api_key:api_secret \
-X POST "https://api.testingbot.com/v1/app-automate/maestro/:id/run" \
-d '{
  "metadata": {
    "commitSha": "abc123def456",
    "pullRequestId": "42",
    "repoName": "myapp",
    "repoOwner": "myorg"
  },
  "capabilities": [{
    "platformName": "Android",
    "version": "14",
    "deviceName": "Pixel 8"
  }]
}' \
-H "Content-Type: application/json"

Device Orientation

Set the device orientation at the start of your test.

Option Type Values Default
orientation string "PORTRAIT", "LANDSCAPE" PORTRAIT
testingbot maestro app.apk ./flows \
  --device "Pixel 8" \
  --deviceVersion "14" \
  --orientation LANDSCAPE
curl -u api_key:api_secret \
-X POST "https://api.testingbot.com/v1/app-automate/maestro/:id/run" \
-d '{
  "capabilities": [{
    "platformName": "Android",
    "version": "14",
    "deviceName": "Pixel 8",
    "orientation": "LANDSCAPE"
  }]
}' \
-H "Content-Type: application/json"

Soft Keyboard (Android)

By default, the Android soft keyboard is hidden during Maestro tests. Use the showKeyboard option to display the soft keyboard on Android devices.

Option Type Default Platform
maestroOptions.showKeyboard boolean false Android only
curl -u api_key:api_secret \
-X POST "https://api.testingbot.com/v1/app-automate/maestro/:id/run" \
-d '{
  "maestroOptions": {
    "showKeyboard": true
  },
  "capabilities": [{
    "platformName": "Android",
    "version": "14",
    "deviceName": "Pixel 8"
  }]
}' \
-H "Content-Type: application/json"

Platform Configuration

Platform-specific settings allow you to optimize the environment for Android or iOS. These are configured in your config.yaml file under the platform key.

iOS specifics

Key Description
disableAnimations Enables Reduce Motion on the iOS Simulator to prevent flakiness caused by system-level animations.

Android specifics

Key Description
disableAnimations Disables system-level window, transition and animator animations on the Android Emulator.

Example config.yaml

platform:
  ios:
    disableAnimations: true
  android:
    disableAnimations: true

Device Timezone

Set the device timezone for your test. Useful for testing time-sensitive features.

Option Type Example
timeZone string (IANA) "America/New_York", "Europe/London", "Asia/Tokyo"
testingbot maestro app.zip ./flows \
  --platform iOS \
  --device "iPhone 15" \
  --deviceVersion "17.2" \
  --timezone "America/New_York"
curl -u api_key:api_secret \
-X POST "https://api.testingbot.com/v1/app-automate/maestro/:id/run" \
-d '{
  "capabilities": [{
    "platformName": "iOS",
    "version": "17.2",
    "deviceName": "iPhone 15",
    "timeZone": "America/New_York"
  }]
}' \
-H "Content-Type: application/json"

See the full list of timezone identifiers.

Device Locale

Set the device locale to test localized content and formatting. The locale affects language, date formats, number formats, and currency display.

Option Type Format Example
locale string language_COUNTRY "de_DE", "fr_CA", "ja_JP"
testingbot maestro app.zip ./flows \
  --platform iOS \
  --device "iPhone 15" \
  --deviceVersion "17.2" \
  --device-locale "de_DE"
curl -u api_key:api_secret \
-X POST "https://api.testingbot.com/v1/app-automate/maestro/:id/run" \
-d '{
  "capabilities": [{
    "platformName": "iOS",
    "version": "17.2",
    "deviceName": "iPhone 15",
    "locale": "de_DE"
  }]
}' \
-H "Content-Type: application/json"

Common Locale Codes

Region Locale Code
English (US) en_US
English (UK) en_GB
German (Germany) de_DE
French (France) fr_FR
French (Canada) fr_CA
Spanish (Spain) es_ES
Spanish (Mexico) es_MX
Japanese ja_JP
Chinese (Simplified) zh_CN
Chinese (Traditional) zh_TW
Korean ko_KR
Portuguese (Brazil) pt_BR
Italian it_IT
Dutch nl_NL
Russian ru_RU
Arabic ar_SA
Hindi hi_IN

Maestro config.yaml

You can include a config.yaml file in your Maestro flows zip file. This configuration file lets you define options that apply to all your flows.

Supported config.yaml Options

Option Description
includeTags Only run flows with these tags
excludeTags Skip flows with these tags
env Environment variables available in all flows
platform Platform-specific settings for iOS and Android (see Platform Configuration)

Example config.yaml

env:
  API_URL: https://api.example.com
  DEBUG: "true"

includeTags:
  - smoke
  - critical

TestingBot Tunnel

Use TestingBot Tunnel to allow your app to access private or staging backend servers during tests.

Use Cases

  • Test against staging APIs not accessible from the public internet
  • Access localhost services running on your machine
  • Test with private databases or internal services

When a TestingBot Tunnel is active on your account, Maestro tests automatically route traffic through it. No additional configuration is needed.

To start a tunnel, download and run the TestingBot Tunnel client before starting your tests.

You can also use the built-in tunnel option to automatically start a tunnel for the duration of your test run.

See the dedicated Maestro Tunnel guide for use cases, a staging token helper and CI/CD examples.

CLI Reference

When using the TestingBot CLI, these options are available as command-line flags:

App & Flows

The application and flows are normally passed as positional arguments (testingbot maestro app.apk ./flows), but you can also set them explicitly:

CLI Option Description
--app <path> Path to the application under test (.apk, .ipa, .app, or .zip)
--other-app <path> Additional app to install alongside --app. Can be repeated, up to 4 times.
--app-url <url> Download the app from an http(s) URL instead of a local file: .apk, .ipa, .zip or an EAS Build iOS .tar.gz (the .app inside is extracted automatically). Every positional argument is then a flow. Signed URLs such as EAS links expire after about an hour. See Expo / EAS Build.
--app-binary-id <projectId> Reuse the app of a project uploaded earlier (testingbot upload or any previous run's project ID) instead of uploading one. Every positional argument is then a flow. See Reuse an Uploaded App.

Device Options

CLI Option Description
--device <name> Device name (e.g., "Pixel 9", "iPhone 17")
--platform <platform> Platform: Android or iOS
--deviceVersion <version> OS version (e.g., "14", "17.2")
--real-device Use a real device instead of emulator/simulator
--device-matrix <cells> Run every flow on each listed device: <device>[:<version>][:real], comma-separated or repeatable. Cannot be combined with --device or --deviceVersion. See Device Matrix.
--google-play Use the Google Play Store-enabled version (Android emulator only)
--orientation <orientation> Screen orientation: PORTRAIT or LANDSCAPE
--device-locale <locale> Device locale (e.g., "en_US", "de_DE")
--timezone <timezone> Timezone (e.g., "America/New_York", "Europe/London")

Test Configuration

CLI Option Description
--name <name> Name for this Maestro run, used for dashboard identification and build grouping
--groups <names> Tag the test session with one or more groups (comma-separated)
--include-tags <tags> Only run flows with these tags (comma-separated)
--exclude-tags <tags> Exclude flows with these tags (comma-separated)
--exclude-flows <paths> Flow files, directories or glob patterns to leave out of the run (comma-separated, repeatable). An excluded flow that another flow still invokes via runFlow is bundled as a subflow but never runs on its own.
-e, --env <KEY=VALUE> Environment variable for flows (can be repeated)
--maestro-version <version> Maestro version to use (e.g., "2.0.10")
--config <path> Path to a custom Maestro config file (default: config.yaml in project root)

Execution Options

CLI Option Description
--retry <count> Retry failed flows up to N times (0-2, default 0). Stops as soon as a flow passes.
--async Start tests and exit immediately without waiting for results
--dry-run Validate and prepare everything but skip the HTTP calls. Shows what would be sent.
-q, --quiet Quieter console output without progress updates
--json Print results as a single JSON document on stdout (logs move to stderr). Implies --quiet. Exit code 2 when flows fail. See JSON Output.
--json-file Write the JSON results to a file (default <projectId>_testingbot.json). Exit code stays 0 when flows fail so the pipeline can gate on the file.
--json-file-name <path> Custom path for the JSON results file (requires --json-file)

CI/CD Integration

CLI Option Description
--commit-sha <sha> Git commit SHA associated with this test run
--pull-request-id <id> Pull request ID this test run originated from
--repo-name <name> Repository name (e.g., GitHub repo slug)
--repo-owner <owner> Repository owner (e.g., GitHub organization or username)
--branch <name> Git branch this test run was built from
--pr-url <url> Pull request URL this test run originated from
-m, --metadata <KEY=VALUE> Free-form metadata attached to the run and shown in the dashboard (repeatable)
--check-name <name> Name the GitHub pull request check TestingBot / <name>, so several runs on one commit (iOS, Android) post separate checks. See GitHub PR Checks.

With the TestingBot GitHub App installed, a run carrying the repository and full commit SHA also posts a status check on the pull request.

Network & Location

CLI Option Description
--throttle-network <speed> Network throttling: 4G, 3G, Edge, airplane, or disable
--geo-country-code <code> Geographic IP location (ISO country code, e.g., "US", "DE")

Report & Artifacts

CLI Option Description
--report <format> Download report after completion: html, html-detailed, junit, or allure (Allure result files under allure-results/)
--report-output-dir <path> Directory to save reports (required when --report is used)
--download-artifacts [mode] Download test artifacts (logs, screenshots, video) after completion. Mode: all (default) or failed.
--artifacts-output-dir <path> Directory to save artifacts zip (defaults to the current directory)

Tunnel Options

CLI Option Description
-t, --tunnel Start a TestingBot Tunnel for this test run (cannot be combined with --async)
--tunnel-identifier <id> Identifier for the tunnel, allowing multiple tunnels in parallel

Advanced Options

CLI Option Description
--ignore-checksum-check Skip checksum verification and always upload the app
--shard-split <number> Split flows into N parallel sessions for faster execution. More information in the Shard Splitting section.

Authentication & Debugging

Credentials are normally resolved from testingbot login, the TB_KEY / TB_SECRET environment variables, or a ~/.testingbot file. You can also pass them explicitly:

CLI Option Description
--api-key <key> TestingBot API key
--api-secret <secret> TestingBot API secret
--debug Enable debug logging of API responses

Other Commands

Besides maestro, the CLI has commands for working with projects after they were started. All of them accept the authentication and --json flags above.

Command Description
testingbot upload <app> Upload an app once and print a project ID to reuse with --app-binary-id
testingbot status --id <projectId> [--wait] Show every run and flow of a project; --wait blocks with the live flow table until it finishes (Ctrl-C detaches without cancelling)
testingbot artifacts --id <projectId> Download --report and/or --download-artifacts for a finished project
testingbot list [--count] [--offset] List recent Maestro projects, newest first
testingbot login Authenticate via the browser and store the credentials in ~/.testingbot

See Async runs, status and artifacts for a pipeline example.

Frequently asked questions

How do I pin a specific Maestro version on TestingBot?

Pass the maestroVersion option in your run configuration. See the Set Maestro Version section for the list of supported versions and CLI / API examples.

How do I pass environment variables to Maestro flows?

Use the env option to inject environment variables into the Maestro run. The flows can then read them with the ${VARIABLE_NAME} syntax inside the YAML. See the Environment Variables section for examples.

Can I run only a subset of my Maestro flows?

Yes. Use flows to whitelist specific files, or includeTags and excludeTags to filter by Maestro tag. Only the flows that survive the filter are scheduled, so the rest do not consume a device session, and a filter that matches nothing is rejected rather than run. See the Select Specific Flows, Include Tags and Exclude Tags sections.

How do I split Maestro flows into parallel shards?

Pass shardSplit with the number of parallel sessions you want. Each shard runs a subset of the flows on its own device session. See the Shard Split section for details.

Can I change the device timezone, locale or geolocation for Maestro tests?

Yes. Use the timezone, locale and geolocation options to control the device environment. See the Device Timezone, Device Locale and IP Geolocation sections.

Can I test a private or staging server with Maestro on TestingBot?

Yes. Start the TestingBot Tunnel and pass tunnelIdentifier in your Maestro run config. The device will route traffic through your tunnel so it can reach internal APIs. See the TestingBot Tunnel section.

Was this page helpful?
Last updated