import { expect, test, type Page } from "@playwright/test"; import { mockBackend } from "./support/mockBackend"; test.setTimeout(90_000); async function prepare(page: Page) { await mockBackend(page); await page.route("**/api/v1/admin/**", (route) => route.fulfill({ json: route.request().url().endsWith("/users/me") ? { id: "playwright-user", is_system_admin: true, system_role: "system_admin" } : [], })); } test("菜单点击后立即反馈,等待页面响应时显示路由骨架", async ({ page }) => { await prepare(page); await page.goto("/system-admin"); await expect(page.getByRole("link", { name: "审计日志", exact: true })).toBeVisible(); await page.locator("[data-page-scroll-content]").evaluate((element) => { element.scrollTop = element.scrollHeight; }); let release: () => void = () => {}; const gate = new Promise((resolve) => { release = resolve; }); let waiting = false; await page.route("**/audit-logs?*", async (route) => { if (route.request().headers().rsc !== "1") return route.fallback(); waiting = true; await gate; await route.continue(); }); try { await page.getByRole("link", { name: "审计日志", exact: true }).click(); await expect.poll(() => waiting).toBe(true); await expect(page.getByRole("progressbar", { name: "正在切换页面", exact: true })).toBeVisible({ timeout: 1500 }); await expect(page.getByRole("status", { name: "正在加载审计日志", exact: true })).toBeVisible(); } finally { release(); } await expect(page.getByRole("heading", { name: "审计日志", exact: true })).toBeVisible(); await expect(page.getByRole("progressbar", { name: "正在切换页面", exact: true })).toHaveCount(0); }); test("地图页面切换复用原地图,并显示目标面板的既有骨架", async ({ page }) => { await prepare(page); await page.route("**/ows?**", (route) => route.fulfill({ json: { type: "FeatureCollection", features: [] } })); await page.route("**/api/v1/scada-devices", (route) => route.fulfill({ json: [] })); await page.goto("/network-simulation"); const map = page.locator(".ol-viewport").first(); await expect(map).toBeVisible({ timeout: 60_000 }); await map.evaluate((element) => element.setAttribute("data-navigation-map", "original")); let release: () => void = () => {}; const gate = new Promise((resolve) => { release = resolve; }); await page.route("**/scada-data-cleaning?*", async (route) => { if (route.request().headers().rsc !== "1") return route.fallback(); await gate; await route.continue(); }); try { await page.getByRole("link", { name: "SCADA 数据清洗", exact: true }).click(); await expect(page.getByRole("status", { name: "正在加载数据清洗", exact: true })).toBeVisible(); await expect(page.locator('[data-navigation-map="original"]')).toBeVisible(); await expect(page.locator("[data-map-page-content]")).toHaveCSS("display", "none"); await page.screenshot({ path: "test-results/navigation-map-skeleton.png" }); } finally { release(); } await expect(page).toHaveURL(/\/scada-data-cleaning$/); await expect(page.locator("[data-map-page-content]")).toHaveCSS("display", "contents"); await expect(page.locator('[data-navigation-map="original"]')).toBeVisible(); await expect(page.getByRole("progressbar", { name: "正在切换页面", exact: true })).toHaveCount(0); await page.goBack(); await expect(page).toHaveURL(/\/network-simulation$/); await expect(page.locator('[data-navigation-map="original"]')).toBeVisible(); await expect(page.getByRole("progressbar", { name: "正在切换页面", exact: true })).toHaveCount(0); }); test("移动端收起菜单后仍显示页面切换反馈,窄屏无溢出", async ({ page }) => { await prepare(page); await page.setViewportSize({ width: 375, height: 812 }); await page.goto("/system-admin"); await page.getByRole("button", { name: "open drawer", exact: true }).click(); let release: () => void = () => {}; const gate = new Promise((resolve) => { release = resolve; }); await page.route("**/audit-logs?*", async (route) => { if (route.request().headers().rsc !== "1") return route.fallback(); await gate; await route.continue(); }); try { await page.getByRole("link", { name: "审计日志", exact: true }).click(); for (const width of [375, 320]) { await page.setViewportSize({ width, height: 812 }); await expect(page.getByRole("progressbar", { name: "正在切换页面", exact: true })).toBeVisible(); await expect(page.getByRole("status", { name: "正在加载审计日志", exact: true })).toBeVisible(); expect(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth)).toBe(true); await page.screenshot({ path: `test-results/navigation-mobile-${width}.png` }); } } finally { release(); } await expect(page.getByRole("heading", { name: "审计日志", exact: true })).toBeVisible(); await expect(page.getByRole("progressbar", { name: "正在切换页面", exact: true })).toHaveCount(0); });