diff --git a/ui/litellm-dashboard/e2e_tests/fixtures/migratedPages.ts b/ui/litellm-dashboard/e2e_tests/fixtures/migratedPages.ts index f2ba66147ea4..b14c9c365775 100644 --- a/ui/litellm-dashboard/e2e_tests/fixtures/migratedPages.ts +++ b/ui/litellm-dashboard/e2e_tests/fixtures/migratedPages.ts @@ -7,10 +7,10 @@ * - server-root-path mount: SERVER_ROOT_PATH=/ npm run e2e:migration:root * * Keep this in lockstep with MIGRATED_PAGES in src/utils/migratedPages.ts. - * Pending (uncomment as each PR lands): playground, and the leaf-pages batch - * (budgets, caching, cost-tracking, guardrails, guardrails-monitor, logs, - * mcp-servers, memory, policies, projects, prompts, search-tools, skills, - * tag-management, tool-policies, transform-request, ui-theme, vector-stores, - * workflows, access-groups). + * Pending (add as each PR lands): the leaf-pages batch (budgets, caching, + * cost-tracking, guardrails, guardrails-monitor, logs, mcp-servers, memory, + * policies, projects, prompts, search-tools, skills, tag-management, + * tool-policies, transform-request, ui-theme, vector-stores, workflows, + * access-groups). */ -export const MIGRATED_E2E_SEGMENTS: string[] = ["api-reference"]; +export const MIGRATED_E2E_SEGMENTS: string[] = ["api-reference", "playground"]; diff --git a/ui/litellm-dashboard/e2e_tests/tests/navigation/sidebar.spec.ts b/ui/litellm-dashboard/e2e_tests/tests/navigation/sidebar.spec.ts index b8fb95b764d0..474be30899b6 100644 --- a/ui/litellm-dashboard/e2e_tests/tests/navigation/sidebar.spec.ts +++ b/ui/litellm-dashboard/e2e_tests/tests/navigation/sidebar.spec.ts @@ -9,6 +9,17 @@ const sidebarButtons = { [Role.ProxyAdmin]: ["Virtual Keys", "Playground", "Models", "Usage", "Teams", "Internal Users", "AI Hub"], }; +// Route segment for pages migrated to path routes; mirror of MIGRATED_PAGES in src/utils/migratedPages.ts. +const migratedPageSegments: Partial> = { + [Page.ApiRef]: "api-reference", + [Page.LlmPlayground]: "playground", +}; + +function expectedUrlPattern(pageKey: Page): RegExp { + const segment = migratedPageSegments[pageKey]; + return segment ? new RegExp(`/ui/${segment}/?($|\\?)`) : new RegExp(`[?&]page=${pageKey}(&|$)`); +} + const roles = [{ role: Role.ProxyAdmin, storage: ADMIN_STORAGE_PATH }]; for (const { role, storage } of roles) { @@ -35,8 +46,7 @@ for (const { role, storage } of roles) { await tab.click(); - // Verify URL contains the correct page query parameter - await expect(page).toHaveURL(new RegExp(`[?&]page=${expectedPage}(&|$)`)); + await expect(page).toHaveURL(expectedUrlPattern(expectedPage)); } }); @@ -50,13 +60,13 @@ for (const { role, storage } of roles) { // Test direct navigation to verify the helper function works await navigateToPage(page, Page.ApiKeys); - await expect(page).toHaveURL(new RegExp(`[?&]page=${Page.ApiKeys}(&|$)`)); + await expect(page).toHaveURL(expectedUrlPattern(Page.ApiKeys)); await navigateToPage(page, Page.Models); - await expect(page).toHaveURL(new RegExp(`[?&]page=${Page.Models}(&|$)`)); + await expect(page).toHaveURL(expectedUrlPattern(Page.Models)); await navigateToPage(page, Page.LlmPlayground); - await expect(page).toHaveURL(new RegExp(`[?&]page=${Page.LlmPlayground}(&|$)`)); + await expect(page).toHaveURL(expectedUrlPattern(Page.LlmPlayground)); }); }); } diff --git a/ui/litellm-dashboard/src/app/page.tsx b/ui/litellm-dashboard/src/app/page.tsx index 12dd39a1c21f..996f63966d81 100644 --- a/ui/litellm-dashboard/src/app/page.tsx +++ b/ui/litellm-dashboard/src/app/page.tsx @@ -2,7 +2,6 @@ import SidebarProvider from "@/app/(dashboard)/components/SidebarProvider"; import OldModelDashboard from "@/app/(dashboard)/models-and-endpoints/ModelsAndEndpointsView"; -import PlaygroundPage from "@/app/(dashboard)/playground/page"; import AdminPanel from "@/components/AdminPanel"; import AgentsPanel from "@/components/agents"; import BudgetPanel from "@/components/budgets/budget_panel"; @@ -406,8 +405,6 @@ function CreateKeyPageContent() { premiumUser={premiumUser} teams={teams} /> - ) : page == "llm-playground" ? ( - ) : page == "users" ? ( { expect(migratedHref("/api-reference")).toBe("/ui/api-reference"); }); - it("maps both the api_ref id and the hyphenated alias to the api-reference route", async () => { + it("maps legacy page ids (and the hyphenated api-reference alias) to their route segments", async () => { vi.doMock("@/components/networking", () => ({ serverRootPath: "/" })); const { MIGRATED_PAGES } = await import("./migratedPages"); expect(MIGRATED_PAGES.api_ref).toBe("api-reference"); expect(MIGRATED_PAGES["api-reference"]).toBe("api-reference"); + expect(MIGRATED_PAGES["llm-playground"]).toBe("playground"); }); }); @@ -49,6 +50,8 @@ describe("legacyKeyForPathname", () => { // Resolves to the sidebar key api_ref, not the hyphenated alias, so highlighting works. expect(legacyKeyForPathname("/ui/api-reference")).toBe("api_ref"); expect(legacyKeyForPathname("/ui/api-reference/")).toBe("api_ref"); + expect(legacyKeyForPathname("/ui/playground")).toBe("llm-playground"); + expect(legacyKeyForPathname("/ui/playground/")).toBe("llm-playground"); }); it("returns null for a not-yet-migrated path", async () => { diff --git a/ui/litellm-dashboard/src/utils/migratedPages.ts b/ui/litellm-dashboard/src/utils/migratedPages.ts index 2c27e4fee64d..e20e8b5a8ea3 100644 --- a/ui/litellm-dashboard/src/utils/migratedPages.ts +++ b/ui/litellm-dashboard/src/utils/migratedPages.ts @@ -12,6 +12,7 @@ export const MIGRATED_PAGES: Record = { api_ref: "api-reference", // Legacy alias: older bookmarks used the hyphenated ?page=api-reference form. "api-reference": "api-reference", + "llm-playground": "playground", }; function uiBase(): string {