Testing Guide
Automated E2E testing infrastructure using Maestro for Sanctiv React Native app. Related:- SETUP.md - Development environment setup
- ARCHITECTURE.md - System architecture
- PUBLISHING.md - EAS Build and deployment
Overview
Maestro enables AI agents and developers to verify React Native code works correctly on iOS/Android simulators before committing, reducing blind fixes and improving code quality. Why Maestro:- YAML tests (agent-friendly syntax)
- Screenshot capture on every step
- Works in CI/CD (GitHub Actions)
- Free local testing, pay only for cloud
- Used by: Microsoft, Meta, Uber, Disney, Stripe, Bluesky
Quick Start
Prerequisites
- macOS with Xcode 15+ (for iOS testing)
- iOS Simulator - Test with
open -a Simulator - Bun installed - Run
bun --versionto verify - EAS CLI - Run
eas --versionto verify
Installation
Running Tests
Test Structure
⚠️ Pre-Commit Validation (REQUIRED)
ALWAYS run these commands before committing any dependency changes, fixes, or features:expo doctor is critical:
- Detects version mismatches between Expo SDK and dependencies
- Prevents CI build failures from incompatible package versions
- Catches issues like
@expo/metro-runtimeversion mismatches - Must show 0 critical errors before pushing
Test Flows
smoke.yaml - Verifies app launches successfully- Tags:
smoke,critical - Validates: App launches, welcome screen appears
- Tags:
onboarding,critical - Validates: Welcome features, loading state, auto-navigation to main app
- Tags:
journal,critical - Validates: Journal tab, mock data loading, tab navigation (Insights, Goals, Progress)
Writing Tests
Basic Commands
Creating New Tests
- Create new YAML file in
.maestro/flows/ - Follow existing test structure:
- Test locally before committing:
- Add screenshots at key steps for debugging
- Use descriptive names and tags
Test Best Practices
Element Matching:- Use wildcards for partial matches:
"Welcome*" - Check for typos in text assertions
- Use
maestro studioto inspect app elements
- Add explicit waits before assertions
- Increase timeout in config.yaml for slow operations
- Account for animations that delay rendering
- Capture at every major step
- Use descriptive names:
journal-01-home,journal-02-create - Screenshots saved to
~/.maestro/tests/ - Note: Add screenshots to PR comments for documentation, not to version control
Testing Requirements for AI Agents
Before Committing Code
AI agents MUST run relevant E2E tests before committing fixes:- Identify affected flows (onboarding, journal, etc.)
- Run tests:
bun run test:e2e:<flow-name> - If tests fail:
- Check screenshots in
~/.maestro/tests/ - Analyze failure reasons
- Fix issues
- Re-run tests
- Check screenshots in
- Only commit when tests pass
- Include test results in commit message
Writing New Tests for Features
When adding features, create corresponding E2E tests:- Create YAML file in
.maestro/flows/ - Test critical user paths
- Add screenshots at key steps
- Tag appropriately (
smoke,critical, etc.) - Verify tests pass locally
Test-Driven Development for Bug Fixes
- Write failing test that reproduces bug
- Fix the bug
- Verify test now passes
- Commit both fix and test
CI/CD Integration
Overview: Two-Tier E2E Testing
We use a two-tier E2E testing strategy optimized for cost and confidence:| Tier | Environment | Workflow Location | Label | Auto-Trigger |
|---|---|---|---|---|
| Tier 1 | iOS Simulator | .eas/workflows/2-pr-e2e.yml | run-e2e | ✅ On “Ready for Review” |
| Tier 2 | Real iPhones | .github/workflows/maestro-cloud.yml | run-e2e-real | ❌ Manual only |
When to Use Each Tier
| Scenario | Tier 1 (Simulator) | Tier 2 (Real Device) |
|---|---|---|
| Normal PR development | ✅ Auto | ❌ Skip |
| Complex UI changes | ✅ Auto | ⚠️ Consider |
| Device-specific features | ✅ Auto | ✅ Required |
| Pre-production release | ✅ Auto | ✅ Required |
| Hotfix | ✅ Auto | ⚠️ Optional |
Trigger Strategy
Tier 1: Simulator E2E (EAS Workflows) - Uses A+B+D pattern:| Event | E2E Runs? | Why |
|---|---|---|
| Create draft PR | ❌ | Save resources during development |
| Push to draft | ❌ | Still drafting |
| Mark ready for review | ✅ | Ready for validation |
| Push (no label) | ❌ | Single validation is enough |
Add run-e2e label | ✅ | Enable continuous mode |
| Push (with label) | ✅ | Continuous testing active |
| Event | E2E Runs? | Why |
|---|---|---|
| Create/push/ready | ❌ | Expensive, not for every PR |
Add run-e2e-real label | ✅ | Explicit opt-in for real devices |
| Push (with label) | ✅ | Continuous real device testing |
Workflow 1: EAS Workflows (Simulator)
File:.eas/workflows/e2e-ios.yml
Best for: Default E2E testing, fast feedback
Workflow 2: Maestro Cloud (Real Devices)
File:.github/workflows/maestro-cloud.yml
Best for: Production confidence, real device validation
EXPO_TOKEN- EAS Build authenticationMAESTRO_CLOUD_API_KEY- Maestro Cloud API key
Workflow 3: OTA Preview Updates
File:.eas/workflows/preview-update.yml
Purpose: Instant JS updates for PR testing
Agent PR Workflow
For AI agents (Cursor, Claude Code, etc.):| Label | Tier | What It Does |
|---|---|---|
run-e2e | 1 | Re-run simulator tests (cheap, fast) |
run-e2e-real | 2 | Run real device tests (expensive, thorough) |
build-dev | - | Create development build for hot reload |
EAS Build Profiles
The workflows use theseeas.json profiles:
| Profile | Purpose | Output |
|---|---|---|
e2e-test | EAS Workflows Maestro | .app (simulator) |
preview | Maestro Cloud + OTA | .ipa (signed) |
development | Hot reload on device | .ipa (dev client) |
Authentication in Tests
For tests requiring authenticated users (journal, profile, etc.), use dedicated test accounts. Option 1: Test Account Credentials (Recommended)Multi-Tenant Testing
Testorg_id isolation (critical for Sanctiv’s multi-tenant architecture):
Android Testing
While iOS-only testing is sufficient to start, here’s how to add Android support: Prerequisites:- Android Studio installed
- Android Emulator configured
ANDROID_HOMEenvironment variable set
Troubleshooting
Issue: “Maestro command not found”
Solution:Issue: “App not found”
Solution:- Update
appIdin test files to match actual bundle ID (com.sanctiv.app) - Check
app.jsonfor correctios.bundleIdentifier
Issue: “Element not found”
Solution:- Use
maestro studioto inspect app and find correct element identifiers - Use wildcards:
"Welcome*"instead of exact text - Add wait commands before assertions
Issue: Tests pass locally but fail in CI
Solution:- Check simulator/emulator versions match
- Increase timeouts in CI environment
- Verify all environment variables are set
- Review GitHub Actions logs for specific errors
Issue: Build fails in CI
Symptom: App build fails during Maestro workflow Solution:- Check Xcode setup: Ensure correct Xcode version is selected
- Verify dependencies: Run
bun installlocally to ensure it works - Check build logs: Look for specific compilation errors
- For EAS builds: Ensure
EXPO_TOKENhas proper permissions (only needed for EAS builds, not Maestro testing)
Issue: Flaky Tests
Solution:- Add explicit waits before assertions
- Increase timeout in config.yaml
- Check for animations that might delay rendering
- Verify mock data loads consistently
Maestro Studio (Local Development)
Setup Maestro Studio
1. Install Maestro CLI (if not already installed):http://localhost:8080
Running Tests Locally with Maestro Studio
1. Start your app in development mode:- Click “Create a new test” or open existing flow files
- Use the inspector to find element selectors
- Click “Run Locally” to execute tests on your simulator
- View screenshots and test results in the Studio interface
Using Maestro Studio Inspector
The inspector helps you find correct element selectors:- Launch Studio:
maestro studio - Connect device: Select your iOS Simulator from the device list
- Inspect elements: Click on UI elements to see their selectors
- Copy selectors: Use the copied selectors in your test flows
Troubleshooting Local Setup
Issue: Maestro Studio won’t connect to simulator Solution:- Verify
appIdin flow files matches your bundle ID (com.sanctiv.app) - Ensure app is installed:
xcrun simctl listapps booted | grep sanctiv
- Ensure iOS Simulator is running
- Check Maestro can see devices:
maestro devices - Restart Maestro Studio:
maestro studio
Maestro Studio (Legacy)
Interactive tool for inspecting app elements and building tests visually. Launch:- Inspect element hierarchy
- Test commands interactively
- Record interactions
- Generate test YAML
Cost Breakdown
Free Tier (Current Setup)
- Local testing: FREE
- Maestro CLI: FREE
- Maestro Studio: FREE
- GitHub Actions (public repos): FREE
Paid Tier (Future - Optional)
- Maestro Cloud (iOS): $250/device/month
- Maestro Cloud (Android): $250/device/month
- Need hosted iOS simulators
- Want parallel test execution
- Require device farm access
Additional Resources
Official Documentation
Case Studies
Community Resources
Last Updated: 2025-11-07 Related Issue: #51