Skip to content

test(maestro): working E2E suite (iOS FlipcashUITests parity) + central tagging + beta-flag launch hook - #1180

Open
bmc08gt wants to merge 19 commits into
code/cashfrom
test/maestro-e2e-suite
Open

test(maestro): working E2E suite (iOS FlipcashUITests parity) + central tagging + beta-flag launch hook#1180
bmc08gt wants to merge 19 commits into
code/cashfrom
test/maestro-e2e-suite

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Summary

Turns the drifted, non-running maestro/ suite into a working, verified Maestro E2E suite — the Android counterpart to iOS's FlipcashUITests — plus the infrastructure to keep it healthy, drive beta-gated features, and provision test accounts. Every flow listed as verified is green against a booted emulator.

Infrastructure

  • Made the suite runnable — fixed the stale appId (.dev is deprecated → com.flipcash.app.android) across all 36 files.
  • Central screen-root tagging. Flows anchor on <name>_screen resource-ids that were never added to the screens. Rather than hand-tag ~15 composables (which drifts), the tag is applied once where every destination is registered — annotatedEntry (NavMetadata.kt) wraps each entry in a tagged Box, defaulting to an id derived from the route type name (AppRoute.Menu.MyAccountmy_account_screen), with an override where the id differs. Flow steps (onboarding, withdraw/deposit/swap wizards) register through the same helper, so they're tagged the same way.
  • Beta flags from a launch arg — a debug-only MainActivity hook reads a betaFlags extra and force-enables flags, mirroring iOS's --beta-flags (no Labs-UI toggling).
  • Purchase-method tagsBottomBarAction gained an optional testTag; the Add Money methods are now anchored (purchase_method_coinbase/_phantom/_other_wallet) — the Coinbase (Google Pay) option is icon-only and wasn't addressable before.
  • Runner + docsmaestro/run.sh loads .env, approves App Links, auto-seeds the send-to-contact recipient, forwards all env vars, targets a device. maestro/README.md documents setup, the tagging convention, the beta-flag mechanism, the two-path phone-verification story, coverage, and roadmap.

Verified green

Login/logout (seed) · account+settings nav · wallet→token info · discovery→leaderboard→token info · direct-send (phone gate) · deposit (USDC) · withdraw (amount entry) · buy (→ confirm purchase) · sell (→ amount entry) · currency creator (intro + $20 gate) · coinbase onramp (method → onramp entry) · tipping setup (create account → tip card renders) · tip chat (open + send) · blocking (block → verify → unblock) · tip deeplink (→ tip flow) · USDF-only gate (reserves-only → give→Discover) · give/bill round-trip · token-info deeplink · screenshot suite.

Scaffolded — pending account provisioning (not tooling)

  • send_to_contact.yaml — the contact is auto-seeded by the runner; needs a send-enabled (phone-linked) account. Phone-linking is proven except for one dependency: the app's SMS auto-read works (adb emu sms send → SMS User Consent), but the backend requires the real code, which is sent to the entered number and never reaches the emulator. Unblock = route the verification SMS to the emulator (dev webhook → adb emu sms send) or use a disposable-number provider. Fully documented in the README.

Env (maestro/.env, git-ignored)

SEED_PHRASE, LOGIN_DEEPLINK, TIPCARD_DEEPLINK (same primary account); USDF_ONLY_DEEPLINK (reserves-only gate account); CONTACT_NAME/CONTACT_PHONE (send-to-contact recipient).

Not yet wired

CI. Intended follow-up: a flipcash_maestro Fastlane lane (--include-tags smoke --exclude-tags spends-funds) on a KVM emulator per PR.

Independent of the launched-flag removal in #1179.

bmc08gt added 3 commits July 31, 2026 13:27
The debug build's applicationId is `com.flipcash.app.android` (the `.dev`
suffix is deprecated), but every flow still declared
`com.flipcash.app.android.dev`, so none of them could launch or drive the app.
Point all flows/subflows/helpers/screenshot groups at the real appId.
…ntry

Maestro/UiAutomator flows anchor on `<name>_screen` resource-ids, but those tags
were never added to the screen composables, so the flows couldn't find them.

Rather than hand-tag ~15 screen roots (which drifts), apply the tag once at the
single place every destination is registered: `annotatedEntry` now wraps each
entry in a tagged Box, defaulting to an id derived from the route type name
(`AppRoute.Menu.MyAccount` -> `my_account_screen`) with an optional override for
routes whose id differs from their name (Give -> cash_screen, Token.Info ->
token_info_screen, Token.Transactions -> transaction_history_screen).

