import { expect, test, type Page } from "@playwright/test"; import { mockAgentApi } from "./support/mock-agent-api"; test("temporary Agent analysis windows float above the persistent map workspace", async ({ page }) => { await prepareMainFrame(page); await page.goto("/", { waitUntil: "domcontentloaded" }); const frame = page.getByTestId("workbench-main-frame"); const mapWindow = page.locator("#workspace-map"); const testButton = page.getByRole("button", { name: "测试打开 Agent 多图表窗口" }).first(); await expect(frame).toBeVisible(); await expect(mapWindow).toBeVisible(); await expect(testButton).toBeVisible(); await expect(page.getByLabel("工作台导航")).toHaveCount(0); await expect(page.getByLabel("Agent 命令面板")).toBeVisible(); await expect(mapWindow.getByRole("navigation", { name: "地图工具" })).toBeVisible(); await expect(page.locator(".workspace-window-titlebar")).toHaveCount(0); await testButton.click(); await expect(page.getByRole("heading", { name: "北辰分区压力异常诊断", exact: true })).toBeVisible(); await expect(mapWindow).toBeVisible(); await testButton.click(); await expect(page.getByRole("heading", { name: "供水服务分区平衡分析", exact: true })).toBeVisible(); await expect(page.getByText("2 / 6 个临时分析窗")).toBeVisible(); await openWindowOperationMenu(page, "供水服务分区平衡分析"); await page.getByRole("menuitem", { name: "最小化" }).click(); await expect(page.getByRole("button", { name: "恢复供水服务分区平衡分析" })).toBeVisible(); await page.getByRole("button", { name: "恢复供水服务分区平衡分析" }).click(); await expect(page.getByRole("heading", { name: "供水服务分区平衡分析", exact: true })).toBeVisible(); await openWindowOperationMenu(page, "供水服务分区平衡分析"); await page.getByRole("menuitem", { name: "关闭并销毁" }).click(); await openWindowOperationMenu(page, "北辰分区压力异常诊断"); await page.getByRole("menuitem", { name: "关闭并销毁" }).click(); await expect(mapWindow).toBeVisible(); await expect(page.getByRole("heading", { name: "北辰分区压力异常诊断", exact: true })).toHaveCount(0); await expect(page.getByText("0 / 6 个临时分析窗")).toBeVisible(); }); test("the map document floats and minimizes to its taskbar entry", async ({ page }) => { await prepareMainFrame(page); await page.goto("/", { waitUntil: "domcontentloaded" }); const workspace = page.locator("#main-workspace"); const mapWindow = page.locator("#workspace-map"); const dockedBox = await workspace.boundingBox(); expect(dockedBox).not.toBeNull(); await openWindowOperationMenu(page, "供水管网地图"); await page.getByRole("menuitem", { name: "恢复为浮动窗口" }).click(); const floatingBox = await mapWindow.boundingBox(); expect(floatingBox).not.toBeNull(); expect(floatingBox!.width).toBeLessThan(dockedBox!.width); expect(floatingBox!.height).toBeLessThan(dockedBox!.height); await expect(mapWindow).toHaveCSS("border-radius", "0px"); const floatingClassName = await mapWindow.getAttribute("class"); expect(floatingClassName).not.toContain("ring-1"); expect(await mapWindow.evaluate((element) => getComputedStyle(element).boxShadow)).not.toBe("none"); await expect(page.getByRole("button", { name: "打开供水管网地图窗口操作" })).toBeAttached(); await openWindowOperationMenu(page, "供水管网地图"); await page.getByRole("menuitem", { name: "最小化" }).click(); await expect(mapWindow).toBeHidden(); const restoreTask = page.getByRole("button", { name: "恢复供水管网地图" }); await expect(restoreTask).toBeVisible(); await restoreTask.click(); await expect(mapWindow).toBeVisible(); await expect(page.getByRole("button", { name: "打开供水管网地图窗口操作" })).toBeAttached(); }); test("the test control cycles through three trusted document profiles", async ({ page }) => { await prepareMainFrame(page); await page.goto("/", { waitUntil: "domcontentloaded" }); const testButton = page.getByRole("button", { name: "测试打开 Agent 多图表窗口" }).first(); await testButton.click(); await testButton.click(); await testButton.click(); await expect(page.getByRole("heading", { name: "北辰分区压力异常诊断", exact: true })).toBeAttached(); await expect(page.getByRole("heading", { name: "供水服务分区平衡分析", exact: true })).toBeAttached(); await expect(page.getByRole("heading", { name: "低压事件调度处置流程", exact: true })).toBeVisible(); await expect(page.getByText("3 / 6 个临时分析窗")).toBeVisible(); }); test("task view shows every window and fills the workspace with the selected one", async ({ page }) => { await prepareMainFrame(page); await page.goto("/", { waitUntil: "domcontentloaded" }); const testButton = page.getByRole("button", { name: "测试打开 Agent 多图表窗口" }).first(); await testButton.click(); await testButton.click(); await openWindowOperationMenu(page, "北辰分区压力异常诊断"); await page.getByRole("menuitem", { name: "最小化" }).click(); await page.getByRole("button", { name: "任务视图" }).click(); await expect(page.getByRole("dialog", { name: "任务视图" })).toBeVisible(); await expect(page.getByRole("button", { name: /打开供水管网地图并铺满主视图/ })).toBeVisible(); await expect(page.getByRole("button", { name: /打开北辰分区压力异常诊断并铺满主视图,当前已最小化/ })).toBeVisible(); await expect(page.getByRole("button", { name: /打开供水服务分区平衡分析并铺满主视图/ })).toBeVisible(); await page.getByRole("button", { name: /打开供水服务分区平衡分析并铺满主视图/ }).click(); await expect(page.getByRole("dialog", { name: "任务视图" })).toHaveCount(0); const workspaceBox = await page.locator("#main-workspace").boundingBox(); const selectedBox = await page.locator("section[aria-label='供水服务分区平衡分析']").boundingBox(); expect(workspaceBox).not.toBeNull(); expect(selectedBox).not.toBeNull(); expect(Math.abs(selectedBox!.width - workspaceBox!.width)).toBeLessThanOrEqual(2); expect(Math.abs(selectedBox!.height - workspaceBox!.height)).toBeLessThanOrEqual(2); await page.getByRole("button", { name: "任务视图" }).click(); await page.keyboard.press("Escape"); await expect(page.getByRole("dialog", { name: "任务视图" })).toHaveCount(0); await expect(page.getByRole("button", { name: "任务视图" })).toBeFocused(); }); test("temporary documents survive a mobile breakpoint round trip", async ({ page }) => { await prepareMainFrame(page); await page.goto("/", { waitUntil: "domcontentloaded" }); await page.getByRole("button", { name: "测试打开 Agent 多图表窗口" }).first().click(); const analysisHeading = page.locator("h2", { hasText: "北辰分区压力异常诊断" }); await expect(analysisHeading).toBeVisible(); await page.setViewportSize({ width: 390, height: 844 }); await expect(page.locator("#workspace-map")).toBeVisible(); await expect(analysisHeading).toBeAttached(); await expect(analysisHeading).toBeHidden(); await page.setViewportSize({ width: 1440, height: 900 }); await expect(analysisHeading).toBeVisible(); await expect(page.locator("#workspace-map")).toBeVisible(); }); test("layout presets arrange transient windows and keep the map visible", async ({ page }) => { await prepareMainFrame(page); await page.goto("/", { waitUntil: "domcontentloaded" }); const testButton = page.getByRole("button", { name: "测试打开 Agent 多图表窗口" }).first(); await testButton.click(); await testButton.click(); await testButton.click(); await applyTaskViewLayout(page, "主次"); const workspace = page.locator("#main-workspace"); await expect(workspace).toHaveAttribute("data-layout-mode", "primary"); await expect(page.locator("#workspace-map")).toBeVisible(); await expect(page.locator("section[aria-label='低压事件调度处置流程']")).toBeVisible(); await expect(page.locator("section[aria-label='北辰分区压力异常诊断']")).toBeHidden(); await expect(page.locator("section[aria-label='低压事件调度处置流程']")).toHaveCSS("border-radius", "0px"); const workspaceBox = await workspace.boundingBox(); const primaryBox = await page.locator("section[aria-label='低压事件调度处置流程']").boundingBox(); expect(workspaceBox).not.toBeNull(); expect(primaryBox).not.toBeNull(); expect(primaryBox!.width).toBeGreaterThan(workspaceBox!.width * 0.6); await testButton.click(); await expect(page.locator("section[aria-label='北辰分区压力异常诊断']").last()).toBeVisible(); const newPrimaryBox = await page.locator("section[aria-label='北辰分区压力异常诊断']").last().boundingBox(); expect(newPrimaryBox).not.toBeNull(); expect(newPrimaryBox!.width).toBeGreaterThan(workspaceBox!.width * 0.6); }); test("dragging a small window onto the primary window swaps their complete slots", async ({ page }) => { await prepareMainFrame(page); await page.goto("/", { waitUntil: "domcontentloaded" }); await page.getByRole("button", { name: "测试打开 Agent 多图表窗口" }).first().click(); await applyTaskViewLayout(page, "主次"); const mapWindow = page.locator("#workspace-map"); const analysisWindow = page.locator("section[aria-label='北辰分区压力异常诊断']"); const mapBefore = await mapWindow.boundingBox(); const analysisBefore = await analysisWindow.boundingBox(); expect(mapBefore).not.toBeNull(); expect(analysisBefore).not.toBeNull(); expect(mapBefore!.width).toBeLessThan(analysisBefore!.width); await page.mouse.move(mapBefore!.x + 72, mapBefore!.y + 22); await page.keyboard.down("Alt"); await page.mouse.down(); await page.mouse.move( analysisBefore!.x + analysisBefore!.width / 2, analysisBefore!.y + analysisBefore!.height / 2, { steps: 10 } ); await expect(page.getByText("释放以交换")).toBeVisible(); await page.mouse.up(); await page.keyboard.up("Alt"); const mapAfter = await mapWindow.boundingBox(); const analysisAfter = await analysisWindow.boundingBox(); expect(mapAfter).not.toBeNull(); expect(analysisAfter).not.toBeNull(); expect(mapAfter!.width).toBeGreaterThan(analysisAfter!.width); expect(Math.abs(mapAfter!.x - analysisBefore!.x)).toBeLessThanOrEqual(2); expect(Math.abs(analysisAfter!.x - mapBefore!.x)).toBeLessThanOrEqual(2); await expect(page.getByText("供水管网地图与北辰分区压力异常诊断已交换位置")).toBeAttached(); }); test("dropping on blank workspace exits auto layout and Escape cancels a drag", async ({ page }) => { await prepareMainFrame(page); await page.goto("/", { waitUntil: "domcontentloaded" }); await page.getByRole("button", { name: "测试打开 Agent 多图表窗口" }).first().click(); await applyTaskViewLayout(page, "双栏"); const workspace = page.locator("#main-workspace"); const analysisWindow = page.locator("section[aria-label='北辰分区压力异常诊断']"); const before = await analysisWindow.boundingBox(); const workspaceBox = await workspace.boundingBox(); expect(before).not.toBeNull(); expect(workspaceBox).not.toBeNull(); await page.mouse.move(before!.x + 80, before!.y + 22); await page.keyboard.down("Alt"); await page.mouse.down(); await page.mouse.move(workspaceBox!.x + 4, workspaceBox!.y + 4, { steps: 8 }); await page.keyboard.press("Escape"); await page.keyboard.up("Alt"); await expect(workspace).toHaveAttribute("data-layout-mode", "split"); const afterCancel = await analysisWindow.boundingBox(); expect(Math.abs(afterCancel!.x - before!.x)).toBeLessThanOrEqual(2); await page.mouse.move(before!.x + 80, before!.y + 22); await page.keyboard.down("Alt"); await page.mouse.down(); await page.mouse.move(workspaceBox!.x + 4, workspaceBox!.y + 4, { steps: 8 }); await page.mouse.up(); await page.keyboard.up("Alt"); await expect(workspace).toHaveAttribute("data-layout-mode", "free"); await expect(page.getByText("北辰分区压力异常诊断已转为自由排列")).toBeAttached(); }); async function openWindowOperationMenu(page: Page, title: string) { const window = page.locator(`section[aria-label='${title}']`); await page.getByRole("button", { name: `切换到${title}` }).click(); await window.hover(); await page.getByRole("button", { name: `打开${title}窗口操作` }).click(); } async function applyTaskViewLayout(page: Page, layoutName: string) { await page.getByRole("button", { name: "任务视图" }).click(); await page.getByRole("button", { name: new RegExp(`^${layoutName}:`) }).click(); } async function prepareMainFrame(page: Page) { await mockAgentApi(page); await page.route("**/runtime-config.js", async (route) => { await route.fulfill({ contentType: "application/javascript", body: `globalThis.__TJWATER_CONFIG__ = { TJWATER_AUTH_MODE: "disabled", TJWATER_MAPBOX_ACCESS_TOKEN: "", TJWATER_MAP_URL: "https://workspace-map.invalid/geoserver", TJWATER_GEOSERVER_WORKSPACE: "tjwater", TJWATER_AGENT_API_BASE_URL: "http://127.0.0.1:8787", TJWATER_ENABLE_DEV_PANEL: "true", TJWATER_ENABLE_MSW: "false" };` }); }); await page.route("https://workspace-map.invalid/**", async (route) => { await route.fulfill({ status: 204 }); }); }