This directory contains end-to-end tests for GuildPass Mobile using Maestro, an Expo-compatible mobile UI testing framework.
- ✅ Validates onboarding screen display
- ✅ Tests navigation to profile screen
- File:
01-onboarding-to-profile.yaml
- ✅ Tests manual wallet address input
- ✅ Validates wallet connection flow
- ✅ Confirms connected state display
- File:
02-wallet-entry.yaml
- ✅ Tests navigation to guilds list
- ✅ Validates guild card display
- ✅ Tests guild detail navigation
- ✅ Confirms membership status display
- File:
03-guild-navigation.yaml
- ✅ Tests successful access check flow
- ✅ Validates form input and submission
- ✅ Confirms success result display
- File:
04-access-check-success.yaml - Note: Requires mock API to return success response
- ✅ Tests failed access check flow
- ✅ Validates error handling
- ✅ Confirms error message display
- File:
05-access-check-failure.yaml - Note: Requires mock API to return error response
- ✅ Tests settings navigation
- ✅ Validates reset functionality
- ✅ Confirms app returns to disconnected state
- File:
06-reset-app-state.yaml
macOS/Linux:
curl -Ls "https://get.maestro.mobile.dev" | bashWindows:
# Using WSL (recommended)
wsl
curl -Ls "https://get.maestro.mobile.dev" | bashVerify installation:
maestro --versioniOS Simulator:
# Install Xcode from App Store
# Open Xcode and install iOS Simulator
xcrun simctl list devicesAndroid Emulator:
# Install Android Studio
# Create an AVD (Android Virtual Device)
# Start emulator
emulator -list-avds
emulator @your_avd_nameDevelopment Build (recommended for E2E testing):
# iOS
npx expo run:ios
# Android
npx expo run:androidThe app will be installed on the simulator/emulator with the bundle ID xyz.guildpass.mobile.
In a separate terminal:
pnpm start# Run all flows
maestro test .maestro/
# Run specific flow
maestro test .maestro/01-onboarding-to-profile.yaml
# Run with recording
maestro test --format junit --output test-results .maestro/# Open Maestro Studio for interactive testing
maestro studioTest IDs follow this naming convention:
- Screens:
{screen-name}-screen(e.g.,onboarding-screen) - Buttons:
{action}-button(e.g.,wallet-connect-button) - Inputs:
{field-name}-input(e.g.,wallet-address-input) - Navigation:
navigate-{destination}-button - Results:
{feature}-resultor{feature}-error
For tests that depend on API responses (access checks), you can:
-
Use environment variables to switch between mock and real API:
env: MOCK_API_SUCCESS: true
-
Set up a local mock server using tools like:
-
Configure mock endpoint in
.env.test:EXPO_PUBLIC_API_URL=http://localhost:3000
See .github/workflows/e2e-tests.yml for automated E2E testing on PR and push events.
The workflow:
- Sets up Node.js and dependencies
- Installs Maestro CLI
- Builds Expo development build
- Starts iOS Simulator or Android Emulator
- Runs all Maestro test flows
- Uploads test results and recordings as artifacts
# Verify app is installed
xcrun simctl listapps booted | grep guildpass
# Reinstall app
npx expo run:ios --device- Increase timeout in flow:
- assertVisible: id: "element-id" timeout: 10000
- Check testID is correctly added to component
- Verify element is visible (not hidden or scrolled off-screen)
- Use Maestro Studio to inspect element hierarchy
# Reset iOS Simulator
xcrun simctl erase all
# Restart Android Emulator
adb reboot- Keep tests independent: Each test should be able to run in isolation
- Use descriptive test IDs: Make element identification clear
- Add timeouts: Network requests need appropriate wait times
- Clean state: Reset app state between tests when needed
- Mock network: Reduce flakiness by mocking API responses
- Record failures: Use
--format junitto capture test results
When adding new screens or features:
- Add
testIDprops to interactive elements - Create corresponding Maestro flow in
.maestro/ - Update this README with new test coverage
- Ensure tests pass locally before opening PR