Files
next-tjwater-frontend/tests/browser/investigation-retention-playback.e2e.ts
T

125 lines
9.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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([]);
});