# Maestro E2E Conventions (Professional Standard) This document defines **how we write and maintain Maestro E2E tests** in this repo, so they stay stable, readable, and useful as a regression safety net—**without** relying on fragile patterns. Applies to: - Client: `apps/mobile/apps/client/maestro/**` - Staff: `apps/mobile/apps/staff/maestro/**` Related: - Happy-path catalog: `docs/testing/maestro-e2e-happy-paths.md` - Run guide + troubleshooting: `docs/research/maestro-test-run-instructions.md` --- ## Test taxonomy (what “professional” means here) We maintain 3 tiers of flows: - **Smoke (deterministic)**: fast, minimal prerequisites, should pass for a standard test account most of the time. - Targets: `make test-e2e-client-smoke`, `make test-e2e-staff-smoke` - **Happy path (business-critical)**: core “golden paths”, may have real-data dependencies (invoices, shifts, etc.). - Targets: `make test-e2e-client-happy-path`, `make test-e2e-staff-happy-path` - **Data-dependent / state-change flows**: require seeded data (pending invoice, scheduled shift, pending compliance doc). - These are valuable but should be explicitly documented as prerequisites. Rule of thumb: - If a flow is **time/location/data dependent**, do **not** include it in smoke. --- ## File naming & structure - **File name**: use verbs + scope + suffix. - Good: `create_hub_e2e.yaml`, `invoice_approval_e2e.yaml`, `tab_bar_roundtrip.yaml` - Avoid: `test1.yaml`, `new.yaml` - **Folders map to product areas**: `auth/`, `navigation/`, `orders/`, `billing/`, `hubs/`, `profile/`, `compliance/`, `shifts/`, `availability/`, `home/`, `payments/`. --- ## YAML header standard (required) Each flow should start with: - A short description: **what** and **why** - **Prerequisites** (if any) - **Run command** including required env vars - `appId: ...` Example header shape (keep short): ```yaml # Client App — E2E: # Purpose: # Prerequisite: # Run: maestro test auth/sign_in.yaml -e ... appId: com.krowwithus.client --- ``` --- ## Selector strategy (stability rules) Priority order: 1. **`id:` selectors** (best) 2. **Accessible text labels** that are stable (good) 3. **Coordinates / `point:`** (last resort; document why) If you must use coordinates: - Prefer *relative* safe coordinates inside a stable container (not global corners). - Add a comment explaining what UI element it targets and why there’s no better selector. --- ## Waiting strategy (reduce flakes) Use explicit waits around network UI and animations: - Prefer `extendedWaitUntil` for content that depends on API/network. - Use `waitForAnimationToEnd` after navigation transitions. - Avoid long fixed sleeps; wait for a **specific UI marker**. Guideline timeouts: - 10–15s typical - 20s only when you know the call is slow (uploads, approvals) --- ## Assertions (what “comprehensive” should mean) Every flow should have: - **Entry assertion**: confirms you are on the expected starting screen (e.g., `assertVisible: "Home"`). - **Critical path assertions**: confirm key steps actually happened (not just taps). - **Exit assertion**: confirms the expected final state (success message, returned screen, etc.). Avoid “silent passes” where taps happen but no success state is asserted. --- ## Data prerequisites (must be explicit) If a flow needs data: - Document it in the YAML header and in `docs/testing/maestro-e2e-happy-paths.md`. - Prefer using a dedicated “test account” with predictable fixtures. Examples in this repo: - Client invoice approval requires “Awaiting Approval” invoices. - Staff clock-in/out requires an active shift and location constraints. - Staff document upload requires pushing `fixture.pdf` to the device. --- ## Fixtures & helper scripts If a flow needs a file fixture: - Put it alongside the flow (e.g. `compliance/fixture.pdf`). - Provide a script to push it to the emulator/device. Current helper scripts: - `apps/mobile/apps/staff/maestro/compliance/push_fixture.sh` - `apps/mobile/apps/staff/maestro/compliance/push_upload_fixture.sh` (compat wrapper) --- ## Suite composition rules Professional suites should: - Start with a **single** `sign_in.yaml` - Prefer sequential execution: `--shard-split=1` (already defaulted) - Avoid mixing flows that fight over navigation state unless they’re designed to run back-to-back Recommended usage: - Developers run **smoke** on local changes. - QA runs **happy path** before release.