import { expect, test, type Page } from "@playwright/test"; import { mockScadaApi } from "./support/mock-scada-api"; test("SCADA properties temporarily replace the task ticker", async ({ page }) => { await mockFeaturePanelRuntime(page); await page.goto("/", { waitUntil: "domcontentloaded" }); await page.waitForFunction(() => ( Boolean(window.__waterNetworkMap?.getLayer("scada-pressure-hit")) && (window.__waterNetworkMap?.querySourceFeatures("scada").length ?? 0) > 0 )); const taskTicker = page.locator(".agent-task-ticker"); await expect(taskTicker).toBeVisible(); await clickFirstScadaFeature(page); await expect(page.getByRole("button", { name: "关闭要素信息" })).toBeVisible(); await expect(page.getByRole("heading", { name: "SCADA SCADA-OVERLAP-1" })).toBeVisible(); await expect(page.getByText("压力监测", { exact: true })).toBeVisible(); await expect(taskTicker).toBeHidden(); await page.getByRole("button", { name: "关闭要素信息" }).click(); await expect(taskTicker).toBeVisible(); }); test("GIS inventory attributes stay folded until requested", async ({ page }) => { await mockFeaturePanelRuntime(page); await page.route( "https://tjwater-api.invalid/api/v1/elements/scada/SCADA-OVERLAP-1/gis-properties", (route) => route.fulfill({ contentType: "application/json", body: JSON.stringify({ element_type: "scada", element_id: "SCADA-OVERLAP-1", groups: [{ dataset_key: "fx_water_assets_20200423", dataset_title: "奉贤全网除头桥 GIS 数据导出", source_date: "2020-04-23", layer_key: "fx_20200423_flow_meters", layer_name: "流量仪", source_fid: 12, match_method: "geometry", match_distance_m: 0.2, attributes: { 设备类别: "LLY", 干管口径: 300 } }] }) }) ); await page.goto("/", { waitUntil: "domcontentloaded" }); await page.waitForFunction(() => ( Boolean(window.__waterNetworkMap?.getLayer("scada-pressure-hit")) && (window.__waterNetworkMap?.querySourceFeatures("scada").length ?? 0) > 0 )); await clickFirstScadaFeature(page); const featurePanel = page.getByRole("complementary", { name: "要素属性" }); const collapsedWidth = (await featurePanel.boundingBox())?.width ?? 0; await expect(page.getByText("1 份")).toBeVisible(); await expect(page.getByText("设备类别").first()).toBeHidden(); await page.getByText("GIS 台账属性").click(); await expect.poll(async () => (await featurePanel.boundingBox())?.width ?? 0) .toBeGreaterThan(collapsedWidth + 100); await expect(page.getByText("流量仪", { exact: true })).toBeVisible(); await expect(page.getByText("设备类别").first()).toBeHidden(); const datasetIndicator = page .getByText("流量仪", { exact: true }) .locator("xpath=ancestor::summary") .locator('[data-disclosure-indicator="accordion"]'); await expect.poll(() => datasetIndicator.evaluate((element) => getComputedStyle(element).transform)) .toBe("none"); await page.getByText("流量仪", { exact: true }).click(); await expect.poll(() => datasetIndicator.evaluate((element) => getComputedStyle(element).transform)) .toContain("-1"); await expect(page.getByText("设备类别").first()).toBeVisible(); await expect(page.getByText("口径", { exact: true })).toBeVisible(); await expect(page.getByText("300 mm")).toBeVisible(); await page.setViewportSize({ width: 375, height: 812 }); await expect.poll(async () => (await featurePanel.boundingBox())?.x ?? -1) .toBeGreaterThanOrEqual(12); await expect.poll(async () => { const box = await featurePanel.boundingBox(); return (box?.x ?? 0) + (box?.width ?? 0); }).toBeLessThanOrEqual(363); }); async function clickFirstScadaFeature(page: Page) { const fireMapClick = () => page.evaluate(() => { const map = window.__waterNetworkMap; const feature = map?.querySourceFeatures("scada")[0]; if (!map || feature?.geometry.type !== "Point") { throw new Error("No SCADA point is available for the feature popover test"); } const projectedPoint = map.project(feature.geometry.coordinates as [number, number]); map.fire("click", { point: projectedPoint, lngLat: map.unproject(projectedPoint), originalEvent: new MouseEvent("click") }); }); const closeButton = page.getByRole("button", { name: "关闭要素信息" }); await expect.poll(async () => { await fireMapClick(); return closeButton.isVisible(); }).toBe(true); } async function mockFeaturePanelRuntime(page: 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://feature-panel-map.invalid/geoserver", TJWATER_GEOSERVER_WORKSPACE: "tjwater_next", TJWATER_SERVER_API_BASE_URL: "https://tjwater-api.invalid", TJWATER_AGENT_URL: "http://127.0.0.1:8787", TJWATER_WORKBENCH_RUNTIME_MODE: "demo", TJWATER_ENABLE_DEV_PANEL: "false", TJWATER_ENABLE_MSW: "false" };` }); }); await page.route("https://feature-panel-map.invalid/**", async (route) => { await route.fulfill({ status: 204, body: "" }); }); await mockScadaApi(page, [{ device_id: "SCADA-OVERLAP-1", device_type: "pressure", node_id: "J-1", link_id: null, api_query_id: "overlap-query-1", measurement_unit: "MPa", transmission_mode: "realtime", transmission_frequency: "2s", reliability: 100, x: 1, y: 2, longitude: 121.5, latitude: 31 }]); }