Files
next-tjwater-frontend/src/app/app.e2e.ts
T
jiang c0e4231b83
Generic Container CI/CD / test-build-publish (push) Successful in 1m52s
Frontend CI/CD / build-test-publish-and-deploy (push) Successful in 1m52s
feat: expand intelligent investigation workspace
2026-10-30 17:30:19 +08:00

151 lines
6.4 KiB
TypeScript

import { readThemeColor } from "../../tests/browser/support/theme-colors";
import { expect, test } from "@playwright/test";
import { mockAgentApi } from "../../tests/browser/support/mock-agent-api";
import { mockWorkbenchContext } from "../../tests/browser/support/mock-workbench-context";
test.beforeEach(async ({ page }) => {
await mockWorkbenchContext(page);
await mockAgentApi(page);
});
test("renders the migrated WebGIS workbench shell", async ({ page }) => {
const riveRequests: string[] = [];
page.on("request", (request) => {
if (/\.riv(?:\?|$)/.test(request.url())) {
riveRequests.push(request.url());
}
});
await page.goto("/");
await expect(page).toHaveTitle("供水管网智慧运维系统");
const faviconHref = await page.locator('link[rel="icon"]').getAttribute("href");
expect(faviconHref).toBe("/favicon.svg");
const favicon = await page.request.get(faviconHref!);
expect(favicon.ok()).toBe(true);
expect(favicon.headers()["content-type"]).toContain("image/svg+xml");
await expect(page.getByText("供水管网智慧运维系统")).toBeVisible();
await expect(page.getByText("运维工作台")).toBeVisible();
await expect(page.getByLabel("Agent 折叠栏")).toBeVisible();
await expect(page.getByLabel("Agent 命令面板")).toHaveCount(0);
await page.getByRole("button", { name: /展开 Agent 助手面板/ }).click();
await expect(page.getByLabel("推荐问题")).toBeVisible();
const runtimeConfig = await page.evaluate(() => globalThis.__TJWATER_CONFIG__);
expect(runtimeConfig).toMatchObject({
TJWATER_MAP_URL: expect.any(String),
TJWATER_GEOSERVER_WORKSPACE: expect.any(String),
TJWATER_SERVER_API_BASE_URL: expect.any(String),
TJWATER_AGENT_URL: expect.any(String)
});
expect(Object.keys(runtimeConfig as Record<string, unknown>)).not.toContainEqual(
expect.stringMatching(/^(NEXT_PUBLIC_|VITE_)/)
);
expect(runtimeConfig).not.toHaveProperty("TJWATER_TTS_API_URL");
expect(runtimeConfig).not.toHaveProperty("EDGE_TTS_VOICE");
const mapAsset = await page.request.get("/map/valve.png");
expect(mapAsset.ok()).toBe(true);
expect(mapAsset.headers()["content-type"]).toBe("image/png");
await expect(page.getByLabel("Agent 状态").first()).toBeVisible();
await expect.poll(() => riveRequests.length, { timeout: 25_000 }).toBe(1);
});
test("animates the compact header menu without overflowing", async ({ page }) => {
await page.emulateMedia({ reducedMotion: "no-preference" });
await page.setViewportSize({ width: 375, height: 812 });
await page.goto("/");
await page.locator('button[aria-label^="查看待办与告警"]:visible').click();
const menu = page.locator('[role="menu"][data-state="open"]');
await expect(menu).toBeVisible();
const animation = await menu.evaluate((element) => {
const style = window.getComputedStyle(element);
return {
duration: Number.parseFloat(style.animationDuration) * 1_000,
name: style.animationName
};
});
expect(animation.name).toContain("enter");
expect(animation.duration).toBeGreaterThan(0);
const menuBounds = await menu.boundingBox();
expect(menuBounds).not.toBeNull();
expect(menuBounds!.x).toBeGreaterThanOrEqual(0);
expect(menuBounds!.x + menuBounds!.width).toBeLessThanOrEqual(375);
});
test("renders map notices through a single toaster", async ({ page }) => {
await page.goto("/");
await expect(page.locator("[data-sonner-toaster]")).toHaveCount(1);
await page.getByLabel("打开用户菜单").click();
await page.getByRole("menuitem", { name: /查看运行状态/ }).click();
await expect(page.getByText("数据状态", { exact: true })).toBeVisible();
});
test("preserves compact typography in header and agent controls", async ({ page }) => {
await page.setViewportSize({ width: 1440, height: 900 });
await page.goto("/");
await page.getByRole("button", { name: /展开 Agent 助手面板/ }).click();
const headerControl = page
.locator("header.acrylic-navigation button.font-semibold:visible")
.first();
const approvalControl = page.getByRole("button", { name: "权限批准模式" });
const suggestion = page.locator("[aria-label=推荐问题] button").first();
await expect(headerControl).toHaveCSS("font-weight", "600");
await expect(approvalControl).toHaveCSS("font-size", "14px");
await expect(approvalControl).toHaveCSS("line-height", "20px");
await expect(suggestion).toHaveCSS("font-size", "14px");
await expect(suggestion).toHaveCSS("font-weight", "400");
});
test("lets interactive utilities override surface materials", async ({ page }) => {
await page.goto("/");
await page.getByRole("button", { name: /展开 Agent 助手面板/ }).click();
await page.addStyleTag({ content: "*,*::before,*::after{transition:none!important}" });
const suggestion = page.locator("[aria-label=推荐问题] button").first();
const restingBackground = await suggestion.evaluate(
(element) => window.getComputedStyle(element).backgroundColor
);
await suggestion.hover();
const hoverBackground = await suggestion.evaluate(
(element) => window.getComputedStyle(element).backgroundColor
);
expect(hoverBackground).not.toBe(restingBackground);
});
test("keeps menu origin and the solid Main Frame styling through Tailwind v4", async ({ page }) => {
await page.setViewportSize({ width: 1440, height: 900 });
await page.goto("/");
await page.getByLabel("打开用户菜单").click();
const menu = page.locator('[role="menu"][data-state="open"]');
const menuTransformOrigin = await menu.evaluate(
(element) => window.getComputedStyle(element).transformOrigin
);
expect(menuTransformOrigin).not.toBe("50% 50%");
await page.keyboard.press("Escape");
await page.getByRole("button", { name: /展开 Agent 助手面板/ }).click();
const navigation = page.getByRole("complementary", { name: "Agent 命令面板" });
const navigationMaterial = await navigation.evaluate((element) => {
const style = window.getComputedStyle(element);
return {
backdropFilter: style.backdropFilter,
backgroundColor: style.backgroundColor
};
});
expect(navigationMaterial.backdropFilter).toBe("none");
expect(navigationMaterial.backgroundColor).toBe(await readThemeColor(navigation, "--surface-navigation"));
await expect(page.locator("#main-workspace")).toHaveAttribute("data-layout-mode", "default");
await expect(page.getByRole("toolbar", { name: "工作区窗口任务栏" })).toHaveCount(0);
});