fix(e2e): tolerate login rate limit and harden mail wait #277

Merged
Claude-Run merged 1 commit from fix/BUNYIP-267-e2e-login-backoff-mail-hardening into main 2026-06-30 05:11:16 +02:00
Member

The Playwright e2e suite (run #1306) failed two specs on harness-timing fragility, not product bugs. The auth-ui login spec hit bunyip's 5/min-per-email login rate limit ("Too many requests. Please wait 2 seconds and try again.") and failed with no retry, and the password-reset spec timed out after 30s waiting for the reset email when the Stalwart relay lagged.

loginViaHub now wraps the credential submit in a backoff loop: a rate-limit error_box is classified (not a credential error), and the helper waits out the interval bunyip names before resubmitting, up to four attempts. A Playwright-level retry cannot do this because re-running the test fires another login POST immediately and deepens the 5/min hole, which is why the auth-ui project keeps retries: 0. The single-attempt logic is split into submitLoginOnce, which now races the 2FA redirect against the error_box so a rate-limit rejection is detected in ~1s instead of after the 2FA wait's full 15s timeout, keeping each retry within the test budget. The login spec is marked test.slow() to give the backoff room.

waitForLink now resolves the JMAP session and polls inside a per-iteration try/catch, so a single transient relay/session hiccup re-polls on the next interval instead of aborting the whole wait, and a timeout reports the last poll error. The password-reset spec re-requests the reset once if the first email has not landed within 40s (two requests stay within the 3/hour PASSWORD_RESET limit) and is marked test.slow() so the doubled wait does not trip the per-test timeout.

#BUNYIP-267

The Playwright e2e suite (run #1306) failed two specs on harness-timing fragility, not product bugs. The auth-ui login spec hit bunyip's 5/min-per-email login rate limit ("Too many requests. Please wait 2 seconds and try again.") and failed with no retry, and the password-reset spec timed out after 30s waiting for the reset email when the Stalwart relay lagged. loginViaHub now wraps the credential submit in a backoff loop: a rate-limit error_box is classified (not a credential error), and the helper waits out the interval bunyip names before resubmitting, up to four attempts. A Playwright-level retry cannot do this because re-running the test fires another login POST immediately and deepens the 5/min hole, which is why the auth-ui project keeps retries: 0. The single-attempt logic is split into submitLoginOnce, which now races the 2FA redirect against the error_box so a rate-limit rejection is detected in ~1s instead of after the 2FA wait's full 15s timeout, keeping each retry within the test budget. The login spec is marked test.slow() to give the backoff room. waitForLink now resolves the JMAP session and polls inside a per-iteration try/catch, so a single transient relay/session hiccup re-polls on the next interval instead of aborting the whole wait, and a timeout reports the last poll error. The password-reset spec re-requests the reset once if the first email has not landed within 40s (two requests stay within the 3/hour PASSWORD_RESET limit) and is marked test.slow() so the doubled wait does not trip the per-test timeout. #BUNYIP-267
fix(e2e): tolerate login rate limit and harden mail wait
All checks were successful
E2E / Playwright against deployment (pull_request) Successful in 40s
Check / fmt + clippy + build + tests (pull_request) Successful in 22m57s
Create release / Create release from merged PR (pull_request) Has been skipped
071b8d82e7
The Playwright e2e suite (run #1306) failed two specs on harness-timing fragility, not product bugs. The auth-ui login spec hit bunyip's 5/min-per-email login rate limit ("Too many requests. Please wait 2 seconds and try again.") and failed with no retry, and the password-reset spec timed out after 30s waiting for the reset email when the Stalwart relay lagged.

loginViaHub now wraps the credential submit in a backoff loop: a rate-limit error_box is classified (not a credential error), and the helper waits out the interval bunyip names before resubmitting, up to four attempts. A Playwright-level retry cannot do this because re-running the test fires another login POST immediately and deepens the 5/min hole, which is why the auth-ui project keeps retries: 0. The single-attempt logic is split into submitLoginOnce, which now races the 2FA redirect against the error_box so a rate-limit rejection is detected in ~1s instead of after the 2FA wait's full 15s timeout, keeping each retry within the test budget. The login spec is marked test.slow() to give the backoff room.

waitForLink now resolves the JMAP session and polls inside a per-iteration try/catch, so a single transient relay/session hiccup re-polls on the next interval instead of aborting the whole wait, and a timeout reports the last poll error. The password-reset spec re-requests the reset once if the first email has not landed within 40s (two requests stay within the 3/hour PASSWORD_RESET limit) and is marked test.slow() so the doubled wait does not trip the per-test timeout.

#BUNYIP-267
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/bunyip!277
No description provided.