98 lines
3.1 KiB
TypeScript
98 lines
3.1 KiB
TypeScript
import { expect, test, type Page, type Route } from "@playwright/test";
|
|
|
|
function accessToken() {
|
|
const payload = Buffer.from(JSON.stringify({ exp: 4102444800 })).toString("base64url");
|
|
return `test.${payload}.token`;
|
|
}
|
|
|
|
async function seedAuth(page: Page) {
|
|
await page.addInitScript((token) => {
|
|
localStorage.setItem("notelett_auth_user", JSON.stringify({ id: "user-1", email: "user@example.com", name: "Review Tester" }));
|
|
localStorage.setItem("notelett_access_token", token);
|
|
localStorage.setItem("notelett_refresh_token", "refresh-token");
|
|
}, accessToken());
|
|
}
|
|
|
|
function json(route: Route, body: unknown, status = 200) {
|
|
return route.fulfill({
|
|
status,
|
|
contentType: "application/json",
|
|
body: JSON.stringify(body),
|
|
});
|
|
}
|
|
|
|
function actionDoc(id: string, afterSummary: string, state: string) {
|
|
return {
|
|
id,
|
|
productId: "notelett",
|
|
workspaceId: "ws-1",
|
|
noteId: "note-1",
|
|
actorId: "agent-1",
|
|
actorType: "agent",
|
|
actionType: "update",
|
|
state,
|
|
afterSummary,
|
|
beforeSummary: "Before text",
|
|
updatedAt: "2026-05-05T00:00:00.000Z",
|
|
updatedBy: "agent-1",
|
|
};
|
|
}
|
|
|
|
async function mockReviewApis(page: Page) {
|
|
await page.route("**/api/auth/refresh", (route) =>
|
|
json(route, { accessToken: accessToken(), refreshToken: "refresh-token" }),
|
|
);
|
|
await page.route("**/api/kill-switch**", (route) =>
|
|
json(route, { disabled: false, message: null }),
|
|
);
|
|
await page.route("**/api/**", (route) => {
|
|
const url = new URL(route.request().url());
|
|
const path = url.pathname.replace(/^\/api/, "");
|
|
|
|
if (path === "/note-agent-actions/pending") {
|
|
return json(route, {
|
|
items: [
|
|
actionDoc("act-1", "Approve release summary", "proposed"),
|
|
actionDoc("act-2", "Reject stale task", "proposed"),
|
|
],
|
|
total: 2,
|
|
});
|
|
}
|
|
if (path === "/note-agent-actions") {
|
|
return json(route, {
|
|
items: [actionDoc("act-3", "Previous review", "approved")],
|
|
total: 1,
|
|
});
|
|
}
|
|
if (path === "/broadcasts/active" || path === "/surveys/active") {
|
|
return json(route, { items: [], total: 0 });
|
|
}
|
|
|
|
return json(route, {});
|
|
});
|
|
}
|
|
|
|
test.beforeEach(async ({ page }) => {
|
|
await seedAuth(page);
|
|
await mockReviewApis(page);
|
|
});
|
|
|
|
for (const viewport of [
|
|
{ name: "desktop", width: 1440, height: 1000 },
|
|
{ name: "mobile", width: 390, height: 900 },
|
|
]) {
|
|
test(`reviews visual smoke - ${viewport.name}`, async ({ page }) => {
|
|
await page.setViewportSize({ width: viewport.width, height: viewport.height });
|
|
await page.goto("/reviews");
|
|
await expect(page.getByRole("heading", { name: "Agent review" })).toBeVisible();
|
|
await expect(page.getByRole("heading", { name: "Approval queue" })).toBeVisible();
|
|
await expect(page.getByRole("button", { name: /Approve release summary/ })).toBeVisible();
|
|
|
|
const overflow = await page.evaluate(() => document.documentElement.scrollWidth > document.documentElement.clientWidth);
|
|
expect(overflow).toBe(false);
|
|
|
|
const screenshot = await page.screenshot({ fullPage: true });
|
|
expect(screenshot.byteLength).toBeGreaterThan(10_000);
|
|
});
|
|
}
|