Skip to content

FAQ & Troubleshooting

Comprehensive guide to common questions, issues, and solutions when using mobile-automator.

Table of Contents

  1. General Questions
  2. Setup & Installation
  3. Test Generation
  4. Test Execution
  5. Integration
  6. Performance & Optimization
  7. Troubleshooting
  8. Getting Help
  9. Glossary

General Questions

What is mobile-automator?

Answer: mobile-automator is a host-agnostic mauto CLI that lets any AI coding agent generate and execute mobile tests using natural language. Instead of writing tests manually in Appium, XCTest, or Espresso, you describe what you want to test in simple language; your agent drives the device through mauto verbs (which wrap mobile-mcp) to author JSON test scenarios and replay them automatically.

Key point: It's NOT a direct testing tool like Selenium or Appium. It splits the work into a brain (your AI agent, which decides what to do) and hands (mauto verbs, which perform deterministic actions). Any agent — Claude Code, Cursor, Gemini CLI, GitHub Copilot, OpenAI Agents, or any MCP-capable agent — can be the brain.

How is mobile-automator different from Appium/XCTest/Espresso?

Aspect mobile-automator Traditional Frameworks
Test Language Natural language descriptions Code (Java, Python, Swift, Kotlin)
Selector Strategy Visible text + role + coordinates Hard-coded IDs/XPaths
Wait Strategy Automatic with intelligent retries Manual explicit waits
Domain Knowledge Auto-detected from project Embedded in test code
Portability One scenario runs on Android & iOS Per-platform test suites
Learning Curve Minimal (describe in words) Steep (framework-specific)
Maintenance Scenarios are plain JSON Manual test updates
Test Speed Optimized for clarity, not performance Optimized for speed

Do I need to write code?

Answer: No. Tests are described in plain English. Your agent converts them to JSON scenarios and drives the device through mauto verbs. You never touch code unless you want to hand-edit a scenario.

Example flow:

Natural Language: "User logs in with email and password"
↓
Generated JSON: scenario_login_happy_path.json
↓
Executed Automatically: Tap fields, type text, verify dashboard

What platforms does mobile-automator support?

Answer: Currently supported: - ✅ Android (via mobile-mcp) - ✅ iOS (via mobile-mcp) - ✅ Flutter (Android & iOS cross-platform) - ✅ React Native (Android & iOS cross-platform) - ✅ Kotlin Multiplatform (KMP) (Android & iOS) - ✅ Compose Multiplatform (CMP) (Android & iOS)

See our examples for Android and iOS patterns.

When should I use agnostic vs aware mode?

Answer: Choose platform-agnostic when your app ships to both Android and iOS from a shared codebase (Flutter, React Native, Kotlin Multiplatform, Compose Multiplatform) and you want a single set of test scenarios that run on either platform without modification.

Choose platform-aware when: - Your project targets only one OS (pure Android or pure iOS native app) - Your tests intentionally exercise OS-specific behaviour or UI patterns - You have a legacy project already configured in aware mode and you don't need cross-platform portability

In practice: if you are using Flutter, React Native, KMP, or CMP, start with agnostic. For native Android-only or iOS-only apps, use aware.

How do I choose a mode for a new project?

Answer: Set the mode when you scaffold the workspace with mauto setup:

mauto setup                 # platform-aware (default)
mauto setup --mode agnostic # platform-agnostic

The chosen mode is stored as mode in mobile-automator/config.json (read it back with mauto config get mode). In agnostic mode, OS-shaped gestures become four semantic actions — press_back, dismiss_keyboard, grant_permission, deny_permission — resolved to the right native primitive at runtime, so one scenario covers both platforms.

What is the $schema_version field?

Answer: Every test scenario JSON file includes a $schema_version field (currently "2.1") as its first field. This enables version detection for schema evolution. All scenarios must include this field.

Does the agent remember anything between sessions?

Answer: Yes. mobile-automator keeps a small cross-session memory under mobile-automator/memory/, so the agent gets smarter about your app over time instead of re-discovering the same quirks on every run. There are three kinds:

  • run-history (run-history.md) — machine-owned. Auto-harvested on mauto result finalize: typed observations (regression / flakiness / state context) are folded into a bounded rolling per-scenario summary. You don't edit this by hand.
  • app-knowledge (app-knowledge.md) — agent-authored durable facts about the app (selectors, conventions, gotchas).
  • preferences (preferences.md) — agent-authored testing preferences.

Inspect memory (prints raw markdown, not the JSON envelope):

