fix(e2e): probe data routes for bearer, merge auth-ui to dodge rate limit #103

Merged
nrupard merged 2 commits from fix/e2e-spa-bearer-intercept-and-logout into main 2026-06-05 18:11:10 +02:00
Owner

Summary

Two follow-up failures from the post-#102 E2E run; both addressed here.

Setup test captured no Bearer header. SPA login completed, URL left /login, but no /api/v1 request with Authorization: Bearer fired within 20s. The post-login landing route apparently does not hydrate from the API on its own. Three fixes:

  • After loginViaSpa, force a navigation to /dashboard then /tickets (skip the second if the first already produced a token). Either is a safe data-loading route the SPA will fetch against.
  • Track every observed /api/v1 request URL. On timeout the error names them so the next failure tells us whether the SPA hits a different API base, a different path, or nothing at all.
  • Bump post-login timeout 20s → 30s for slow staging hydrates.
  • Wrap expect.poll in try/catch so the URL list can be folded into the thrown message (expect.poll's message is a static string).

Auth-ui logout test could not log in. Per-email login rate limit is 5/min (src/modules/auth/routes.rs). Run tally on the previous shape: setup × 2 retries (2) + auth-ui test 4 (1) + auth-ui test 5 × 2 retries (2) = 5. The 5th attempt is the one that 429s, leaving the SPA on /login. Merge the two auth-ui tests into a single login + logout round-trip; brings the auth-ui contribution from 1-4 logins down to 1-2 (test body + at most one retry).

Test plan

  • Post-merge run: setup captures bearer (within 30s after probing /dashboard or /tickets) and api project tests run; auth-ui's single round-trip test passes without hitting the login rate limiter.
  • If setup still times out, the new error message lists the /api/v1 URLs the SPA actually fired so the next debug round is precise.
## Summary Two follow-up failures from the post-#102 E2E run; both addressed here. **Setup test captured no Bearer header.** SPA login completed, URL left `/login`, but no `/api/v1` request with `Authorization: Bearer` fired within 20s. The post-login landing route apparently does not hydrate from the API on its own. Three fixes: - After `loginViaSpa`, force a navigation to `/dashboard` then `/tickets` (skip the second if the first already produced a token). Either is a safe data-loading route the SPA will fetch against. - Track every observed `/api/v1` request URL. On timeout the error names them so the next failure tells us whether the SPA hits a different API base, a different path, or nothing at all. - Bump post-login timeout 20s → 30s for slow staging hydrates. - Wrap `expect.poll` in `try/catch` so the URL list can be folded into the thrown message (`expect.poll`'s `message` is a static string). **Auth-ui logout test could not log in.** Per-email login rate limit is 5/min (`src/modules/auth/routes.rs`). Run tally on the previous shape: setup × 2 retries (2) + auth-ui test 4 (1) + auth-ui test 5 × 2 retries (2) = 5. The 5th attempt is the one that 429s, leaving the SPA on `/login`. Merge the two auth-ui tests into a single login + logout round-trip; brings the auth-ui contribution from 1-4 logins down to 1-2 (test body + at most one retry). ## Test plan - [ ] Post-merge run: setup captures bearer (within 30s after probing /dashboard or /tickets) and api project tests run; auth-ui's single round-trip test passes without hitting the login rate limiter. - [ ] If setup still times out, the new error message lists the `/api/v1` URLs the SPA actually fired so the next debug round is precise.
fix(e2e): force a post-login probe + merge auth-ui tests to dodge rate limit
All checks were successful
Check / fmt + clippy + compile + tests (pull_request) Successful in 2m6s
de17374ebd
Two follow-up failures on PR #102:

1. setup test captured no Bearer header within 20s after a successful SPA
   login. The post-login landing route apparently does not fire any
   /api/v1 call on its own, so the listener had nothing to grab. Two
   changes here:
   - After loginViaSpa, navigate to /dashboard then /tickets (skip the
     second if the first already produced a token). Either is a safe
     data-loading route; any subsequent SPA fetch carries the Bearer.
   - Track every /api/v1 request URL we DID see. On timeout, the error
     names which URLs flew past so the next failure tells us whether the
     SPA hits a different API base, a different path, or nothing at all.
   - Bump the post-login timeout from 20s to 30s for slow staging hydrates.
   - Wrap expect.poll in try/catch so the dynamic URL list can be folded
     into the thrown message (expect.poll's `message` is a static string).

2. auth-ui logout test stalled on the login form because the per-email
   login rate limit (5/min, src/modules/auth/routes.rs) was already
   spent by then. Tally per CI run on the previous shape: setup x 2
   retries (2 logins) + auth-ui test4 (1) + auth-ui test5 x 2 retries
   (2) = 5; the 5th attempt is the one that 429s. Merge the two auth-ui
   tests into a single login + logout round-trip. Brings auth-ui's
   contribution from 1-4 logins down to 1-2 (test body + at most one
   retry).

#PMS-140
test(e2e): harden auth-ui locators with .first(), tighten /api/v1 filter
All checks were successful
Create release / Create release from merged PR (pull_request) Has been skipped
Check / fmt + clippy + compile + tests (pull_request) Successful in 58s
66e3433413
Review follow-up on PR #103:

- auth.spec.ts: `page.getByRole('button', { name: 'User menu' })` and `page.getByRole('menu')` would throw a strict-mode violation if the SPA ever rendered a duplicate (e.g. a mobile-nav copy of the avatar button, or a future drawer also carrying role="menu"). Pin both to `.first()` since the top-bar avatar is the one we want either way.
- global.setup.ts: restore the trailing slash on the `/api/v1/` substring filter so the listener cannot match unrelated paths that merely contain the literal text (`/api/v1foo`, a query string carrying it, etc).

#PMS-140
nrupard deleted branch fix/e2e-spa-bearer-intercept-and-logout 2026-06-05 18:11:10 +02:00
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/mokosh-server!103
No description provided.