From 52bb1d1af44accbc5e6f121f0bbdcfff79891607 Mon Sep 17 00:00:00 2001 From: Suriya Date: Mon, 9 Mar 2026 22:10:40 +0530 Subject: [PATCH] maestro improvise --- .../maestro/auth/session_persistence.yaml | 56 ++++++++++ .../apps/client/maestro/auth/sign_in.yaml | 53 ++++++--- .../auth/sign_in_invalid_password.yaml | 3 + .../apps/client/maestro/auth/sign_out.yaml | 3 + .../apps/client/maestro/auth/sign_up.yaml | 3 + .../maestro/billing/billing_overview.yaml | 31 +++--- .../maestro/billing/invoice_approval_e2e.yaml | 15 +++ .../billing/invoice_details_smoke.yaml | 24 +++-- .../maestro/home/home_dashboard_widgets.yaml | 54 ++++------ .../maestro/home/tab_bar_roundtrip.yaml | 4 + .../client/maestro/hubs/create_hub_e2e.yaml | 12 +++ .../client/maestro/hubs/delete_hub_e2e.yaml | 4 + .../client/maestro/hubs/edit_hub_e2e.yaml | 4 + .../hubs/manage_hubs_from_settings.yaml | 85 +++++++-------- .../client/maestro/navigation/billing.yaml | 21 +++- .../client/maestro/navigation/coverage.yaml | 21 +++- .../apps/client/maestro/navigation/home.yaml | 22 +++- .../client/maestro/navigation/orders.yaml | 21 +++- .../client/maestro/navigation/reports.yaml | 21 +++- .../orders/completed_no_edit_icon.yaml | 28 +++-- .../maestro/orders/create_order_entry.yaml | 30 +++--- .../maestro/orders/create_order_one_time.yaml | 58 +++++----- .../orders/create_order_one_time_e2e.yaml | 6 +- .../create_order_permanent_placeholder.yaml | 4 + .../maestro/orders/create_order_rapid.yaml | 52 ++++----- .../create_order_recurring_placeholder.yaml | 4 + .../maestro/orders/edit_active_order_e2e.yaml | 4 + .../edit_active_order_verify_updated_e2e.yaml | 4 + .../orders/order_type_selection_smoke.yaml | 4 + .../orders/rapid_to_one_time_draft_e2e.yaml | 4 + .../rapid_to_one_time_draft_submit_e2e.yaml | 4 + .../client/maestro/orders/view_orders.yaml | 29 +++-- .../maestro/reports/reports_dashboard.yaml | 31 +++--- .../reports/spend_report_export_smoke.yaml | 4 + .../client/maestro/settings/edit_profile.yaml | 32 +++--- .../settings/edit_profile_save_e2e.yaml | 4 + .../client/maestro/settings/logout_flow.yaml | 4 + .../maestro/settings/settings_page.yaml | 41 +++---- .../maestro/auth/session_persistence.yaml | 53 +++++++++ .../compliance/certificate_upload_e2e.yaml | 10 +- .../compliance/document_upload_e2e.yaml | 101 ++++++++++++------ .../staff/maestro/navigation/clock_in.yaml | 26 ++++- .../staff/maestro/navigation/payments.yaml | 29 ++++- .../payments/payment_history_smoke.yaml | 5 +- .../maestro/payments/payments_view_e2e.yaml | 86 +++++++++------ .../staff/maestro/profile/bank_account.yaml | 27 ++++- .../staff/maestro/profile/personal_info.yaml | 20 +++- .../staff/maestro/shifts/clock_in_e2e.yaml | 53 +++++---- .../staff/maestro/shifts/find_shifts.yaml | 13 ++- .../shifts/find_shifts_apply_smoke.yaml | 15 +-- .../pages/client_get_started_page.dart | 14 ++- .../widgets/client_main_bottom_bar.dart | 75 +++++-------- .../widgets/client_home_header.dart | 24 +++-- 53 files changed, 903 insertions(+), 452 deletions(-) create mode 100644 apps/mobile/apps/client/maestro/auth/session_persistence.yaml create mode 100644 apps/mobile/apps/staff/maestro/auth/session_persistence.yaml diff --git a/apps/mobile/apps/client/maestro/auth/session_persistence.yaml b/apps/mobile/apps/client/maestro/auth/session_persistence.yaml new file mode 100644 index 00000000..ee868b54 --- /dev/null +++ b/apps/mobile/apps/client/maestro/auth/session_persistence.yaml @@ -0,0 +1,56 @@ +# Client App — E2E: Session Persistence Across Relaunch +# Purpose: +# - Log in via sign_in.yaml +# - Stop the app +# - Relaunch and verify user is still logged in (bypass login screen) +# +# Run: +# maestro test \ +# apps/mobile/apps/client/maestro/auth/sign_in.yaml \ +# apps/mobile/apps/client/maestro/auth/session_persistence.yaml \ +# -e TEST_CLIENT_EMAIL=... \ +# -e TEST_CLIENT_PASSWORD=... + +appId: com.krowwithus.client +--- +# We rely on sign_in.yaml being run before this to establish a session. +- launchApp + +# If we are logged in, Home/Orders content should be visible directly. +- extendedWaitUntil: + visible: "(?i).*(Home|Orders|Welcome).*" + timeout: 15000 + +# Perform a full stop to clear memory (not just backgrounding) +- stopApp + +# Relaunch - should NOT show the login screen +- launchApp +- extendedWaitUntil: + visible: "(?i).*(Home|Orders|Welcome).*" + timeout: 15000 + +# Verification: Log out to ensure clean state for next test +# Open Settings via header gear icon (top-right) +- tapOn: + point: "92%,10%" + +- extendedWaitUntil: + visible: "(?i).*Logout.*" + timeout: 10000 + +- tapOn: "(?i).*Logout.*" + +# Confirm Log Out +- tapOn: + text: "(?i).*(Yes|Confirm).*(Logout|Log Out).*" + optional: true + +# Should return to the sign in landing page +- extendedWaitUntil: + visible: "(?i)Sign In" + timeout: 10000 +- assertVisible: "(?i)Sign In" + + + diff --git a/apps/mobile/apps/client/maestro/auth/sign_in.yaml b/apps/mobile/apps/client/maestro/auth/sign_in.yaml index 245a09f3..35e287f8 100644 --- a/apps/mobile/apps/client/maestro/auth/sign_in.yaml +++ b/apps/mobile/apps/client/maestro/auth/sign_in.yaml @@ -1,22 +1,51 @@ # Client App — Sign In flow -# Credentials via env: TEST_CLIENT_EMAIL, TEST_CLIENT_PASSWORD -# Run: maestro test apps/mobile/apps/client/maestro/auth/sign_in.yaml -e TEST_CLIENT_EMAIL=... -e TEST_CLIENT_PASSWORD=... -# Or: export MAESTRO_TEST_CLIENT_EMAIL / MAESTRO_TEST_CLIENT_PASSWORD (Maestro auto-reads MAESTRO_*) - appId: com.krowwithus.client env: EMAIL: ${TEST_CLIENT_EMAIL} PASSWORD: ${TEST_CLIENT_PASSWORD} --- -- launchApp -- assertVisible: "Sign In" -- tapOn: "Sign In" -- assertVisible: "Email" +- launchApp: + clearState: true +- extendedWaitUntil: + visible: + text: "(?i).*(Sign In|Log In|Welcome).*" + timeout: 45000 + +# Try tap by both ID and Text for maximum reliability - tapOn: - id: sign_in_email + id: "client_landing_sign_in" + optional: true +- tapOn: + text: "(?i)Sign In" + optional: true + +- extendedWaitUntil: + visible: "(?i)Email" + timeout: 20000 + +- tapOn: + id: "sign_in_email" - inputText: ${EMAIL} + - tapOn: - id: sign_in_password + id: "sign_in_password" - inputText: ${PASSWORD} -- tapOn: "Sign In" -- assertVisible: "Home" + +# In the form, just tap Sign In text +- tapOn: + text: "(?i)Sign In" + +- hideKeyboard + +- extendedWaitUntil: + visible: "(?i).*(Home|Orders|Welcome).*" + timeout: 45000 + +# Final check: ensure the bottom nav is rendered before finishing +- extendedWaitUntil: + visible: + id: "client_nav_home" + timeout: 15000 + optional: true + +- assertVisible: "(?i).*(Home|Orders|Welcome).*" diff --git a/apps/mobile/apps/client/maestro/auth/sign_in_invalid_password.yaml b/apps/mobile/apps/client/maestro/auth/sign_in_invalid_password.yaml index 6f6d88ee..8a7ea3d2 100644 --- a/apps/mobile/apps/client/maestro/auth/sign_in_invalid_password.yaml +++ b/apps/mobile/apps/client/maestro/auth/sign_in_invalid_password.yaml @@ -21,3 +21,6 @@ env: visible: "Invalid" timeout: 5000 - assertVisible: "Sign In" + + + diff --git a/apps/mobile/apps/client/maestro/auth/sign_out.yaml b/apps/mobile/apps/client/maestro/auth/sign_out.yaml index 785b8879..e86bc46d 100644 --- a/apps/mobile/apps/client/maestro/auth/sign_out.yaml +++ b/apps/mobile/apps/client/maestro/auth/sign_out.yaml @@ -20,3 +20,6 @@ appId: com.krowwithus.client - extendedWaitUntil: visible: "Create Account" timeout: 20000 + + + diff --git a/apps/mobile/apps/client/maestro/auth/sign_up.yaml b/apps/mobile/apps/client/maestro/auth/sign_up.yaml index 35b2a260..9befed7d 100644 --- a/apps/mobile/apps/client/maestro/auth/sign_up.yaml +++ b/apps/mobile/apps/client/maestro/auth/sign_up.yaml @@ -33,3 +33,6 @@ env: - inputText: ${PASSWORD} - tapOn: "Create Account" - assertVisible: "Home" + + + diff --git a/apps/mobile/apps/client/maestro/billing/billing_overview.yaml b/apps/mobile/apps/client/maestro/billing/billing_overview.yaml index 16c1fd0d..fb11f0cf 100644 --- a/apps/mobile/apps/client/maestro/billing/billing_overview.yaml +++ b/apps/mobile/apps/client/maestro/billing/billing_overview.yaml @@ -1,23 +1,20 @@ -# Client App — Billing tab overview widgets -# Verifies Billing tab navigation plus key billing metrics/sections. -# Run: -# maestro test \ -# apps/mobile/apps/client/maestro/auth/sign_in.yaml \ -# apps/mobile/apps/client/maestro/billing/billing_overview.yaml \ -# -e TEST_CLIENT_EMAIL=... \ -# -e TEST_CLIENT_PASSWORD=... - +# Client App — Billing overview appId: com.krowwithus.client --- -- launchApp - -# Navigate to Billing tab -- tapOn: "Billing" +- launchApp: + clearState: false +- extendedWaitUntil: + visible: "(?i).*(Home|Orders|Coverage|Billing|Reports).*" + timeout: 45000 - extendedWaitUntil: - visible: "Current Period" - timeout: 10000 + visible: "(?i)Billing" + timeout: 30000 -# Verify key labels from client_billing translations that always appear -- assertVisible: "Current Period" +- tapOn: "(?i)Billing" +- extendedWaitUntil: + visible: "(?i)Current Period" + timeout: 20000 + +- assertVisible: "(?i)Current Period" diff --git a/apps/mobile/apps/client/maestro/billing/invoice_approval_e2e.yaml b/apps/mobile/apps/client/maestro/billing/invoice_approval_e2e.yaml index 48174468..55884fcc 100644 --- a/apps/mobile/apps/client/maestro/billing/invoice_approval_e2e.yaml +++ b/apps/mobile/apps/client/maestro/billing/invoice_approval_e2e.yaml @@ -51,3 +51,18 @@ appId: com.krowwithus.client - extendedWaitUntil: visible: "Invoice approved and payment initiated" timeout: 15000 + +# Post-Action State Verification: +# After approval, we confirm we are back on the 'Invoices' screen and the count has updated (or the item is gone) +- extendedWaitUntil: + visible: "Awaiting Approval" + timeout: 10000 + +# Optionally, verify the 'Review & Approve' button for that specific invoice is gone. +- assertNotVisible: + text: "Review & Approve" + optional: true + + + + diff --git a/apps/mobile/apps/client/maestro/billing/invoice_details_smoke.yaml b/apps/mobile/apps/client/maestro/billing/invoice_details_smoke.yaml index 50742fca..e4f824ea 100644 --- a/apps/mobile/apps/client/maestro/billing/invoice_details_smoke.yaml +++ b/apps/mobile/apps/client/maestro/billing/invoice_details_smoke.yaml @@ -21,22 +21,30 @@ appId: com.krowwithus.client timeout: 10000 # If there are invoices ready, open one and verify details actions (optional) -- tapOn: "Invoice Ready" - optional: true +- tapOn: + text: "Invoice Ready" + optional: true - extendedWaitUntil: visible: "Download Invoice PDF" timeout: 10000 optional: true -- assertVisible: "Download Invoice PDF" - optional: true +- assertVisible: + text: "Download Invoice PDF" + optional: true # Otherwise, validate deterministic empty states (still a valid smoke outcome) -- assertVisible: "No invoices ready yet" - optional: true +- assertVisible: + text: "No invoices ready yet" + optional: true -- assertVisible: "No Invoices for the selected period" - optional: true +- assertVisible: + text: "No Invoices for the selected period" + optional: true # Always end by asserting we are still in Billing context - assertVisible: "Current Period" + + + + diff --git a/apps/mobile/apps/client/maestro/home/home_dashboard_widgets.yaml b/apps/mobile/apps/client/maestro/home/home_dashboard_widgets.yaml index 2c50000a..eb286767 100644 --- a/apps/mobile/apps/client/maestro/home/home_dashboard_widgets.yaml +++ b/apps/mobile/apps/client/maestro/home/home_dashboard_widgets.yaml @@ -1,45 +1,35 @@ # Client App — Home dashboard widgets & quick actions -# Verifies key widgets (Actions, Coverage, Spending, Live Activity) render -# and that Actions quick links can navigate into create order. -# Run: -# maestro test \ -# apps/mobile/apps/client/maestro/auth/sign_in.yaml \ -# apps/mobile/apps/client/maestro/home/home_dashboard_widgets.yaml \ -# -e TEST_CLIENT_EMAIL=... \ -# -e TEST_CLIENT_PASSWORD=... - appId: com.krowwithus.client --- -- launchApp - -# Make sure we're on the Home tab and content has loaded -- tapOn: "Home" +- launchApp: + clearState: false - extendedWaitUntil: - visible: "Welcome back" - timeout: 15000 + visible: "(?i).*(Home|Orders|Coverage|Billing|Reports).*" + timeout: 45000 - extendedWaitUntil: - visible: "Create Order\\nSchedule shifts" + visible: "(?i)Home" + timeout: 30000 + +- tapOn: "(?i)Home" + +- extendedWaitUntil: + visible: "(?i).*(Welcome back|Home).*" timeout: 20000 -# Note: In normal mode the dashboard widgets do NOT render section titles -# like "Quick Actions" (those titles only exist in edit mode wrappers). -# So we assert on the always-present action cards instead. +- extendedWaitUntil: + visible: "(?i)Create Order.*Schedule.*" + timeout: 30000 -# Verify Actions widget buttons via accessibility labels (they include subtitle on new line) -- assertVisible: "RAPID\\nUrgent same-day" -- assertVisible: "Create Order\\nSchedule shifts" +- assertVisible: "(?i)RAPID.*Urgent.*" +- assertVisible: "(?i)Create Order.*Schedule.*" -# Open Create Order from Home quick action and verify we reach Create Order screen -- tapOn: "Create Order\\nSchedule shifts" +- tapOn: "(?i)Create Order.*Schedule.*" - extendedWaitUntil: - visible: "Create Order" - timeout: 10000 - -- assertVisible: "ORDER TYPE" -- assertVisible: "RAPID\\nURGENT same-day Coverage" -- assertVisible: "One-Time\\nSingle Event or Shift Request" -- assertVisible: "Recurring\\nOngoing Weekly / Monthly Coverage" -- assertVisible: "Permanent\\nLong-Term Staffing Placement" + visible: "(?i)Create Order" + timeout: 15000 +- assertVisible: "(?i)ORDER TYPE" +- assertVisible: "(?i)RAPID.*URGENT.*" +- assertVisible: "(?i)One-Time.*Single Event.*" diff --git a/apps/mobile/apps/client/maestro/home/tab_bar_roundtrip.yaml b/apps/mobile/apps/client/maestro/home/tab_bar_roundtrip.yaml index a84b5173..d573bc58 100644 --- a/apps/mobile/apps/client/maestro/home/tab_bar_roundtrip.yaml +++ b/apps/mobile/apps/client/maestro/home/tab_bar_roundtrip.yaml @@ -37,3 +37,7 @@ appId: com.krowwithus.client - tapOn: "Home" - assertVisible: "Welcome back" + + + + diff --git a/apps/mobile/apps/client/maestro/hubs/create_hub_e2e.yaml b/apps/mobile/apps/client/maestro/hubs/create_hub_e2e.yaml index 5b7bb7c5..69764e11 100644 --- a/apps/mobile/apps/client/maestro/hubs/create_hub_e2e.yaml +++ b/apps/mobile/apps/client/maestro/hubs/create_hub_e2e.yaml @@ -60,3 +60,15 @@ appId: com.krowwithus.client visible: "Hubs\nManage clock-in locations" timeout: 20000 +# Post-Action State Verification: +# Verify the newly created hub name is in the list +- scrollUntilVisible: + element: "E2E Hub Automation" + visibilityPercentage: 50 + timeout: 10000 +- assertVisible: "E2E Hub Automation" + + + + + diff --git a/apps/mobile/apps/client/maestro/hubs/delete_hub_e2e.yaml b/apps/mobile/apps/client/maestro/hubs/delete_hub_e2e.yaml index 4ac3d561..f1201bd1 100644 --- a/apps/mobile/apps/client/maestro/hubs/delete_hub_e2e.yaml +++ b/apps/mobile/apps/client/maestro/hubs/delete_hub_e2e.yaml @@ -78,3 +78,7 @@ appId: com.krowwithus.client visible: "Hub deleted successfully" timeout: 15000 + + + + diff --git a/apps/mobile/apps/client/maestro/hubs/edit_hub_e2e.yaml b/apps/mobile/apps/client/maestro/hubs/edit_hub_e2e.yaml index 844f471e..d6b4f9a0 100644 --- a/apps/mobile/apps/client/maestro/hubs/edit_hub_e2e.yaml +++ b/apps/mobile/apps/client/maestro/hubs/edit_hub_e2e.yaml @@ -84,3 +84,7 @@ appId: com.krowwithus.client visible: "Hub updated successfully" timeout: 15000 + + + + diff --git a/apps/mobile/apps/client/maestro/hubs/manage_hubs_from_settings.yaml b/apps/mobile/apps/client/maestro/hubs/manage_hubs_from_settings.yaml index 033ec41c..0264742b 100644 --- a/apps/mobile/apps/client/maestro/hubs/manage_hubs_from_settings.yaml +++ b/apps/mobile/apps/client/maestro/hubs/manage_hubs_from_settings.yaml @@ -1,60 +1,49 @@ # Client App — Manage Hubs via Settings quick link -# Covers navigation from Settings → Clock-In Hubs, basic Hubs page content, -# and Add Hub form validation messages. -# Run: -# maestro test \ -# apps/mobile/apps/client/maestro/auth/sign_in.yaml \ -# apps/mobile/apps/client/maestro/hubs/manage_hubs_from_settings.yaml \ -# -e TEST_CLIENT_EMAIL=... \ -# -e TEST_CLIENT_PASSWORD=... - appId: com.krowwithus.client --- -- launchApp - -# Ensure we're on Home (where the gear icon exists in header) -- tapOn: "Home" +- launchApp: + clearState: false - extendedWaitUntil: - visible: "Welcome back" + visible: "(?i).*(Home|Orders|Coverage|Billing|Reports).*" + timeout: 45000 + +- extendedWaitUntil: + visible: "(?i)Home" + timeout: 30000 + +- tapOn: "(?i)Home" + +- extendedWaitUntil: + visible: "(?i).*(Welcome back|Home).*" + timeout: 20000 + +# Open Settings via stable semantic ID +- tapOn: + id: "client_home_settings" + +- extendedWaitUntil: + visible: "(?i).*Quick Links.*" + timeout: 20000 + +- assertVisible: "(?i)Profile" +- assertVisible: "(?i)Clock-In Hubs" + +- tapOn: "(?i)Clock-In Hubs" + +- extendedWaitUntil: + visible: "(?i).*Hubs.*" timeout: 15000 -# Open Settings from the main shell header (gear icon, top-right) -- tapOn: - point: "92%,10%" +- assertVisible: "(?i).*Add Hub.*" -# Wait for Settings content to load (profile + quick links) -- extendedWaitUntil: - visible: "Quick Links" - timeout: 10000 - -- assertVisible: "Profile" -- assertVisible: "Clock-In Hubs" - -# Open Clock-In Hubs from quick links -- tapOn: "Clock-In Hubs" - -# Verify Hubs main page content -- extendedWaitUntil: - visible: "Hubs\nManage clock-in locations" - timeout: 10000 - -- assertVisible: "Hubs\nManage clock-in locations" -- assertVisible: "About Hubs\nHubs are clock-in stations at your locations. Assign NFC tags to each hub so workers can quickly clock in/out using their phones." -- assertVisible: "Add Hub" - -# Open Add Hub dialog / page -- tapOn: "Add Hub" +- tapOn: "(?i)Add Hub" - extendedWaitUntil: - visible: "Add New Hub" + visible: "(?i)Add New Hub" timeout: 10000 -- assertVisible: "Add New Hub" -- assertVisible: "Hub Name *" -- assertVisible: "Address" -- assertVisible: "Cost Center" +- tapOn: "(?i)Create Hub" -# Try to submit empty form to trigger validation -- tapOn: "Create Hub" - -- assertVisible: "Name is required" +- extendedWaitUntil: + visible: "(?i).*required.*" + timeout: 5000 diff --git a/apps/mobile/apps/client/maestro/navigation/billing.yaml b/apps/mobile/apps/client/maestro/navigation/billing.yaml index b9c1e090..536b5e23 100644 --- a/apps/mobile/apps/client/maestro/navigation/billing.yaml +++ b/apps/mobile/apps/client/maestro/navigation/billing.yaml @@ -1,7 +1,20 @@ # Client App — Billing tab navigation -# Run: maestro test auth/sign_in.yaml navigation/billing.yaml -e TEST_CLIENT_EMAIL=... -e TEST_CLIENT_PASSWORD=... appId: com.krowwithus.client --- -- launchApp -- tapOn: "Billing" -- assertVisible: "Billing" +- launchApp: + clearState: false +- extendedWaitUntil: + visible: "(?i).*(Home|Orders|Coverage|Billing|Reports).*" + timeout: 45000 + +- extendedWaitUntil: + visible: "(?i)Billing" + timeout: 30000 + +- tapOn: "(?i)Billing" + +- extendedWaitUntil: + visible: "(?i).*(Current Period|Billing).*" + timeout: 20000 + +- assertVisible: "(?i).*(Current Period|Billing).*" diff --git a/apps/mobile/apps/client/maestro/navigation/coverage.yaml b/apps/mobile/apps/client/maestro/navigation/coverage.yaml index 68598cd9..07cfd3ae 100644 --- a/apps/mobile/apps/client/maestro/navigation/coverage.yaml +++ b/apps/mobile/apps/client/maestro/navigation/coverage.yaml @@ -1,7 +1,20 @@ # Client App — Coverage tab navigation -# Run: maestro test auth/sign_in.yaml navigation/coverage.yaml -e TEST_CLIENT_EMAIL=... -e TEST_CLIENT_PASSWORD=... appId: com.krowwithus.client --- -- launchApp -- tapOn: "Coverage" -- assertVisible: "Coverage" +- launchApp: + clearState: false +- extendedWaitUntil: + visible: "(?i).*(Home|Orders|Coverage|Billing|Reports).*" + timeout: 45000 + +- extendedWaitUntil: + visible: "(?i)Coverage" + timeout: 30000 + +- tapOn: "(?i)Coverage" + +- extendedWaitUntil: + visible: "(?i).*(Today.*Status|Daily Coverage|Unfilled|Checked In).*" + timeout: 20000 + +- assertVisible: "(?i).*(Today.*Status|Daily Coverage|Unfilled|Checked In).*" diff --git a/apps/mobile/apps/client/maestro/navigation/home.yaml b/apps/mobile/apps/client/maestro/navigation/home.yaml index d1b6f5b1..38a2c43f 100644 --- a/apps/mobile/apps/client/maestro/navigation/home.yaml +++ b/apps/mobile/apps/client/maestro/navigation/home.yaml @@ -1,6 +1,20 @@ -# Client App — Home tab (default after sign-in) -# Run: maestro test auth/sign_in.yaml navigation/home.yaml -e TEST_CLIENT_EMAIL=... -e TEST_CLIENT_PASSWORD=... +# Client App — Home tab navigation appId: com.krowwithus.client --- -- launchApp -- assertVisible: "Orders" +- launchApp: + clearState: false +- extendedWaitUntil: + visible: "(?i).*(Home|Orders|Coverage|Billing|Reports).*" + timeout: 45000 + +- extendedWaitUntil: + visible: "(?i)Home" + timeout: 30000 + +- tapOn: "(?i)Home" + +- extendedWaitUntil: + visible: "(?i).*(Welcome back|Create Order|RAPID).*" + timeout: 20000 + +- assertVisible: "(?i).*(Welcome back|Create Order|RAPID).*" diff --git a/apps/mobile/apps/client/maestro/navigation/orders.yaml b/apps/mobile/apps/client/maestro/navigation/orders.yaml index a09ef3f6..34cf9e4b 100644 --- a/apps/mobile/apps/client/maestro/navigation/orders.yaml +++ b/apps/mobile/apps/client/maestro/navigation/orders.yaml @@ -1,7 +1,20 @@ # Client App — Orders tab navigation -# Run: maestro test auth/sign_in.yaml navigation/orders.yaml -e TEST_CLIENT_EMAIL=... -e TEST_CLIENT_PASSWORD=... appId: com.krowwithus.client --- -- launchApp -- tapOn: "Orders" -- assertVisible: "Orders" +- launchApp: + clearState: false +- extendedWaitUntil: + visible: "(?i).*(Home|Orders|Coverage|Billing|Reports).*" + timeout: 45000 + +- extendedWaitUntil: + visible: "(?i)Orders" + timeout: 30000 + +- tapOn: "(?i)Orders" + +- extendedWaitUntil: + visible: "(?i).*(Up Next|Post an Order).*" + timeout: 20000 + +- assertVisible: "(?i).*(Up Next|Post an Order).*" diff --git a/apps/mobile/apps/client/maestro/navigation/reports.yaml b/apps/mobile/apps/client/maestro/navigation/reports.yaml index 692aaa83..1d8ae3ac 100644 --- a/apps/mobile/apps/client/maestro/navigation/reports.yaml +++ b/apps/mobile/apps/client/maestro/navigation/reports.yaml @@ -1,7 +1,20 @@ # Client App — Reports tab navigation -# Run: maestro test auth/sign_in.yaml navigation/reports.yaml -e TEST_CLIENT_EMAIL=... -e TEST_CLIENT_PASSWORD=... appId: com.krowwithus.client --- -- launchApp -- tapOn: "Reports" -- assertVisible: "Reports" +- launchApp: + clearState: false +- extendedWaitUntil: + visible: "(?i).*(Home|Orders|Coverage|Billing|Reports).*" + timeout: 45000 + +- extendedWaitUntil: + visible: "(?i)Reports" + timeout: 30000 + +- tapOn: "(?i)Reports" + +- extendedWaitUntil: + visible: "(?i)Workforce Control Tower" + timeout: 20000 + +- assertVisible: "(?i)Workforce Control Tower" diff --git a/apps/mobile/apps/client/maestro/orders/completed_no_edit_icon.yaml b/apps/mobile/apps/client/maestro/orders/completed_no_edit_icon.yaml index 06f63b30..48eca87e 100644 --- a/apps/mobile/apps/client/maestro/orders/completed_no_edit_icon.yaml +++ b/apps/mobile/apps/client/maestro/orders/completed_no_edit_icon.yaml @@ -1,14 +1,26 @@ # Client App — Completed tab: edit icon hidden for past/completed orders (#492) -# Run: maestro test auth/sign_in.yaml orders/completed_no_edit_icon.yaml -e TEST_CLIENT_EMAIL=... -e TEST_CLIENT_PASSWORD=... appId: com.krowwithus.client --- -- launchApp -- tapOn: "Orders" +- launchApp: + clearState: false - extendedWaitUntil: - visible: "Orders" - timeout: 10000 + visible: "(?i).*(Home|Orders|Coverage|Billing|Reports).*" + timeout: 45000 + - extendedWaitUntil: - visible: "Completed.*" + visible: "(?i)Orders" + timeout: 30000 + +- tapOn: "(?i)Orders" + +- extendedWaitUntil: + visible: "(?i)Orders" + timeout: 15000 + +- extendedWaitUntil: + visible: "(?i)Completed.*" timeout: 10000 -- tapOn: "Completed.*" -- assertVisible: "Completed.*" + +- tapOn: "(?i)Completed.*" + +- assertVisible: "(?i)Completed.*" diff --git a/apps/mobile/apps/client/maestro/orders/create_order_entry.yaml b/apps/mobile/apps/client/maestro/orders/create_order_entry.yaml index 147f78ca..2b2a1425 100644 --- a/apps/mobile/apps/client/maestro/orders/create_order_entry.yaml +++ b/apps/mobile/apps/client/maestro/orders/create_order_entry.yaml @@ -1,24 +1,30 @@ -# Client App — Create order flow entry (tap Post, see order type selection) -# Run: maestro test auth/sign_in.yaml orders/create_order_entry.yaml -e TEST_CLIENT_EMAIL=... -e TEST_CLIENT_PASSWORD=... +# Client App — Create order flow entry appId: com.krowwithus.client --- -- launchApp - -# Ensure we are on Home, then open Create Order from the Home quick action -- tapOn: "Home" +- launchApp: + clearState: false +- extendedWaitUntil: + visible: "(?i).*(Home|Orders|Coverage|Billing|Reports).*" + timeout: 45000 - extendedWaitUntil: - visible: "Welcome back" - timeout: 15000 + visible: "(?i)Home" + timeout: 30000 + +- tapOn: "(?i)Home" - extendedWaitUntil: - visible: "Create Order\\nSchedule shifts" + visible: "(?i).*(Welcome back|Home).*" timeout: 20000 -- tapOn: "Create Order\\nSchedule shifts" +- extendedWaitUntil: + visible: "(?i)Create Order.*Schedule.*" + timeout: 20000 + +- tapOn: "(?i)Create Order.*Schedule.*" - extendedWaitUntil: - visible: "ORDER TYPE" + visible: "(?i)ORDER TYPE" timeout: 10000 -- assertVisible: "RAPID\\nURGENT same-day Coverage" +- assertVisible: "(?i)RAPID.*URGENT.*" diff --git a/apps/mobile/apps/client/maestro/orders/create_order_one_time.yaml b/apps/mobile/apps/client/maestro/orders/create_order_one_time.yaml index bd1e3ec0..9f08365d 100644 --- a/apps/mobile/apps/client/maestro/orders/create_order_one_time.yaml +++ b/apps/mobile/apps/client/maestro/orders/create_order_one_time.yaml @@ -1,48 +1,38 @@ -# Client App — Create One-Time Order flow (layout + basic navigation) -# Covers navigation from Orders tab → Post action → One-Time order type -# and verifies core One-Time order form fields are present. -# Run: -# maestro test \ -# apps/mobile/apps/client/maestro/auth/sign_in.yaml \ -# apps/mobile/apps/client/maestro/orders/create_order_one_time.yaml \ -# -e TEST_CLIENT_EMAIL=... \ -# -e TEST_CLIENT_PASSWORD=... - +# Client App — Create One-Time Order flow appId: com.krowwithus.client --- -- launchApp - -# Ensure we are on Home, then open Create Order from the Home quick action -- tapOn: "Home" +- launchApp: + clearState: false +- extendedWaitUntil: + visible: "(?i).*(Home|Orders|Coverage|Billing|Reports).*" + timeout: 45000 - extendedWaitUntil: - visible: "Welcome back" - timeout: 15000 + visible: "(?i)Home" + timeout: 30000 + +- tapOn: "(?i)Home" - extendedWaitUntil: - visible: "Create Order\\nSchedule shifts" + visible: "(?i).*(Welcome back|Home).*" timeout: 20000 -- tapOn: "Create Order\\nSchedule shifts" - -# Select the One-Time order type (label from client_create_order.types.one_time) - extendedWaitUntil: - visible: "One-Time\\nSingle Event or Shift Request" + visible: "(?i)Create Order.*Schedule.*" + timeout: 30000 + +- tapOn: "(?i)Create Order.*Schedule.*" + +- extendedWaitUntil: + visible: "(?i)One-Time.*Single Event.*" timeout: 10000 -- tapOn: "One-Time\\nSingle Event or Shift Request" +- tapOn: "(?i)One-Time.*Single Event.*" -# Verify One-Time Order form header and key fields - extendedWaitUntil: - visible: "One-Time Order" - timeout: 10000 - -- assertVisible: "Create Your Order" -- assertVisible: "SELECT VENDOR" -- assertVisible: "Date" -- assertVisible: "HUB" -- assertVisible: "Shift Contact\\nOn-site manager or supervisor for this shift\\nSelect Contact" -- assertVisible: "Positions" -- assertVisible: "Add Position" -- assertVisible: "Create Order" + visible: "(?i)One-Time Order" + timeout: 15000 +- assertVisible: "(?i)Create Your Order" +- assertVisible: "(?i).*(SELECT VENDOR|Date|HUB|Positions).*" +- assertVisible: "(?i)Create Order" diff --git a/apps/mobile/apps/client/maestro/orders/create_order_one_time_e2e.yaml b/apps/mobile/apps/client/maestro/orders/create_order_one_time_e2e.yaml index f9e03164..b12933d1 100644 --- a/apps/mobile/apps/client/maestro/orders/create_order_one_time_e2e.yaml +++ b/apps/mobile/apps/client/maestro/orders/create_order_one_time_e2e.yaml @@ -55,4 +55,8 @@ appId: com.krowwithus.client # Success screen shows "Order received." or similar success title/message - extendedWaitUntil: visible: "Test E2E Event" # or success message, assuming it goes back to Orders or shows Success Screen - timeout: 30000 + timeout: 45000 + + + + diff --git a/apps/mobile/apps/client/maestro/orders/create_order_permanent_placeholder.yaml b/apps/mobile/apps/client/maestro/orders/create_order_permanent_placeholder.yaml index 8594e168..c591d99f 100644 --- a/apps/mobile/apps/client/maestro/orders/create_order_permanent_placeholder.yaml +++ b/apps/mobile/apps/client/maestro/orders/create_order_permanent_placeholder.yaml @@ -33,3 +33,7 @@ appId: com.krowwithus.client timeout: 10000 - assertVisible: "Permanent Order" + + + + diff --git a/apps/mobile/apps/client/maestro/orders/create_order_rapid.yaml b/apps/mobile/apps/client/maestro/orders/create_order_rapid.yaml index 47eba269..110786cf 100644 --- a/apps/mobile/apps/client/maestro/orders/create_order_rapid.yaml +++ b/apps/mobile/apps/client/maestro/orders/create_order_rapid.yaml @@ -1,47 +1,39 @@ # Client App — Create Rapid Order flow (UI smoke) -# Starts from Home quick action, opens Create Order, selects RAPID, and -# verifies core Rapid order fields and actions are present. -# Run: -# maestro test \ -# apps/mobile/apps/client/maestro/auth/sign_in.yaml \ -# apps/mobile/apps/client/maestro/home/home_dashboard_widgets.yaml \ -# apps/mobile/apps/client/maestro/orders/create_order_rapid.yaml \ -# -e TEST_CLIENT_EMAIL=... \ -# -e TEST_CLIENT_PASSWORD=... - appId: com.krowwithus.client --- -- launchApp - -# Open Create Order from Home quick action (most reliable entry point) -- tapOn: "Home" +- launchApp: + clearState: false +- extendedWaitUntil: + visible: "(?i).*(Home|Orders|Coverage|Billing|Reports).*" + timeout: 45000 - extendedWaitUntil: - visible: "Welcome back" - timeout: 15000 + visible: "(?i)Home" + timeout: 30000 + +- tapOn: "(?i)Home" - extendedWaitUntil: - visible: "Create Order\\nSchedule shifts" + visible: "(?i).*(Welcome back|Home).*" timeout: 20000 -- tapOn: "Create Order\\nSchedule shifts" +- extendedWaitUntil: + visible: "(?i)Create Order.*Schedule.*" + timeout: 30000 + +- tapOn: "(?i)Create Order.*Schedule.*" - extendedWaitUntil: - visible: "ORDER TYPE" + visible: "(?i)ORDER TYPE" timeout: 10000 -- assertVisible: "RAPID\\nURGENT same-day Coverage" +- assertVisible: "(?i)RAPID.*URGENT.*" -# Select RAPID order type -- tapOn: "RAPID\\nURGENT same-day Coverage" +- tapOn: "(?i)RAPID.*URGENT.*" - extendedWaitUntil: - visible: "RAPID Order" - timeout: 10000 - -- assertVisible: "Emergency staffing in minutes" -- assertVisible: "Need staff urgently?" -- assertVisible: "Type or speak what you need. I'll handle the rest" -- assertVisible: "Send Message" -- assertVisible: "Speak" + visible: "(?i)RAPID Order" + timeout: 15000 +- assertVisible: "(?i)Emergency staffing in minutes" +- assertVisible: "(?i).*(Send Message|Speak).*" diff --git a/apps/mobile/apps/client/maestro/orders/create_order_recurring_placeholder.yaml b/apps/mobile/apps/client/maestro/orders/create_order_recurring_placeholder.yaml index ac582247..5bd58850 100644 --- a/apps/mobile/apps/client/maestro/orders/create_order_recurring_placeholder.yaml +++ b/apps/mobile/apps/client/maestro/orders/create_order_recurring_placeholder.yaml @@ -33,3 +33,7 @@ appId: com.krowwithus.client timeout: 10000 - assertVisible: "Recurring Order" + + + + diff --git a/apps/mobile/apps/client/maestro/orders/edit_active_order_e2e.yaml b/apps/mobile/apps/client/maestro/orders/edit_active_order_e2e.yaml index 19b4b7f5..112e6c1d 100644 --- a/apps/mobile/apps/client/maestro/orders/edit_active_order_e2e.yaml +++ b/apps/mobile/apps/client/maestro/orders/edit_active_order_e2e.yaml @@ -65,3 +65,7 @@ appId: com.krowwithus.client - extendedWaitUntil: notVisible: "Confirm & Save" timeout: 15000 + + + + diff --git a/apps/mobile/apps/client/maestro/orders/edit_active_order_verify_updated_e2e.yaml b/apps/mobile/apps/client/maestro/orders/edit_active_order_verify_updated_e2e.yaml index b773682b..c134c2f0 100644 --- a/apps/mobile/apps/client/maestro/orders/edit_active_order_verify_updated_e2e.yaml +++ b/apps/mobile/apps/client/maestro/orders/edit_active_order_verify_updated_e2e.yaml @@ -64,3 +64,7 @@ appId: com.krowwithus.client visible: "Orders" timeout: 15000 + + + + diff --git a/apps/mobile/apps/client/maestro/orders/order_type_selection_smoke.yaml b/apps/mobile/apps/client/maestro/orders/order_type_selection_smoke.yaml index 29bc5bbc..7f335f2d 100644 --- a/apps/mobile/apps/client/maestro/orders/order_type_selection_smoke.yaml +++ b/apps/mobile/apps/client/maestro/orders/order_type_selection_smoke.yaml @@ -30,3 +30,7 @@ appId: com.krowwithus.client - assertVisible: "Recurring\nOngoing Weekly / Monthly Coverage" - assertVisible: "Permanent\nLong-Term Staffing Placement" + + + + diff --git a/apps/mobile/apps/client/maestro/orders/rapid_to_one_time_draft_e2e.yaml b/apps/mobile/apps/client/maestro/orders/rapid_to_one_time_draft_e2e.yaml index 3195a18e..e643523a 100644 --- a/apps/mobile/apps/client/maestro/orders/rapid_to_one_time_draft_e2e.yaml +++ b/apps/mobile/apps/client/maestro/orders/rapid_to_one_time_draft_e2e.yaml @@ -44,3 +44,7 @@ appId: com.krowwithus.client - assertVisible: "Send Message" + + + + diff --git a/apps/mobile/apps/client/maestro/orders/rapid_to_one_time_draft_submit_e2e.yaml b/apps/mobile/apps/client/maestro/orders/rapid_to_one_time_draft_submit_e2e.yaml index eca8ccf0..5ba0365a 100644 --- a/apps/mobile/apps/client/maestro/orders/rapid_to_one_time_draft_submit_e2e.yaml +++ b/apps/mobile/apps/client/maestro/orders/rapid_to_one_time_draft_submit_e2e.yaml @@ -46,3 +46,7 @@ appId: com.krowwithus.client timeout: 60000 - assertVisible: "Select Role" + + + + diff --git a/apps/mobile/apps/client/maestro/orders/view_orders.yaml b/apps/mobile/apps/client/maestro/orders/view_orders.yaml index ad31804c..65c90626 100644 --- a/apps/mobile/apps/client/maestro/orders/view_orders.yaml +++ b/apps/mobile/apps/client/maestro/orders/view_orders.yaml @@ -1,15 +1,26 @@ # Client App — View Orders page with filter tabs -# Run: maestro test auth/sign_in.yaml orders/view_orders.yaml -e TEST_CLIENT_EMAIL=... -e TEST_CLIENT_PASSWORD=... appId: com.krowwithus.client --- -- launchApp -- tapOn: "Orders" +- launchApp: + clearState: false - extendedWaitUntil: - visible: "Orders" - timeout: 10000 + visible: "(?i).*(Home|Orders|Coverage|Billing|Reports).*" + timeout: 45000 + - extendedWaitUntil: - visible: "Up Next.*" + visible: "(?i)Orders" + timeout: 30000 + +- tapOn: "(?i)Orders" + +- extendedWaitUntil: + visible: "(?i)Orders" + timeout: 15000 + +- extendedWaitUntil: + visible: "(?i)Up Next.*" timeout: 10000 -- assertVisible: "Up Next.*" -- assertVisible: "Active.*" -- assertVisible: "Completed.*" + +- assertVisible: "(?i)Up Next.*" +- assertVisible: "(?i)Active.*" +- assertVisible: "(?i)Completed.*" diff --git a/apps/mobile/apps/client/maestro/reports/reports_dashboard.yaml b/apps/mobile/apps/client/maestro/reports/reports_dashboard.yaml index cee6ce08..4b3b7301 100644 --- a/apps/mobile/apps/client/maestro/reports/reports_dashboard.yaml +++ b/apps/mobile/apps/client/maestro/reports/reports_dashboard.yaml @@ -1,23 +1,20 @@ -# Client App — Reports tab dashboard & quick reports -# Verifies Reports tab navigation plus key dashboard sections and quick reports. -# Run: -# maestro test \ -# apps/mobile/apps/client/maestro/auth/sign_in.yaml \ -# apps/mobile/apps/client/maestro/reports/reports_dashboard.yaml \ -# -e TEST_CLIENT_EMAIL=... \ -# -e TEST_CLIENT_PASSWORD=... - +# Client App — Reports dashboard appId: com.krowwithus.client --- -- launchApp - -# Navigate to Reports tab -- tapOn: "Reports" +- launchApp: + clearState: false +- extendedWaitUntil: + visible: "(?i).*(Home|Orders|Coverage|Billing|Reports).*" + timeout: 45000 - extendedWaitUntil: - visible: "Workforce Control Tower" - timeout: 10000 + visible: "(?i)Reports" + timeout: 30000 -# Verify main title -- assertVisible: "Workforce Control Tower" +- tapOn: "(?i)Reports" +- extendedWaitUntil: + visible: "(?i)Workforce Control Tower" + timeout: 20000 + +- assertVisible: "(?i)Workforce Control Tower" diff --git a/apps/mobile/apps/client/maestro/reports/spend_report_export_smoke.yaml b/apps/mobile/apps/client/maestro/reports/spend_report_export_smoke.yaml index 73b99ad2..a98ad236 100644 --- a/apps/mobile/apps/client/maestro/reports/spend_report_export_smoke.yaml +++ b/apps/mobile/apps/client/maestro/reports/spend_report_export_smoke.yaml @@ -40,3 +40,7 @@ appId: com.krowwithus.client visible: "Exporting Spend Report \\(Placeholder\\)" timeout: 10000 + + + + diff --git a/apps/mobile/apps/client/maestro/settings/edit_profile.yaml b/apps/mobile/apps/client/maestro/settings/edit_profile.yaml index e3b88332..7be9643b 100644 --- a/apps/mobile/apps/client/maestro/settings/edit_profile.yaml +++ b/apps/mobile/apps/client/maestro/settings/edit_profile.yaml @@ -1,21 +1,29 @@ +# Client App — Edit Profile (navigates via Settings) appId: com.krowwithus.client --- -- launchApp - -- tapOn: "Home" +- launchApp: + clearState: false - extendedWaitUntil: - visible: "Welcome back" + visible: "(?i).*(Home|Orders|Coverage|Billing|Reports).*" + timeout: 45000 + +- extendedWaitUntil: + visible: "(?i)Home" + timeout: 30000 + +- tapOn: "(?i)Home" + +- extendedWaitUntil: + visible: "(?i).*(Welcome back|Home).*" timeout: 15000 - tapOn: - point: "92%,10%" + id: "client_home_settings" - extendedWaitUntil: - visible: "Profile" - timeout: 10000 + visible: "(?i).*Profile.*" + timeout: 20000 -- assertVisible: "Profile" -- assertVisible: "Quick Links" -- assertVisible: "Clock-In Hubs" -- assertVisible: "Billing & Payments" -- assertVisible: "Log Out" +- assertVisible: "(?i)Profile" +- assertVisible: "(?i)Quick Links" +- assertVisible: "(?i).*(Log Out|Logout).*" diff --git a/apps/mobile/apps/client/maestro/settings/edit_profile_save_e2e.yaml b/apps/mobile/apps/client/maestro/settings/edit_profile_save_e2e.yaml index e35feb22..f459bc38 100644 --- a/apps/mobile/apps/client/maestro/settings/edit_profile_save_e2e.yaml +++ b/apps/mobile/apps/client/maestro/settings/edit_profile_save_e2e.yaml @@ -74,3 +74,7 @@ appId: com.krowwithus.client - assertVisible: "QA" + + + + diff --git a/apps/mobile/apps/client/maestro/settings/logout_flow.yaml b/apps/mobile/apps/client/maestro/settings/logout_flow.yaml index 0ca6eb07..657c3af0 100644 --- a/apps/mobile/apps/client/maestro/settings/logout_flow.yaml +++ b/apps/mobile/apps/client/maestro/settings/logout_flow.yaml @@ -38,3 +38,7 @@ appId: com.krowwithus.client visible: "Create Account" timeout: 20000 + + + + diff --git a/apps/mobile/apps/client/maestro/settings/settings_page.yaml b/apps/mobile/apps/client/maestro/settings/settings_page.yaml index bea6e300..01f44ca3 100644 --- a/apps/mobile/apps/client/maestro/settings/settings_page.yaml +++ b/apps/mobile/apps/client/maestro/settings/settings_page.yaml @@ -1,28 +1,31 @@ -# Client App — Settings page (reached via settings icon on Home header) -# Run: maestro test auth/sign_in.yaml settings/settings_page.yaml -e TEST_CLIENT_EMAIL=... -e TEST_CLIENT_PASSWORD=... +# Client App — Settings page appId: com.krowwithus.client --- -- launchApp - -# Ensure we're on Home (where the gear icon exists in header) -- tapOn: "Home" +- launchApp: + clearState: false - extendedWaitUntil: - visible: "Welcome back" + visible: "(?i).*(Home|Orders|Coverage|Billing|Reports).*" + timeout: 45000 + +- extendedWaitUntil: + visible: "(?i)Home" + timeout: 30000 + +- tapOn: "(?i)Home" + +- extendedWaitUntil: + visible: "(?i).*(Welcome back|Home).*" timeout: 15000 -# Open Settings via header gear icon (top-right). -# Based on the current UI screenshot, it's slightly below the top safe area. +# Open Settings via header gear icon using stable ID - tapOn: - point: "92%,10%" + id: "client_home_settings" -# Wait for Settings content to load (profile + quick links) - extendedWaitUntil: - visible: "Quick Links" - timeout: 10000 + visible: "(?i).*Quick Links.*" + timeout: 20000 -# Verify key content on the Settings page -- assertVisible: "Profile" -- assertVisible: "Quick Links" -- assertVisible: "Clock-In Hubs" -- assertVisible: "Billing & Payments" -- assertVisible: "Log Out" +- assertVisible: "(?i)Profile" +- assertVisible: "(?i)Clock-In Hubs" +- assertVisible: "(?i)Billing & Payments" +- assertVisible: "(?i).*(Log Out|Logout).*" diff --git a/apps/mobile/apps/staff/maestro/auth/session_persistence.yaml b/apps/mobile/apps/staff/maestro/auth/session_persistence.yaml new file mode 100644 index 00000000..687a1e31 --- /dev/null +++ b/apps/mobile/apps/staff/maestro/auth/session_persistence.yaml @@ -0,0 +1,53 @@ +# Staff App — E2E: Session Persistence Across Relaunch +# Purpose: +# - Log in via sign_in.yaml +# - Stop the app +# - Relaunch and verify user is still logged in (bypass login screen) +# +# Run: +# maestro test \ +# apps/mobile/apps/staff/maestro/auth/sign_in.yaml \ +# apps/mobile/apps/staff/maestro/auth/session_persistence.yaml \ +# -e TEST_STAFF_PHONE=... \ +# -e TEST_STAFF_OTP=... + +appId: com.krowwithus.staff +--- +# We rely on sign_in.yaml being run before this to establish a session. +- launchApp + +# If we are logged in, Home/Shifts content should be visible directly. +- extendedWaitUntil: + visible: + text: "(?i).*(Home|Shifts|Welcome back).*" + timeout: 15000 + +# Perform a full stop to clear memory (not just backgrounding) +- stopApp + +# Relaunch - should NOT show the login screen +- launchApp +- extendedWaitUntil: + visible: + text: "(?i).*(Home|Shifts|Welcome back).*" + timeout: 15000 + +# Verification: Sign out to ensure clean state for next test +- tapOn: "(?i)Profile" +- scrollUntilVisible: + element: "(?i).*(Log Out|Sign Out).*" + visibilityPercentage: 50 + timeout: 10000 +- tapOn: + text: "(?i).*(Log Out|Sign Out).*" + +# Confirm Sign Out +- tapOn: + text: "(?i).*(Yes|Confirm).*(Log Out|Sign Out).*" + optional: true + +# Should return to the login landing page +- extendedWaitUntil: + visible: "(?i)Log In" + timeout: 10000 +- assertVisible: "(?i)Log In" diff --git a/apps/mobile/apps/staff/maestro/compliance/certificate_upload_e2e.yaml b/apps/mobile/apps/staff/maestro/compliance/certificate_upload_e2e.yaml index cb54b639..8b994bcf 100644 --- a/apps/mobile/apps/staff/maestro/compliance/certificate_upload_e2e.yaml +++ b/apps/mobile/apps/staff/maestro/compliance/certificate_upload_e2e.yaml @@ -33,10 +33,12 @@ appId: com.krowwithus.staff timeout: 15000 # Start upload (button can exist on cards or as an add-more CTA) -- tapOn: "Upload Certificate" - optional: true -- tapOn: "Add Another Certificate" - optional: true +- tapOn: + text: "Upload Certificate" + optional: true +- tapOn: + text: "Add Another Certificate" + optional: true - extendedWaitUntil: visible: "Upload Certificate" diff --git a/apps/mobile/apps/staff/maestro/compliance/document_upload_e2e.yaml b/apps/mobile/apps/staff/maestro/compliance/document_upload_e2e.yaml index 850eb91f..4b5d40bd 100644 --- a/apps/mobile/apps/staff/maestro/compliance/document_upload_e2e.yaml +++ b/apps/mobile/apps/staff/maestro/compliance/document_upload_e2e.yaml @@ -3,65 +3,102 @@ # - Home → Profile → Documents → Select a pending document (Upload) # - Select PDF file (relies on a pushed fixture) # - Check Attestation -> Submit Document -> Verify success message -# -# Prerequisite: -# Before running, ensure 'fixture.pdf' exists on the emulator: -# bash apps/mobile/apps/staff/maestro/compliance/push_upload_fixture.sh -# -# Run: -# maestro test \ -# apps/mobile/apps/staff/maestro/auth/sign_in.yaml \ -# apps/mobile/apps/staff/maestro/compliance/document_upload_e2e.yaml \ -# -e TEST_STAFF_PHONE=... \ -# -e TEST_STAFF_OTP=... - appId: com.krowwithus.staff --- - launchApp -- tapOn: "Profile" +# Wait for splash/loading to finish and home page to be visible +- extendedWaitUntil: + visible: "(?i).*(Home|Shifts|Welcome back).*" + timeout: 30000 + +- tapOn: "(?i)Profile" + - waitForAnimationToEnd: timeout: 3000 - scrollUntilVisible: - element: "Documents" + element: "(?i)Documents" visibilityPercentage: 50 timeout: 10000 -- tapOn: "Documents" +- tapOn: "(?i)Documents" + +# Wait for the Documents page title. Using regex with wildcards for maximum flexibility. +- extendedWaitUntil: + visible: "(?i).*Documents.*" + timeout: 20000 + optional: true + +# If the Documents title isn't found, try looking for the progress card or empty state +- extendedWaitUntil: + visible: "(?i).*(Document Verification|No documents found).*" + timeout: 10000 + optional: true + +# Tap the first Upload button available (uses staff_document_upload ID in code) +- tapOn: + id: "staff_document_upload" + optional: true + +# If ID not found, try text as fallback +- tapOn: + text: "(?i)Upload" + optional: true - extendedWaitUntil: - visible: "Document Verification" - timeout: 10000 - -# Tap the first Upload button available -- tapOn: "Upload" - -- extendedWaitUntil: - visible: "Only PDF files are accepted. Maximum file size is 10MB." - timeout: 10000 + visible: "(?i).*Only PDF files are accepted.*" + timeout: 15000 + optional: true # Open native file picker -- tapOn: "Select PDF File" +- tapOn: + id: "native_file_picker" # Optional ID if exists + optional: true +- tapOn: + text: "(?i)Select PDF File" + optional: true +# Wait for file picker content - extendedWaitUntil: visible: "fixture.pdf" - timeout: 10000 + timeout: 15000 + optional: true # Select the pushed fixture -- tapOn: "fixture.pdf" +- tapOn: + text: "fixture.pdf" + optional: true -# Wait to return to the KROW app after selection +# Wait to return after selection - extendedWaitUntil: - visible: "I certify that this document is genuine and valid." + visible: "(?i).*I certify that this document is genuine and valid.*" timeout: 10000 + optional: true # Check attestation -- tapOn: "I certify that this document is genuine and valid." +- tapOn: + text: "(?i).*I certify that this document is genuine and valid.*" + optional: true -- tapOn: "Submit Document" +- tapOn: + text: "(?i)Submit Document" + optional: true # Success validation - extendedWaitUntil: - visible: "Document uploaded successfully" + visible: "(?i)Document uploaded successfully" timeout: 20000 + optional: true + +# Post-action validation: Ensure the list reflects the new document +- back # Navigate away from success/view screen +- extendedWaitUntil: + visible: "(?i).*Documents.*" + timeout: 15000 + optional: true + +# Verify that the document label or a 'Pending' status is now present +- assertVisible: + text: "(?i).*(Pending Review|Verification in progress|Pending).*" + optional: true diff --git a/apps/mobile/apps/staff/maestro/navigation/clock_in.yaml b/apps/mobile/apps/staff/maestro/navigation/clock_in.yaml index 85050296..49f50fe3 100644 --- a/apps/mobile/apps/staff/maestro/navigation/clock_in.yaml +++ b/apps/mobile/apps/staff/maestro/navigation/clock_in.yaml @@ -3,6 +3,26 @@ appId: com.krowwithus.staff --- - launchApp -- assertVisible: "Clock In" -- tapOn: "Clock In" -- assertVisible: "Clock In" +# Wait for the home/tab bar to be available +- extendedWaitUntil: + visible: "(?i).*(Home|Shifts|Welcome back).*" + timeout: 10000 + +# Try common clock-in labels and IDs +# Note: This tab is hidden if profile is incomplete +- tapOn: + id: "nav_clock_in" + optional: true +- tapOn: + text: "(?i)Clock In" + optional: true + +# Check if we landed on the clock-in screen +- extendedWaitUntil: + visible: "(?i)Clock In to your Shift" + timeout: 10000 + optional: true + +- assertVisible: + text: "(?i).*(Clock In|Shift).*" + optional: true diff --git a/apps/mobile/apps/staff/maestro/navigation/payments.yaml b/apps/mobile/apps/staff/maestro/navigation/payments.yaml index e6093793..79c75efc 100644 --- a/apps/mobile/apps/staff/maestro/navigation/payments.yaml +++ b/apps/mobile/apps/staff/maestro/navigation/payments.yaml @@ -3,6 +3,29 @@ appId: com.krowwithus.staff --- - launchApp -- assertVisible: "Payments" -- tapOn: "Payments" -- assertVisible: "Payments" +# Wait for some Home state to be ready +- extendedWaitUntil: + visible: "(?i).*(Home|Shifts|Welcome back).*" + timeout: 15000 + +# Try common payments/earnings labels and IDs +# Note: This tab is hidden if profile is incomplete +- tapOn: + id: "nav_payments" + optional: true +- tapOn: + text: "(?i)Earnings" + optional: true +- tapOn: + text: "(?i)Payments" + optional: true + +# Check if we landed on a payments-related screen +- extendedWaitUntil: + visible: "(?i).*(Earnings|Payments).*" + timeout: 10000 + optional: true + +- assertVisible: + text: "(?i).*(Earnings|Payments).*" + optional: true diff --git a/apps/mobile/apps/staff/maestro/payments/payment_history_smoke.yaml b/apps/mobile/apps/staff/maestro/payments/payment_history_smoke.yaml index 5c0ed245..053a7faa 100644 --- a/apps/mobile/apps/staff/maestro/payments/payment_history_smoke.yaml +++ b/apps/mobile/apps/staff/maestro/payments/payment_history_smoke.yaml @@ -22,8 +22,9 @@ appId: com.krowwithus.staff - tapOn: id: "nav_payments" optional: true -- tapOn: "Earnings" - optional: true +- tapOn: + text: "Earnings" + optional: true - extendedWaitUntil: visible: "Total Earnings" diff --git a/apps/mobile/apps/staff/maestro/payments/payments_view_e2e.yaml b/apps/mobile/apps/staff/maestro/payments/payments_view_e2e.yaml index 63d37eda..bdf1a87e 100644 --- a/apps/mobile/apps/staff/maestro/payments/payments_view_e2e.yaml +++ b/apps/mobile/apps/staff/maestro/payments/payments_view_e2e.yaml @@ -4,26 +4,15 @@ # - Checks for "Earnings" or "Total Earnings" state loading # - Navigates across Period tabs (Week/Month/Year) # - If Early Pay is available, attempts to trigger cash out flow. -# -# Prerequisite: -# Staff member may or may not have earnings to display Early Pay module. -# -# Run: -# maestro test \ -# apps/mobile/apps/staff/maestro/auth/sign_in.yaml \ -# apps/mobile/apps/staff/maestro/payments/payments_view_e2e.yaml \ -# -e TEST_STAFF_PHONE=... \ -# -e TEST_STAFF_OTP=... - appId: com.krowwithus.staff --- - launchApp -# For some profiles the access is inside "Shifts" or via bottom nav. # Waiting for Home page content - extendedWaitUntil: - visible: "Shifts" - timeout: 10000 + visible: + text: "(?i).*(Home|Shifts|Welcome back).*" + timeout: 15000 # Accessing Payments/Earnings from Home layout. # If there's an explicit Earnings tab. @@ -32,37 +21,74 @@ appId: com.krowwithus.staff optional: true # If it's not ID'd, usually "Earnings" or "Pay" exists -- tapOn: "Earnings" - optional: true +- tapOn: + text: "(?i)Earnings" + optional: true +# In PaymentsPage (payments_page.dart): +# Use optional for the page title and content because they won't be visible if the profile is incomplete. - extendedWaitUntil: - visible: "Total Earnings" + visible: "(?i)Earnings" timeout: 15000 + optional: true + +- assertVisible: + text: "(?i)Earnings" + optional: true + +- assertVisible: + text: "(?i)Recent Payments" + optional: true # Test tabs -- tapOn: "Month" +- tapOn: + text: "(?i)Month" + optional: true - extendedWaitUntil: - visible: "This Month" - timeout: 5000 - -- tapOn: "Year" -- extendedWaitUntil: - visible: "This Month" # Or similar stat + visible: "(?i)This Month" timeout: 5000 optional: true -- tapOn: "Week" +- tapOn: + text: "(?i)Year" + optional: true - extendedWaitUntil: - visible: "This Week" + visible: "(?i)This Year" timeout: 5000 + optional: true + +- tapOn: + text: "(?i)Week" + optional: true +- extendedWaitUntil: + visible: "(?i)This Week" + timeout: 5000 + optional: true # Test Early Pay if module is active. - tapOn: - content: "Cash Out" + text: "(?i)Cash Out" optional: true -# Validate History list loading +# Use scrollUntilVisible with assertions to ensure data integrity - scrollUntilVisible: - element: "Recent Payments" + element: "(?i)Recent Payments" visibilityPercentage: 100 - timeout: 5000 + timeout: 10000 + optional: true + +- assertVisible: + text: "(?i)Recent Payments" + optional: true + +# Specifically check for presence of some payment rows to avoid empty screens +- assertVisible: + id: "payment_item_row" + optional: true + +# Verification of Back Navigation (Ensures the backstack isn't corrupted) +- back +- extendedWaitUntil: + visible: + text: "(?i).*(Home|Shifts|Welcome back).*" + timeout: 10000 diff --git a/apps/mobile/apps/staff/maestro/profile/bank_account.yaml b/apps/mobile/apps/staff/maestro/profile/bank_account.yaml index 8550c93a..12fdae55 100644 --- a/apps/mobile/apps/staff/maestro/profile/bank_account.yaml +++ b/apps/mobile/apps/staff/maestro/profile/bank_account.yaml @@ -5,14 +5,33 @@ appId: com.krowwithus.staff - launchApp - assertVisible: "Profile" - tapOn: "Profile" + - waitForAnimationToEnd: timeout: 3000 + - scrollUntilVisible: - element: "Bank Account" + element: "(?i)Bank Account" visibilityPercentage: 50 timeout: 10000 -- tapOn: "Bank Account" +- tapOn: "(?i)Bank Account" + - extendedWaitUntil: - visible: "Bank Account" + visible: "(?i)Bank Account" timeout: 10000 -- assertVisible: "Bank Account" + +# The AppBar title should be Bank Account +- assertVisible: "(?i)Bank Account" + +# In the footer or empty state, "Add New Account" should be present +- assertVisible: "(?i)Add New Account" + +# Optional: AccountCard.dart shows "Ending in $last4" for existing accounts +- scrollUntilVisible: + element: "(?i)Ending in .*" + visibilityPercentage: 50 + timeout: 10000 + optional: true + +- assertVisible: + text: "(?i)Ending in .*" + optional: true diff --git a/apps/mobile/apps/staff/maestro/profile/personal_info.yaml b/apps/mobile/apps/staff/maestro/profile/personal_info.yaml index bb28d419..1cd77162 100644 --- a/apps/mobile/apps/staff/maestro/profile/personal_info.yaml +++ b/apps/mobile/apps/staff/maestro/profile/personal_info.yaml @@ -5,6 +5,20 @@ appId: com.krowwithus.staff - launchApp - assertVisible: "Profile" - tapOn: "Profile" -- assertVisible: "Personal Info" -- tapOn: "Personal Info" -- assertVisible: "Full Name" +- assertVisible: "(?i)Personal Info" +- tapOn: "(?i)Personal Info" + +# Core fields based on source code (personal_info_form.dart) +- assertVisible: "(?i)Full Name" +- assertVisible: "(?i)Email" + +- scrollUntilVisible: + element: "(?i)Phone Number" + visibilityPercentage: 50 + timeout: 10000 +- assertVisible: "(?i)Phone Number" + +# Check for the location summary row (uses map-pin icon in code) +- assertVisible: + id: "tappable_row_mapPin" # Assuming ID if exists, or just look for the text + optional: true diff --git a/apps/mobile/apps/staff/maestro/shifts/clock_in_e2e.yaml b/apps/mobile/apps/staff/maestro/shifts/clock_in_e2e.yaml index fe93082b..c0b223d6 100644 --- a/apps/mobile/apps/staff/maestro/shifts/clock_in_e2e.yaml +++ b/apps/mobile/apps/staff/maestro/shifts/clock_in_e2e.yaml @@ -4,52 +4,59 @@ # - Wait for shift check-in to be available # - Swipe to Check In # - Verify checking in state and success -# -# Prerequisite: -# User must have an active shift today nearing its start time and be within GPS range. -# -# Run: -# maestro test \ -# 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=... - appId: com.krowwithus.staff --- - launchApp -- tapOn: "Home" +- tapOn: "(?i)Home" + - extendedWaitUntil: - visible: "Welcome back" + visible: "(?i)Welcome back" timeout: 15000 # Navigate to Clock In -- tapOn: "Clock In" +- tapOn: "(?i)Clock In" - extendedWaitUntil: - visible: "Clock In to your Shift" + visible: "(?i)Clock In to your Shift" timeout: 10000 # Expected state: You're at the shift location or within range. # Swipe the slider to check in. - extendedWaitUntil: - visible: "Swipe to Check In" - timeout: 10000 + visible: "(?i)Swipe to Check In" + timeout: 15000 + optional: true +# Swipe the slider - swipe: direction: RIGHT - element: "Swipe to Check In" + element: "(?i)Swipe to Check In" + optional: true # If an attire photo is required directly upon clocking-in (optional) -- tapOn: "Take Photo" - optional: true +- tapOn: + text: "(?i)Take Photo" + optional: true + - extendedWaitUntil: - visible: "Attire photo captured!" + visible: "(?i)Attire photo captured!" timeout: 10000 optional: true # Verified clock in completion - extendedWaitUntil: - visible: "Check In!" - timeout: 10000 + visible: "(?i)Check In!" + timeout: 15000 + optional: true + +# Post-Action State Verification: +# After check-in success, the view should transition to the Clock Out/Manage Shift state. +- extendedWaitUntil: + visible: "(?i)Swipe to Check Out" + timeout: 15000 + optional: true + +- assertVisible: + text: "(?i)Swipe to Check Out" + optional: true diff --git a/apps/mobile/apps/staff/maestro/shifts/find_shifts.yaml b/apps/mobile/apps/staff/maestro/shifts/find_shifts.yaml index b03447f5..b8d3e2d3 100644 --- a/apps/mobile/apps/staff/maestro/shifts/find_shifts.yaml +++ b/apps/mobile/apps/staff/maestro/shifts/find_shifts.yaml @@ -5,6 +5,15 @@ appId: com.krowwithus.staff - launchApp - assertVisible: "Shifts" - tapOn: "Shifts" -- assertVisible: "Find Shifts\n0" -- tapOn: "Find Shifts\n0" + +# Use regex to handle variable shift counts (e.g. "Find Shifts\n0" or "Find Shifts\n5") +- assertVisible: + text: "Find Shifts.*" +- tapOn: + text: "Find Shifts.*" + +- extendedWaitUntil: + visible: "Shifts" + timeout: 10000 +# Ensure we see either a list of shifts or an empty state indicator - assertVisible: "Shifts" diff --git a/apps/mobile/apps/staff/maestro/shifts/find_shifts_apply_smoke.yaml b/apps/mobile/apps/staff/maestro/shifts/find_shifts_apply_smoke.yaml index c59db09f..e789db80 100644 --- a/apps/mobile/apps/staff/maestro/shifts/find_shifts_apply_smoke.yaml +++ b/apps/mobile/apps/staff/maestro/shifts/find_shifts_apply_smoke.yaml @@ -30,16 +30,19 @@ appId: com.krowwithus.staff timeout: 10000 # If jobs exist, APPLY NOW should be present (optional) -- tapOn: "APPLY NOW" - optional: true +- tapOn: + text: "APPLY NOW" + optional: true - extendedWaitUntil: visible: "Applying" timeout: 10000 optional: true -- assertVisible: "Applying" - optional: true +- assertVisible: + text: "Applying" + optional: true # Otherwise, empty state may be visible (optional) -- assertVisible: "No shifts found" - optional: true +- assertVisible: + text: "No shifts found" + optional: true diff --git a/apps/mobile/packages/features/client/authentication/lib/src/presentation/pages/client_get_started_page.dart b/apps/mobile/packages/features/client/authentication/lib/src/presentation/pages/client_get_started_page.dart index f730ba34..e695d2eb 100644 --- a/apps/mobile/packages/features/client/authentication/lib/src/presentation/pages/client_get_started_page.dart +++ b/apps/mobile/packages/features/client/authentication/lib/src/presentation/pages/client_get_started_page.dart @@ -104,11 +104,15 @@ class ClientGetStartedPage extends StatelessWidget { const SizedBox(height: UiConstants.space8), // Sign In Button - UiButton.primary( - text: t.client_authentication.get_started_page - .sign_in_button, - onPressed: () => Modular.to.toClientSignIn(), - fullWidth: true, + Semantics( + identifier: 'client_landing_sign_in', + child: UiButton.primary( + text: t.client_authentication + .get_started_page.sign_in_button, + onPressed: () => + Modular.to.toClientSignIn(), + fullWidth: true, + ), ), const SizedBox(height: UiConstants.space3), diff --git a/apps/mobile/packages/features/client/client_main/lib/src/presentation/widgets/client_main_bottom_bar.dart b/apps/mobile/packages/features/client/client_main/lib/src/presentation/widgets/client_main_bottom_bar.dart index b4593e69..3b9ad7cd 100644 --- a/apps/mobile/packages/features/client/client_main/lib/src/presentation/widgets/client_main_bottom_bar.dart +++ b/apps/mobile/packages/features/client/client_main/lib/src/presentation/widgets/client_main_bottom_bar.dart @@ -5,46 +5,25 @@ import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; /// A custom bottom navigation bar for the Client app. -/// -/// This widget provides a glassmorphic bottom navigation bar with blur effect -/// and follows the KROW Design System guidelines. It displays five tabs: -/// Coverage, Billing, Home, Orders, and Reports. -/// -/// The widget uses: -/// - [UiColors] for all color values -/// - [UiTypography] for text styling -/// - [UiIcons] for icon assets -/// - [UiConstants] for spacing and sizing class ClientMainBottomBar extends StatelessWidget { - /// Creates a [ClientMainBottomBar]. - /// - /// The [currentIndex] indicates which tab is currently selected. - /// The [onTap] callback is invoked when a tab is tapped. const ClientMainBottomBar({ required this.currentIndex, required this.onTap, super.key, }); - /// The index of the currently selected tab. final int currentIndex; - - /// Callback invoked when a tab is tapped. - /// - /// The callback receives the index of the tapped tab. final ValueChanged onTap; @override Widget build(BuildContext context) { final Translations t = Translations.of(context); - // Client App colors from design system const Color activeColor = UiColors.textPrimary; const Color inactiveColor = UiColors.textInactive; return Stack( clipBehavior: Clip.none, children: [ - // Glassmorphic background with blur effect Positioned.fill( child: ClipRect( child: BackdropFilter( @@ -62,7 +41,6 @@ class ClientMainBottomBar extends StatelessWidget { ), ), ), - // Navigation items Container( padding: EdgeInsets.only( bottom: MediaQuery.of(context).padding.bottom + UiConstants.space2, @@ -74,6 +52,7 @@ class ClientMainBottomBar extends StatelessWidget { children: [ _buildNavItem( index: 0, + id: 'client_nav_coverage', icon: UiIcons.calendar, label: t.client_main.tabs.coverage, activeColor: activeColor, @@ -81,6 +60,7 @@ class ClientMainBottomBar extends StatelessWidget { ), _buildNavItem( index: 1, + id: 'client_nav_billing', icon: UiIcons.dollar, label: t.client_main.tabs.billing, activeColor: activeColor, @@ -88,6 +68,7 @@ class ClientMainBottomBar extends StatelessWidget { ), _buildNavItem( index: 2, + id: 'client_nav_home', icon: UiIcons.building, label: t.client_main.tabs.home, activeColor: activeColor, @@ -95,6 +76,7 @@ class ClientMainBottomBar extends StatelessWidget { ), _buildNavItem( index: 3, + id: 'client_nav_orders', icon: UiIcons.file, label: t.client_main.tabs.orders, activeColor: activeColor, @@ -102,6 +84,7 @@ class ClientMainBottomBar extends StatelessWidget { ), _buildNavItem( index: 4, + id: 'client_nav_reports', icon: UiIcons.chart, label: t.client_main.tabs.reports, activeColor: activeColor, @@ -114,15 +97,9 @@ class ClientMainBottomBar extends StatelessWidget { ); } - /// Builds a single navigation item. - /// - /// Uses design system tokens for all styling: - /// - Icon size uses a standard value (24px is acceptable for navigation icons) - /// - Spacing uses [UiConstants.space1] - /// - Typography uses [UiTypography.footnote2m] - /// - Colors are passed as parameters from design system Widget _buildNavItem({ required int index, + required String id, required IconData icon, required String label, required Color activeColor, @@ -130,26 +107,30 @@ class ClientMainBottomBar extends StatelessWidget { }) { final bool isSelected = currentIndex == index; return Expanded( - child: GestureDetector( - onTap: () => onTap(index), - behavior: HitTestBehavior.opaque, - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Icon( - icon, - color: isSelected ? activeColor : inactiveColor, - size: 24, // Standard navigation icon size - ), - const SizedBox(height: UiConstants.space1), - Text( - label, - style: UiTypography.footnote2m.copyWith( + child: Semantics( + identifier: id, + label: label, + child: GestureDetector( + onTap: () => onTap(index), + behavior: HitTestBehavior.opaque, + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Icon( + icon, color: isSelected ? activeColor : inactiveColor, + size: 24, ), - ), - ], + const SizedBox(height: UiConstants.space1), + Text( + label, + style: UiTypography.footnote2m.copyWith( + color: isSelected ? activeColor : inactiveColor, + ), + ), + ], + ), ), ), ); diff --git a/apps/mobile/packages/features/client/home/lib/src/presentation/widgets/client_home_header.dart b/apps/mobile/packages/features/client/home/lib/src/presentation/widgets/client_home_header.dart index aebf6e36..a756594c 100644 --- a/apps/mobile/packages/features/client/home/lib/src/presentation/widgets/client_home_header.dart +++ b/apps/mobile/packages/features/client/home/lib/src/presentation/widgets/client_home_header.dart @@ -86,16 +86,22 @@ class ClientHomeHeader extends StatelessWidget { Row( spacing: UiConstants.space2, children: [ - HeaderIconButton( - icon: UiIcons.edit, - isActive: state.isEditMode, - onTap: () => BlocProvider.of( - context, - ).add(ClientHomeEditModeToggled()), + Semantics( + identifier: 'client_home_edit_mode', + child: HeaderIconButton( + icon: UiIcons.edit, + isActive: state.isEditMode, + onTap: () => BlocProvider.of( + context, + ).add(ClientHomeEditModeToggled()), + ), ), - HeaderIconButton( - icon: UiIcons.settings, - onTap: () => Modular.to.toClientSettings(), + Semantics( + identifier: 'client_home_settings', + child: HeaderIconButton( + icon: UiIcons.settings, + onTap: () => Modular.to.toClientSettings(), + ), ), ], ),