# Stage 10 acceptance: Chat tab (3 sub-tabs). # # Flow: # 1. Cold-start onboarding (abbreviated; mirrors 01_smoke) → home with a # phone-verified customer so the dev seed endpoints can find them. # 2. Seed a completed chat_sessions row → Selesai sub-tab has data. # 3. Seed a pending payment_sessions row → Pembayaran sub-tab has data # AND the bottom-nav chat tab should render a red dot (visual; not # asserted because Maestro can't reliably introspect small pixel state). # 4. Tap the "💬 chat" bottom-nav icon → /chat redirects to /chat/aktif. # 5. Aktif sub-tab: no active session, so empty state copy shows. # 6. Tap "pembayaran" pill → row with preview "menunggu pembayaran sesi" # and the "bayar Rp..." chip. # 7. Tap "selesai" pill → row with seeded mitra name. Tap the row → # transcript screen opens. # 8. Back → still on /chat/selesai (URL is source of truth for the sub-tab). # # Pre-req: client_app debug APK installed, backend reachable on # BACKEND_INTERNAL_URL with NODE_ENV != 'production' so /internal/_test/* # routes are registered, AND at least one mitra is online in the dev DB. # # Run: # maestro test client_app/.maestro/flows/09_chat_tab.yaml appId: com.halobestie.client.client_app env: TEST_PHONE: "+628155556678" BACKEND_INTERNAL_URL: http://localhost:3001 --- # Wipe prior state for TEST_PHONE so the run is hermetic. - runScript: file: ../scripts/reset_phone.js env: TEST_PHONE: ${TEST_PHONE} BACKEND_INTERNAL_URL: ${BACKEND_INTERNAL_URL} - launchApp: clearState: true # Onboarding carousel → splash → home (1st time view). - extendedWaitUntil: visible: text: "Mulai" timeout: 15000 - tapOn: text: "Mulai" retryTapIfNoChange: true # Verif choice sheet → "Lanjut sebagai Tamu" → name → phone OTP - extendedWaitUntil: visible: text: "Lanjut sebagai Tamu" timeout: 10000 - tapOn: text: "Lanjut sebagai Tamu" retryTapIfNoChange: true - extendedWaitUntil: visible: text: "Nama panggilan" timeout: 10000 - tapOn: text: "Nama panggilan" - inputText: "Maestro" - hideKeyboard - tapOn: text: "Lanjut" retryTapIfNoChange: true - extendedWaitUntil: visible: text: "Verifikasi Akun" timeout: 15000 - tapOn: text: "Nomor HP" - inputText: ${TEST_PHONE} - hideKeyboard - tapOn: text: "Kirim OTP" retryTapIfNoChange: true - extendedWaitUntil: visible: text: "Masukkan OTP" timeout: 15000 - runScript: file: ../scripts/peek_otp.js env: TEST_PHONE: ${TEST_PHONE} BACKEND_INTERNAL_URL: ${BACKEND_INTERNAL_URL} - inputText: ${output.OTP} - extendedWaitUntil: notVisible: text: "Masukkan OTP" timeout: 15000 # Returning users land on SHomeReturning with "Mulai Curhat". - extendedWaitUntil: visible: text: "Mulai Curhat" timeout: 20000 # Seed a completed session → Selesai sub-tab populated. - runScript: file: ../scripts/seed_history_session.js env: TEST_PHONE: ${TEST_PHONE} BACKEND_INTERNAL_URL: ${BACKEND_INTERNAL_URL} # Seed a pending payment → Pembayaran sub-tab populated + red dot eligibility. - runScript: file: ../scripts/seed_pending_payment.js env: TEST_PHONE: ${TEST_PHONE} BACKEND_INTERNAL_URL: ${BACKEND_INTERNAL_URL} # Tap "💬 chat" in the bottom nav → /chat → redirected to /chat/aktif. - tapOn: text: "chat" retryTapIfNoChange: true - extendedWaitUntil: visible: text: "aktif" timeout: 10000 # Sub-tab pills visible; the heading "chat" duplicates with the nav label # so assert what's unique to the chat-tab shell. - assertVisible: "aktif" - assertVisible: "pembayaran" - assertVisible: "selesai" # Aktif default body: empty state since no active session was seeded. - assertVisible: "belum ada chat di sini" # Pembayaran sub-tab → seeded pending initial payment is visible. - tapOn: text: "pembayaran" - extendedWaitUntil: visible: text: "menunggu pembayaran sesi" timeout: 5000 - assertVisible: text: "bayar Rp.*" # Selesai sub-tab → seeded completed session is visible. - tapOn: text: "selesai" - extendedWaitUntil: visible: text: ".* menit" timeout: 5000 # Tap the row → opens the read-only transcript screen. - tapOn: text: ".* menit" - extendedWaitUntil: visible: text: "Transkrip Chat" timeout: 10000 # Back returns us to /chat/selesai (URL preserves sub-tab state). - back - extendedWaitUntil: visible: text: "selesai" timeout: 5000 - assertVisible: "selesai"