Removes the now-redundant per-screen tags from TokenInfoScreen and MessengerScreen
(they're covered centrally); the pre-login landing keeps a manual `login_screen`
tag since it isn't a nav entry.
- account_navigation.yaml: login -> menu -> My Account -> App Settings
- wallet_token_info.yaml: login -> wallet -> token info + market-cap chart
- run.sh: loads .env creds, approves App Links (fresh-install gotcha), targets a device
- README: setup, the deeplink-login entry, the central tagging convention, coverage + roadmap

Both flows pass green against emulator-5554.
@github-actions github-actions Bot added type: test Test additions or improvements area: ui Compose UI, theme, components, resources area: tokens Token accounts, balances, token info area: onboarding labels Jul 31, 2026
bmc08gt added 2 commits July 31, 2026 13:43
Flow steps register through the same annotatedEntry helper, so they get the same
auto-derived screen-root tags — OnboardingStep.SeedInput already yields
seed_input_screen with no per-screen edit. Add overrides only where the step name
is generic/ambiguous:
- OnboardingStep.Start -> login_screen (the pre-login landing)
- WithdrawalStep.Amount/Destination/Confirmation -> withdraw_*_screen (the bare
  Destination/SelectToken names collide with the deposit flow's steps)

Log Out moved to the My Account screen, so route logout.yaml through
navigate_to_my_account; login_logout.yaml now starts from a cleared (logged-out)
state so the real seed-login UI is exercised. Both verified green.
…ted nav

New verified flows (all green against emulator-5554):
- direct_send.yaml     — send entry → phone gate
- discovery_leaderboard.yaml — Discover → leaderboard → token info
- withdraw.yaml        — menu → Withdraw Money → USDC → amount entry (fund-safe)
- deposit.yaml         — menu → Add Money → Other Wallet → USDC deposit (fund-safe)

Repair navigation subflows against relabeled UI:
- navigate_to_withdraw: "Withdraw Funds" → "Withdraw Money" + USDC step + Next
- navigate_to_give: nav-bar "Give" → "Cash"
- navigate_to_advanced_features: "Advanced Features" → "Advanced"

README: refresh coverage (7 green flows), note account-blocked journeys (Direct Send
contact list / Chat need a phone-linked account) and remaining roadmap.
@github-actions github-actions Bot added the area: payments Payments, transfers, intents, billing label Jul 31, 2026
bmc08gt added 4 commits July 31, 2026 14:34
Add a debug-only (UI_TESTABLE) MainActivity hook that reads a `betaFlags` launch
argument (comma-separated FeatureFlag.key list) and force-enables those flags, so
UI tests can exercise beta-gated features without toggling them in the Labs UI —
mirroring iOS's --beta-flags.

Maestro support:
- subflows/login_with_flags.yaml — seed login with flags (existing account)
- subflows/create_account.yaml — new account via onboarding (test phone
  +1 500-555-0000, all-zero OTP) with optional push-permission handling, for
  one-run-per-account setup
- tipping_setup.yaml — create account with tipping_enabled, set up the tip card
  (name step), assert the tip card renders. Verified green.
- run.sh forwards BETA_FLAGS; README documents the mechanism.
Seed-logs into the tips account with tipping_enabled, opens the tip conversation
from the Tips tab, asserts the tip event + composer, and sends a message.
Verified green (requires SEED_PHRASE and LOGIN_DEEPLINK to point at the same
tip-enabled test account).
Enables tipping+blocklist at launch, opens the tip conversation, blocks the
participant from their profile, verifies they appear in My Account -> Blocked,
then unblocks to restore a clean account. Verified green.
Opens a tip-card deeplink (TIPCARD_DEEPLINK from .env) and asserts the tip flow
presents. A fresh login clears the local balance cache, so the flow forces a
balance sync (opens the Wallet) before opening the deeplink — otherwise the
transiently-empty giveable balance trips the add-money/discover gate. run.sh
forwards TIPCARD_DEEPLINK.
@bmc08gt bmc08gt changed the title test(maestro): verified E2E foundation + central screen-root tagging test(maestro): working E2E suite (iOS FlipcashUITests parity) + central tagging + beta-flag launch hook Jul 31, 2026
bmc08gt added 2 commits July 31, 2026 16:02
Add an optional testTag to BottomBarAction (applied at render in BottomBarContainer)
and set it on the Add Money purchase methods: purchase_method_coinbase /
purchase_method_phantom / purchase_method_other_wallet. The Coinbase (Google Pay)
option is icon-only with no text, so it wasn't addressable by Maestro before.
- buy.yaml: token info → Buy → payment currency → confirm purchase (fund-safe)
- sell.yaml: token info → Sell → amount entry (fund-safe)
- currency_creator.yaml: Discover → Create Your Own Currency → intro + $20 gate
- coinbase_onramp.yaml: Add Money → Coinbase/Google Pay → onramp (phone verify),
  with coinbase_onramp_sandbox_enabled set for a future sandbox purchase

All verified green against emulator-5554.
@github-actions github-actions Bot added the area: notifications Push notifications, in-app messaging label Jul 31, 2026
bmc08gt added 7 commits July 31, 2026 16:03
…sioning-blocked

Note how iOS handles each: send-to-contact runs against a phone-provisioned account;
the Coinbase purchase isn't automated on iOS either (E2E stops at verification, order
logic is unit-tested), so our onramp-entry flow is already at parity.
- login_usdf_only.yaml + usdf_only_gate.yaml: deeplink login into a dedicated
  reserves-only account and assert the give→Discover gate (mirrors iOS
  GiveDiscoverGateRegressionTests). Needs USDF_ONLY_DEEPLINK.
- send_to_contact.yaml: send to an on-Flipcash contact (mirrors iOS SendSmokeTests).
  Parameterized by CONTACT_NAME/CONTACT_PHONE; needs a phone-linked account + the
  contact seeded in the emulator.
- run.sh forwards USDF_ONLY_DEEPLINK / CONTACT_NAME / CONTACT_PHONE; README documents
  the new .env keys and marks both flows as provisioning-pending scaffolds.
run.sh now seeds CONTACT_NAME/CONTACT_PHONE into the emulator's contacts before
running flows (idempotent; skips if already present). Verified: wiping contacts
and running the runner re-creates the contact. Removes a manual setup step for
send-to-contact — only a send-enabled (phone-linked) account remains.
Onboarding/account creation uses the backend test number (+15005550000 / 000000);
linking a phone to enable the send flow must use the emulator's real number + real
SMS (adb emu sms send), since the test number isn't a linkable identity for
send-to-contact.
… send

The app auto-extracts the SMS code, so linking a phone for the send flow just needs
the code delivered to the emulator (adb emu sms send). It's a one-time per-account
provisioning step, not a per-run action.
…code delivery blocks)

