Files
textbee/web/e2e/session-calls.spec.ts
isra el 18e7d1b3d8 perf(web): make dashboard navigation fast and cut session fetches
- prefetch route-tab links so tab clicks reuse a cached payload instead
  of paying an uncached server round trip each time
- add loading.tsx boundaries (dashboard root and each section) so clicks
  paint within a frame; section-level files keep the header and tabs
  mounted while only the content area swaps
- link the sidebar Account item and the checkout page straight to
  /dashboard/account/billing. The /dashboard/account redirect stub stays
  for old links, but no internal link pays the extra hop anymore. The
  stub also dropped query params, which silently ate the plan-change
  success toast.
- set QueryClient defaults (staleTime 60s, no focus refetch, retry 1);
  mutations already invalidate their keys, so the user's own changes
  stay instant. Device messages and webhook deliveries get a 15s
  staleTime since they change from outside the tab.
- replace the axios getCachedSession TTL cache with a token seeded from
  the server session in Providers and kept in sync by a session bridge.
  Requests attach the token synchronously; /api/auth/session is only a
  deduped fallback, instead of a refetch every 2 minutes with a
  thundering herd on expiry.
- swap the billing card's 16px loading spinner for a card-shaped
  skeleton so the tab no longer looks blank while loading

Tests: interceptor seeding/dedupe/signed-out behavior, provider
defaults and token seeding, nav active-state matching, tab prefetch,
billing loading state, plus e2e coverage for direct-to-billing
navigation and an at-most-one-session-call budget guard.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 13:49:14 +03:00

47 lines
1.7 KiB
TypeScript

import { expect, test } from '@playwright/test'
import { authenticate } from './session'
import { mockApi } from './mock-api'
// Serverless-cost regression guard. The API client's token is seeded from the
// server-fetched session, so browsing the dashboard must not keep calling
// /api/auth/session. Before this guard, the axios interceptor refetched the
// session every 2 minutes with no dedupe, so a burst of queries fanned out
// one session call each.
test('dashboard navigation makes at most one /api/auth/session call', async ({
page,
context,
}) => {
await authenticate(context)
await mockApi(page)
let sessionCalls = 0
page.on('request', (request) => {
if (new URL(request.url()).pathname === '/api/auth/session') {
sessionCalls += 1
}
})
await page.goto('/dashboard')
await expect(
page.getByRole('heading', { name: 'Welcome back, Test', level: 2 })
).toBeVisible()
const mainNav = page.getByRole('navigation', { name: 'Main' })
const tabs = page.getByRole('navigation', { name: 'Section navigation' })
await mainNav.getByRole('link', { name: 'Messaging' }).click()
await expect(page).toHaveURL(/\/dashboard\/messaging$/)
await tabs.getByRole('link', { name: 'History' }).click()
await expect(page).toHaveURL(/\/dashboard\/messaging\/history$/)
await mainNav.getByRole('link', { name: 'Webhooks' }).click()
await expect(page).toHaveURL(/\/dashboard\/webhooks$/)
await tabs.getByRole('link', { name: 'Deliveries' }).click()
await expect(page).toHaveURL(/\/dashboard\/webhooks\/deliveries$/)
await mainNav.getByRole('link', { name: 'Account' }).click()
await expect(page).toHaveURL(/\/dashboard\/account\/billing$/)
expect(sessionCalls).toBeLessThanOrEqual(1)
})