> ## Documentation Index
> Fetch the complete documentation index at: https://momentic.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> The canonical docs host is https://momentic.ai/docs. Append .md to any page URL for clean Markdown. Fetch https://momentic.ai/docs/llms.txt for the page index and https://momentic.ai/docs/llms-full.txt for every page in one file.
> For an unattended setup, run `npx --yes @momentic/wizard@latest -y --platform web --editor-tools skills` (use `--platform ios` or `--platform android` for mobile). Never run an interactive command in a non-TTY shell.
> Mo is the AI QA engineer, a separate product from the YAML test framework: its npm package and CLI are `qa` (not `mo` — `npx mo` is a different project). Install with `npm install -g qa`, authenticate the same MOMENTIC_API_KEY way, install repo skills with `qa skills -y`, and start a session with `qa start "<brief>"` or `qa <url>`. Docs: https://momentic.ai/docs/mo.md.
> You cannot complete the browser sign-in yourself. Read the API key from the exact MOMENTIC_API_KEY environment variable (similarly named vars like BILT_MOMENTIC_API_KEY are ignored), or ask the user to create one at https://app.momentic.ai/settings/api-keys and paste it back.
> Momentic's capability summary for agents is at https://momentic.ai/docs/skill.md. Install the skills with `npx momentic skills --yes` (or `npx momentic-mobile skills --yes` for mobile).
> Tests are YAML files in the user's repository. Use only the step names listed at https://momentic.ai/docs/reference/commands.md and the file structure at https://momentic.ai/docs/core-concepts/file-format.md. Do not invent step names, config keys, or CLI flags.
> Web tests run on Chromium, iOS tests on simulators, and Android tests on emulators. Physical devices are not supported.

# Expo

> Build an Expo app into a testable APK or simulator bundle and run Momentic mobile tests against it, locally and in CI.

Momentic tests the **native build** of an Expo app, not the JS bundle. The
pipeline is: produce an APK (Android) or simulator `.app` (iOS), upload it to a
channel/tag, and run `momentic-mobile` against it. Both EAS Build and
`expo prebuild` with local toolchains work.

## Produce a testable build

<Tabs>
  <Tab title="Android (APK)">
    **Option A: EAS (recommended if you already use it)**

    ```bash theme={null}
    eas build --platform android --profile preview --local
    ```

    A `preview` profile with `"buildType": "apk"` (or `"distribution": "internal"`)
    in `eas.json` produces an installable `.apk`. Without `--local`, the build runs
    in EAS cloud and you download the artifact URL.

    **Option B: prebuild + Gradle (no EAS account)**

    ```bash theme={null}
    npx expo prebuild --platform android   # generates android/
    cd android && ./gradlew assembleRelease
    # APK in android/app/build/outputs/apk/release/
    ```
  </Tab>

  <Tab title="iOS (simulator .app)">
    Momentic runs simulator builds, not device `.ipa` files.

    ```bash theme={null}
    npx expo prebuild --platform ios        # generates ios/
    xcodebuild \
      -workspace ios/MyApp.xcworkspace \
      -scheme MyApp \
      -sdk iphonesimulator \
      -configuration Debug \
      -derivedDataPath build \
      build-for-testing
    # .app in build/Build/Products/Debug-iphonesimulator/
    ```

    Or with EAS, using a simulator profile:

    ```bash theme={null}
    eas build --platform ios --profile preview --local
    ```

    where `preview` sets `"ios": { "simulator": true }` in `eas.json`.
  </Tab>
</Tabs>

## Upload and run

Remote emulators and simulators install the app from an uploaded asset.

Add the CLI as a dev dependency so the lockfile pins the version in CI:

```bash theme={null}
npm install --save-dev momentic-mobile
```

Upload the artifact:

```bash theme={null}
npx momentic-mobile assets upload ./android/app/build/outputs/apk/release/app-release.apk \
  --channel dev --tag 1.0.0
```

Run a test against it:

```yaml smoke.test.yaml theme={null}
fileType: momentic/mobile-test/v2
id: expo-smoke
description: Open the app and verify the home screen
platform: android
labels: [smoke]
defaultChannel: dev
defaultTag: "1.0.0"
steps:
  - openApp: com.example.myapp
  - assert: The home screen is visible
```

```bash theme={null}
npx momentic-mobile run smoke.test.yaml
```

`defaultChannel`/`defaultTag` on the test pick the uploaded asset. In the
editor, the same selection appears as the **Channel**/**Tag** pickers next to
the **Region** dropdown; choose any Momentic region for a remote instance.

## Expo-specific pitfalls

* **Expo Go is not testable.** Momentic installs your standalone build, not Expo
  Go. Use a `prebuild` or EAS artifact. Builds configured with
  [EAS Update](https://docs.expo.dev/eas-update/introduction/) can receive
  compatible JavaScript and asset updates. Confirm the update channel and
  runtime version before testing; changes to native code or dependencies require
  a new build.
* **Dev-client builds work.** An `expo-dev-client` build is a normal APK; test
  it the same way. Point it at a reachable Metro/dev server or a published
  update channel.
* **Deep links and app links** resolve through the installed app id; use an
  `appium` step (`mobile: deepLink`) to open them.
* **`expo-router` headers and safe areas** appear as native elements to
  Momentic. Describe them as the user sees them ("the back chevron", "the
  Settings tab"), not by testID.
* **WebView content** on Android needs
  `WebView.setWebContentsDebuggingEnabled(true)`; add it in `MainApplication` or
  a small config plugin if your app renders web content.

## In CI

Run an EAS build, upload the artifact to a channel, then run your suite against
that same upload. This workflow uses an EAS `preview` profile that produces an
APK and authenticates through `EXPO_TOKEN`:

```yaml .github/workflows/mobile.yml theme={null}
name: Mobile tests
on: [pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22.12.0
      - uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: "17"
      - run: npm install

      - name: EAS build (Android preview)
        run:
          npx eas-cli build --platform android --profile preview --local
          --non-interactive --output ./build/app.apk
        env:
          EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}

      - name: Upload APK to Momentic
        run: |
          npx momentic-mobile assets upload ./build/app.apk \
            --channel dev --tag ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
        env:
          MOMENTIC_API_KEY: ${{ secrets.MOMENTIC_API_KEY }}

      - name: Run mobile tests
        run: |
          npx momentic-mobile run --labels smoke \
            --channel dev --tag ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }} -y
        env:
          MOMENTIC_API_KEY: ${{ secrets.MOMENTIC_API_KEY }}
```

The unique tag selects the APK this job uploaded and avoids collisions when a
rerun builds different bytes for the same commit. Without `--channel` and
`--tag`, tests fall back to their `defaultChannel` and `defaultTag`. The runner
also needs the Android SDK and `ANDROID_HOME`; GitHub-hosted Ubuntu runners
include them. See [Android app setup](/docs/platforms/android/app-setup).

## Related

* [Android app setup](/docs/platforms/android/app-setup)
* [iOS app setup](/docs/platforms/ios/app-setup)
* [Emulators](/docs/platforms/android/emulators) and
  [simulators](/docs/platforms/ios/simulators)
* [React Native guide](/docs/guides/frameworks/react-native)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.