mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-09 03:18:44 +00:00
* test(e2e): cover Internal User create-key flow when in no teams The seeded e2e-internal-user is in two teams, so the "no team" branch of the Create Key modal — where the team dropdown must render empty — was unreachable. Seeds a noteam@test.local user and adds a spec that logs in fresh, opens the modal, and asserts the dropdown has zero options. * test(e2e): harden no-team dropdown assertion + add with-teams counterpart Replace the one-shot count() check with a settled-empty assertion: wait for the dropdown's loaded "No teams found" state before asserting zero options, so the test can't pass on a transient empty frame while the team-options request is still in flight. Add internalUserWithTeams.spec.ts as the differential partner; it logs in as the seeded e2e-internal-user (two team memberships) and asserts the dropdown lists exactly those teams. Without it, the no-team spec's zero-options assertion would still pass against a regression that empties the dropdown for every user.
41 lines
2.1 KiB
TypeScript
41 lines
2.1 KiB
TypeScript
import { test, expect } from "@playwright/test";
|
|
import { dismissFeedbackPopup } from "../../helpers/navigation";
|
|
|
|
/**
|
|
* Logs in fresh inside the test rather than reusing a stored session because
|
|
* this user (seeded with no team memberships) only exists for this one spec —
|
|
* extending globalSetup + the Role enum + the storage-path map for a single
|
|
* assertion isn't worth the maintenance cost.
|
|
*/
|
|
test.describe("Internal User with no team memberships", () => {
|
|
test.use({ storageState: { cookies: [], origins: [] } });
|
|
|
|
test("Create Key team dropdown is empty when the user belongs to no teams", async ({ page }) => {
|
|
// Log in via the form as the no-team seeded user.
|
|
await page.goto("/ui/login");
|
|
await page.getByPlaceholder("Enter your username").fill("noteam@test.local");
|
|
await page.getByPlaceholder("Enter your password").fill("test");
|
|
await page.getByRole("button", { name: "Login", exact: true }).click();
|
|
await expect(page.getByText("Virtual Keys")).toBeVisible({ timeout: 15_000 });
|
|
await dismissFeedbackPopup(page);
|
|
|
|
// Open the Create Key modal.
|
|
await page.getByRole("button", { name: /Create New Key/i }).click();
|
|
await expect(page.getByText("Key Ownership")).toBeVisible({ timeout: 10_000 });
|
|
|
|
const teamSelect = page.locator(".ant-select", { hasText: "Search or select a team" });
|
|
await teamSelect.click();
|
|
|
|
const dropdown = page.locator(".ant-select-dropdown:visible").first();
|
|
await expect(dropdown).toBeVisible({ timeout: 5_000 });
|
|
|
|
// Wait for the settled-empty state, not a transient one. The dropdown shows
|
|
// a spinner while teams load and only swaps in "No teams found" once the
|
|
// request resolves with nothing (team_dropdown.tsx renders the spinner when
|
|
// isLoading and this copy otherwise). Asserting on it means a regression
|
|
// where teams DO load for this user fails here instead of racing a one-shot
|
|
// count() against an in-flight request.
|
|
await expect(dropdown.getByText("No teams found")).toBeVisible({ timeout: 10_000 });
|
|
await expect(dropdown.getByRole("option")).toHaveCount(0);
|
|
});
|
|
});
|