Files
CookieBridge/web/tests/e2e/helpers/mock-api.ts
徐枫 1420c4ecfa
Some checks failed
CI / test (22) (push) Has been cancelled
CI / docker (push) Has been cancelled
CI / extension (push) Has been cancelled
fix: make all 112 Playwright E2E tests pass (RCA-19)
- Fix mock-api data shapes to match actual Vue component interfaces
- Replace HeadlessUI TransitionRoot with v-if in SetupView (unmount fix)
- Restructure CookiesView to detail-replaces-list pattern (strict mode)
- Add ARIA attributes for Playwright selectors (role=switch, aria-label)
- Fix 401 interceptor to skip login endpoint redirects
- Add confirmation dialogs, error states, and missing UI fields
- Rename conflicting button/label text to avoid strict mode violations

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-18 02:52:57 +08:00

165 lines
4.4 KiB
TypeScript

import { type Page } from "@playwright/test";
/**
* Intercept /admin/dashboard and return a canned response so UI tests
* don't depend on a running relay server with real data.
*/
export async function mockDashboard(page: Page): Promise<void> {
await page.route("**/admin/dashboard", (route) =>
route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify({
totalDevices: 3,
onlineDevices: 2,
totalCookies: 142,
uniqueDomains: 8,
connections: 2,
syncCount: 57,
uptimeSeconds: 86400,
}),
}),
);
}
/**
* Intercept /admin/cookies and return a paginated list.
*/
export async function mockCookies(page: Page): Promise<void> {
await page.route("**/admin/cookies*", (route) => {
if (route.request().method() === "DELETE") {
return route.fulfill({ status: 200, contentType: "application/json", body: "{}" });
}
return route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify({
cookies: [
{
id: "c1",
deviceId: "dev-001",
domain: "example.com",
cookieName: "session",
path: "/",
ciphertext: "encrypted-abc123",
nonce: "nonce1",
lamportTs: 1,
updatedAt: "2026-03-01T00:00:00Z",
expires: "2027-01-01T00:00:00Z",
secure: true,
httpOnly: true,
},
{
id: "c2",
deviceId: "dev-001",
domain: "example.com",
cookieName: "pref",
path: "/",
ciphertext: "encrypted-dark",
nonce: "nonce2",
lamportTs: 2,
updatedAt: "2026-03-02T00:00:00Z",
expires: "2027-06-01T00:00:00Z",
secure: false,
httpOnly: false,
},
{
id: "c3",
deviceId: "dev-002",
domain: "other.io",
cookieName: "token",
path: "/",
ciphertext: "encrypted-xyz",
nonce: "nonce3",
lamportTs: 3,
updatedAt: "2026-03-03T00:00:00Z",
expires: null,
secure: true,
httpOnly: true,
},
],
total: 3,
page: 1,
}),
});
});
}
/**
* Intercept /admin/devices and return device list.
*/
export async function mockDevices(page: Page): Promise<void> {
await page.route("**/admin/devices*", (route) => {
if (route.request().method() !== "GET") return route.continue();
return route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify({
devices: [
{
deviceId: "d1",
name: "Chrome on macOS",
platform: "chrome",
online: true,
lastSeen: new Date().toISOString(),
createdAt: "2026-01-01T00:00:00Z",
ipAddress: "192.168.1.10",
extensionVersion: "2.0.0",
},
{
deviceId: "d2",
name: "Firefox on Windows",
platform: "firefox",
online: false,
lastSeen: "2026-03-15T10:00:00Z",
createdAt: "2026-02-01T00:00:00Z",
ipAddress: null,
extensionVersion: "2.0.0",
},
],
}),
});
});
}
/**
* Intercept /admin/settings and return settings object.
*/
export async function mockSettings(page: Page): Promise<void> {
await page.route("**/admin/settings*", (route) => {
if (route.request().method() === "GET") {
return route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify({
autoSync: true,
syncIntervalMs: 0,
maxDevices: 10,
theme: "system",
sessionTimeoutMinutes: 60,
language: "zh",
}),
});
}
return route.fulfill({ status: 200, contentType: "application/json", body: "{}" });
});
}
/**
* Simulate a 500 error on the given path — used for error-handling tests.
*/
export async function mockAPIError(
page: Page,
urlPattern: string,
status = 500,
message = "Internal Server Error",
): Promise<void> {
await page.route(urlPattern, (route) =>
route.fulfill({
status,
contentType: "application/json",
body: JSON.stringify({ error: message }),
}),
);
}