mauto memory show                              # everything
mauto memory show --kind app-knowledge         # one kind
mauto memory show --kind run-history --scenario login_happy_path

Add or remove agent-authored entries (only app-knowledge and preferences are writable — run-history is not):

mauto memory add "Login button is labeled 'Sign in', not 'Log in'" --kind app-knowledge
mauto memory forget --kind app-knowledge --match "Sign in"

Entries are exact-match de-duped and written under an advisory lock with atomic writes, so concurrent runs won't corrupt the files. The generate and execute workflows consult memory before work and save durable knowledge they learn.

Can I use mobile-automator with my existing tests?

Answer: Partially. If you have: - Appium/Espresso/XCTest tests → No direct import, but use mobile-automator for new tests - Custom test infrastructure → Yes, mobile-automator complements existing tools

Best approach: Run mobile-automator alongside existing tests for new features.


Setup & Installation

How do I install mobile-automator?

Answer: mauto is published on npm:

npm i -g mobile-automator      # exposes `mauto` globally

Or run it ad hoc with npx mobile-automator <verb>. To run unreleased changes, clone the repo and npm install && npm link instead.

Then, from your mobile project, wire it into your agent and scaffold the workspace:

cd /path/to/mobile-project
mauto init --agent claude      # or: cursor | gemini | copilot | agents | all
mauto setup                    # add --mode agnostic for cross-platform apps
mauto devices                  # confirm a device is visible

See the installation guide for full details.

Setup failed. What do I do?

Answer: If mauto setup fails:

  1. Check the error message — Note what went wrong (e.g., a missing package ID, no detectable platform)
  2. Fix the issue — Provide the value when prompted, or pass it explicitly
  3. Re-run mauto setup — It rescaffolds the workspace
  4. Verify completion — Check that mobile-automator/config.json was created (mauto config get mode)

The workspace state lives entirely in mobile-automator/config.json; there is no separate resume file to clean up.

"Platform detection failed" — What should I do?

Cause: Your project structure doesn't match recognized patterns.

Solutions: 1. Manually select your platform when prompted 2. Ensure build files exist: - Android: build.gradle or build.gradle.kts - iOS: Xcode.xcodeproj or .xcworkspace - Flutter: pubspec.yaml 3. Provide platform details manually if auto-detection fails

Example: If setup can't detect iOS, you'll be prompted:

Platform detection failed.
Supported: android, ios, flutter, react-native, kmp, cmp
Enter your platform: ios

"Package ID not found" — How do I fix this?

Cause: Auto-detection can't find your app's package ID.

Solutions:

For Android: - Check app/build.gradle for applicationId:

defaultConfig {
  applicationId "com.example.myapp"  // ← This one
}
- Or check AndroidManifest.xml for package attribute

For iOS: - Check Xcode project General tab > Bundle Identifier - Or check Info.plist for CFBundleIdentifier - Or check ${PROJECT_DIR}/project.pbxproj for PRODUCT_BUNDLE_IDENTIFIER

When setup prompts, enter the full package ID (e.g., com.example.app for Android, com.example.MyApp for iOS).

"Agent skills weren't installed" — Why?

Cause: mauto init didn't write the Agent Skills into your host's skills directory.

Solutions: 1. Re-run init for your agent — mauto init --agent claude (or cursor | gemini | copilot | agents | all) 2. Check the skills directory — Confirm the files landed in your host's skills dir:

# examples per host
ls -la .claude/skills/
ls -la .cursor/skills/
ls -la .gemini/skills/
3. Verify the workspace config — mauto config get mode should return your mode 4. For Claude Code / Cursor, confirm init also wrote the command files and MCP entry:
ls -la .claude/commands/ .mcp.json


Test Generation

How do I generate a test scenario?

Answer: 1. Ensure setup is complete: mobile-automator/config.json exists 2. Confirm a device is visible: mauto devices (pin one with mauto devices use <id> if needed) 3. From inside your agent, launch the generate workflow: - Claude Code: /mobile-automator-generate - Cursor: ask in plain language (e.g. "generate a login test") - Any other agent: mauto mcp (MCP prompts) or mauto guide generate + call verbs directly 4. Describe your test in natural language when prompted 5. Review the generated JSON in mobile-automator/scenarios/

Example prompt:

Describe the test scenario:
> User logs in with email and password, verifies dashboard loads

Generated: mobile-automator/scenarios/login_happy_path.json

"Element not found when generating" — What does this mean?