Verified: valid-format number accepted (emulator 555 number is invalid); adb emu sms
send + Android SMS User Consent auto-fills the code; but the backend requires the real
code, which is sent to the entered number and never reaches the emulator. Unblock =
route the verification SMS to the emulator (backend webhook -> adb emu sms send).
- run.sh: env-var-first creds (CI secrets) with maestro/.env fallback, optional .env,
  and a `--tags <tag>` mode that runs the suite tag-filtered with JUnit output.
- Fastfile: flipcash_maestro lane installs the debug build and runs run.sh in tag mode
  (MAESTRO_TAGS default smoke, MAESTRO_EXCLUDE_TAGS default spends-funds).
- .github/workflows/maestro.yml: boots a KVM x86_64 emulator, sets up build secrets,
  installs the Maestro CLI, runs the lane, uploads the JUnit report. Triggers:
  workflow_dispatch (choose tags) + nightly schedule; PR-gating opt-in.
- README: document the lane, workflow, local usage, and required GitHub secrets.

Verified locally: `run.sh --tags gate` runs the tagged flow and emits maestro-report.xml.
@bmc08gt
bmc08gt requested a review from jeffyanta as a code owner July 31, 2026 21:23
Tag tipping_setup (the only flow that onboards a new account) with `creates-account`
and exclude `spends-funds,creates-account` by default in run.sh and the workflow, so the
smoke/nightly run never has side effects. `smoke` was already free of account-creating
flows; this makes it explicit and robust. Run such flows deliberately by clearing the
exclude (MAESTRO_EXCLUDE_TAGS=).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: notifications Push notifications, in-app messaging area: onboarding area: payments Payments, transfers, intents, billing area: tokens Token accounts, balances, token info area: ui Compose UI, theme, components, resources type: test Test additions or improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant