# Maestro E2E Happy Path Test Cases This document describes the End-to-End (E2E) **happy path** test cases for the KROW mobile applications (Client and Staff), implemented with [Maestro](https://maestro.mobile.dev/). It supports **ticket #572**: implement and document E2E happy path tests so core functionalities remain stable and regressions are caught early. ## Overview | Item | Description | |------|-------------| | **Framework** | Maestro | | **Apps** | Client (`com.krowwithus.client`), Staff (`com.krowwithus.staff`) | | **Scope** | Happy path user flows only (success paths; negative/edge cases are separate) | | **Run locally** | See [How to run](#how-to-run) and [docs/research/maestro-test-run-instructions.md](../research/maestro-test-run-instructions.md) | ## Prerequisites - **Maestro CLI** installed ([Install guide](../research/maestro-test-run-instructions.md#1-install-maestro-cli)) - **Firebase test phone** for Staff app (e.g. +1 555-555-1234 / OTP 123123) - **Client & Staff APKs** built and installed on device/emulator - **Env variables** set for credentials (never hardcode; see [Credentials](#credentials)) ## Credentials | App | Flow | Env variables | |-----|------|----------------| | Client | sign_in / sign_up | `TEST_CLIENT_EMAIL`, `TEST_CLIENT_PASSWORD`, `TEST_CLIENT_COMPANY` (sign_up only) | | Staff | sign_in / sign_up | `TEST_STAFF_PHONE`, `TEST_STAFF_OTP`, `TEST_STAFF_SIGNUP_PHONE` (sign_up only) | Example (Bash): `export TEST_CLIENT_EMAIL=testclient@gmail.com TEST_CLIENT_PASSWORD=testclient!` `export TEST_STAFF_PHONE=5555551234 TEST_STAFF_OTP=123123` --- ## Client App — Happy Path Test Cases All client flows assume the app is **not** logged in at start unless noted (e.g. flows that run after `sign_in.yaml`). ### Auth | ID | Test | Purpose | Steps | Expected outcome | How to run | |----|------|----------|-------|-------------------|------------| | C-AUTH-1 | **sign_in** | Verify user can sign in with email/password | Launch app → Sign In → enter email/password (env) → Sign In | Home tab visible, authenticated | `maestro test apps/mobile/apps/client/maestro/auth/sign_in.yaml -e TEST_CLIENT_EMAIL=... -e TEST_CLIENT_PASSWORD=...` | | C-AUTH-2 | **sign_up** | Verify new client can register | Launch app → Create Account → email, password, company (env) → submit | Home tab visible, authenticated | Same as above + `-e TEST_CLIENT_COMPANY=...` | | C-AUTH-3 | **sign_out** | Verify user can log out | Run after sign_in → Settings (gear) → Log Out → confirm | Create Account / login screen visible | Run `sign_in.yaml` then `auth/sign_out.yaml` (or use `settings/logout_flow.yaml` for gear-based logout) | ### Navigation | ID | Test | Purpose | Steps | Expected outcome | How to run | |----|------|----------|-------|-------------------|------------| | C-NAV-1 | **home** | Home tab loads after login | Launch (logged in) → tap Home | "Welcome back" and home content visible | `navigation/home.yaml` after sign_in | | C-NAV-2 | **orders** | Orders tab opens | Tap Orders | Orders list or empty state visible | `navigation/orders.yaml` | | C-NAV-3 | **billing** | Billing tab opens | Tap Billing | Billing / invoices section visible | `navigation/billing.yaml` | | C-NAV-4 | **coverage** | Coverage tab opens | Tap Coverage | Coverage screen visible | `navigation/coverage.yaml` | | C-NAV-5 | **reports** | Reports tab opens | Tap Reports | Reports screen visible | `navigation/reports.yaml` | ### Orders | ID | Test | Purpose | Steps | Expected outcome | How to run | |----|------|----------|-------|-------------------|------------| | C-ORD-1 | **view_orders** | Orders list loads | After sign_in → Orders → list loads | Order list or empty state | `orders/view_orders.yaml` | | C-ORD-2 | **create_order_entry** | Reach create-order entry (type selection) | Home → Create Order | One-Time / Rapid / etc. options visible | `orders/create_order_entry.yaml` | | C-ORD-2b | **create_order_rapid** | Rapid order screen renders | Home → Create Order → Rapid | Rapid order screen + actions visible | `orders/create_order_rapid.yaml` | | C-ORD-2c | **rapid_to_one_time_draft_submit_e2e** | Rapid → parsed One-Time draft (true E2E) | Rapid → pick example message → Send Message | One-Time draft screen visible | `orders/rapid_to_one_time_draft_submit_e2e.yaml` | | C-ORD-3 | **create_order_one_time_e2e** | Full flow: create one-time order | Home → Create Order → One-Time → fill Event Name, Role → Create | Success; back to orders or confirmation | `orders/create_order_one_time_e2e.yaml` | | C-ORD-4 | **completed_no_edit_icon** | Completed orders do not show edit | Open orders → completed order | No edit action on completed order | `orders/completed_no_edit_icon.yaml` (#492) | | C-ORD-5 | **edit_active_order_verify_updated_e2e** | Edit active order + verify update confirmation | Orders/Home → Edit active order → Confirm & Save | “Order Updated!” confirmation visible | `orders/edit_active_order_verify_updated_e2e.yaml` (requires active order) | ### Hubs | ID | Test | Purpose | Steps | Expected outcome | How to run | |----|------|----------|-------|-------------------|------------| | C-HUB-1 | **create_hub_e2e** | Create a clock-in hub and see it in list | Settings (gear) → Clock-In Hubs → Add Hub → name, address → Create | Hubs list visible; new hub present | `hubs/create_hub_e2e.yaml` | | C-HUB-2 | **manage_hubs_from_settings** | Open hubs management from settings | Settings → Clock-In Hubs | Hubs list / management screen | `hubs/manage_hubs_from_settings.yaml` | | C-HUB-3 | **edit_hub_e2e** | Create hub then edit hub name | Hubs → Add Hub → open details → Edit Hub → Save | Hub updated success message | `hubs/edit_hub_e2e.yaml` | | C-HUB-4 | **delete_hub_e2e** | Create hub then delete hub | Hubs → Add Hub → open details → Delete → confirm | Hub deleted success message | `hubs/delete_hub_e2e.yaml` | ### Billing | ID | Test | Purpose | Steps | Expected outcome | How to run | |----|------|----------|-------|-------------------|------------| | C-BIL-1 | **billing_overview** | Billing tab and overview load | Tap Billing | Billing overview / tabs visible | `billing/billing_overview.yaml` | | C-BIL-2 | **invoice_approval_e2e** | Approve a pending invoice | Billing → Awaiting Approval → first invoice → Review & Approve → Approve | Success feedback; back to list | `billing/invoice_approval_e2e.yaml` (requires at least one invoice in "Awaiting Approval") | | C-BIL-3 | **invoice_details_smoke** | Open invoice details or verify empty state | Billing → (Invoice Ready if exists) | Invoice detail actions visible OR empty-state copy visible | `billing/invoice_details_smoke.yaml` | ### Reports | ID | Test | Purpose | Steps | Expected outcome | How to run | |----|------|----------|-------|-------------------|------------| | C-RPT-1 | **reports_dashboard** | Reports dashboard loads | Tap Reports | Reports dashboard visible | `reports/reports_dashboard.yaml` | | C-RPT-2 | **spend_report_export_smoke** | Spend report export placeholder | Reports → Spend Report → Export | “Exporting Spend Report (Placeholder)” shown | `reports/spend_report_export_smoke.yaml` | ### Settings & Home | ID | Test | Purpose | Steps | Expected outcome | How to run | |----|------|----------|-------|-------------------|------------| | C-SET-1 | **settings_page** | Settings screen opens | After sign_in → Settings (gear) | Quick Links, Log Out, etc. visible | `settings/settings_page.yaml` | | C-SET-2 | **edit_profile** | Edit profile screen opens and is usable | Settings → profile edit entry | Profile form visible | `settings/edit_profile.yaml` | | C-SET-2b | **edit_profile_save_e2e** | Edit profile save + re-open verification | Settings → Edit Profile → Save Changes → re-open | “Profile updated successfully” + “QA” visible | `settings/edit_profile_save_e2e.yaml` | | C-SET-3 | **logout_flow** | Log out via Settings gear | Settings (gear) → Log Out → confirm | Create Account / login screen | `settings/logout_flow.yaml` | | C-HOM-1 | **home_dashboard_widgets** | Dashboard widgets and quick actions render | Home → check Actions, Coverage, etc. | Widgets and "Create Order" visible | `home/home_dashboard_widgets.yaml` | | C-HOM-2 | **tab_bar_roundtrip** | All main tabs can be opened in sequence | Home → Orders → Billing → Coverage → Reports → Home | No crash; each tab loads | `home/tab_bar_roundtrip.yaml` | --- ## Staff App — Happy Path Test Cases ### Auth | ID | Test | Purpose | Steps | Expected outcome | How to run | |----|------|----------|-------|-------------------|------------| | S-AUTH-1 | **sign_in** | Staff signs in with phone + OTP | Launch → enter phone (env) → OTP (env) | Home / main app visible | `maestro test apps/mobile/apps/staff/maestro/auth/sign_in.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...` | | S-AUTH-2 | **sign_up** | New staff registers with phone | Launch → sign up path → phone (env) → OTP (env) | Onboarding or home | Same + `TEST_STAFF_SIGNUP_PHONE` | | S-AUTH-3 | **sign_out** | Staff logs out from Profile | After sign_in → Profile → Sign Out | Log In screen visible | `auth/sign_out.yaml` after sign_in | ### Navigation | ID | Test | Purpose | Steps | Expected outcome | How to run | |----|------|----------|-------|-------------------|------------| | S-NAV-1 | **home** | Home tab loads | Tap Home | Welcome / home content | `navigation/home.yaml` | | S-NAV-2 | **shifts** | Shifts tab opens | Tap Shifts | Shifts list or empty state | `navigation/shifts.yaml` | | S-NAV-3 | **profile** | Profile tab opens | Tap Profile | Profile sections visible | `navigation/profile.yaml` | | S-NAV-4 | **payments** | Payments tab opens | Tap Payments | Payments screen | `navigation/payments.yaml` | | S-NAV-5 | **clock_in** (tab) | Clock In tab opens | Tap Clock In | Clock In UI visible | `navigation/clock_in.yaml` | | S-NAV-6 | **availability** | Availability screen opens | From home or profile → Availability | Availability UI | `navigation/availability.yaml` | ### Shifts | ID | Test | Purpose | Steps | Expected outcome | How to run | |----|------|----------|-------|-------------------|------------| | S-SHF-1 | **find_shifts** | Shifts list / find shifts loads | Shifts tab → find shifts | Shifts or empty state | `shifts/find_shifts.yaml` | | S-SHF-1b | **find_shifts_apply_smoke** | Find shifts + optionally apply | Shifts → Find Shifts → (APPLY NOW if exists) | Applying dialog OR empty-state visible | `shifts/find_shifts_apply_smoke.yaml` | | S-SHF-2 | **clock_in_e2e** | Clock in to an active shift | Clock In tab → Swipe to Check In (optional attire photo) | Check-in success | `shifts/clock_in_e2e.yaml` (requires active shift today, within range) | | S-SHF-3 | **clock_out_e2e** | Clock out from shift | After clocked in → Clock Out | Clock-out success | `shifts/clock_out_e2e.yaml` (requires clocked-in state) | ### Availability | ID | Test | Purpose | Steps | Expected outcome | How to run | |----|------|----------|-------|-------------------|------------| | S-AVL-1 | **set_availability_e2e** | Set or view availability | Open availability → set days/times → save | Success or list updated | `availability/set_availability_e2e.yaml` | ### Profile | ID | Test | Purpose | Steps | Expected outcome | How to run | |----|------|----------|-------|-------------------|------------| | S-PRF-1 | **personal_info** | Personal info section opens | Profile → Personal Info | Form/section visible | `profile/personal_info.yaml` | | S-PRF-2 | **documents_list** | Documents list opens | Profile → Documents | Documents list | `profile/documents_list.yaml` | | S-PRF-3 | **certificates_list** | Certificates list opens | Profile → Certificates | Certificates list | `profile/certificates_list.yaml` | | S-PRF-4 | **time_card** | Time card section opens | Profile → Time Card | Time card UI | `profile/time_card.yaml` | | S-PRF-5 | **bank_account** | Bank account section opens | Profile → Bank Account | Bank account UI | `profile/bank_account.yaml` | | S-PRF-5b | **bank_account_fields_smoke** | Bank account fields visible (when add form is shown) | Profile → Bank Account | Routing/Account number labels visible OR added state | `profile/bank_account_fields_smoke.yaml` | | S-PRF-4b | **time_card_detail_smoke** | Timecard summary labels render | Profile → Timecard | Hours Worked + Total Earnings visible | `profile/time_card_detail_smoke.yaml` | | S-PRF-9 | **tax_forms_smoke** | Tax forms screen loads | Profile → Tax Forms | Tax Forms title visible | `profile/tax_forms_smoke.yaml` | | S-PRF-10 | **attire_validation_e2e** | Attire validation checklist | Profile → Attire → Save Attire | Validation checklist appears | `profile/attire_validation_e2e.yaml` | | S-PRF-6 | **faqs** | FAQs open | Profile → FAQs | FAQ content | `profile/faqs.yaml` | | S-PRF-7 | **privacy_security** | Privacy & Security opens | Profile → Privacy & Security | Screen visible | `profile/privacy_security.yaml` | | S-PRF-8 | **emergency_contact** | Emergency contact opens | Profile → Emergency Contact | Form/section visible | `profile/emergency_contact.yaml` | ### Compliance | ID | Test | Purpose | Steps | Expected outcome | How to run | |----|------|----------|-------|-------------------|------------| | S-CMP-1 | **document_upload_banner** | Document upload CTA visible | After sign_in → navigate to docs | Upload banner/CTA visible | `compliance/document_upload_banner.yaml` (#550) | | S-CMP-2 | **certificate_upload_banner** | Certificate upload CTA visible | Navigate to certificates | Upload banner visible | `compliance/certificate_upload_banner.yaml` (#551) | | S-CMP-3 | **attire_upload_banner** | Attire upload CTA visible | Navigate to attire | Upload banner visible | `compliance/attire_upload_banner.yaml` (#552) | | S-CMP-4 | **document_upload_e2e** | Upload a document (full flow) | Open documents → upload (e.g. PDF) | Upload success | `compliance/document_upload_e2e.yaml` | | S-CMP-5 | **certificate_upload_e2e** | Upload a certificate (full flow) | Certificates → Upload Certificate → upload PDF | Success snackbar visible | `compliance/certificate_upload_e2e.yaml` (requires fixture.pdf pushed) | ### Payments & Home | ID | Test | Purpose | Steps | Expected outcome | How to run | |----|------|----------|-------|-------------------|------------| | S-PAY-1 | **payments_view_e2e** | Payments screen loads and is usable | Tap Payments | Payments list or empty state | `payments/payments_view_e2e.yaml` | | S-PAY-2 | **payment_history_smoke** | Payments history section visible | Earnings → scroll to Recent Payments | Recent Payments visible | `payments/payment_history_smoke.yaml` | | S-HOM-1 | **benefits** | Benefits section loads | Home → Benefits | Benefits content visible | `home/benefits.yaml` (#524) | --- ## How to run ### Make targets (recommended) From **project root** with env vars set: | Target | Description | |--------|-------------| | `make test-e2e` | Auth flows only (Client + Staff sign_in, sign_up, invalid password/OTP) | | `make test-e2e-client` | Client auth (sign_in, sign_up) | | `make test-e2e-client-extended` | Client: auth + navigation + orders + settings | | `make test-e2e-client-smoke` | Client: deterministic smoke suite | | `make test-e2e-client-orders-smoke` | Client: orders smoke (RAPID → One-Time draft) | | `make test-e2e-client-hubs-e2e` | Client: hubs manage + edit + delete | | `make test-e2e-client-billing-smoke` | Client: billing smoke (overview + invoice details/empty state) | | `make test-e2e-client-reports-smoke` | Client: reports smoke (dashboard + export) | | `make test-e2e-client-settings-e2e` | Client: settings E2E (edit profile save + logout) | | `make test-e2e-client-orders-data` | Client: orders data-dependent (edit active order) | | `make test-e2e-client-happy-path` | Client: auth + hubs + create order E2E + billing + reports + logout | | `make test-e2e-staff` | Staff auth (sign_in, sign_up) | | `make test-e2e-staff-extended` | Staff: auth + navigation + profile + compliance + shifts + benefits | | `make test-e2e-staff-smoke` | Staff: deterministic smoke suite | | `make test-e2e-staff-profile-smoke` | Staff: profile smoke (timecard/bank/tax/attire validation) | | `make test-e2e-staff-payments-smoke` | Staff: payments smoke (earnings history) | | `make test-e2e-staff-shifts-smoke` | Staff: shifts smoke (find shifts; optionally apply) | | `make test-e2e-staff-compliance-e2e` | Staff: compliance E2E (document + certificate uploads) | | `make test-e2e-staff-happy-path` | Staff: auth + clock in/out + availability + document upload + payments + sign out | | `make test-e2e-extended` | Both apps: full extended suites | ### Single flow (Maestro CLI) ```bash # Client sign_in then create hub maestro test --shard-split=1 \ apps/mobile/apps/client/maestro/auth/sign_in.yaml \ apps/mobile/apps/client/maestro/hubs/create_hub_e2e.yaml \ -e TEST_CLIENT_EMAIL=... -e TEST_CLIENT_PASSWORD=... # Staff sign_in then clock in E2E maestro test --shard-split=1 \ apps/mobile/apps/staff/maestro/auth/sign_in.yaml \ apps/mobile/apps/staff/maestro/shifts/clock_in_e2e.yaml \ -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=... ``` Use `--shard-split=1` to run flows sequentially and reduce "tcp:7001 closed" issues between flows. ### Success criteria - **Pass:** Maestro exits with code 0; all steps in the YAML complete (elements found, assertions passed). - **Fail:** Any step times out or an assertion fails; Maestro exits non-zero and reports the failing step. ### Prerequisites that can cause failures - **invoice_approval_e2e**: Test account must have at least one invoice in "Awaiting Approval". Otherwise the flow may timeout or not find "Review & Approve". - **edit_active_order_verify_updated_e2e**: Test account must have at least one active (OPEN) order. Otherwise the flow may not find an edit action. - **rapid_to_one_time_draft_submit_e2e**: Requires RAPID parsing to return a One-Time draft screen (network/service dependency). - **clock_in_e2e / clock_out_e2e**: Staff user must have an active shift (today, within check-in window) and be within GPS range (or use mock location). - **document_upload_e2e**: May require a fixture file; see `apps/mobile/apps/staff/maestro/compliance/` for scripts/fixtures. - **certificate_upload_e2e**: Requires `fixture.pdf` pushed to the device (same fixture script as document upload). --- ## CI/CD E2E runs in GitHub Actions: [.github/workflows/maestro-e2e.yml](../../.github/workflows/maestro-e2e.yml). It runs on: - `workflow_dispatch` (manual) - Pull requests / pushes that touch `apps/mobile/**/maestro/**` or the workflow file Required secrets: `TEST_CLIENT_EMAIL`, `TEST_CLIENT_PASSWORD`, `TEST_CLIENT_COMPANY`, `TEST_STAFF_PHONE`, `TEST_STAFF_OTP`, `TEST_STAFF_SIGNUP_PHONE`. --- ## References - [Maestro test run instructions](../research/maestro-test-run-instructions.md) — install, env vars, troubleshooting - [Flutter testing tools](../research/flutter-testing-tools.md) — context on Maestro vs other tests - Client Maestro README: `apps/mobile/apps/client/maestro/README.md` - Staff Maestro README: `apps/mobile/apps/staff/maestro/README.md`