# ts-mitra-A-08 — §A.2 CODE_MISMATCH inline + OTP_ATTEMPTS_EXCEEDED blocked popup # Spec ref: requirement/flow_mitra.mermaid.md §A.2 # · 401 CODE_MISMATCH (attempts < 5) inline branch # · 429 OTP_ATTEMPTS_EXCEEDED (5th wrong attempt) blocked-dialog branch # # Walks: # 1. Seed active mitra + request OTP normally → S3b # 2. Submit a deliberately-wrong 6-digit code → backend returns 401 CODE_MISMATCH # → notifier (otp_screen.dart L237-246) renders inline "Kode salah. Tersisa # N percobaan." and clears the fields # 3. Repeat 4 more wrong submits — on the 5th the backend's # `attempts >= verify_max_attempts` gate (otp.service.js:195) returns 429 # OTP_ATTEMPTS_EXCEEDED → `_showBlockedDialog()` shows the "Terlalu banyak # percobaan" AlertDialog with the "Minta kode baru" CTA. # 4. Tap the CTA → `context.pop()` returns to S3a. # # The "Tersisa N percobaan" string and the popup title are hardcoded in # otp_screen.dart L172 + L242 — those are the stable assertion targets. # # Wrong code chosen: '999999'. peek_otp.js returns the seeded stub; for the # tiny chance that 999999 actually matches the stub we accept a re-run. appId: com.mybestie.mitra env: TEST_PHONE: "+628200000801" MITRA_DISPLAY_NAME: "Maestro Mismatch" BACKEND_INTERNAL_URL: http://localhost:3001 --- - runScript: file: ../scripts/seed_mitra.js env: TEST_PHONE: ${TEST_PHONE} MITRA_DISPLAY_NAME: ${MITRA_DISPLAY_NAME} IS_ACTIVE: "true" BACKEND_INTERNAL_URL: ${BACKEND_INTERNAL_URL} - runScript: file: ../scripts/reset_phone.js env: TEST_PHONE: ${TEST_PHONE} BACKEND_INTERNAL_URL: ${BACKEND_INTERNAL_URL} - launchApp: clearState: true - extendedWaitUntil: visible: text: "(?s).*Halo Mitra Bestie.*" timeout: 10000 # S3a → S3b - tapOn: point: "50%, 53%" - inputText: "8200000801" - tapOn: "(?s).*kirim kode.*" - extendedWaitUntil: visible: text: "(?s).*masukin 6 digit kode.*" timeout: 10000 # Attempt 1 — wrong 6-digit code → inline "Kode salah. Tersisa 4 percobaan." - inputText: "999999" - extendedWaitUntil: visible: text: "(?s).*Kode salah.*Tersisa.*percobaan.*" timeout: 10000 - takeScreenshot: ts-mitra-A-08-mismatch-after-attempt-1 # Attempts 2-4 — fields auto-clear on each mismatch so we can just keep typing # the same wrong code. The auto-submit fires when the 6th digit lands. - inputText: "999999" - extendedWaitUntil: visible: text: "(?s).*Kode salah.*" timeout: 10000 - inputText: "999999" - extendedWaitUntil: visible: text: "(?s).*Kode salah.*" timeout: 10000 - inputText: "999999" - extendedWaitUntil: visible: text: "(?s).*Kode salah.*" timeout: 10000 # Attempt 5 — backend now returns 429 OTP_ATTEMPTS_EXCEEDED → blocked dialog. - inputText: "999999" - extendedWaitUntil: visible: text: "(?s).*Terlalu banyak percobaan.*" timeout: 10000 - assertVisible: text: "(?s).*Minta kode baru.*" - takeScreenshot: ts-mitra-A-08-blocked-dialog # Tap "Minta kode baru" → returns to S3a (context.pop() in the dialog action). - tapOn: "(?s).*Minta kode baru.*" - extendedWaitUntil: visible: text: "(?s).*Halo Mitra Bestie.*" timeout: 8000