Migrate from Maestro

View as Markdown

Maestro is already close to where TesterArmy starts: flows are declarative YAML (tapOn, inputText, assertVisible) instead of imperative code. The friction that remains is the matching layer - flows still reference text, IDs, and indexes that drift as your UI changes, and you maintain a tree of .yaml files plus the local Maestro runtime.

TesterArmy replaces the YAML flow with natural-language steps executed by an AI agent that sees the screen, running on cloud simulators and emulators. Because Maestro flows already read like instructions, this is close to a one-to-one conversion. The fastest path is letting your coding agent (Claude Code, Cursor, Codex) read your flow files and convert them with the TesterArmy CLI.

How concepts map

MaestroTesterArmy
A flow .yaml fileA mobile test with natural-language steps
launchApp, tapOn, inputText, scrollact steps (“Tap Sign in”, “Enter the email”)
assertVisible, assertNotVisibleassert steps (“The home feed is visible”)
Login sub-flowslogin step + project credentials
runFlow reusable sub-flowsRepeated steps, or project memories for shared context
env: variables / flow parametersRepresentative values written into step text
Selectors (text, id, index, point)Not needed - the agent finds elements visually
Retries, waitForAnimationToEnd, extendedWaitUntilNot needed - the agent waits like a human
appId + local buildAn uploaded app build (iOS Simulator .app, Android .apk/.apks)
Local simulators/emulators / Maestro CloudManaged cloud simulators/emulators
maestro test in CIGitHub Actions or ta ci

What translates and what doesn’t

This is the easiest mobile migration: each YAML command maps almost directly onto a TesterArmy step. tapOn/inputText/scroll become act steps, assertVisible/assertNotVisible become assert steps, and selector details (text, id, index) are simply dropped because the agent works from intent.

Things to leave behind:

  • Low-level commands like pressKey, raw tapOn by point, or runScript JavaScript - express the user-visible intent as a step instead.
  • Physical-device-only features - camera and biometrics (Face ID, Touch ID) are not available on simulators. Contact us if you need real devices.
  • Device-build artifacts (.ipa, .aab, .xapk) - TesterArmy needs an iOS Simulator .app or an Android .apk/.apks. See App Uploads.

Prerequisites

$npm install -g testerarmy
$ta auth

Get an API key from the dashboard. For non-interactive agent sessions, set TESTERARMY_API_KEY instead. You also need a mobile build: an iOS Simulator .app or an Android .apk/.apks - see App Uploads.

The migration prompt

Paste this into your coding agent in the repository that contains your Maestro flows:

Migrate this repository's Maestro flows to TesterArmy using the TesterArmy
CLI (`ta`). Verify auth first with `ta status --json`, and use `ta --help`
plus subcommand help to discover commands. Prefer --json output.
1. Discover: find all Maestro flow files (.maestro/ or *.yaml flows with an
appId and commands). Read shared sub-flows referenced by runFlow and any
env config. Note whether flows target iOS, Android, or both.
2. Create a TesterArmy mobile project (skip if one exists in
`ta projects list`):
echo '{"name":"<app name>","url":"","projectType":"mobile"}' | ta projects create --json
3. Build and upload the app artifact. For iOS use an iOS Simulator `.app`
build; for Android use a release `.apk` or `.apks`. Do not use .ipa,
.aab, or .xapk. Upload it:
ta upload-app --app-path <path-to-build> --project <projectId> --json
Report the uploaded app ID.
4. Convert each reusable Maestro sub-flow (runFlow) into a project memory
so every test run knows about it (category site_structure, importance
high), e.g. "Login sub-flow: tap Sign in, enter email and password,
land on the home feed."
echo '{"category":"site_structure","title":"...","content":"...","importance":"high"}' | ta memories create --project <projectId> --json
5. Convert each Maestro flow into a TesterArmy mobile test:
- tapOn / inputText / scroll / launchApp -> steps with type "act"
- assertVisible / assertNotVisible -> steps with type "assert"
- login sub-flows -> one step with type "login"
- Where env variables or parameters supplied values, write the
representative case in plain English.
- Drop all selector details (text matchers, id, index, point) and wait
commands - the agent finds elements visually and waits on its own.
- Keep tests focused: 3-10 steps. Split flows covering multiple journeys
into separate tests.
Create each test with platform "mobile":
echo '{"title":"<flow name>","description":"Migrated from <flow file>","platform":"mobile","steps":[{"title":"Tap Sign in","type":"act"},{"title":"The home feed is visible","type":"assert"}]}' | ta tests create --project <projectId> --json
Step types: act, assert, login, screenshot.
6. Never hardcode passwords in test steps. If flows read credentials from
env config, tell me which credentials to add and I will run:
echo '{"kind":"login","label":"...","username":"...","password":"..."}' | ta projects credentials-create <projectId> --json
7. Tell me each created test ID and remind me to select the uploaded app
on each test (dashboard App Upload tab), then run them to verify. A
migrated test can also be run remotely with
`ta tests run <testId> --remote --wait --json` once the app is selected.
8. Report a summary table: Maestro flow file -> TesterArmy test ID, the
uploaded app ID, plus anything you intentionally skipped and why.

After the migration

  1. Open each migrated test in the dashboard, select your uploaded build in the App Upload tab, and run it to confirm it passes - see App Uploads.
  2. Add credentials for the logins your sub-flows handled.
  3. Wire the suite into CI with GitHub Actions or Expo EAS, replacing your maestro test job.
  4. Retire the .maestro flow files and local runtime once TesterArmy runs are green.

Next steps