# Stage 3 acceptance: drive a payment session into the expired state and # verify the expired screen renders. # # Flow: # home → tap CTA → /payment/entry → /payment/method-pick (or # discount-paywall — both arrive at /payment/method) → /payment/method → # tap bayar → /payment/waiting/:id → force-expire via dev endpoint → # poller transitions to /payment/expired/:id. # # Pre-req: # 1. The customer is already onboarded + on /home (run flow 01 first, or # launchApp with clearState=false on a state past onboarding). # 2. At least one mitra is ONLINE on the target backend (so the CTA is # enabled). Use mitra_app or the manual seed. # 3. Backend reachable at BACKEND_INTERNAL_URL with NODE_ENV != 'production' # (so the _test routes register). # # Run: # maestro test client_app/.maestro/flows/04_payment_expired.yaml appId: ${APP_ID_ANDROID} env: BACKEND_INTERNAL_URL: http://localhost:3001 --- - launchApp: clearState: false - assertVisible: "Mulai Curhat" # Step 1: tap CTA — home routes to /payment/entry which decides the next leg # based on first-session-discount eligibility. - tapOn: "Mulai Curhat" # Step 2: regardless of which entry path was chosen, the customer ends up at # /payment/method-pick (non-eligible) or /payment/discount-paywall (eligible). # Both have a way forward to /payment/method. Wait for either landmark. - extendedWaitUntil: visible: text: "pilih cara curhat|sesi pertama|pilih durasi" timeout: 10000 # Step 3: pick chat (if on method-pick) and a tier (if on duration-pick), # or tap mulai (if on discount paywall). Each branch funnels into # /payment/method. - runFlow: when: visible: text: "pilih cara curhat" commands: - tapOn: "chat" - extendedWaitUntil: visible: text: "pilih durasi" timeout: 5000 - tapOn: text: "5 menit" retryTapIfNoChange: true - tapOn: text: "bayar" retryTapIfNoChange: true - runFlow: when: visible: text: "sesi pertama" commands: - tapOn: text: "mulai" retryTapIfNoChange: true # Step 4: on the cara-bayar screen, QRIS is preselected. Tap pay. - extendedWaitUntil: visible: text: "cara bayar" timeout: 10000 - tapOn: text: "bayar" retryTapIfNoChange: true # Step 5: we should now be on the QR/waiting screen. The header shows the # countdown ("kedaluwarsa dalam"). Force-expire via the dev endpoint. - extendedWaitUntil: visible: text: "kedaluwarsa dalam" timeout: 10000 - runScript: file: ../scripts/force_expire_latest_payment.js env: BACKEND_INTERNAL_URL: ${BACKEND_INTERNAL_URL} # Step 6: poller picks up `expired` within ~3s and routes to expired screen. - extendedWaitUntil: visible: text: "pembayaran kedaluwarsa" timeout: 10000 - assertVisible: "coba lagi" - assertVisible: "kembali ke home"