e2e refactoring

This commit is contained in:
yuneng-jiang 2026-01-08 21:50:19 -08:00
parent c81ac6cf46
commit 4d28359608
5 changed files with 114 additions and 7 deletions

View File

@ -0,0 +1,38 @@
import { Page } from "./pages";
/**
* Maps sidebar menu item labels to their corresponding page enum values.
* This mapping is for the admin role.
*/
export const menuLabelToPage: Record<string, Page> = {
"Virtual Keys": Page.ApiKeys,
Playground: Page.LlmPlayground,
Models: Page.Models,
"Models + Endpoints": Page.Models,
Usage: Page.NewUsage,
Teams: Page.Teams,
"Internal Users": Page.Users,
"Internal User": Page.Users, // Legacy label support
Organizations: Page.Organizations,
"API Reference": Page.ApiRef,
"AI Hub": Page.ModelHubTable,
"Model Hub": Page.ModelHubTable,
Logs: Page.Logs,
Guardrails: Page.Guardrails,
// Settings submenu items
"Router Settings": Page.RouterSettings,
"Logging & Alerts": Page.LoggingAndAlerts,
"Admin Settings": Page.AdminPanel,
"Cost Tracking": Page.CostTracking,
"UI Theme": Page.UiTheme,
// Experimental submenu items
Caching: Page.Caching,
Prompts: Page.Prompts,
Budgets: Page.Budgets,
"API Playground": Page.TransformRequest,
"Tag Management": Page.TagManagement,
"Old Usage": Page.Usage,
// Tools submenu items
"MCP Servers": Page.McpServers,
"Vector Stores": Page.VectorStores,
};

View File

@ -0,0 +1,33 @@
/**
* Enum for all page query parameters supported in the app.
* These values correspond to the `page` query parameter used in the URL.
*/
export enum Page {
ApiKeys = "api-keys",
Models = "models",
LlmPlayground = "llm-playground",
Users = "users",
Teams = "teams",
Organizations = "organizations",
AdminPanel = "admin-panel",
ApiRef = "api_ref",
LoggingAndAlerts = "logging-and-alerts",
Budgets = "budgets",
Guardrails = "guardrails",
Agents = "agents",
Prompts = "prompts",
TransformRequest = "transform-request",
RouterSettings = "router-settings",
UiTheme = "ui-theme",
CostTracking = "cost-tracking",
ModelHubTable = "model-hub-table",
Caching = "caching",
PassThroughSettings = "pass-through-settings",
Logs = "logs",
McpServers = "mcp-servers",
SearchTools = "search-tools",
TagManagement = "tag-management",
VectorStores = "vector-stores",
NewUsage = "new_usage",
Usage = "usage",
}

View File

@ -0,0 +1,12 @@
import { Page } from "../fixtures/pages";
import { Page as PlaywrightPage } from "@playwright/test";
/**
* Navigates to a specific page using the page query parameter.
* Uses relative path which will be resolved against the baseURL configured in playwright.config.ts
* @param page - The Playwright page object
* @param pageEnum - The page enum value to navigate to
*/
export async function navigateToPage(page: PlaywrightPage, pageEnum: Page): Promise<void> {
await page.goto(`/ui?page=${pageEnum}`);
}

View File

@ -14,7 +14,7 @@ test.describe("Add Model", () => {
await providerInputDropdown.fill("Anthropic");
await page.waitForTimeout(1000);
await providerInputDropdown.press("Enter");
await page.waitForTimeout(1000);
await page.waitForTimeout(2000);
const providerModelsDropdown = page.locator(".ant-select-selection-overflow").first();
await providerModelsDropdown.click();

View File

@ -1,6 +1,9 @@
import test, { expect } from "@playwright/test";
import { Role } from "../../fixtures/roles";
import { ADMIN_STORAGE_PATH } from "../../constants";
import { Page } from "../../fixtures/pages";
import { menuLabelToPage } from "../../fixtures/menuMappings";
import { navigateToPage } from "../../helpers/navigation";
const sidebarButtons = {
[Role.ProxyAdmin]: [
@ -9,9 +12,7 @@ const sidebarButtons = {
"Models",
"Usage",
"Teams",
"Internal User",
"Settings",
"Experimental",
"Internal Users",
"API Reference",
"AI Hub",
],
@ -23,13 +24,36 @@ for (const { role, storage } of roles) {
test.describe(`${role} sidebar`, () => {
test.use({ storageState: storage });
test("can see and navigate all sidebar buttons", async ({ page }) => {
test("should navigate to correct URL when clicking sidebar menu items from homepage", async ({ page }) => {
await page.goto("/ui");
for (const button of sidebarButtons[role as keyof typeof sidebarButtons]) {
const tab = page.getByRole("menuitem", { name: button });
for (const buttonLabel of sidebarButtons[role as keyof typeof sidebarButtons]) {
const expectedPage = menuLabelToPage[buttonLabel];
if (!expectedPage) {
throw new Error(`No page mapping found for menu label: ${buttonLabel}`);
}
const tab = page.getByRole("menuitem", { name: buttonLabel });
await expect(tab).toBeVisible();
await tab.click();
// Verify URL contains the correct page query parameter
await expect(page).toHaveURL(new RegExp(`[?&]page=${expectedPage}(&|$)`));
}
});
test("should navigate directly to page using navigation helper", async ({ page }) => {
// Test direct navigation to verify the helper function works
await navigateToPage(page, Page.ApiKeys);
await expect(page).toHaveURL(new RegExp(`[?&]page=${Page.ApiKeys}(&|$)`));
await navigateToPage(page, Page.Models);
await expect(page).toHaveURL(new RegExp(`[?&]page=${Page.Models}(&|$)`));
await navigateToPage(page, Page.LlmPlayground);
await expect(page).toHaveURL(new RegExp(`[?&]page=${Page.LlmPlayground}(&|$)`));
});
});
}