Workflow Examples
These examples cover the workflows readers are most likely to need first: connect to a device, open an app, inspect the screen, act, wait, verify, recover from common UI issues, and collect evidence.
Assumptions:
- The
android-emu-agentCLI is installed and onPATH. See Installation. - The daemon can reach an emulator or device.
com.example.appis the target package../artifacts/is local scratch space and is ignored by git.
Replace placeholders such as <session-id>, <device-serial>, and <apk-path> before running a
command.
Connect to a Device and Start a Session
Use this flow at the start of an automation run.
Confirm that the Android SDK can see a target:
adb devices
android-emu-agent device list
Optional: boot an emulator if no target is running:
android-emu-agent emulator list-avds
android-emu-agent emulator start <avd-name> --wait-boot
Start the daemon and check its status:
android-emu-agent daemon start
android-emu-agent daemon status --json
Start a session:
android-emu-agent session start --device <device-serial> --json
Verify that the response includes status: done and session_id.
Install or Reset an App Before Testing
Use this flow when a run must start from a known app state.
Install or replace the APK:
android-emu-agent app install <apk-path> --session <session-id> --grant-permissions --json
Optional: clear app data:
android-emu-agent app reset <session-id> com.example.app
Launch the app:
android-emu-agent app launch <session-id> com.example.app
android-emu-agent wait idle <session-id> --timeout-ms 5000
Verify the foreground app:
android-emu-agent expect current-app <session-id> --package com.example.app
If installation fails, check that the target allows APK installs and that <apk-path> points to a
local APK file.
Inspect a Screen and Tap a Control
Use this flow for the normal observe, act, verify loop.
Capture a compact text snapshot:
android-emu-agent ui snapshot <session-id> --format text
Tap a ref from the snapshot:
android-emu-agent action tap <session-id> ^g1a1
Verify the new screen:
android-emu-agent ui snapshot <session-id> --format text
If the target should be reusable across app versions, prefer a semantic selector:
android-emu-agent action tap <session-id> 'text:"Sign in" || id:com.example:id/sign_in'
Fill a Form
Use refs from a fresh snapshot for text fields. This avoids typing into the wrong field after the UI changes.
Launch the screen and wait for it to settle:
android-emu-agent app launch <session-id> com.example.app
android-emu-agent wait idle <session-id> --timeout-ms 5000
android-emu-agent ui snapshot <session-id> --format text
Set text on the email and password fields:
android-emu-agent action set-text <session-id> ^g1a2 "agent@example.com"
android-emu-agent action set-text <session-id> ^g1a3 "test-password"
Submit and verify the next state:
android-emu-agent action tap <session-id> ^g1a4
android-emu-agent expect exists <session-id> --text "Welcome" --timeout-ms 10000
If the keyboard blocks the submit button, dismiss it before tapping:
android-emu-agent action back <session-id>
android-emu-agent wait idle <session-id> --timeout-ms 3000
Wait for Navigation or Loading State
Use waits instead of fixed sleeps. Wait commands return structured timeout errors when the expected state does not appear.
android-emu-agent action tap <session-id> 'text:"Checkout" || id:com.example:id/checkout'
android-emu-agent wait gone <session-id> --text "Loading" --timeout-ms 10000
android-emu-agent wait exists <session-id> --text "Payment" --timeout-ms 10000
android-emu-agent expect activity <session-id> CheckoutActivity --timeout-ms 5000
If the wait times out, capture a fresh snapshot and check whether the app navigated to a different state than expected.
Recover When an Element Is Missing
Use this flow after ERR_NOT_FOUND, ERR_STALE_REF, or a snapshot that does not show the target.
Wait for the UI to settle:
android-emu-agent wait idle <session-id> --timeout-ms 3000
Capture a full snapshot once:
android-emu-agent ui snapshot <session-id> --full --format text
Inspect selector capability support:
android-emu-agent device capabilities --session <session-id> --json
Retry with a semantic selector:
android-emu-agent action tap <session-id> 'text-contains:"Continue" enabled:true clickable:true'
If no selector is reliable, capture a screenshot before using coordinates:
android-emu-agent ui screenshot <session-id> --pull --output ./artifacts/missing-target.png
android-emu-agent action tap <session-id> coords:540,1820
Use coordinates as the last resort because they are sensitive to device size, orientation, font scale, and layout changes.
Handle Permission and System Setup
Use this flow when an app needs notification, camera, location, or other runtime permission setup before a test.
List requested and granted permissions:
android-emu-agent system permissions list com.example.app --session <session-id> --json
Grant a runtime permission:
android-emu-agent system permissions grant com.example.app android.permission.POST_NOTIFICATIONS --session <session-id> --json
Optional: open Android system surfaces for manual or agent inspection:
android-emu-agent system notifications open --session <session-id>
android-emu-agent system quick-settings open --session <session-id>
Permission changes still follow Android runtime permission rules. If a permission cannot be granted, check the app manifest, Android version, and device policy.
Run a Reusable Task Script
Use a .aea script when a flow should be checked in, reviewed, and repeated.
Validate the script without touching a device:
android-emu-agent task validate examples/tasks/checkout-smoke.aea
Run it against the active session:
android-emu-agent task run examples/tasks/checkout-smoke.aea --session <session-id> --json
If it fails, inspect the failure payload and preserve evidence:
android-emu-agent artifact save-snapshot <session-id> --json
android-emu-agent artifact screenshot <session-id> --pull --output ./artifacts/task-failure.png --json
For writing task scripts, use the task script guide. For exact grammar, use the
.aea specification.
Collect Evidence After a Failed Flow
Use this sequence after a failed action, failed expectation, crash, or confusing UI state. It collects bounded evidence without changing app state further.
Save the latest structured UI state:
android-emu-agent artifact save-snapshot <session-id> --json
Capture a screenshot:
android-emu-agent artifact screenshot <session-id> --pull --output ./artifacts/failure-screen.png --json
Pull focused logs from the last few minutes:
android-emu-agent artifact logs \
--session <session-id> \
--app com.example.app \
--type errors \
--since "10m ago" \
--json
Add current app and task context:
android-emu-agent app current --session <session-id> --json
android-emu-agent app task-stack --session <session-id> --json
Create one bundle with available evidence:
android-emu-agent artifact bundle <session-id> --json
If the failure looks like a crash or ANR, add reliability data:
android-emu-agent reliability profile com.example.app --session <session-id> --json
android-emu-agent reliability exit-info com.example.app --session <session-id> --json
Record a Trace for a Flaky Flow
Use traces when a flow fails intermittently and you need replayable daemon request/response evidence. Replay is a dry-run plan, so inspecting a trace does not mutate a device.
android-emu-agent trace start <session-id> --label checkout-flake
android-emu-agent ui snapshot <session-id> --format text
android-emu-agent action tap <session-id> 'text:"Checkout" || id:com.example:id/checkout'
android-emu-agent wait exists <session-id> --text "Payment" --timeout-ms 5000
android-emu-agent trace stop <session-id> --output ./artifacts/checkout-flake.aea-trace.zip
android-emu-agent trace replay ./artifacts/checkout-flake.aea-trace.zip --until-failure
android-emu-agent trace export ./artifacts/checkout-flake.aea-trace.zip --output ./artifacts/checkout-flake.md
Attach the .aea-trace.zip, exported Markdown, and any screenshots or logs collected during the
same run.
Use Visual Grounding for Screenshot Review
Use visual grounding when text output is not enough and a human or vision model needs screenshot coordinates for selected refs. Grounding uses the latest snapshot; it does not run OCR or image matching.
android-emu-agent ui snapshot <session-id> --format text
android-emu-agent ui ground <session-id> --ref ^g1a1 --ref ^g1a4 --pull --output ./artifacts/grounding.json --json
android-emu-agent ui screenshot <session-id> --pull --output ./artifacts/screen.png --json
Verify that grounding.json includes coordinate_space, screenshot_path, ref, bounds, and
center fields for the selected refs.
Preflight an Intent or Deep Link
Use resolve-intent before launching an implicit intent or deep link on a device that may have
multiple handlers.
android-emu-agent app resolve-intent \
--session <session-id> \
--action android.intent.action.VIEW \
--data "https://example.com/deep" \
--json
android-emu-agent app deeplink <session-id> "https://example.com/deep"
android-emu-agent wait activity <session-id> DeepLinkActivity --timeout-ms 10000
If the preflight is ambiguous, launch with an explicit package or component:
android-emu-agent app intent <session-id> \
--action android.intent.action.VIEW \
--data "https://example.com/deep" \
--package com.example.app
Use --component com.example.app/.DeepLinkActivity when you know the exact activity and want to
avoid resolver choice entirely.
Attach a Debugger at Startup
Use this flow when UI-level signals are not enough and the target app is debuggable.
android-emu-agent app launch <session-id> com.example.app --wait-debugger
android-emu-agent debug attach --session <session-id> --package com.example.app --keep-suspended
android-emu-agent debug break set com.example.app.MainActivity 42 --session <session-id>
android-emu-agent debug resume --session <session-id>
android-emu-agent debug events --session <session-id>
android-emu-agent debug observe --session <session-id> --json
android-emu-agent debug detach --session <session-id>
Debugger commands require JDK 17+ and a debuggable app. Use --process on debug attach when the
package has multiple debuggable processes.