mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-01 07:03:02 +00:00
* test(integration): answer the model-info refresh GET in the mixed MCP responses wire peer
The proxy's periodic model-info refresh sends GET /v1/models to the deployment api_base, which tripped the peer's /responses-only assertion when a tick landed mid-test
* test(e2e): wait for the api-keys URL after clicking Virtual Keys in onboarding
/ui already renders the Virtual Keys heading, so the helper returned before navigation finished. The late route change moved focus and closed the account menu popover in hideLiteAdmin
* test(proxy): stop two unit modules leaking app.openapi_schema and a session-wide Router
test_custom_openapi cached a stripped schema on app.openapi_schema and never cleared it, breaking later openapi route tests. test_proxy_reject_logging built a module-level Router that stayed in the live router registry all session and re-added cost-map keys during a reload. Reset the schema via monkeypatch and make the Router a function-scoped fixture
(cherry picked from commit a292fd409f)
70 lines
3.3 KiB
TypeScript
70 lines
3.3 KiB
TypeScript
import { expect, type APIRequestContext, type Page } from "@playwright/test";
|
|
import { UI_BASE_URL } from "../constants";
|
|
import { masterKey, rootPath } from "./traffic";
|
|
|
|
const endpoint = (route: string): string => `${UI_BASE_URL}${rootPath()}${route}`;
|
|
|
|
export async function setInvitedUserPassword(
|
|
request: APIRequestContext,
|
|
userId: string,
|
|
password: string,
|
|
): Promise<void> {
|
|
const invitation = await request.post(endpoint("/invitation/new"), {
|
|
headers: { Authorization: `Bearer ${masterKey()}` },
|
|
data: { user_id: userId },
|
|
});
|
|
expect(invitation.ok(), `Create invitation for ${userId}: HTTP ${invitation.status()}`).toBe(true);
|
|
const { id } = await invitation.json();
|
|
expect(typeof id, "invitation ID").toBe("string");
|
|
|
|
const onboarding = await request.get(endpoint("/onboarding/get_token"), {
|
|
params: { invite_link: id },
|
|
});
|
|
expect(onboarding.ok(), `Get onboarding session for ${userId}: HTTP ${onboarding.status()}`).toBe(true);
|
|
const { token } = await onboarding.json();
|
|
const payload = JSON.parse(Buffer.from(token.split(".")[1], "base64url").toString("utf-8"));
|
|
expect(typeof payload.key, "onboarding credential").toBe("string");
|
|
const claimed = await request.post(endpoint("/onboarding/claim_token"), {
|
|
headers: { Authorization: `Bearer ${payload.key}` },
|
|
data: { invitation_link: id, user_id: userId, password },
|
|
});
|
|
expect(claimed.ok(), `Claim invitation for ${userId}: HTTP ${claimed.status()}`).toBe(true);
|
|
}
|
|
|
|
export async function readDashboardSession(page: Page): Promise<{
|
|
key: string;
|
|
user_id: string;
|
|
password_reset_required?: boolean;
|
|
}> {
|
|
await expect.poll(async () => (await page.context().cookies()).some((cookie) => cookie.name === "token")).toBe(true);
|
|
const cookie = (await page.context().cookies()).find((candidate) => candidate.name === "token")!;
|
|
return JSON.parse(Buffer.from(cookie.value.split(".")[1], "base64url").toString("utf-8"));
|
|
}
|
|
|
|
export async function expectUnrestrictedDashboard(page: Page): Promise<void> {
|
|
const virtualKeys = page.getByRole("complementary").getByRole("link", { name: "Virtual Keys", exact: true });
|
|
await expect(virtualKeys).toBeVisible({ timeout: 30_000 });
|
|
const session = await readDashboardSession(page);
|
|
expect(session.password_reset_required === true, "login must not require a password reset").toBe(false);
|
|
await virtualKeys.click();
|
|
await expect(page).toHaveURL(/\/ui\/api-keys\/?$/);
|
|
await expect(page.getByRole("main").getByRole("heading", { name: "Virtual Keys", exact: true })).toBeVisible({
|
|
timeout: 30_000,
|
|
});
|
|
const info = await page.request.get(endpoint("/user/info"), {
|
|
headers: { Authorization: `Bearer ${session.key}` },
|
|
params: { user_id: session.user_id },
|
|
});
|
|
expect(info.ok(), `Read own user with dashboard session: HTTP ${info.status()}`).toBe(true);
|
|
expect((await info.json()).user_id).toBe(session.user_id);
|
|
}
|
|
|
|
export async function logInThroughLoginPage(page: Page, email: string, password: string): Promise<void> {
|
|
await page.goto(`${rootPath()}/ui/login`);
|
|
await page.getByPlaceholder("Enter your username").fill(email);
|
|
await page.getByPlaceholder("Enter your password").fill(password);
|
|
await page.getByRole("button", { name: "Login", exact: true }).click();
|
|
await page.waitForURL((url) => url.pathname.startsWith(`${rootPath()}/ui`) && !url.pathname.includes("/login"), {
|
|
timeout: 30_000,
|
|
});
|
|
}
|