litellm/ui/litellm-dashboard/e2e_tests/serverRootPath.config.ts
ryan-crabbe-berri 73e9071311
refactor(ui): extract auth state into AuthContext (#28910)
* refactor(ui): extract auth state into AuthContext

Move auth state (token, userID, userRole, accessToken, premiumUser, userEmail,
disabledPersonalKeyCreation, showSSOBanner) out of src/app/page.tsx into a
new AuthProvider at src/contexts/AuthContext.tsx. Wrapped at the root layout
so login/onboarding/dashboard routes all have access via useAuth().

Day 1 foundation for the App Router migration: migrated (dashboard)/X/page.tsx
route entry points won't have a parent passing props, so shared auth state
must live in a context they can read from.

Sub-components are unchanged — they still receive accessToken/userID/userRole
as props from page.tsx (which now reads them from useAuth()). Only the
page.tsx → top-level-page-component handoff is de-drilled; deeper prop
drilling is left for the per-page migration to address.

Net change: -86 lines from page.tsx (state + two effects moved), +5 in
layout.tsx (provider wrap), new AuthContext.tsx (~140 lines), test update
to wrap CreateKeyPage in AuthProvider.

Fixes LIT-3366
Part of LIT-3128

* fix(ui): await getUiConfig before clearing authLoading

The AuthContext refactor flipped authLoading to false synchronously on mount
while letting getUiConfig() run fire-and-forget. On SERVER_ROOT_PATH deployments
this races the unauthenticated login-redirect effect: the redirect fires with
proxyBaseUrl still at its module-init value, sending users to /ui/login instead
of {SERVER_ROOT_PATH}/ui/login.

Restores the original sequencing inside AuthProvider's mount effect and adds a
Playwright spec wired into the existing SERVER_ROOT_PATH workflow matrix. The
spec delays the config endpoint via page.route() to make the race deterministic
across CI runners.
2026-05-26 17:53:03 -07:00

33 lines
935 B
TypeScript

import { defineConfig, devices } from "@playwright/test";
// Minimal config for the SERVER_ROOT_PATH redirect spec. Deliberately does NOT
// reuse the main e2e config because:
// - globalSetup logs in via http://localhost:4000/ui/login, which 404s when
// the proxy is mounted under a non-root path.
// - The redirect spec must run against a clean, unauthenticated session, so
// no storage state should be loaded.
export default defineConfig({
testDir: "./tests/login",
testMatch: ["serverRootPathRedirect.spec.ts"],
fullyParallel: false,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: 1,
reporter: "list",
use: {
trace: "on-first-retry",
actionTimeout: 15 * 1000,
navigationTimeout: 30 * 1000,
},
projects: [
{
name: "chromium",
use: { ...devices["Desktop Chrome"] },
},
],
timeout: 60 * 1000,
expect: {
timeout: 10 * 1000,
},
});