momentic-mobile tests while preserving the
behavior each flow checks. Both use YAML, but launch behavior, selectors,
variables, subflows, and assertions need review rather than a key rename.
Prepare the project
Complete the iOS or Android setup and keep your Maestro files and CI job. Momentic uses a separate CLI andmomentic.config.yaml; it does not execute Maestro flow files.
- Android needs an APK,
adb, andANDROID_HOMEorANDROID_SDK_ROOT, even for remote emulators. Local emulators also need an installed AVD. See Android app setup. - iOS needs a simulator
.appbuild, not a device.ipa. Local simulators require macOS, Xcode, and idb. Remote simulators use an uploaded build. See iOS app setup. - Momentic supports emulators and simulators, not physical devices. Keep Maestro coverage that requires device hardware or an unsupported OS version.
- Record the selected flow’s build, initial app state, permissions, test data, assertions, and hooks. Use the same conditions when comparing results.
Before and after
A representative Maestro flow:checkout.yaml
checkout.test.yaml
EMAIL to the existing staging environment in momentic.config.yaml. Do
not replace other environments or settings:
momentic.config.yaml
defaultEnv: staging selects that environment. A shell variable only becomes
available through an explicit variable reference or inheritFromShell: true;
shell inheritance defaults to false. Put secrets in an ignored environment
file or your CI secret store. See
environment variables.
For remote Android execution, upload the APK to a channel and pin the build tag
when running the file:
mobile-tests/checkout.test.yaml under the project’s
configured include paths, and replace the APK path with your build. Without a
channel or an explicit installation step, openApp assumes the app is already
installed. For local execution, pass an AVD and APK, or an iOS simulator type
and .app path. See
mobile run options.
Command mapping
Preserve selectors, checks, and waits
Maestro’s text and ID selectors use regular expressions. Momentic target descriptions are natural language, not regular expressions or Maestro selector objects. Translate the intended target, including any parent, position, index, or state constraint. Do not paste an ID regex intotap and assume it keeps the original match.
Use element visibility checks for
visible or hidden elements. Use
element content checks for
exact text. checkScreenContains searches the screen hierarchy or WebView
content and can match offscreen content; it does not replace assertVisible.
Use AI assertions when the intended check
is semantic, and review whether that changes the original contract.
Preserve extendedWaitUntil timeouts on a condition step in milliseconds. For
example, wait up to 30 seconds for the confirmation to become visible:
Subflows, variables, and hooks
Extract a reusable sequence into a mobile module. MaprunFlow.env values to
module inputs instead of putting every flow’s variables in the global project
environment. Keep defaults local to the module, and use setVariable or
saveAs for values created during a test. See
module parameters and
variable scope.
This module takes one input and has no nested module calls:
modules/enter-email.module.yaml
env.EMAIL is an expression; use { string: "jeff@example.com" } to pass a
literal. Flatten nested runFlow calls into the module’s steps, or invoke each
module from the test. A module cannot call another module. Module paths are
relative to the calling file, so mobile-tests/checkout.test.yaml uses
../modules/enter-email.module.yaml for the module shown above.
Translate when conditions to an assertion-based if where possible. Split
platform-specific behavior into iOS and Android tests or modules; the mobile
if condition is not a Maestro platform selector. Check loop bounds and retry
boundaries rather than renaming repeat or retry mechanically.
Move each top-level flow’s onFlowStart and onFlowComplete behavior into
before and after. Modules do not have Maestro flow hooks. Inline a subflow’s
setup at its original call site. Put cleanup that must survive a subflow failure
in the test’s after, and check that its ordering and scope still match the
original flow. A failed before skips the main steps; after still runs, so
cleanup must tolerate incomplete setup. Running one step in the editor skips
test hooks. Validate them with a whole-test run. See
before and after sections.
Check
Maestro launch options
separately. Its default launchApp restarts the app, and options can clear app
data or the iOS keychain and set permissions. Momentic’s killApp stops the
current foreground app. Use it before openApp only when the intended app is
already in the foreground; it does not target the identifier passed to a later
openApp. The Android example uses shell am force-stop to stop that package
regardless of which app is active. Neither method clears app data. To reset app
data on Android, use an adb step:
What does not map
- Momentic has no separate inspector app like Maestro Studio: the local editor’s
element picker plus
debugStatecover element inspection. - Maestro
runScriptandevalScriptcode needs adaptation. Momentic’sjavascriptstep runs in a Node sandbox with its own globals; Maestro’soutputobject and UI commands do not become Momentic APIs. Useenv,setVariable, andsaveAsfor data, and preset or AI steps for UI actions. - Physical devices are not supported: remote execution is emulators and simulators only.
- Maestro’s tolerance and optional-element flags have no equivalent: Momentic
resolves target descriptions rather than Maestro selector flags. For an
optional action, use an
ifstep with an element check and nestedthensteps. Mobileifhas noelsebranch. See mobile conditionals. - A
maestro cloudcommand and its workspace configuration do not transfer to Momentic. Configure build upload, test selection, parallelism, reporting, and scheduling explicitly in your CI provider.
Incremental strategy
- Port one bounded flow end to end, including its hooks, subflows, inputs,
waits, and cleanup. Start with a flow whose repeated locator failures you can
compare. Keep Maestro installed and preserve the
.maestrodirectory. - Lint and run the file on the intended target. Compare both runners on the same build and starting state. Inspect screenshots at assertions, including a case where the expected outcome is absent.
- Separate environment values from module parameters. Pin the app build tag and check the OS version, permissions, and reset behavior before comparing stability.
- Add a separate Momentic CI job with its own test data. Do not run both
runners concurrently on the same local emulator. Remote Momentic tests use
independent emulator sessions; local Android parallel tests need distinct
AVDs, and local iOS runs should use
--parallel 1. - Replace gates flow by flow after reviewing equivalent coverage and repeated results. Retain legacy flows for hardware, OS, selectors, or reset behavior you have not migrated. Remove their CI jobs and files only after that coverage is accounted for.
momentic-mobile from the lockfile, set MOMENTIC_API_KEY from
the CI secret store, and provide the platform prerequisites. Upload the build
with a unique tag, then use that same tag when running tests. Add
--reporter junit to generate reports under ./reports, and preserve the run
command’s exit status as the job result. See
GitHub Actions or the
other CI guides.