- Customer: com.halobestie.client.client_app → com.mybestie - Mitra: com.halobestie.mitra.mitra_app → com.mybestie.mitra - iOS bundle IDs renamed to match (no .clientApp/.mitra camelCase legacy) Mechanical rename touches Android build.gradle/Manifest/MainActivity package, iOS pbxproj/Info.plist bundle IDs, Firebase configs (google-services.json + GoogleService-Info.plist + firebase_options.dart), new HaloBestie/Mitra launcher icons via flutter_launcher_icons (pubspec config + adaptive-icon resources + AppIcon imageset), and the appId references in every customer maestro flow + both .maestro/config.yaml files. brandLogoBg (#FF699F) added to halo_tokens for the launcher pink. Followup: re-register apps in Firebase consoles using the new package IDs; strategy memo at project-firebase-env-strategy. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
162 lines
4.5 KiB
YAML
162 lines
4.5 KiB
YAML
# 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.mybestie
|
|
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"
|