Cause: The agent couldn't find an element you described on the current screen.

Solutions: 1. Check app state — Ensure app is in the right state (logged out for login test) 2. Be more specific — Use visible text or position: "Blue login button in bottom right" 3. Use element labels — Reference the element's accessibility label if available 4. Check if element exists — Take a screenshot manually (mauto screenshot <path>) to verify 5. Use alternative references — Describe location: "Button below password field"

"Generator misinterpreted my intent" — How do I fix it?

Answer: You can edit the generated JSON directly:

  1. Review generated scenario — Check mobile-automator/scenarios/
  2. Edit JSON manually — Fix targets, actions, assertions
  3. Validate schema — Run mauto validate <file> (see the schema reference)
  4. Re-execute — Run the execute workflow with the corrected scenario

Common edits: - Adjust the target's visible text or role - Add/remove assertions - Adjust timeout values - Add wait steps before actions

Can I generate tests for multiple platforms?

Answer: Yes. If you set up in platform-agnostic mode (mauto setup --mode agnostic), a single scenario runs on both Android and iOS — OS gestures resolve to the four semantic actions at replay time.

In platform-aware mode, generate a scenario on each platform separately and mark the platform field ("android" or "ios") to capture platform-specific behaviors.

How do I parameterize tests (different data)?

Answer: Use the variables section in scenarios:

{
  "variables": {
    "test_email": {
      "type": "string",
      "description": "Email used to log in",
      "value": "user@example.com"
    },
    "test_password": {
      "type": "string",
      "description": "Password used to log in",
      "value": "SecurePassword123"
    }
  },
  "steps": [
    {
      "id": "enter_email",
      "action": "type",
      "target": "email_input",
      "value": "{{test_email}}",
      "description": "Type the test email into the email field"
    }
  ]
}

For running with different values, manually edit the JSON or wire the values in from your CI pipeline.


Test Execution

How do I execute a test scenario?

Answer: From inside your agent, launch the execute workflow:

  • Claude Code: /mobile-automator-execute
  • Cursor: ask in plain language (e.g. "execute the login scenario")
  • Any other agent: mauto mcp (MCP prompts) or mauto guide execute + call verbs directly

The agent then: 1. Selects a scenario — from mobile-automator/scenarios/ 2. Confirms the device — uses the pinned/visible device (mauto devices) 3. Confirms app installation — installs a named artifact if you gave one; otherwise builds it in platform-aware projects, or asks you to install it yourself in platform-agnostic projects 4. Runs the test — executes all steps and assertions

Results saved to: mobile-automator/results/<run_id>.json

"Step failed: Element not found" during execution

Cause: Element isn't on screen when the step tries to use it.

Solutions: 1. Add explicit wait — Insert a wait step before the action:

{
  "steps": [
    {
      "id": "wait_for_button",
      "action": "wait_for_element",
      "target": "button_id",
      "description": "Wait for the button to appear",
      "wait_config": { "type": "element_visible", "timeout_ms": 5000 }
    }
  ]
}

  1. Verify app state — Ensure app is in expected state before executing
  2. Check the target — Verify you're using the element's visible text/role
  3. Increase timeout — Slow devices may need longer waits
  4. Add screenshot assertion — Debug what's actually on screen:
    {
      "assertions": [
        {
          "id": "verify_screen",
          "after_step": "wait_for_button",
          "type": "screenshot_match",
          "reference_screenshot": "expected_screen.png",
          "description": "Screen matches the expected baseline"
        }
      ]
    }
    

"Assertion failed: Expected X, got Y"

Cause: Assertion condition wasn't met during test.

Solutions: 1. Check assertion syntax — Verify expected_text, expected_value, expected_substring 2. Verify actual app data — Manually check what value is displayed 3. Handle dynamic content — If value changes, use text_contains instead of text_matches 4. Add debug screenshot — Insert a capture step to see actual state:

{
  "steps": [
    {
      "id": "capture_state",
      "action": "capture_value",
      "target": "title",
      "capture_to": "actual_title",
      "description": "Capture the current title"
    }
  ]
}

"Test timed out" error

Cause: Step took too long or app is hung.

Solutions: 1. Increase timeout — Default is 10s, try 15-30s:

{
  "id": "wait_for_loading",
  "action": "wait_for_loading_complete",
  "description": "Wait for loading to complete",
  "wait_config": { "type": "loading_complete", "timeout_ms": 30000 }
}

  1. Check device state — Is device frozen or unresponsive?

    mauto devices      # confirm the device is still visible
    adb devices        # Android
    xcrun simctl list  # iOS
    

  2. Simplify steps — Break into smaller scenarios

  3. Add intermediate waits — Between rapid actions:

    {
      "steps": [
        {
          "id": "wait_before_next",
          "action": "wait_for_loading_complete",
          "description": "Brief wait before the next action",
          "wait_config": { "type": "loading_complete", "timeout_ms": 2000 }
        }
      ]
    }
    

  4. Reduce app complexity — Close other apps, reduce network load

How do I debug a failed test?

Answer: Check the result JSON for detailed info:

cat mobile-automator/results/run_20260301_143022.json

Look for: - observations — AI insights about failure (flakiness, regression, state context) - steps_executed — Which step failed and why - assertion_results — Which assertion failed - captured_variables — What values were captured - screenshots — Screenshots of failure state

Example output:

{
  "observations": [
    {
      "type": "flakiness",
      "message": "Step 4 failed due to loading indicator still visible",
      "suggestion": "Increase wait timeout or add explicit wait_for_loading_complete"
    }
  ],
  "steps_executed": [
    {
      "step_id": "tap_login",
      "status": "passed"
    },
    {
      "step_id": "wait_for_dashboard",
      "status": "failed",
      "error": "Element not found after 5 seconds"
    }
  ]
}

Can I run tests in parallel?

Answer: Not yet, but you can: 1. Run sequential scenarios — Execute multiple scenarios one after another 2. Use different test jobs — Run tests in CI/CD on different devices 3. Separate data — Ensure tests don't share data between runs 4. Use variables — Parameterize tests to avoid conflicts

Parallel execution is on the roadmap.


Integration

How do I integrate with CI/CD?

Answer: mobile-automator works in CI/CD pipelines. The agent drives mauto verbs directly via mauto bootstrap + mauto guide <topic>, or you script the verbs yourself:

#!/bin/bash
# Install mauto (first time only)
npm i -g mobile-automator

# Wire into the project + scaffold the workspace (first time only)
mauto init --agent agents
mauto setup

# Confirm a device is visible
mauto devices

# Validate a scenario before running it
mauto validate mobile-automator/scenarios/login_flow.json

# (Your agent replays the scenario via mauto guide execute + verbs.)

# Check results
cat mobile-automator/results/latest.json | jq '.status'

CI/CD tips: - Cache node_modules so npm install is fast on subsequent runs - Connect a device or boot an emulator/simulator in the CI environment - Run mauto verbs with --human off (the default JSON envelope is machine-readable) - Archive result files as CI artifacts

Can I use mobile-automator with GitHub Actions?

Answer: Yes! Example workflow:

name: Mobile Tests
on: [push]

jobs:
  test:
    runs-on: macos-latest  # For iOS simulator
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '20'

      - name: Install mauto
        run: npm i -g mobile-automator

      - name: Wire into project & scaffold workspace
        run: |
          mauto init --agent agents
          mauto setup

      - name: Check device is visible
        run: mauto devices

      - name: Validate scenarios
        run: mauto validate mobile-automator/scenarios/login_flow.json

      - name: Upload Results
        uses: actions/upload-artifact@v3
        with:
          name: test-results
          path: mobile-automator/results/

Performance & Optimization

How do I make tests run faster?

Answer: Test execution speed depends on app, network, and device:

  1. Reduce waits — Use shorter wait timeouts for fast-responding apps (e.g., wait_config.timeout_ms of 3000 instead of 10000)
  2. Remove unnecessary assertions — Only assert critical checks
  3. Optimize element selection — Use unique, visible targets
  4. Test on faster device — High-end device > low-end device
  5. Improve network — Fast connection > slow connection
  6. Parallelize if possible — Run multiple tests on different devices

Benchmark: Typical test scenario takes 10-60 seconds depending on app complexity.

Are tests slower than manual testing?

Answer: Yes, typically 2-5x slower. Why? - Screenshot analysis and AI vision - Safe waits to avoid flakiness - Detailed logging and assertions - Result collection and reporting

Trade-off: Slower execution but: - ✅ 100% reproducible - ✅ Zero human error - ✅ 24/7 availability - ✅ Easy to scale to many tests

How do I optimize for mobile devices with low memory?

Answer: 1. Run tests individually — Not in parallel 2. Clear app cache between tests:

