From e555a79cee7a4becd2c31898cacfe5b5108e0b92 Mon Sep 17 00:00:00 2001 From: yuneng-jiang Date: Fri, 6 Nov 2026 14:59:01 -0800 Subject: [PATCH] test(e2e): follow the Aria sidebar move and the Skills Hub rename in UI specs (#50453) #50009 moved Aria out of the dashboard header into the sidebar with its own page, and #50195 renamed the Skills nav link and AI Hub tab to Skills Hub and relabeled the skills search box. The UI e2e specs still looked for the old header button, dialog and labels, so the scheduled litellm-e2e run has been red since build 815. --- tests/e2e/ui/fixtures/migratedPages.ts | 2 +- tests/e2e/ui/helpers/navigation.ts | 2 +- .../e2e/ui/tests/logs/logsPagination.spec.ts | 31 +++++++++++-------- tests/e2e/ui/tests/modelHub/modelHub.spec.ts | 13 +++----- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/e2e/ui/fixtures/migratedPages.ts b/tests/e2e/ui/fixtures/migratedPages.ts index 6fa8d0c2587..e49168ebb4a 100644 --- a/tests/e2e/ui/fixtures/migratedPages.ts +++ b/tests/e2e/ui/fixtures/migratedPages.ts @@ -79,7 +79,7 @@ export const MIGRATED_E2E_PAGES: Readonly> = { group: "Tools", content: { role: "heading", name: "Tool Policies" }, }, - skills: { segment: "skills", linkName: "Skills", content: { role: "heading", name: "Skills" } }, + skills: { segment: "skills", linkName: "Skills Hub", content: { role: "heading", name: "Skills Hub" } }, caching: { segment: "caching", linkName: "Response Cache", content: { role: "tab", name: "Cache Settings" } }, "cost-tracking": { segment: "cost-tracking", diff --git a/tests/e2e/ui/helpers/navigation.ts b/tests/e2e/ui/helpers/navigation.ts index 3943526aebf..af261044c84 100644 --- a/tests/e2e/ui/helpers/navigation.ts +++ b/tests/e2e/ui/helpers/navigation.ts @@ -79,7 +79,7 @@ export async function setAriaHidden(page: PlaywrightPage, hidden: boolean): Prom } await page.keyboard.press("Escape"); await expect(panel).toBeHidden(); - const aria = page.getByRole("banner").getByRole("button", { name: "Aria Agent", exact: true }); + const aria = sidebarLink(page, "Aria Agent"); if (premium && hidden) { await expect(aria).toBeHidden(); } else { diff --git a/tests/e2e/ui/tests/logs/logsPagination.spec.ts b/tests/e2e/ui/tests/logs/logsPagination.spec.ts index a611f760e8b..b81708d1cd1 100644 --- a/tests/e2e/ui/tests/logs/logsPagination.spec.ts +++ b/tests/e2e/ui/tests/logs/logsPagination.spec.ts @@ -1,6 +1,12 @@ import { test, expect, type APIRequestContext, type Locator, type Page as PlaywrightPage } from "@playwright/test"; import { ADMIN_STORAGE_PATH } from "../../constants"; -import { navigateToPage, dismissFeedbackPopup, setAriaHidden } from "../../helpers/navigation"; +import { + navigateToPage, + dismissFeedbackPopup, + expectUiRoute, + setAriaHidden, + sidebarLink, +} from "../../helpers/navigation"; import { Page } from "../../fixtures/pages"; import { CHAT_MODEL_A, @@ -51,12 +57,18 @@ async function setRowsPerPage(page: PlaywrightPage, size: "25" | "50" | "100"): await page.getByRole("option", { name: size, exact: true }).click(); } -test.describe("Logs pagination with Aria in the header", () => { +async function openAriaFromSidebar(page: PlaywrightPage): Promise { + await sidebarLink(page, "Aria Agent").click(); + await expectUiRoute(page, "aria"); + await expect(page.getByRole("region", { name: "Aria Agent", exact: true })).toBeVisible(); +} + +test.describe("Logs pagination with Aria in the sidebar", () => { test.use({ storageState: ADMIN_STORAGE_PATH }); test("keeps pagination reachable and Aria available at 1440px", async ({ page, request }) => { await page.setViewportSize({ width: 1440, height: 900 }); - const alias = `e2e-aria-header-${uniqueSuffix()}`; + const alias = `e2e-aria-sidebar-${uniqueSuffix()}`; const key = await createVirtualKey(request, { key_alias: alias }); try { const ids = await Promise.all( @@ -76,20 +88,13 @@ test.describe("Logs pagination with Aria in the header", () => { await expect(visibleTestId(page, "pagination-range")).toHaveText("Showing 1-25 of 26"); await visibleTestId(page, "pagination-next").click(); await expect(visibleTestId(page, "pagination-range")).toHaveText("Showing 26-26 of 26"); - - const aria = page.getByRole("banner").getByRole("button", { name: "Aria Agent", exact: true }); - await aria.click(); - await expect(page.getByRole("dialog", { name: "Aria Agent", exact: true })).toBeVisible(); - await page.keyboard.press("Escape"); - await expect(aria).toBeFocused(); await visibleTestId(page, "pagination-first").click(); await expect(visibleTestId(page, "pagination-range")).toHaveText("Showing 1-25 of 26"); + + await openAriaFromSidebar(page); for (const destination of [Page.NewUsage, Page.LlmPlayground, Page.ApiKeys]) { await navigateToPage(page, destination); - await aria.click(); - await expect(page.getByRole("dialog", { name: "Aria Agent", exact: true })).toBeVisible(); - await page.keyboard.press("Escape"); - await expect(aria).toBeFocused(); + await openAriaFromSidebar(page); } } finally { await deleteVirtualKey(request, key.token); diff --git a/tests/e2e/ui/tests/modelHub/modelHub.spec.ts b/tests/e2e/ui/tests/modelHub/modelHub.spec.ts index 517ec64c7df..18a685f052d 100644 --- a/tests/e2e/ui/tests/modelHub/modelHub.spec.ts +++ b/tests/e2e/ui/tests/modelHub/modelHub.spec.ts @@ -39,21 +39,16 @@ test.describe("AI Hub (internal admin view)", () => { }); }); - test("AI Hub tab list renders Model Hub, Agent Hub, MCP Hub and Skill Hub", async ({ page }) => { + test("AI Hub tab list renders Model Hub, Agent Hub, MCP Hub and Skills Hub", async ({ page }) => { await navigateToPage(page, Page.ModelHubTable); - // The tab strip lives in the main view; check each tab is present and clickable. - // (The "Claude Code Plugin Marketplace" tab from the manual-QA checklist was - // renamed to "Skill Hub" — verify the current label here so the test stays - // in sync with the UI.) - // // Note: unlike the public /ui/model_hub_table view (test below), the admin // ModelHubTable renders all four tabs unconditionally — there are no `&&` // guards around Agent Hub or MCP Hub in the source // (ModelHubTable.tsx ~L436-439). Asserting all four here is intentional: // this pins the manual-QA contract that the AI Hub tab strip exposes // exactly these labels regardless of seeded agent/MCP data. - for (const tabName of ["Model Hub", "Agent Hub", "MCP Hub", "Skill Hub"]) { + for (const tabName of ["Model Hub", "Agent Hub", "MCP Hub", "Skills Hub"]) { const tab = page.getByRole("tab", { name: tabName }); await expect(tab, `${tabName} tab should be present`).toBeVisible({ timeout: 5_000 }); await tab.click(); @@ -75,7 +70,7 @@ test.describe("Public model hub (/ui/model_hub_table)", () => { await expect(page.getByRole("tab")).toHaveCount(2); await page.getByRole("tab", { name: "Skills Hub", exact: true }).click(); await expect( - page.getByRole("textbox", { name: "Search skills", exact: true }), + page.getByRole("textbox", { name: "Search skills, tags, or people…", exact: true }), ).toBeVisible(); }); @@ -105,7 +100,7 @@ test.describe("Public model hub (/ui/model_hub_table)", () => { await dismissFeedbackPopup(page); await page.getByRole("checkbox", { name: domain, exact: true }).check(); await page - .getByRole("textbox", { name: "Search skills", exact: true }) + .getByRole("textbox", { name: "Search skills, tags, or people…", exact: true }) .fill(skillName); await page.getByRole("link").filter({ hasText: skillName }).click();