This directory contains end-to-end (E2E) tests for freighter-mobile using Maestro. E2E tests validate critical user flows by running the app in a simulator/emulator and simulating real user interactions.
- Overview
- Documentation Index
- Prerequisites
- Test Structure
- Quick Start
- Test Flows
- Known Limitations
- Troubleshooting
- Resources
flowchart LR
subgraph Local
A[.env + Simulator] --> B[yarn test:e2e]
B --> C[Maestro runs flows]
end
subgraph CI
D[GitHub Actions] --> E[Build app]
E --> F[Matrix: 3 flows × Android/iOS]
F --> G[Upload artifacts]
end
C --> H[e2e-artifacts/]
G --> H
E2E tests run locally (with Maestro CLI + simulator/emulator) or in CI
(GitHub Actions). Both produce artifacts (logs, recordings, screenshots) under
e2e-artifacts/ for debugging.
Detailed guides live in e2e/docs/:
| Topic | File | Description |
|---|---|---|
| CI & Triggers | ci-and-triggers.md | When tests run, branch filters, manual runs (workflow_dispatch, /e2e), CI matrix parallelism |
| Local Setup & Env | local-setup-and-env.md | .env for E2E, E2E_TEST_RECOVERY_PHRASE, E2E_TEST_FUNDED_RECOVERY_PHRASE, how secrets/vars are used in CI |
| Running Tests | running-tests.md | Run in CI vs locally, single flow by platform + name |
| Artifacts & Debugging | artifacts-and-debugging.md | Artifact layout, logs, recordings, screenshots, how to debug failures |
| Creating Tests | creating-tests.md | Maestro YAML (API), Maestro Studio, recording flows, best practices (e.g. prefer testID) |
brew tap mobile-dev-inc/tap
brew install mobile-dev-inc/tap/maestro
maestro --version- Set
IS_E2E_TEST=truein.env(enables test-specific app behavior). - For Import Wallet flows: set
E2E_TEST_RECOVERY_PHRASEin.env. - For Send/Swap/WalletConnect flows (use ImportFundedWallet): set
E2E_TEST_FUNDED_RECOVERY_PHRASEin.env. See local-setup-and-env.md and.env.example.
- iOS: Run
yarn ios(oryarn ios-dev) to boot a simulator and install the app - Android: Run
yarn android(oryarn android-dev) to start an emulator and install the app
e2e/
├── config.yaml # Maestro config (appId, disableAnimations)
├── README.md # This file
├── docs/ # Detailed guides (see Documentation Index)
├── scripts/ # Helper scripts (start/stop mock server)
└── flows/
├── debug/ # Debug flows for development
├── onboarding/ # Wallet creation and import flows
│ ├── CreateWallet.yaml
│ ├── ImportWallet.yaml
│ └── ImportFundedWallet.yaml
├── transactions/ # Transaction flows (send and swap on testnet)
│ ├── SendClassicToken.yaml # Send 0.000001 XLM on testnet to a provisioned recipient
│ ├── SendFederatedAddress.yaml # Send 0.000001 XLM and 0.000001 USDC on testnet to a federated address (freighter.c7*lobstr.co)
│ └── SwapClassicToken.yaml # Swap 0.000001 XLM → USDC on testnet
└── walletconnect/ # WalletConnect integration tests
└── SignMessageMockDapp.yaml
-
Configure
.envCheck.env.example, setIS_E2E_TEST=trueand:E2E_TEST_RECOVERY_PHRASEfor Import Wallet flowsE2E_TEST_FUNDED_RECOVERY_PHRASEfor Send/Swap/WalletConnect flows
-
Build and run the app (e.g. iOS):
yarn ios-dev
-
Run an E2E test:
yarn test:e2e:ios CreateWallet
For Android use
yarn test:e2e:android. See running-tests.md for all platforms, single-flow runs, and CI behaviour.
| Flow | File | Description |
|---|---|---|
| Create Wallet | flows/onboarding/CreateWallet.yaml |
"Create a new wallet" → password → recovery phrase → skip validation → skip biometrics → home |
| Import Wallet | flows/onboarding/ImportWallet.yaml |
"I already have a wallet" → password → recovery phrase → skip biometrics → home |
| Import Funded Wallet | flows/onboarding/ImportFundedWallet.yaml |
Import wallet with funded account (uses E2E_TEST_FUNDED_RECOVERY_PHRASE) |
| Send Classic Token | flows/transactions/SendClassicToken.yaml |
Imports funded wallet → home → switch to testnet → send 0.000001 XLM to provisioned recipient → confirm → "Sent" |
| Send Federated Address | flows/transactions/SendFederatedAddress.yaml |
Imports provisioned funded wallet → home → switch to testnet → send 0.000001 XLM then 0.000001 USDC to a federated address (freighter.c7*lobstr.co) → confirm each |
| Swap Classic Token | flows/transactions/SwapClassicToken.yaml |
Imports funded wallet → home → switch to testnet → swap 0.000001 XLM → USDC → confirm → "Swapped" |
| WC Sign Message (Mock dApp) | flows/walletconnect/SignMessageMockDapp.yaml |
Connect to dApp → approve signMessage → verify signature returned |
Test data: Password TestPassword123!;
- Recovery phrase from
E2E_TEST_RECOVERY_PHRASEfor ImportWallet - Funded recovery phrase from
E2E_TEST_FUNDED_RECOVERY_PHRASEfor ImportFundedWallet
See Test Data in local-setup-and-env. Never use these in production or commit real secrets.
WalletConnect tests: Require mock dApp server running. See WalletConnect E2E Testing for setup and Mock dApp README for server usage.
- Recovery phrase validation (Create Wallet): The flow skips validation (taps "Skip") and does not exercise the word-grid confirmation. Adding full validation would require test flow changes and UI-specific selectors.
- Biometrics: Always skipped in E2E flows for simplification (we tap Skip / Don't Allow). Biometric enrollment or verification is not exercised.
- ImportWallet vs ImportFundedWallet:
ImportWalletusesE2E_TEST_RECOVERY_PHRASEfor basic wallet import flowsImportFundedWalletusesE2E_TEST_FUNDED_RECOVERY_PHRASEand is required for Send/Swap/WalletConnect flows that need funded accounts- Ensure both recovery phrases are set in
.envlocally or in CI secrets
- WalletConnect: Requires mock dApp server to simulate external requests. Server must be running before executing WalletConnect flows. Not all production dApps support all WalletConnect methods in testing.
| Issue | Checklist |
|---|---|
| Tests don't start | App built and running in simulator/emulator; IS_E2E_TEST=true in .env; maestro --version works |
| Element not found | Correct screen; testIDs in components; run maestro test --debug |
| Timeouts | Increase timeouts in flows; ensure simulator/emulator has enough resources; check network |
For debugging failures using logs, recordings, and screenshots, see artifacts-and-debugging.md.