Test Node CLI Reference
Complete command-line reference for Test Node. The Test Node executes automated tests on devices connected to DeviceLab, supporting multiple frameworks including Maestro, Appium, Espresso, and XCUITest.
Synopsis
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- [OPTIONS]
Replace YOUR_ORG_KEY with your organization ID from the DeviceLab dashboard.
Options
--name <string>
Set a custom name for this test run. Default: system hostname.
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- \
--name "GitHub - Alpha Release Pipeline" \
--framework maestro \
--app ./app.apk \
--tests ./tests/
Naming examples for CI/CD:
GitHub - Alpha Release PipelineGitLab - Nightly RegressionJenkins - PR Validation #1842CircleCI - Smoke TestsLocal - Manual QA Session
--framework <string>
Required. Test framework to use.
| Value | Description |
|---|---|
maestro |
Maestro UI testing framework |
appium |
Appium automation framework |
espresso |
Android Espresso tests |
xcuitest |
iOS XCUITest tests |
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- \
--framework maestro \
--app ./app.apk \
--tests ./flows/
--app <path>
Path to application file.
| Extension | Platform |
|---|---|
.apk |
Android |
.aab |
Android (App Bundle) |
.ipa |
iOS |
.app |
iOS (Simulator) |
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- \
--framework maestro \
--app ./build/app-debug.apk \
--tests ./flows/
Required for: maestro, espresso, xcuitest
Optional for: appium
--tests <path>
Path to test files or directory.
# Directory of test files
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- \
--framework maestro \
--app ./app.apk \
--tests ./maestro-tests/
Required for: maestro, espresso, xcuitest
Optional for: appium
--suite <path>
Specific suite file to run. Maestro only.
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- \
--framework maestro \
--app ./app.apk \
--tests ./maestro-tests/ \
--suite regression.yaml
Note:
--suiterequires--teststo specify the directory containing the suite file.
--platform <string>
Target platform. Auto-detected from app extension if not specified.
| Value | Description |
|---|---|
android |
Android devices/emulators |
ios |
iOS devices/simulators |
--device-names <string>
Comma-separated list of specific device names.
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- \
--framework maestro \
--app ./app.apk \
--tests ./flows/ \
--device-names "Pixel 8,iPhone 15 Pro,iPad Air"
--device-count <int>
Number of devices to allocate. Default: 1.
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- \
--framework maestro \
--app ./app.apk \
--tests ./flows/ \
--device-count 5
Note: Ignored if
--device-namesis specified.
--test-timeout <int>
Timeout in minutes for each test. Default: framework-specific.
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- \
--framework maestro \
--app ./app.apk \
--tests ./flows/ \
--test-timeout 30
--cli-params <string>
Parameters to pass to the test framework.
# Maestro environment variables
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- \
--framework maestro \
--app ./app.apk \
--tests ./flows/ \
--cli-params "-e USERNAME=test -e PASSWORD=secret"
--max-retries <int>
Maximum number of retries for failed tests. Default: 0 (no retries).
| Value | Behavior |
|---|---|
0 (default) |
No retries - failed tests stay failed |
1 |
Retry once (max 2 total attempts) |
2 |
Retry twice (max 3 total attempts) |
3 |
Retry 3 times (max 4 total attempts) |
# Retry failed tests up to 3 times
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- \
--framework maestro \
--app ./app.apk \
--tests ./flows/ \
--max-retries 3
# Combined with other options
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- \
--framework maestro \
--app ./app.apk \
--tests ./flows/ \
--device-count 2 \
--max-retries 2
Tip: Use retries to handle flaky tests in CI/CD pipelines. A test must fail all retry attempts before being marked as failed in the final results.
Framework-Specific Requirements
Maestro
| Option | Required |
|---|---|
--framework |
Yes (maestro) |
--app |
Yes |
--tests |
Yes (directory) |
--suite |
No |
Appium
| Option | Required |
|---|---|
--framework |
Yes (appium) |
--app |
No |
--tests |
No |
Espresso
| Option | Required |
|---|---|
--framework |
Yes (espresso) |
--app |
Yes (app APK) |
--tests |
Yes (test APK) |
XCUITest
| Option | Required |
|---|---|
--framework |
Yes (xcuitest) |
--app |
Yes (.app or .ipa) |
--tests |
Yes (test bundle) |
Exit Codes
| Code | Description |
|---|---|
0 |
Success |
1 |
Invalid arguments or framework |
2 |
Port unavailable |
3 |
Connection error |
4 |
Configuration error |
5 |
Test execution error |
Examples
Basic Maestro Test
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- \
--framework maestro \
--app ./app.apk \
--tests ./maestro-tests/
GitHub Actions - Release Pipeline
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- \
--name "GitHub - v2.1.0 Release Validation" \
--framework maestro \
--app ./app-release.apk \
--tests ./maestro-tests/ \
--suite regression.yaml \
--device-count 5
GitLab CI - Nightly Tests
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- \
--name "GitLab - Nightly E2E Tests" \
--framework maestro \
--app ./app.apk \
--tests ./e2e-tests/ \
--device-count 10 \
--test-timeout 45
Jenkins - PR Validation
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- \
--name "Jenkins - PR #${BUILD_NUMBER} Smoke Tests" \
--framework maestro \
--app ./app-debug.apk \
--tests ./smoke-tests/ \
--device-count 3
Parallel Testing with Environment Variables
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- \
--name "CircleCI - Staging Environment" \
--framework maestro \
--app ./app.apk \
--tests ./maestro-tests/ \
--device-count 5 \
--cli-params "-e API_URL=https://staging.api.com -e DEBUG=true"
iOS Testing on Specific Devices
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- \
--name "Manual QA - iOS Compatibility" \
--framework maestro \
--platform ios \
--app ./MyApp.app \
--tests ./maestro-tests/ \
--device-names "iPhone 15 Pro,iPhone 14,iPad Air"
Appium Tests
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- \
--name "Bitrise - Appium Integration Tests" \
--framework appium \
--app ./app.apk
Espresso Tests
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- \
--name "GitHub - Android Unit Tests" \
--framework espresso \
--app ./app.apk \
--tests ./app-androidTest.apk
XCUITest
curl -fsSL https://app.devicelab.dev/test-node/YOUR_ORG_KEY | sh -s -- \
--name "Azure DevOps - iOS UI Tests" \
--framework xcuitest \
--app ./MyApp.ipa \
--tests ./MyAppUITests.xctest
Platform Auto-Detection
| App Extension | Detected Platform |
|---|---|
.apk |
android |
.aab |
android |
.ipa |
ios |
.app |
ios |
Retry Behavior
Test Retries
Use --max-retries to automatically retry failed tests:
- Default:
0(no retries) - Max value: No limit (use reasonable values like 1-3)
- Behavior: Failed tests are re-executed up to the specified number of times
Connection Retries
Built-in connection retry behavior:
- Connection retries: 3 attempts
- Retry delay: 5 seconds
- Retried errors: Health check failures
Graceful Shutdown
Handles SIGINT (Ctrl+C) and SIGTERM:
- Stops signal service
- Stops running tests
- Disconnects from server
- Closes connections