From cce716334806d0c1f554bf0d206958c739af6872 Mon Sep 17 00:00:00 2001 From: Yuneng Jiang Date: Sat, 11 Apr 2026 20:34:50 -0700 Subject: [PATCH] fix CI: replace data-testid selectors with text/role-based selectors The data-testid attributes added to React components are not present in the CI-built UI output. Switch to using getByRole and getByText selectors which work with the rendered DOM regardless of build cache. --- .../tests/modelsPage/addModel.spec.ts | 71 ++++++++----------- 1 file changed, 29 insertions(+), 42 deletions(-) diff --git a/ui/litellm-dashboard/e2e_tests/tests/modelsPage/addModel.spec.ts b/ui/litellm-dashboard/e2e_tests/tests/modelsPage/addModel.spec.ts index c07fd827b39..1a37caf62fd 100644 --- a/ui/litellm-dashboard/e2e_tests/tests/modelsPage/addModel.spec.ts +++ b/ui/litellm-dashboard/e2e_tests/tests/modelsPage/addModel.spec.ts @@ -32,6 +32,17 @@ async function cleanupModels(request: any, searchTerm: string) { } } +/** + * Helper to select a provider from the Add Model form dropdown. + */ +async function selectProvider(page: any, providerName: string) { + const providerDropdown = page.getByRole("combobox", { name: /Provider/i }); + await providerDropdown.fill(providerName); + await page.waitForTimeout(1000); + await providerDropdown.press("Enter"); + await page.waitForTimeout(2000); +} + test.describe("Add Model", () => { test.use({ storageState: ADMIN_STORAGE_PATH }); @@ -39,19 +50,13 @@ test.describe("Add Model", () => { await navigateToPage(page, Page.Models); await page.getByRole("tab", { name: "Add Model" }).click(); - const providerDropdown = page.getByRole("combobox", { name: /Provider/i }); - await providerDropdown.fill("Anthropic"); - await page.waitForTimeout(1000); - await providerDropdown.press("Enter"); - await page.waitForTimeout(2000); + await selectProvider(page, "Anthropic"); - // The model field should be a multi-select dropdown (not a text input) - const modelSelect = page.getByTestId("model-name-select"); - await expect(modelSelect).toBeVisible({ timeout: 10_000 }); - - // Click to open the dropdown and verify provider-specific models are listed + // The model field should be a multi-select dropdown; click to open it const modelDropdown = page.locator(".ant-select-selection-overflow").first(); await modelDropdown.click(); + + // Verify provider-specific models are listed await expect(page.getByTitle("claude-haiku-4-5", { exact: true })).toBeVisible(); }); @@ -110,12 +115,7 @@ test.describe("Add Model", () => { await navigateToPage(page, Page.Models); await page.getByRole("tab", { name: "Add Model" }).click(); - // Select provider: Anthropic - const providerDropdown = page.getByRole("combobox", { name: /Provider/i }); - await providerDropdown.fill("Anthropic"); - await page.waitForTimeout(1000); - await providerDropdown.press("Enter"); - await page.waitForTimeout(2000); + await selectProvider(page, "Anthropic"); // Select model: claude-haiku-4-5 const modelDropdown = page.locator(".ant-select-selection-overflow").first(); @@ -127,15 +127,14 @@ test.describe("Add Model", () => { const apiKeyInput = page.locator('input[type="password"]').first(); await apiKeyInput.fill("sk-bad-key-12345"); - // Click Test Connect - await page.getByTestId("test-connect-btn").click(); + // Click Test Connect button by its text + await page.getByRole("button", { name: "Test Connect" }).click(); // Wait for modal to appear and connection test to complete await expect(page.getByText("Connection Test Results")).toBeVisible({ timeout: 10_000 }); // Verify failure message appears (the test makes a real API call, so it will fail with bad creds) - await expect(page.getByTestId("connection-failure-msg")).toBeVisible({ timeout: 30_000 }); - await expect(page.getByTestId("connection-failure-msg")).toContainText("failed"); + await expect(page.getByText(/Connection to .* failed/)).toBeVisible({ timeout: 30_000 }); }); test("Add specific model and verify it appears in All Models", async ({ page, request }) => { @@ -144,12 +143,7 @@ test.describe("Add Model", () => { await navigateToPage(page, Page.Models); await page.getByRole("tab", { name: "Add Model" }).click(); - // Select provider: Anthropic - const providerDropdown = page.getByRole("combobox", { name: /Provider/i }); - await providerDropdown.fill("Anthropic"); - await page.waitForTimeout(1000); - await providerDropdown.press("Enter"); - await page.waitForTimeout(2000); + await selectProvider(page, "Anthropic"); // Select model: claude-haiku-4-5 const modelDropdown = page.locator(".ant-select-selection-overflow").first(); @@ -161,8 +155,8 @@ test.describe("Add Model", () => { const apiKeyInput = page.locator('input[type="password"]').first(); await apiKeyInput.fill("sk-any-key-for-add-test"); - // Click Add Model - await page.getByTestId("add-model-btn").click(); + // Click Add Model button by its text + await page.getByRole("button", { name: "Add Model" }).last().click(); // Wait for success notification await expect(page.getByText("created successfully")).toBeVisible({ timeout: 15_000 }); @@ -173,12 +167,11 @@ test.describe("Add Model", () => { await page.waitForTimeout(2000); // Search for the model we just added - await page.getByTestId("model-search-input").fill("claude-haiku-4-5"); + await page.locator('input[placeholder="Search model names..."]').fill("claude-haiku-4-5"); await page.waitForTimeout(1000); // Verify the model appears in the results count (not "Showing 0 results") - const resultsCount = page.getByTestId("models-results-count"); - await expect(resultsCount).not.toHaveText("Showing 0 results", { timeout: 15_000 }); + await expect(page.getByText(/Showing \d+ - \d+ of \d+ results/)).toBeVisible({ timeout: 15_000 }); // Verify the model name appears in the table body const tableBody = page.locator("table tbody"); @@ -191,12 +184,7 @@ test.describe("Add Model", () => { await navigateToPage(page, Page.Models); await page.getByRole("tab", { name: "Add Model" }).click(); - // Select provider: Cohere - const providerDropdown = page.getByRole("combobox", { name: /Provider/i }); - await providerDropdown.fill("Cohere"); - await page.waitForTimeout(1000); - await providerDropdown.press("Enter"); - await page.waitForTimeout(2000); + await selectProvider(page, "Cohere"); // Select All Cohere Models (Wildcard) const modelDropdown = page.locator(".ant-select-selection-overflow").first(); @@ -209,8 +197,8 @@ test.describe("Add Model", () => { const apiKeyInput = page.locator('input[type="password"]').first(); await apiKeyInput.fill("sk-any-key-for-wildcard-test"); - // Click Add Model - await page.getByTestId("add-model-btn").click(); + // Click Add Model button by its text + await page.getByRole("button", { name: "Add Model" }).last().click(); // Wait for success notification await expect(page.getByText("created successfully")).toBeVisible({ timeout: 15_000 }); @@ -221,12 +209,11 @@ test.describe("Add Model", () => { await page.waitForTimeout(2000); // Search for the wildcard model - await page.getByTestId("model-search-input").fill("cohere"); + await page.locator('input[placeholder="Search model names..."]').fill("cohere"); await page.waitForTimeout(1000); // Verify the model appears in the results count (not "Showing 0 results") - const resultsCount = page.getByTestId("models-results-count"); - await expect(resultsCount).not.toHaveText("Showing 0 results", { timeout: 15_000 }); + await expect(page.getByText(/Showing \d+ - \d+ of \d+ results/)).toBeVisible({ timeout: 15_000 }); // Verify the wildcard model appears in the table body (wildcard models show as "cohere/*") const tableBody = page.locator("table tbody");