How to test Expo apps using Maestro.
This guide covers how to write, run, and maintain Maestro tests for the ticked-off Expo app.
Maestro is a mobile testing framework that allows us to write UI tests in YAML. All core functionality must be covered by Maestro tests (see AGENTS.md).
Install the Maestro CLI:
brew tap mobile-dev-inc/tap
brew install maestro
Or via npm:
npm install -g maestro-cli
Tests are located in the e2e/flows/ directory:
e2e/
āāā flows/
ā āāā smoke.yaml # Basic app launch and visibility tests
ā āāā navigation.yaml # Navigation flow tests
ā āāā features.yaml # Feature-specific tests
Start the Expo dev server:
expo start --ios # or --android
Run Maestro tests in another terminal:
npm run test:maestro
maestro test e2e/flows/smoke.yaml
Every Maestro test file starts with appId and ---:
appId: com.ticked-off
---
- launchApp
- assertVisible:
text: "Expected text"
| Command | Purpose | Example |
|---|---|---|
launchApp |
Launch the app | - launchApp |
tapOn |
Tap element by text or ID | - tapOn: {text: "Button"} |
assertVisible |
Verify text is visible | - assertVisible: {text: "Hello"} |
assertNotVisible |
Verify text is hidden | - assertNotVisible: {text: "Error"} |
inputText |
Type text into field | - inputText: "user@example.com" |
scroll |
Scroll down | - scroll |
swipe |
Swipe in direction | - swipe: {direction: UP} |
waitForAnimationToEnd |
Wait for animations | - waitForAnimationToEnd |
back |
Press back button | - back |
Use testIDs for reliable test targeting:
<Text testID="welcome-message">Welcome</Text>
Then in Maestro:
- tapOn:
id: "welcome-message"
Keep flows focused - Each flow should test one feature
Use descriptive names - navigation.yaml, not test1.yaml
Minimize nested conditions - Align with project coding standards (AGENTS.md)
Early assertions - Check critical state early in tests
appId: com.ticked-off
---
- launchApp
- assertVisible:
text: "Edit app/index.tsx to edit this screen."
- scroll
- scroll
- assertVisible:
text: "Edit app/index.tsx to edit this screen."
maestro test e2e/flows/smoke.yaml --verbose
waitForAnimationToEnd before assertions on animated elementsFor GitHub Actions, add to .github/workflows/test.yml:
name: Maestro Tests
on: [push, pull_request]
jobs:
maestro:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- uses: maestrosecurity/maestro-action@v1.8.1
with:
maestro-version: latest
workspace: e2e