import { expect, test, type Page } from "@playwright/test"; import type { GeoJSONSource } from "maplibre-gl"; import { investigationFixture, mockInvestigationPresentation, selectInvestigation } from "./support/mock-investigation-presentation"; const sourceCount = (page: Page, id: string) => page.evaluate(async (sourceId) => { const source = window.__waterNetworkMap?.getSource(sourceId) as GeoJSONSource | undefined; const data = await source?.getData(); return data && typeof data !== "string" && data.type === "FeatureCollection" ? data.features.length : 0; }, id); test("More clears controller and investigation overlays while keeping the investigation chart", async ({ page }) => { const task = investigationFixture(78, "清理地图覆盖层验证"); const mock = await mockInvestigationPresentation(page, [task]); await selectInvestigation(page, task.title); await page.waitForFunction(() => Boolean(window.__waterNetworkMap?.getLayer("scada-pressure-hit"))); const presentation = page.getByTestId("investigation-presentation-panel"); await expect(presentation.getByText("跟随所选调查", { exact: true })).toBeVisible(); await mock.emit(task, { action: "highlight_features", layer: "scada", feature_ids: ["P1"], effect: "pulse" }); await expect.poll(() => sourceCount(page, "investigation-presentation-highlights")).toBe(1); await mock.emit(task, { action: "set_overlay", overlay_id: "clear-test", title: "待清理范围", mode: "geometry", evidence_id: "synthetic", data: { type: "FeatureCollection", features: [{ type: "Feature", properties: {}, geometry: { type: "Point", coordinates: [121.48, 31.1] } }] } }); await expect(presentation.getByRole("region", { name: "调查覆盖层" })).toBeVisible(); await mock.emit(task, { action: "open_chart", chart_id: "retain-chart", evidence_refs: ["synthetic"], chart: { title: "保留的调查曲线", chart_type: "line", x_data: ["10:00", "10:15"], series: [{ name: "P1", data: [20, 21] }] } }); const chart = presentation.locator('[data-investigation-chart="retain-chart"]'); await expect(chart).toBeVisible(); await page.getByRole("button", { name: "切换地图 Dev Panel" }).click(); const dev = page.getByTestId("map-dev-panel"); await dev.getByRole("combobox", { name: "业务源" }).click(); await page.getByRole("option", { name: "SCADA", exact: true }).click(); await dev.getByLabel("要素 ID(可多个)").fill("P1"); await dev.getByRole("button", { name: "仅高亮", exact: true }).click(); await dev.locator("summary").filter({ hasText: "水流调试" }).click(); await dev.getByRole("button", { name: "开启水流", exact: true }).click(); await dev.locator("summary").filter({ hasText: "数值标注" }).click(); await dev.getByRole("button", { name: "应用标注", exact: true }).click(); await expect.poll(() => page.evaluate(() => window.__waterNetworkMap?.getFeatureState({ source: "scada", id: "P1" }).highlighted)).toBe(true); await dev.getByRole("button", { name: "关闭 Dev Panel" }).click(); await page.getByRole("button", { name: "更多:更多地图操作", exact: true }).click(); const more = page.getByRole("region", { name: "更多", exact: true }); await more.getByRole("button", { name: /清空所有高亮和覆盖层/ }).click(); await expect.poll(() => sourceCount(page, "investigation-presentation-highlights")).toBe(0); await expect.poll(() => sourceCount(page, "investigation-presentation-overlay")).toBe(0); await expect.poll(() => page.evaluate(() => ({ highlighted: window.__waterNetworkMap?.getFeatureState({ source: "scada", id: "P1" }).highlighted ?? false, flow: window.__waterNetworkMap?.getLayoutProperty("workbench-network-flow-forward", "visibility"), labels: window.__waterNetworkMap?.getLayoutProperty("workbench-value-label-pipes", "visibility") }))).toEqual({ highlighted: false, flow: "none", labels: "none" }); await expect(presentation.getByRole("region", { name: "调查覆盖层" })).toHaveCount(0); await expect(chart).toBeVisible(); await page.screenshot({ path: "/tmp/map-clear-overlays-desktop.png" }); // A later explicit command still works; clearing is a one-time display operation. await mock.emit(task, { action: "highlight_features", layer: "scada", feature_ids: ["P1"], effect: "steady" }); await expect.poll(() => sourceCount(page, "investigation-presentation-highlights")).toBe(1); }); test("mobile More clears drawing and measurement data and remains usable when already empty", async ({ page }) => { await page.setViewportSize({ width: 375, height: 812 }); await mockInvestigationPresentation(page, []); await page.goto("/", { waitUntil: "domcontentloaded" }); await page.waitForFunction(() => Boolean(window.__waterNetworkMap?.getLayer("scada-pressure-hit"))); await page.getByRole("button", { name: "测量:距离与范围测量", exact: true }).click(); await page.getByRole("region", { name: "测量", exact: true }).getByRole("button", { name: /开始测量/ }).click(); await page.locator("canvas.maplibregl-canvas").click({ position: { x: 100, y: 175 } }); await expect.poll(() => sourceCount(page, "workbench-measurement")).toBeGreaterThan(0); await page.getByRole("button", { name: "标注:管理地图标注", exact: true }).click(); await page.getByRole("region", { name: "标注", exact: true }).getByRole("button", { name: "点标注", exact: true }).click(); await page.locator("canvas.maplibregl-canvas").click({ position: { x: 100, y: 175 } }); await expect.poll(() => sourceCount(page, "workbench-drawing-features")).toBe(1); await page.getByRole("button", { name: "更多:更多地图操作", exact: true }).click(); const more = page.getByRole("region", { name: "更多", exact: true }); const clear = more.getByRole("button", { name: /清空所有高亮和覆盖层/ }); await expect(clear).toBeVisible(); await clear.click(); await expect.poll(() => sourceCount(page, "workbench-measurement")).toBe(0); await expect.poll(() => sourceCount(page, "workbench-drawing-features")).toBe(0); await clear.click(); await expect(clear).toBeEnabled(); const box = await more.boundingBox(); expect(box!.x).toBeGreaterThanOrEqual(0); expect(box!.x + box!.width).toBeLessThanOrEqual(375); await page.screenshot({ path: "/tmp/map-clear-overlays-mobile.png" }); });