import { expect, test } from "@playwright/test"; import { mockAgentApi } from "./support/mock-agent-api"; import { mockWorkbenchContext } from "./support/mock-workbench-context"; import { createAnalysisRuntimeSnapshot, MOCK_SPATIAL_ANALYSIS } from "./support/mock-analysis-runtime"; test("nested Resizable groups keep chat, map and analysis independent across breakpoints", async ({ page }) => { await page.setViewportSize({ width: 1920, height: 1000 }); await page.emulateMedia({ reducedMotion: "reduce" }); await mockAgentApi(page); await mockWorkbenchContext(page, createAnalysisRuntimeSnapshot(MOCK_SPATIAL_ANALYSIS)); const errors: string[] = []; page.on("pageerror", (error) => errors.push(error.message)); await page.goto("/", { waitUntil: "domcontentloaded" }); await page.getByRole("button", { name: /展开 Agent 助手面板/ }).click(); const agent = page.getByRole("complementary", { name: "Agent 命令面板" }); await agent.locator("textarea").fill("保留分栏调整中的分析问题"); await page.getByRole("button", { name: "打开最新后端分析成果" }).click(); const outer = page.getByRole("separator", { name: "调整 Agent 面板宽度" }); const inner = page.getByRole("separator", { name: "调整地图与报告宽度" }); const map = page.locator("#workspace-map"); await expect(inner).toBeVisible(); await page.waitForFunction(() => Boolean(window.__waterNetworkMap)); await page.evaluate(() => Object.assign(window, { originalResizableMap: window.__waterNetworkMap })); const outerBox = (await outer.boundingBox())!; await page.mouse.move(outerBox.x + outerBox.width / 2, outerBox.y + outerBox.height / 2); await page.mouse.down(); await page.mouse.move(620, outerBox.y + outerBox.height / 2, { steps: 6 }); await page.mouse.up(); await expect.poll(async () => Math.round((await agent.boundingBox())!.width)).toBe(620); const mapWidth = (await map.boundingBox())!.width; const innerBox = (await inner.boundingBox())!; await page.mouse.move(innerBox.x + innerBox.width / 2, innerBox.y + innerBox.height / 2); await page.mouse.down(); await page.mouse.move(innerBox.x + 40, innerBox.y + innerBox.height / 2, { steps: 6 }); await page.mouse.up(); await expect.poll(async () => (await map.boundingBox())!.width).toBeGreaterThan(mapWidth + 30); await expect.poll(async () => Math.round((await agent.boundingBox())!.width)).toBe(620); await inner.focus(); await page.keyboard.press("Home"); await expect.poll(async () => Math.round((await map.boundingBox())!.width)).toBe(600); await page.keyboard.press("End"); await expect.poll(async () => Math.round((await page.locator("#artifact-workspace").boundingBox())!.width)).toBe(600); await page.evaluate(() => document.fonts.ready); await page.screenshot({ path: "test-results/resizable-three-columns.png" }); await page.setViewportSize({ width: 1280, height: 900 }); await expect(inner).toBeHidden(); await expect(page.locator("#main-workspace")).toHaveAttribute("data-layout-mode", "focus"); await page.setViewportSize({ width: 1920, height: 1000 }); await expect(inner).toBeVisible(); await expect.poll(async () => Math.round((await agent.boundingBox())!.width)).toBe(620); await expect(agent.locator("textarea")).toHaveValue("保留分栏调整中的分析问题"); expect(await page.evaluate(() => window.__waterNetworkMap === (window as unknown as { originalResizableMap: unknown }).originalResizableMap)).toBe(true); expect(await page.evaluate(() => document.documentElement.scrollWidth)).toBe(1920); expect(errors).toEqual([]); });