feat(workbench): expand SCADA monitoring and investigation presentation
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
import { MAP_STYLE_TOKENS } from "../../src/features/workbench/map/map-colors";
|
||||
import { investigationFixture, mockInvestigationPresentation, selectInvestigation } from "./support/mock-investigation-presentation";
|
||||
|
||||
const chart = (index: number) => ({ action: "open_chart", chart_id: "pressure-history", evidence_refs: ["synthetic:pressure"], chart: {
|
||||
title: `压力对比 ${index}`, chart_type: "line", x_data: ["10:00", "10:15"], series: [{ name: "压力(m)", data: [30, 30 - index] }]
|
||||
} });
|
||||
const overlay = { action: "set_overlay", overlay_id: "warning-area", title: "合成影响示意", mode: "geometry", evidence_id: "synthetic:area", data: {
|
||||
type: "FeatureCollection", features: [{ type: "Feature", properties: {}, geometry: { type: "Polygon", coordinates: [[[121.48,31.1],[121.49,31.1],[121.49,31.11],[121.48,31.1]]] } }]
|
||||
} };
|
||||
|
||||
test("successful charts and warning geometry survive stream loss and failed reconnect", async ({ page }, testInfo) => {
|
||||
test.setTimeout(60_000);
|
||||
const task = investigationFixture(1, "断线保留展示核查");
|
||||
const other = investigationFixture(2, "切换后独立调查");
|
||||
const mock = await mockInvestigationPresentation(page, [task, other]);
|
||||
await selectInvestigation(page, task.title);
|
||||
const panel = page.getByLabel("调查实时展示", { exact: true });
|
||||
await expect(panel.getByText("实时跟随", { exact: true })).toBeVisible();
|
||||
await mock.emit(task, chart(1));
|
||||
await expect(panel.getByRole("group", { name: "压力对比 1", exact: true })).toBeVisible();
|
||||
await mock.emit(task, overlay);
|
||||
await expect(panel.getByRole("region", { name: "调查覆盖层" })).toContainText("合成影响示意");
|
||||
const geometry = () => page.evaluate(async () => {
|
||||
const source = window.__waterNetworkMap?.getSource("investigation-presentation-overlay") as { getData: () => Promise<unknown> } | undefined;
|
||||
return source?.getData();
|
||||
});
|
||||
const saved = await geometry();
|
||||
expect(await page.evaluate(() => window.__waterNetworkMap?.getPaintProperty("investigation-presentation-overlay-fill", "fill-color"))).toBe(MAP_STYLE_TOKENS.state.risk);
|
||||
let failCursor = true;
|
||||
await page.route(`**/operational-tasks/${task.task_id}/presentation-cursor`, (route) => failCursor ? route.abort("failed") : route.fallback());
|
||||
const connection = (available: boolean) => page.evaluate((available) => {
|
||||
(window as unknown as { setInvestigationTestConnection: (available: boolean) => void }).setInvestigationTestConnection(available);
|
||||
}, available);
|
||||
await connection(false);
|
||||
await expect(panel.getByText("连接中断", { exact: true })).toBeVisible();
|
||||
await expect(panel.getByRole("group", { name: "压力对比 1", exact: true })).toBeVisible();
|
||||
expect(await geometry()).toEqual(saved);
|
||||
await connection(true);
|
||||
await expect(panel.getByText("部分未完成", { exact: true })).toBeVisible();
|
||||
await expect(panel.getByRole("group", { name: "压力对比 1", exact: true })).toBeVisible();
|
||||
expect(await geometry()).toEqual(saved);
|
||||
await testInfo.attach("results-retained-offline", { body: await page.screenshot({ path: testInfo.outputPath("results-retained-offline.png") }), contentType: "image/png" });
|
||||
failCursor = false;
|
||||
await connection(false);
|
||||
await expect(panel.getByText("连接中断", { exact: true })).toBeVisible();
|
||||
await connection(true);
|
||||
await expect(panel.getByText("实时跟随", { exact: true })).toBeVisible();
|
||||
expect(await geometry()).toEqual(saved);
|
||||
await page.getByRole("region", { name: "工况任务", exact: true }).getByText(other.title, { exact: true }).first().click();
|
||||
await expect(panel.getByRole("group", { name: "压力对比 1", exact: true })).toHaveCount(0);
|
||||
await expect.poll(geometry).toEqual({ type: "FeatureCollection", features: [] });
|
||||
expect(mock.mutations).toEqual([]);
|
||||
});
|
||||
|
||||
test("history playback pauses, seeks and finishes on a frozen snapshot while current receives new results", async ({ page }, testInfo) => {
|
||||
test.setTimeout(60_000);
|
||||
const task = investigationFixture(1, "只读历史播放核查");
|
||||
const saved = [1, 2, 3].map((index) => ({ task_id: task.task_id, event_seq: index, run_id: task.active_run!.run_id,
|
||||
execution_generation: 1, occurred_at: task.created_at, command: chart(index) }));
|
||||
const mock = await mockInvestigationPresentation(page, [task], saved);
|
||||
await selectInvestigation(page, task.title);
|
||||
const panel = page.getByLabel("调查实时展示", { exact: true });
|
||||
await expect(panel.getByRole("group", { name: "压力对比 3", exact: true })).toBeVisible();
|
||||
await page.getByRole("dialog", { name: "压力对比 3", exact: true }).getByRole("button", { name: "关闭窗口", exact: true }).click();
|
||||
await panel.getByRole("button", { name: "播放历史", exact: true }).click();
|
||||
await panel.getByRole("button", { name: "暂停历史播放", exact: true }).click();
|
||||
await expect(panel.getByRole("group", { name: "压力对比 1", exact: true })).toBeVisible();
|
||||
await page.getByRole("dialog", { name: "压力对比 1", exact: true }).getByRole("button", { name: "关闭窗口", exact: true }).click();
|
||||
await panel.getByRole("combobox", { name: "历史播放速度" }).click();
|
||||
await page.getByRole("option", { name: "2×", exact: true }).click();
|
||||
await panel.getByRole("button", { name: "播放历史", exact: true }).click();
|
||||
await mock.emit(task, chart(4));
|
||||
await expect(panel.getByRole("group", { name: "压力对比 3", exact: true })).toBeVisible();
|
||||
await expect(panel.getByRole("button", { name: "播放历史", exact: true })).toBeVisible();
|
||||
await expect(panel.getByRole("group", { name: "压力对比 4", exact: true })).toHaveCount(0);
|
||||
await panel.getByRole("slider", { name: "历史播放进度" }).focus();
|
||||
await page.keyboard.press("Home");
|
||||
await expect(panel.getByRole("group", { name: "压力对比 1", exact: true })).toBeVisible();
|
||||
await testInfo.attach("history-playback-desktop", { body: await panel.screenshot({ path: testInfo.outputPath("history-playback-desktop.png") }), contentType: "image/png" });
|
||||
await page.setViewportSize({ width: 375, height: 720 });
|
||||
await expect(panel.getByRole("slider", { name: "历史播放进度" })).toBeVisible();
|
||||
expect(await panel.evaluate((node) => node.scrollWidth - node.clientWidth)).toBeLessThanOrEqual(1);
|
||||
await testInfo.attach("history-playback-narrow", { body: await panel.screenshot({ path: testInfo.outputPath("history-playback-narrow.png") }), contentType: "image/png" });
|
||||
await page.getByRole("dialog", { name: "压力对比 1", exact: true }).getByRole("button", { name: "关闭窗口", exact: true }).click();
|
||||
await panel.getByRole("button", { name: "回到当前", exact: true }).click();
|
||||
await expect(panel.getByRole("group", { name: "压力对比 4", exact: true })).toBeVisible();
|
||||
expect(mock.mutations).toEqual([]);
|
||||
});
|
||||
|
||||
test("restores a persisted chart when the stream disconnects during display confirmation", async ({ page }, testInfo) => {
|
||||
test.setTimeout(60_000);
|
||||
const task = investigationFixture(1, "图表确认阶段断线恢复");
|
||||
const mock = await mockInvestigationPresentation(page, [task]);
|
||||
await selectInvestigation(page, task.title);
|
||||
const panel = page.getByLabel("调查实时展示", { exact: true });
|
||||
await expect(panel.getByText("实时跟随", { exact: true })).toBeVisible();
|
||||
await mock.emit(task, chart(1));
|
||||
await expect(panel.getByRole("combobox", { name: "切换展示动作" })).toContainText("1. ");
|
||||
await page.evaluate(() => {
|
||||
const observer = new MutationObserver(() => {
|
||||
const plot = document.querySelector('[data-presentation-scope="investigation"] [data-investigation-chart="pressure-history"]');
|
||||
if (!plot?.textContent?.includes("压力对比 2")) return;
|
||||
observer.disconnect();
|
||||
Object.assign(window, { interruptedChartConfirmation: true });
|
||||
(window as unknown as { setInvestigationTestConnection: (available: boolean) => void }).setInvestigationTestConnection(false);
|
||||
});
|
||||
observer.observe(document.body, { childList: true, characterData: true, subtree: true });
|
||||
});
|
||||
await mock.emit(task, chart(2));
|
||||
await expect.poll(() => page.evaluate(() => (window as unknown as { interruptedChartConfirmation?: boolean }).interruptedChartConfirmation)).toBe(true);
|
||||
await expect(panel.getByText("连接中断", { exact: true })).toBeVisible();
|
||||
await expect(panel.getByRole("group", { name: "压力对比 1", exact: true })).toBeVisible();
|
||||
await page.evaluate(() => {
|
||||
(window as unknown as { setInvestigationTestConnection: (available: boolean) => void }).setInvestigationTestConnection(true);
|
||||
});
|
||||
await expect(panel.getByText("实时跟随", { exact: true })).toBeVisible();
|
||||
await expect(panel.getByRole("group", { name: "压力对比 2", exact: true })).toBeVisible();
|
||||
await expect(panel.getByRole("combobox", { name: "切换展示动作" })).toContainText("2 个动作");
|
||||
await testInfo.attach("chart-recovered-after-interrupted-confirmation", {
|
||||
body: await panel.screenshot({ path: testInfo.outputPath("chart-recovered-after-interrupted-confirmation.png") }), contentType: "image/png",
|
||||
});
|
||||
expect(mock.mutations).toEqual([]);
|
||||
});
|
||||
Reference in New Issue
Block a user