maestro cases
This commit is contained in:
@@ -10,6 +10,18 @@ maestro/
|
||||
auth/
|
||||
sign_in.yaml
|
||||
sign_up.yaml
|
||||
navigation/
|
||||
home.yaml
|
||||
orders.yaml
|
||||
billing.yaml
|
||||
coverage.yaml
|
||||
reports.yaml
|
||||
orders/
|
||||
view_orders.yaml
|
||||
completed_no_edit_icon.yaml # #492
|
||||
create_order_entry.yaml
|
||||
settings/
|
||||
settings_page.yaml
|
||||
```
|
||||
|
||||
## Credentials (env, never hardcoded)
|
||||
@@ -19,6 +31,8 @@ maestro/
|
||||
| sign_in | `TEST_CLIENT_EMAIL`, `TEST_CLIENT_PASSWORD` |
|
||||
| sign_up | `TEST_CLIENT_EMAIL`, `TEST_CLIENT_PASSWORD`, `TEST_CLIENT_COMPANY` |
|
||||
|
||||
**Sign-in:** testclient@gmail.com / testclient!
|
||||
|
||||
## Run
|
||||
|
||||
```bash
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# Client App — Sign in with wrong password (negative test)
|
||||
# Uses valid email, invalid password; expects error and stays on Sign In
|
||||
# Run: maestro test .../auth/sign_in_invalid_password.yaml -e TEST_CLIENT_EMAIL=testclient@gmail.com -e TEST_CLIENT_INVALID_PASSWORD=wrongpass
|
||||
appId: com.krowwithus.client
|
||||
env:
|
||||
EMAIL: ${TEST_CLIENT_EMAIL}
|
||||
PASSWORD: ${TEST_CLIENT_INVALID_PASSWORD}
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Sign In"
|
||||
- tapOn: "Sign In"
|
||||
- assertVisible: "Email"
|
||||
- tapOn:
|
||||
id: sign_in_email
|
||||
- inputText: ${EMAIL}
|
||||
- tapOn:
|
||||
id: sign_in_password
|
||||
- inputText: ${PASSWORD}
|
||||
- tapOn: "Sign In"
|
||||
- extendedWaitUntil:
|
||||
visible: "Invalid"
|
||||
timeout: 5000
|
||||
- assertVisible: "Sign In"
|
||||
13
apps/mobile/apps/client/maestro/auth/sign_out.yaml
Normal file
13
apps/mobile/apps/client/maestro/auth/sign_out.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
# Client App — Sign out flow (tap Log Out, confirm in dialog)
|
||||
# Run: maestro test auth/sign_in.yaml auth/sign_out.yaml -e TEST_CLIENT_EMAIL=... -e TEST_CLIENT_PASSWORD=...
|
||||
appId: com.krowwithus.client
|
||||
---
|
||||
- launchApp
|
||||
- tapOn: "Settings"
|
||||
- extendedWaitUntil:
|
||||
visible: "Log Out"
|
||||
timeout: 5000
|
||||
- tapOn: "Log Out"
|
||||
- assertVisible: "Are you sure you want to log out?"
|
||||
- tapOn: "Log Out"
|
||||
- assertVisible: "Sign In"
|
||||
7
apps/mobile/apps/client/maestro/navigation/billing.yaml
Normal file
7
apps/mobile/apps/client/maestro/navigation/billing.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
# 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"
|
||||
7
apps/mobile/apps/client/maestro/navigation/coverage.yaml
Normal file
7
apps/mobile/apps/client/maestro/navigation/coverage.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
# 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"
|
||||
6
apps/mobile/apps/client/maestro/navigation/home.yaml
Normal file
6
apps/mobile/apps/client/maestro/navigation/home.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
# 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=...
|
||||
appId: com.krowwithus.client
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Orders"
|
||||
7
apps/mobile/apps/client/maestro/navigation/orders.yaml
Normal file
7
apps/mobile/apps/client/maestro/navigation/orders.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
# 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"
|
||||
7
apps/mobile/apps/client/maestro/navigation/reports.yaml
Normal file
7
apps/mobile/apps/client/maestro/navigation/reports.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
# 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"
|
||||
@@ -0,0 +1,8 @@
|
||||
# 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"
|
||||
- tapOn: "Completed"
|
||||
- assertVisible: "Completed"
|
||||
@@ -0,0 +1,9 @@
|
||||
# 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=...
|
||||
appId: com.krowwithus.client
|
||||
---
|
||||
- launchApp
|
||||
- tapOn: "Orders"
|
||||
- assertVisible: "Post"
|
||||
- tapOn: "Post"
|
||||
- assertVisible: "Rapid"
|
||||
9
apps/mobile/apps/client/maestro/orders/view_orders.yaml
Normal file
9
apps/mobile/apps/client/maestro/orders/view_orders.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
# 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"
|
||||
- assertVisible: "Up Next"
|
||||
- assertVisible: "Active"
|
||||
- assertVisible: "Completed"
|
||||
14
apps/mobile/apps/client/maestro/settings/edit_profile.yaml
Normal file
14
apps/mobile/apps/client/maestro/settings/edit_profile.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
# Client App — Edit Profile page (Settings > Edit Profile)
|
||||
# Run: maestro test auth/sign_in.yaml settings/edit_profile.yaml -e TEST_CLIENT_EMAIL=... -e TEST_CLIENT_PASSWORD=...
|
||||
appId: com.krowwithus.client
|
||||
---
|
||||
- launchApp
|
||||
- tapOn: "Settings"
|
||||
- extendedWaitUntil:
|
||||
visible: "Edit Profile"
|
||||
timeout: 5000
|
||||
- tapOn: "Edit Profile"
|
||||
- extendedWaitUntil:
|
||||
visible: "Save Changes"
|
||||
timeout: 10000
|
||||
- assertVisible: "Edit Profile"
|
||||
@@ -0,0 +1,7 @@
|
||||
# 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=...
|
||||
appId: com.krowwithus.client
|
||||
---
|
||||
- launchApp
|
||||
- tapOn: "Settings"
|
||||
- assertVisible: "Edit Profile"
|
||||
@@ -75,7 +75,8 @@ android {
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
signingConfig = signingConfigs.getByName("release")
|
||||
// Use default debug signing for local dev (no keystore required)
|
||||
signingConfig = signingConfigs.getByName("debug")
|
||||
}
|
||||
release {
|
||||
signingConfig = signingConfigs.getByName("release")
|
||||
|
||||
@@ -10,6 +10,25 @@ maestro/
|
||||
auth/
|
||||
sign_in.yaml
|
||||
sign_up.yaml
|
||||
navigation/
|
||||
home.yaml
|
||||
shifts.yaml
|
||||
profile.yaml
|
||||
payments.yaml
|
||||
clock_in.yaml
|
||||
profile/
|
||||
personal_info.yaml
|
||||
documents_list.yaml
|
||||
certificates_list.yaml
|
||||
compliance/
|
||||
document_upload_banner.yaml # #550
|
||||
certificate_upload_banner.yaml # #551
|
||||
attire_upload_banner.yaml # #552
|
||||
shifts/
|
||||
find_shifts.yaml
|
||||
incomplete_profile_banner.yaml # #549 (requires incomplete-profile user)
|
||||
home/
|
||||
benefits.yaml # #524
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
@@ -24,6 +43,8 @@ maestro/
|
||||
| sign_in | `TEST_STAFF_PHONE`, `TEST_STAFF_OTP` |
|
||||
| sign_up | `TEST_STAFF_SIGNUP_PHONE`, `TEST_STAFF_OTP` |
|
||||
|
||||
**Sign-in:** +1 555-555-1234 (env: 5555551234) / 123123
|
||||
|
||||
## Run
|
||||
|
||||
```bash
|
||||
|
||||
@@ -15,8 +15,9 @@ env:
|
||||
- tapOn:
|
||||
id: staff_phone_input
|
||||
- inputText: ${PHONE}
|
||||
- hideKeyboard
|
||||
- tapOn: "Send Code"
|
||||
# OTP screen: Continue button visible until we finish typing
|
||||
# OTP screen: Continue visible when ready for OTP entry
|
||||
- assertVisible: "Continue"
|
||||
- tapOn:
|
||||
id: staff_otp_input
|
||||
|
||||
25
apps/mobile/apps/staff/maestro/auth/sign_in_invalid_otp.yaml
Normal file
25
apps/mobile/apps/staff/maestro/auth/sign_in_invalid_otp.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
# Staff App — Sign in with wrong OTP (negative test)
|
||||
# Uses valid test phone, invalid OTP; expects error and stays on OTP screen
|
||||
# Run: maestro test .../auth/sign_in_invalid_otp.yaml -e TEST_STAFF_PHONE=5555551234 -e TEST_STAFF_INVALID_OTP=000000
|
||||
appId: com.krowwithus.staff
|
||||
env:
|
||||
PHONE: ${TEST_STAFF_PHONE}
|
||||
OTP: ${TEST_STAFF_INVALID_OTP}
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Log In"
|
||||
- tapOn: "Log In"
|
||||
- assertVisible: "Send Code"
|
||||
- tapOn:
|
||||
id: staff_phone_input
|
||||
- inputText: ${PHONE}
|
||||
- hideKeyboard
|
||||
- tapOn: "Send Code"
|
||||
- assertVisible: "Continue"
|
||||
- tapOn:
|
||||
id: staff_otp_input
|
||||
- inputText: ${OTP}
|
||||
- extendedWaitUntil:
|
||||
visible: "Invalid"
|
||||
timeout: 5000
|
||||
- assertVisible: "Continue"
|
||||
15
apps/mobile/apps/staff/maestro/auth/sign_out.yaml
Normal file
15
apps/mobile/apps/staff/maestro/auth/sign_out.yaml
Normal file
@@ -0,0 +1,15 @@
|
||||
# Staff App — Sign out flow
|
||||
# Run: maestro test auth/sign_in.yaml auth/sign_out.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...
|
||||
appId: com.krowwithus.staff
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Profile"
|
||||
- tapOn: "Profile"
|
||||
- waitForAnimationToEnd:
|
||||
timeout: 2000
|
||||
- scrollUntilVisible:
|
||||
element: "Sign Out"
|
||||
visibilityPercentage: 50
|
||||
timeout: 10000
|
||||
- tapOn: "Sign Out"
|
||||
- assertVisible: "Log In"
|
||||
@@ -15,8 +15,9 @@ env:
|
||||
- tapOn:
|
||||
id: staff_phone_input
|
||||
- inputText: ${PHONE}
|
||||
- hideKeyboard
|
||||
- tapOn: "Send Code"
|
||||
# OTP auto-submits when 6th digit entered
|
||||
# OTP screen: Continue visible when ready for OTP entry
|
||||
- assertVisible: "Continue"
|
||||
- tapOn:
|
||||
id: staff_otp_input
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# Staff App — Attire upload file restriction banner (#552)
|
||||
# Run: maestro test .../compliance/attire_upload_banner.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...
|
||||
appId: com.krowwithus.staff
|
||||
env:
|
||||
PHONE: ${TEST_STAFF_PHONE}
|
||||
OTP: ${TEST_STAFF_OTP}
|
||||
# Run after sign_in: maestro test auth/sign_in.yaml compliance/attire_upload_banner.yaml -e ...
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Profile"
|
||||
- tapOn: "Profile"
|
||||
- waitForAnimationToEnd:
|
||||
timeout: 3000
|
||||
- scrollUntilVisible:
|
||||
element: "Attire"
|
||||
- assertVisible: "Attire"
|
||||
- tapOn: "Attire"
|
||||
- tapOn: "Shirt"
|
||||
- assertVisible: "Only JPEG, JPG, and PNG"
|
||||
@@ -0,0 +1,19 @@
|
||||
# Staff App — Certificate upload file restriction banner (#551)
|
||||
# Run: maestro test .../compliance/certificate_upload_banner.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...
|
||||
appId: com.krowwithus.staff
|
||||
env:
|
||||
PHONE: ${TEST_STAFF_PHONE}
|
||||
OTP: ${TEST_STAFF_OTP}
|
||||
# Run after sign_in: maestro test auth/sign_in.yaml compliance/certificate_upload_banner.yaml -e ...
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Profile"
|
||||
- tapOn: "Profile"
|
||||
- waitForAnimationToEnd:
|
||||
timeout: 3000
|
||||
- scrollUntilVisible:
|
||||
element: "Certificates"
|
||||
- assertVisible: "Certificates"
|
||||
- tapOn: "Certificates"
|
||||
- tapOn: "Add Another Certificate"
|
||||
- assertVisible: "Only PDF files are accepted"
|
||||
@@ -0,0 +1,24 @@
|
||||
# Staff App — Document upload file restriction banner (#550)
|
||||
# Run: maestro test .../compliance/document_upload_banner.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...
|
||||
appId: com.krowwithus.staff
|
||||
env:
|
||||
PHONE: ${TEST_STAFF_PHONE}
|
||||
OTP: ${TEST_STAFF_OTP}
|
||||
# Run after sign_in: maestro test auth/sign_in.yaml compliance/document_upload_banner.yaml -e ...
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Profile"
|
||||
- tapOn: "Profile"
|
||||
- waitForAnimationToEnd:
|
||||
timeout: 3000
|
||||
- scrollUntilVisible:
|
||||
element: "Documents"
|
||||
- assertVisible: "Documents"
|
||||
- tapOn: "Documents"
|
||||
- extendedWaitUntil:
|
||||
visible:
|
||||
id: "staff_document_upload"
|
||||
timeout: 20000
|
||||
- tapOn:
|
||||
id: "staff_document_upload"
|
||||
- assertVisible: "Only PDF files are accepted"
|
||||
6
apps/mobile/apps/staff/maestro/home/benefits.yaml
Normal file
6
apps/mobile/apps/staff/maestro/home/benefits.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
# Staff App — Benefits section on Home (#524)
|
||||
# Run: maestro test auth/sign_in.yaml home/benefits.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...
|
||||
appId: com.krowwithus.staff
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Home"
|
||||
8
apps/mobile/apps/staff/maestro/navigation/clock_in.yaml
Normal file
8
apps/mobile/apps/staff/maestro/navigation/clock_in.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
# Staff App — Clock In tab navigation
|
||||
# Run: maestro test auth/sign_in.yaml navigation/clock_in.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...
|
||||
appId: com.krowwithus.staff
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Clock In"
|
||||
- tapOn: "Clock In"
|
||||
- assertVisible: "Clock In"
|
||||
6
apps/mobile/apps/staff/maestro/navigation/home.yaml
Normal file
6
apps/mobile/apps/staff/maestro/navigation/home.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
# Staff App — Home tab (default after sign-in)
|
||||
# Run: maestro test auth/sign_in.yaml navigation/home.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...
|
||||
appId: com.krowwithus.staff
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Find Shifts"
|
||||
8
apps/mobile/apps/staff/maestro/navigation/payments.yaml
Normal file
8
apps/mobile/apps/staff/maestro/navigation/payments.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
# Staff App — Payments tab navigation
|
||||
# Run: maestro test auth/sign_in.yaml navigation/payments.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...
|
||||
appId: com.krowwithus.staff
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Payments"
|
||||
- tapOn: "Payments"
|
||||
- assertVisible: "Payments"
|
||||
8
apps/mobile/apps/staff/maestro/navigation/profile.yaml
Normal file
8
apps/mobile/apps/staff/maestro/navigation/profile.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
# Staff App — Profile tab navigation (post sign-in)
|
||||
# Run: maestro test auth/sign_in.yaml navigation/profile.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...
|
||||
appId: com.krowwithus.staff
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Profile"
|
||||
- tapOn: "Profile"
|
||||
- assertVisible: "Personal Info"
|
||||
8
apps/mobile/apps/staff/maestro/navigation/shifts.yaml
Normal file
8
apps/mobile/apps/staff/maestro/navigation/shifts.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
# Staff App — Shifts tab navigation (post sign-in)
|
||||
# Run: maestro test auth/sign_in.yaml navigation/shifts.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...
|
||||
appId: com.krowwithus.staff
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Shifts"
|
||||
- tapOn: "Shifts"
|
||||
- assertVisible: "Find Shifts"
|
||||
18
apps/mobile/apps/staff/maestro/profile/bank_account.yaml
Normal file
18
apps/mobile/apps/staff/maestro/profile/bank_account.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
# Staff App — Bank Account section (Profile > Finance > Bank Account)
|
||||
# Run: maestro test auth/sign_in.yaml profile/bank_account.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...
|
||||
appId: com.krowwithus.staff
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Profile"
|
||||
- tapOn: "Profile"
|
||||
- waitForAnimationToEnd:
|
||||
timeout: 3000
|
||||
- scrollUntilVisible:
|
||||
element: "Bank Account"
|
||||
visibilityPercentage: 50
|
||||
timeout: 10000
|
||||
- tapOn: "Bank Account"
|
||||
- extendedWaitUntil:
|
||||
visible: "Bank Account"
|
||||
timeout: 10000
|
||||
- assertVisible: "Bank Account"
|
||||
@@ -0,0 +1,10 @@
|
||||
# Staff App — Certificates list page
|
||||
# Run: maestro test auth/sign_in.yaml profile/certificates_list.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...
|
||||
appId: com.krowwithus.staff
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Profile"
|
||||
- tapOn: "Profile"
|
||||
- assertVisible: "Certificates"
|
||||
- tapOn: "Certificates"
|
||||
- assertVisible: "Certificates"
|
||||
10
apps/mobile/apps/staff/maestro/profile/documents_list.yaml
Normal file
10
apps/mobile/apps/staff/maestro/profile/documents_list.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
# Staff App — Documents list page
|
||||
# Run: maestro test auth/sign_in.yaml profile/documents_list.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...
|
||||
appId: com.krowwithus.staff
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Profile"
|
||||
- tapOn: "Profile"
|
||||
- assertVisible: "Documents"
|
||||
- tapOn: "Documents"
|
||||
- assertVisible: "Documents"
|
||||
@@ -0,0 +1,18 @@
|
||||
# Staff App — Emergency Contact section (Profile > Onboarding > Emergency Contact)
|
||||
# Run: maestro test auth/sign_in.yaml profile/emergency_contact.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...
|
||||
appId: com.krowwithus.staff
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Profile"
|
||||
- tapOn: "Profile"
|
||||
- waitForAnimationToEnd:
|
||||
timeout: 3000
|
||||
- scrollUntilVisible:
|
||||
element: "Emergency Contact"
|
||||
visibilityPercentage: 50
|
||||
timeout: 10000
|
||||
- tapOn: "Emergency Contact"
|
||||
- extendedWaitUntil:
|
||||
visible: "Save & Continue"
|
||||
timeout: 10000
|
||||
- assertVisible: "Emergency Contact"
|
||||
18
apps/mobile/apps/staff/maestro/profile/faqs.yaml
Normal file
18
apps/mobile/apps/staff/maestro/profile/faqs.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
# Staff App — FAQs section (Profile > Support > FAQs)
|
||||
# Run: maestro test auth/sign_in.yaml profile/faqs.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...
|
||||
appId: com.krowwithus.staff
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Profile"
|
||||
- tapOn: "Profile"
|
||||
- waitForAnimationToEnd:
|
||||
timeout: 3000
|
||||
- scrollUntilVisible:
|
||||
element: "FAQs"
|
||||
visibilityPercentage: 50
|
||||
timeout: 10000
|
||||
- tapOn: "FAQs"
|
||||
- extendedWaitUntil:
|
||||
visible: "FAQs"
|
||||
timeout: 10000
|
||||
- assertVisible: "FAQs"
|
||||
10
apps/mobile/apps/staff/maestro/profile/personal_info.yaml
Normal file
10
apps/mobile/apps/staff/maestro/profile/personal_info.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
# Staff App — Personal Info page
|
||||
# Run: maestro test auth/sign_in.yaml profile/personal_info.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...
|
||||
appId: com.krowwithus.staff
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Profile"
|
||||
- tapOn: "Profile"
|
||||
- assertVisible: "Personal Info"
|
||||
- tapOn: "Personal Info"
|
||||
- assertVisible: "Full Name"
|
||||
18
apps/mobile/apps/staff/maestro/profile/privacy_security.yaml
Normal file
18
apps/mobile/apps/staff/maestro/profile/privacy_security.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
# Staff App — Privacy & Security section (Profile > Support > Privacy & Security)
|
||||
# Run: maestro test auth/sign_in.yaml profile/privacy_security.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...
|
||||
appId: com.krowwithus.staff
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Profile"
|
||||
- tapOn: "Profile"
|
||||
- waitForAnimationToEnd:
|
||||
timeout: 3000
|
||||
- scrollUntilVisible:
|
||||
element: "Privacy & Security"
|
||||
visibilityPercentage: 50
|
||||
timeout: 10000
|
||||
- tapOn: "Privacy & Security"
|
||||
- extendedWaitUntil:
|
||||
visible: "Privacy & Security"
|
||||
timeout: 10000
|
||||
- assertVisible: "Privacy Policy"
|
||||
18
apps/mobile/apps/staff/maestro/profile/time_card.yaml
Normal file
18
apps/mobile/apps/staff/maestro/profile/time_card.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
# Staff App — Timecard section (Profile > Finance > Timecard)
|
||||
# Run: maestro test auth/sign_in.yaml profile/time_card.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...
|
||||
appId: com.krowwithus.staff
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Profile"
|
||||
- tapOn: "Profile"
|
||||
- waitForAnimationToEnd:
|
||||
timeout: 3000
|
||||
- scrollUntilVisible:
|
||||
element: "Timecard"
|
||||
visibilityPercentage: 50
|
||||
timeout: 10000
|
||||
- tapOn: "Timecard"
|
||||
- extendedWaitUntil:
|
||||
visible: "Hours Worked"
|
||||
timeout: 10000
|
||||
- assertVisible: "Timecard"
|
||||
10
apps/mobile/apps/staff/maestro/shifts/find_shifts.yaml
Normal file
10
apps/mobile/apps/staff/maestro/shifts/find_shifts.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
# Staff App — Find Shifts tab
|
||||
# Run: maestro test auth/sign_in.yaml shifts/find_shifts.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...
|
||||
appId: com.krowwithus.staff
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Shifts"
|
||||
- tapOn: "Shifts"
|
||||
- assertVisible: "Find Shifts"
|
||||
- tapOn: "Find Shifts"
|
||||
- assertVisible: "Find Shifts"
|
||||
@@ -0,0 +1,12 @@
|
||||
# Staff App — Incomplete profile banner in Find Shifts (#549)
|
||||
# Requires staff user with INCOMPLETE profile
|
||||
# Run: maestro test auth/sign_in.yaml shifts/incomplete_profile_banner.yaml -e TEST_STAFF_PHONE=... -e TEST_STAFF_OTP=...
|
||||
appId: com.krowwithus.staff
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Shifts"
|
||||
- tapOn: "Shifts"
|
||||
- assertVisible: "Find Shifts"
|
||||
- tapOn: "Find Shifts"
|
||||
- assertVisible: "Your account isn't complete yet."
|
||||
- assertVisible: "Complete your account now"
|
||||
@@ -36,8 +36,22 @@ class _OtpInputFieldState extends State<OtpInputField> {
|
||||
);
|
||||
final List<FocusNode> _focusNodes = List.generate(6, (_) => FocusNode());
|
||||
|
||||
/// Hidden field for E2E: Maestro inputText sends full OTP in one call;
|
||||
/// the 6 visible boxes have maxLength:1 and would truncate.
|
||||
late final TextEditingController _hiddenController;
|
||||
late final FocusNode _hiddenFocusNode;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_hiddenController = TextEditingController();
|
||||
_hiddenFocusNode = FocusNode();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_hiddenController.dispose();
|
||||
_hiddenFocusNode.dispose();
|
||||
for (final TextEditingController controller in _controllers) {
|
||||
controller.dispose();
|
||||
}
|
||||
@@ -47,6 +61,22 @@ class _OtpInputFieldState extends State<OtpInputField> {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
/// Distributes full OTP from hidden field to the 6 visible boxes and notifies Bloc.
|
||||
void _syncFromHidden(BuildContext context, String value) {
|
||||
final String raw = value.replaceAll(RegExp(r'\D'), '');
|
||||
final String digits = raw.length > 6 ? raw.substring(0, 6) : raw;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
final String digit = i < digits.length ? digits[i] : '';
|
||||
if (_controllers[i].text != digit) {
|
||||
_controllers[i].text = digit;
|
||||
}
|
||||
}
|
||||
BlocProvider.of<AuthBloc>(context).add(AuthOtpUpdated(digits));
|
||||
if (digits.length == 6) {
|
||||
widget.onCompleted(digits);
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper getter to compute the current OTP code from all controllers.
|
||||
String get _otpCode => _controllers.map((TextEditingController c) => c.text).join();
|
||||
|
||||
@@ -70,57 +100,79 @@ class _OtpInputFieldState extends State<OtpInputField> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
const double boxWidth = 45;
|
||||
const double boxHeight = 56;
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: List.generate(6, (int index) {
|
||||
final TextField field = TextField(
|
||||
controller: _controllers[index],
|
||||
focusNode: _focusNodes[index],
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: <TextInputFormatter>[FilteringTextInputFormatter.digitsOnly],
|
||||
textAlign: TextAlign.center,
|
||||
maxLength: 1,
|
||||
style: UiTypography.headline3m,
|
||||
decoration: InputDecoration(
|
||||
counterText: '',
|
||||
border: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: widget.error.isNotEmpty
|
||||
? UiColors.textError
|
||||
: (_controllers[index].text.isNotEmpty
|
||||
? UiColors.primary
|
||||
: UiColors.border),
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: UiConstants.radiusMd,
|
||||
borderSide: BorderSide(
|
||||
color: widget.error.isNotEmpty
|
||||
? UiColors.textError
|
||||
: (_controllers[index].text.isNotEmpty
|
||||
? UiColors.primary
|
||||
: UiColors.border),
|
||||
width: 2,
|
||||
SizedBox(
|
||||
width: 300,
|
||||
height: boxHeight,
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: List.generate(6, (int index) {
|
||||
final TextField field = TextField(
|
||||
controller: _controllers[index],
|
||||
focusNode: _focusNodes[index],
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: <TextInputFormatter>[FilteringTextInputFormatter.digitsOnly],
|
||||
textAlign: TextAlign.center,
|
||||
maxLength: 1,
|
||||
style: UiTypography.headline3m,
|
||||
decoration: InputDecoration(
|
||||
counterText: '',
|
||||
border: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: widget.error.isNotEmpty
|
||||
? UiColors.textError
|
||||
: (_controllers[index].text.isNotEmpty
|
||||
? UiColors.primary
|
||||
: UiColors.border),
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: UiConstants.radiusMd,
|
||||
borderSide: BorderSide(
|
||||
color: widget.error.isNotEmpty
|
||||
? UiColors.textError
|
||||
: (_controllers[index].text.isNotEmpty
|
||||
? UiColors.primary
|
||||
: UiColors.border),
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
),
|
||||
onChanged: (String value) =>
|
||||
_onChanged(context: context, index: index, value: value),
|
||||
);
|
||||
return SizedBox(width: boxWidth, height: boxHeight, child: field);
|
||||
}),
|
||||
),
|
||||
Positioned.fill(
|
||||
child: Semantics(
|
||||
identifier: 'staff_otp_input',
|
||||
container: false,
|
||||
child: Opacity(
|
||||
opacity: 0.01,
|
||||
child: TextField(
|
||||
controller: _hiddenController,
|
||||
focusNode: _hiddenFocusNode,
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
LengthLimitingTextInputFormatter(6),
|
||||
],
|
||||
maxLength: 6,
|
||||
onChanged: (String value) =>
|
||||
_syncFromHidden(context, value),
|
||||
),
|
||||
),
|
||||
),
|
||||
onChanged: (String value) =>
|
||||
_onChanged(context: context, index: index, value: value),
|
||||
);
|
||||
return SizedBox(
|
||||
width: 45,
|
||||
height: 56,
|
||||
child: index == 0
|
||||
? Semantics(
|
||||
identifier: 'staff_otp_input',
|
||||
child: field,
|
||||
)
|
||||
: field,
|
||||
);
|
||||
}),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (widget.error.isNotEmpty)
|
||||
Padding(
|
||||
|
||||
@@ -84,6 +84,7 @@ class _PhoneInputFormFieldState extends State<PhoneInputFormField> {
|
||||
Expanded(
|
||||
child: Semantics(
|
||||
identifier: 'staff_phone_input',
|
||||
container: false, // Merge with TextField so tap/input reach the actual field
|
||||
child: TextField(
|
||||
controller: _controller,
|
||||
keyboardType: TextInputType.phone,
|
||||
|
||||
@@ -152,9 +152,14 @@ class DocumentCard extends StatelessWidget {
|
||||
|
||||
Widget _buildActionButton(DocumentStatus status) {
|
||||
final bool isVerified = status == DocumentStatus.verified;
|
||||
return InkWell(
|
||||
onTap: onTap,
|
||||
borderRadius: UiConstants.radiusSm,
|
||||
return Semantics(
|
||||
identifier: 'staff_document_upload',
|
||||
label: isVerified
|
||||
? t.staff_documents.card.view
|
||||
: t.staff_documents.card.upload,
|
||||
child: InkWell(
|
||||
onTap: onTap,
|
||||
borderRadius: UiConstants.radiusSm,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
child: Row(
|
||||
@@ -174,6 +179,7 @@ class DocumentCard extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user