maestro improvise
This commit is contained in:
@@ -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"
|
||||
|
||||
|
||||
|
||||
@@ -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).*"
|
||||
|
||||
@@ -21,3 +21,6 @@ env:
|
||||
visible: "Invalid"
|
||||
timeout: 5000
|
||||
- assertVisible: "Sign In"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20,3 +20,6 @@ appId: com.krowwithus.client
|
||||
- extendedWaitUntil:
|
||||
visible: "Create Account"
|
||||
timeout: 20000
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -33,3 +33,6 @@ env:
|
||||
- inputText: ${PASSWORD}
|
||||
- tapOn: "Create Account"
|
||||
- assertVisible: "Home"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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.*"
|
||||
|
||||
@@ -37,3 +37,7 @@ appId: com.krowwithus.client
|
||||
- tapOn: "Home"
|
||||
- assertVisible: "Welcome back"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -78,3 +78,7 @@ appId: com.krowwithus.client
|
||||
visible: "Hub deleted successfully"
|
||||
timeout: 15000
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -84,3 +84,7 @@ appId: com.krowwithus.client
|
||||
visible: "Hub updated successfully"
|
||||
timeout: 15000
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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).*"
|
||||
|
||||
@@ -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).*"
|
||||
|
||||
@@ -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).*"
|
||||
|
||||
@@ -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).*"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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.*"
|
||||
|
||||
@@ -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.*"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -33,3 +33,7 @@ appId: com.krowwithus.client
|
||||
timeout: 10000
|
||||
- assertVisible: "Permanent Order"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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).*"
|
||||
|
||||
@@ -33,3 +33,7 @@ appId: com.krowwithus.client
|
||||
timeout: 10000
|
||||
- assertVisible: "Recurring Order"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -65,3 +65,7 @@ appId: com.krowwithus.client
|
||||
- extendedWaitUntil:
|
||||
notVisible: "Confirm & Save"
|
||||
timeout: 15000
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -64,3 +64,7 @@ appId: com.krowwithus.client
|
||||
visible: "Orders"
|
||||
timeout: 15000
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -30,3 +30,7 @@ appId: com.krowwithus.client
|
||||
- assertVisible: "Recurring\nOngoing Weekly / Monthly Coverage"
|
||||
- assertVisible: "Permanent\nLong-Term Staffing Placement"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -44,3 +44,7 @@ appId: com.krowwithus.client
|
||||
- assertVisible: "Send Message"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -46,3 +46,7 @@ appId: com.krowwithus.client
|
||||
timeout: 60000
|
||||
- assertVisible: "Select Role"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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.*"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -40,3 +40,7 @@ appId: com.krowwithus.client
|
||||
visible: "Exporting Spend Report \\(Placeholder\\)"
|
||||
timeout: 10000
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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).*"
|
||||
|
||||
@@ -74,3 +74,7 @@ appId: com.krowwithus.client
|
||||
|
||||
- assertVisible: "QA"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -38,3 +38,7 @@ appId: com.krowwithus.client
|
||||
visible: "Create Account"
|
||||
timeout: 20000
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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).*"
|
||||
|
||||
53
apps/mobile/apps/staff/maestro/auth/session_persistence.yaml
Normal file
53
apps/mobile/apps/staff/maestro/auth/session_persistence.yaml
Normal file
@@ -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"
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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<int> 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: <Widget>[
|
||||
// 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: <Widget>[
|
||||
_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: <Widget>[
|
||||
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: <Widget>[
|
||||
Icon(
|
||||
icon,
|
||||
color: isSelected ? activeColor : inactiveColor,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
],
|
||||
const SizedBox(height: UiConstants.space1),
|
||||
Text(
|
||||
label,
|
||||
style: UiTypography.footnote2m.copyWith(
|
||||
color: isSelected ? activeColor : inactiveColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -86,16 +86,22 @@ class ClientHomeHeader extends StatelessWidget {
|
||||
Row(
|
||||
spacing: UiConstants.space2,
|
||||
children: <Widget>[
|
||||
HeaderIconButton(
|
||||
icon: UiIcons.edit,
|
||||
isActive: state.isEditMode,
|
||||
onTap: () => BlocProvider.of<ClientHomeBloc>(
|
||||
context,
|
||||
).add(ClientHomeEditModeToggled()),
|
||||
Semantics(
|
||||
identifier: 'client_home_edit_mode',
|
||||
child: HeaderIconButton(
|
||||
icon: UiIcons.edit,
|
||||
isActive: state.isEditMode,
|
||||
onTap: () => BlocProvider.of<ClientHomeBloc>(
|
||||
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(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user