mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-27 01:22:18 +00:00
test(ui): protect dashboard form cleanup
This commit is contained in:
parent
43f096dde8
commit
0dc2f0b1c1
3 changed files with 61 additions and 58 deletions
|
|
@ -12,17 +12,41 @@ export async function captureRequestBody(
|
|||
match: { method: string; urlIncludes: string },
|
||||
action: () => Promise<void>,
|
||||
): Promise<Record<string, any>> {
|
||||
const pending = page.waitForRequest((req) => req.method() === match.method && req.url().includes(match.urlIncludes));
|
||||
const pending = page.waitForRequest(
|
||||
(req) =>
|
||||
req.method() === match.method && req.url().includes(match.urlIncludes),
|
||||
);
|
||||
await action();
|
||||
const request = await pending;
|
||||
return JSON.parse(request.postData() ?? "{}") as Record<string, any>;
|
||||
}
|
||||
|
||||
/** Reads an endpoint as the master key, so a failure is bad data and not an expired UI token. */
|
||||
export async function readBack<T = any>(page: Page, endpoint: string): Promise<T> {
|
||||
export async function readBack<T = any>(
|
||||
page: Page,
|
||||
endpoint: string,
|
||||
): Promise<T> {
|
||||
const res = await page.request.get(endpoint, {
|
||||
headers: { Authorization: `Bearer ${masterKey()}` },
|
||||
});
|
||||
expect(res.ok(), `GET ${endpoint}`).toBe(true);
|
||||
return (await res.json()) as T;
|
||||
}
|
||||
|
||||
export async function runWithCleanup(
|
||||
action: () => Promise<void>,
|
||||
cleanup: () => Promise<boolean>,
|
||||
): Promise<void> {
|
||||
const outcome = await action().then(
|
||||
() => ({ status: "success" as const }),
|
||||
(error: unknown) => ({ status: "failure" as const, error }),
|
||||
);
|
||||
try {
|
||||
if (outcome.status === "failure") throw outcome.error;
|
||||
} finally {
|
||||
const cleanupSucceeded = await cleanup().catch(() => false);
|
||||
if (outcome.status === "success" && !cleanupSucceeded) {
|
||||
throw new Error("Failed to clean up UI E2E resource");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { test, expect } from "@playwright/test";
|
|||
import { ADMIN_STORAGE_PATH } from "../../constants";
|
||||
import { Page as DashboardPage } from "../../fixtures/pages";
|
||||
import { navigateToPage } from "../../helpers/navigation";
|
||||
import { runWithCleanup } from "../../helpers/roundTrip";
|
||||
import { masterKey, uniqueSuffix } from "../../helpers/traffic";
|
||||
|
||||
test.use({ storageState: ADMIN_STORAGE_PATH });
|
||||
|
|
@ -13,21 +14,9 @@ test.describe("Prompt upload form", () => {
|
|||
}) => {
|
||||
const promptId = `e2e-prompt-${uniqueSuffix()}`;
|
||||
const promptContent = "Hello {{name}}";
|
||||
const cleanup = async (): Promise<boolean> => {
|
||||
try {
|
||||
const response = await page.request.delete(
|
||||
`/prompts/${encodeURIComponent(promptId)}?environment=development`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${masterKey()}` },
|
||||
},
|
||||
);
|
||||
return response.ok();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
const testOutcome = await (async () => {
|
||||
try {
|
||||
|
||||
await runWithCleanup(
|
||||
async () => {
|
||||
await navigateToPage(page, DashboardPage.Prompts);
|
||||
await page.getByRole("button", { name: "Upload .prompt File" }).click();
|
||||
await expect(
|
||||
|
|
@ -71,17 +60,16 @@ test.describe("Prompt upload form", () => {
|
|||
})
|
||||
.toContain(promptContent);
|
||||
await expect(page.getByText(promptId, { exact: true })).toBeVisible();
|
||||
return { passed: true as const };
|
||||
} catch (error) {
|
||||
return { passed: false as const, error };
|
||||
}
|
||||
})();
|
||||
|
||||
try {
|
||||
if (!testOutcome.passed) throw testOutcome.error;
|
||||
} finally {
|
||||
const cleanupSucceeded = await cleanup();
|
||||
if (testOutcome.passed) expect(cleanupSucceeded).toBe(true);
|
||||
}
|
||||
},
|
||||
async () => {
|
||||
const response = await page.request.delete(
|
||||
`/prompts/${encodeURIComponent(promptId)}?environment=development`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${masterKey()}` },
|
||||
},
|
||||
);
|
||||
return response.ok();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@ import { test, expect } from "@playwright/test";
|
|||
import { ADMIN_STORAGE_PATH } from "../../constants";
|
||||
import { Page as DashboardPage } from "../../fixtures/pages";
|
||||
import { navigateToPage } from "../../helpers/navigation";
|
||||
import { captureRequestBody, readBack } from "../../helpers/roundTrip";
|
||||
import {
|
||||
captureRequestBody,
|
||||
readBack,
|
||||
runWithCleanup,
|
||||
} from "../../helpers/roundTrip";
|
||||
import { masterKey, uniqueSuffix } from "../../helpers/traffic";
|
||||
|
||||
test.use({ storageState: ADMIN_STORAGE_PATH });
|
||||
|
|
@ -13,22 +17,9 @@ test.describe("Tag management", () => {
|
|||
const tagName = `e2e-tag-${uniqueSuffix()}`;
|
||||
const description = "synthetic tag description";
|
||||
const updatedDescription = `${description} updated`;
|
||||
const cleanup = async (): Promise<boolean> => {
|
||||
try {
|
||||
const response = await page.request.post("/tag/delete", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${masterKey()}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: { name: tagName },
|
||||
});
|
||||
return response.ok();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
const testOutcome = await (async () => {
|
||||
try {
|
||||
|
||||
await runWithCleanup(
|
||||
async () => {
|
||||
await navigateToPage(page, DashboardPage.TagManagement);
|
||||
await page.getByRole("button", { name: "+ Create New Tag" }).click();
|
||||
await expect(
|
||||
|
|
@ -76,17 +67,17 @@ test.describe("Tag management", () => {
|
|||
return info[tagName]?.description;
|
||||
})
|
||||
.toBe(updatedDescription);
|
||||
return { passed: true as const };
|
||||
} catch (error) {
|
||||
return { passed: false as const, error };
|
||||
}
|
||||
})();
|
||||
|
||||
try {
|
||||
if (!testOutcome.passed) throw testOutcome.error;
|
||||
} finally {
|
||||
const cleanupSucceeded = await cleanup();
|
||||
if (testOutcome.passed) expect(cleanupSucceeded).toBe(true);
|
||||
}
|
||||
},
|
||||
async () => {
|
||||
const response = await page.request.post("/tag/delete", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${masterKey()}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: { name: tagName },
|
||||
});
|
||||
return response.ok();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue