fix(e2e): recover the 2FA single-use collision instead of re-submitting (BUNYIP-453) #446
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/BUNYIP-453-totp-fill-collision-retry"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
BUNYIP-453 (relates BUNYIP-445). The actual root of login.spec's TOTP failure - a harness bug, not the secret.
Problem
fillTotpStep(e2e/lib/login.ts) documents a single-use collision:global.setupandlogin.specboth log in as the e2e account within one 30s TOTP step, so the second reuses a code the first consumed (BUNYIP-428), bunyip rejects it, and the intended handling is to wait out the step and retry with a fresh code.That retry never runs. The fill used
setInputValue, whose 5-attempt loop re-sets the field - but this field auto-submits on six digits (BUNYIP-331), so a rejected code re-renders an empty field andsetInputValuere-submits the SAME rejected code 5x, then throwslogin field value did not stick after a DOM set (holds 0 chars, expected 6). That throw abortsfillTotpStepbefore the step-wait retry, and the 5 rejected submits burn the per-userTWO_FACTOR_VERIFY_FAILUREScap (5 / 15min). This is exactly why staging showslogin.specfailing whileglobal.setup(first login, no collision) passes.Change
Fill the TOTP field with a single inline DOM-set per attempt (not
setInputValue's re-submit loop): re-acquire the re-rendered field, one set + input/change dispatch (auto-submit fires), wait for navigation off /login/2fa; the fallback Verify click fires only if the digits are still in the field (no blank submit after a rejection re-render); on rejection wait out the step and loop to a fresh code; both attempts failing throws a clear "enrolled secret mismatch / forward clock skew" message. At most 2 verify submits total.setInputValueis unchanged and still used for the email/password fields.Verification
tsc --noEmit(e2e, strict) passes.🤖 Generated with Claude Code