{
  "preconditions": {
    "device_actions": [
      {"action": "clear_app_data"}
    ]
  }
}

  1. Reduce screenshot resolution — Configure in the workspace config
  2. Use lightweight assertions — Text checks > visual analysis
  3. Close background apps — Limit system load

Troubleshooting

"mauto: command not found"

Cause: mauto isn't on your PATH.

Solutions:

# Re-install globally
npm i -g mobile-automator

# Check npm's global bin directory is on your PATH
echo "$(npm prefix -g)/bin"

# Verify
which mauto
mauto --help

No device shown by mauto devices:

# Android: check ADB connection
adb devices
adb kill-server && adb start-server

# iOS: list simulators/devices
xcrun simctl list devices

Pin a specific device once it appears:

mauto devices use <id>     # mauto devices clear to unpin

Device state seems stuck or stale

Cause: Device actions run through one long-lived session daemon (a persistent mobile-mcp process). If it wedged — verbs hang, target the wrong device, or return stale screen state — reset it.

Solutions:

# Check whether the daemon is alive, and where its output was captured
mauto session status        # -> { running, in_flight, device, log_path }
tail -50 mobile-automator/.session/daemon.log   # stack traces live here

# Stop it (removes the socket/pidfile); it auto-restarts on the next device verb
mauto session end

# Optionally start a fresh one explicitly
mauto session start

# Re-confirm and re-pin the device
mauto devices               # list connected devices/simulators
mauto devices use <id>      # pin the intended one (mauto devices clear to unpin)

Device precedence is: explicit --device <id> > persisted selection (mauto devices use) > auto-selected lone device. If you have several devices attached and haven't pinned one, pin it to avoid the daemon acting on the wrong target.

App Installation Failures

"App not installed" error: 1. Check build succeeded — Try building manually first 2. Check device space — Free up device storage 3. Check ADB permissions — For Android, authorize device 4. Check app signing — For iOS, verify signing certificate 5. Clear previous install — Uninstall old version first

MCP / Automation Engine Issues

"mobile-mcp not loading":

mobile-mcp is pinned as a dependency of mauto and resolved from node_modules at runtime — it is never fetched on the fly.

# Reinstall dependencies from the cloned repo
cd /path/to/mobile-automator
npm install

# Confirm the pinned engine is present
ls node_modules/@mobilenext/mobile-mcp

# Re-verify the device path end-to-end
mauto devices

If you need a newer engine, bump the @mobilenext/mobile-mcp pin in the repo's package.json and re-run npm install.

Connection & Network Issues

"Connection timeout" or "Network error": 1. Check device connectivity — Enable WiFi/USB debugging 2. Check network speed — Fast network needed for screenshots 3. Check for proxy — Configure if behind corporate proxy 4. Restart device — Sometimes helps with connectivity 5. Use wired connection — USB more stable than WiFi

Memory & Performance Issues

"Out of memory" or "Process killed": 1. Run one test at a time — Not parallel 2. Reduce screenshot resolution — Smaller files 3. Clear device cache — Between test runs 4. Close background apps — Reduce system load 5. Use smaller scenarios — Fewer steps per test

File & Path Issues

"File not found" errors:

# Re-scaffold the workspace if directories are missing
mauto setup

# Check the workspace exists
ls -la mobile-automator/

"Permission denied":

# Fix directory permissions
chmod -R 755 mobile-automator/

# Fix file permissions
chmod 644 mobile-automator/scenarios/*.json


Getting Help

Still stuck? We're here to help:


Glossary

Term Definition
Scenario A test definition in JSON format describing steps and assertions
Step A single action (tap, type, wait, etc.) in a test scenario
Assertion A verification check that passes/fails based on app state
Element A UI component (button, text field, list, etc.) targeted by visible text + role + coordinates
Verb A mauto command (tap, type, swipe, assert, …) that performs a deterministic action and emits the {ok,data,error,hint,schema_version} envelope
MCP Model Context Protocol — standard for tool integration; mauto mcp exposes the workflows as prompts
Agent Skill A native skill mauto init installs into a host's skills directory so the agent knows the generate/execute/setup workflows
Mode platform-aware (default) or platform-agnostic, chosen at mauto setup and stored in mobile-automator/config.json
Semantic action One of press_back, dismiss_keyboard, grant_permission, deny_permission — resolved to a native primitive at replay time (agnostic mode)
Placeholder Template variable replaced when guide content is emitted (e.g., {{app_package}})
Precondition Setup actions required before a test runs
Variable Named value that can be referenced in steps and assertions

Back to Docs →