feat(workbench): expand SCADA monitoring and investigation presentation
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
import { investigationFixture, mockInvestigationPresentation } from "./support/mock-investigation-presentation";
|
||||
import type { OperationalTaskNotification } from "../../src/features/workbench/api/operational-task-client";
|
||||
|
||||
for (const width of [1280, 375, 320]) {
|
||||
test(`待办和告警可独立移除且刷新后保持 ${width}`, async ({ page }, testInfo) => {
|
||||
await page.setViewportSize({ width, height: 900 });
|
||||
const task = investigationFixture(1, "通知移除测试调查");
|
||||
const notification: OperationalTaskNotification = {
|
||||
notification_id: "96000000-0000-4000-8000-000000000011", task_id: task.task_id,
|
||||
kind: "human_input_required", title: "待补充现场流量记录", description: "请核对现场记录后补充资料。",
|
||||
required_permission: null, lifecycle_status: "active", subject_type: "question", subject_id: null,
|
||||
resolved_at: null, resolution_reason: null, status: "unread", version: 1,
|
||||
created_at: task.created_at, read_at: null, read_by: null
|
||||
};
|
||||
await mockInvestigationPresentation(page, [task], [], [notification]);
|
||||
const alert = { id: "pressure-alert-1", source: { kind: "scada_replay", replay_id: "replay-1", rule_id: "pressure-low", batch_sequence: 1 }, condition_id: `operational-task:${task.task_id}`,
|
||||
title: "SCADA 压力持续偏低需要核查现场情况", description: "压力监测点连续出现异常读数,请查看关联调查。",
|
||||
occurred_at: task.created_at, severity: "warning" };
|
||||
let cursor = 10;
|
||||
await page.route("https://tjwater-api.invalid/api/v1/workbench/sync-snapshot", (route) => route.fulfill({ json: {
|
||||
schema: "workbench-sync-snapshot@1", event_cursor: cursor, generated_at: task.created_at,
|
||||
runtime: { availability: "not_configured", source: "none", scenario_availability: "not_configured",
|
||||
artifact_availability: "not_configured", schedule_availability: "not_configured", work_order_availability: "not_configured",
|
||||
alert_availability: "ready", generated_at: task.created_at, conditions: [], alerts: [alert], scenarios: [], latest_analysis: null, work_orders: [] },
|
||||
tasks: [Object.fromEntries(Object.entries(task).filter(([key]) =>
|
||||
!["latest_plan", "latest_report", "latest_progress", "evidence", "actions", "access_requests", "work_order_snapshot", "permissions", "questions"].includes(key)))], notifications: [notification]
|
||||
} }));
|
||||
const writes: string[] = [];
|
||||
page.on("request", (request) => {
|
||||
if (request.url().startsWith("https://tjwater-api.invalid/") && ["POST", "PUT", "PATCH", "DELETE"].includes(request.method())) writes.push(request.url());
|
||||
});
|
||||
await page.goto("/", { waitUntil: "domcontentloaded" });
|
||||
const trigger = page.getByRole("button", { name: /查看待办与告警/ });
|
||||
await expect(trigger).toHaveAccessibleName("查看待办与告警,当前 2 条待处理事项");
|
||||
await trigger.click();
|
||||
const menu = page.getByRole("menu");
|
||||
await expect(menu).toBeVisible();
|
||||
const removeTask = page.getByRole("menuitem", { name: `移除通知:${notification.title}` });
|
||||
await expect(removeTask).toBeVisible();
|
||||
const openTask = page.getByRole("menuitem", { name: `打开通知:${notification.title}` });
|
||||
const actions = await openTask.evaluate((element) => {
|
||||
const open = element.getBoundingClientRect();
|
||||
const remove = element.nextElementSibling!.getBoundingClientRect();
|
||||
return { topDifference: Math.abs(open.top - remove.top), gap: remove.left - open.right };
|
||||
});
|
||||
expect(actions.topDifference).toBeLessThan(1);
|
||||
expect(actions.gap).toBeGreaterThanOrEqual(0);
|
||||
const box = await menu.boundingBox();
|
||||
expect(box!.x).toBeGreaterThanOrEqual(0);
|
||||
expect(box!.x + box!.width).toBeLessThanOrEqual(width);
|
||||
await testInfo.attach(`alert-menu-${width}`, { body: await page.screenshot({ path: testInfo.outputPath("alert-menu.png"), style: "[data-sonner-toaster] { visibility: hidden !important; }" }), contentType: "image/png" });
|
||||
await removeTask.click();
|
||||
await expect(menu).toBeVisible();
|
||||
await expect(trigger).toHaveAccessibleName("查看待办与告警,当前 1 条待处理事项");
|
||||
await expect(page.getByRole("region", { name: "工况任务", exact: true })).toHaveCount(0);
|
||||
// A repeated business snapshot must not restore the removed notification.
|
||||
await page.evaluate((event) => {
|
||||
(window as unknown as { emitInvestigationTestEvent: (value: unknown) => void }).emitInvestigationTestEvent(event);
|
||||
}, { schema: "workbench-event@1", event_seq: ++cursor, event_id: "96000000-0000-4000-8000-000000000012",
|
||||
project_id: task.project_id, topic: "workbench.alert.changed", aggregate_type: "task_alert",
|
||||
aggregate_id: alert.id, aggregate_revision: 2, occurred_at: task.created_at, metadata: {} });
|
||||
await page.getByRole("menuitem", { name: `移除通知:${alert.title}` }).focus();
|
||||
await page.keyboard.press("Enter");
|
||||
await expect(menu).toContainText("当前无待处理事项");
|
||||
await expect(trigger).toHaveAccessibleName("查看待办与告警,当前 0 条待处理事项");
|
||||
await page.keyboard.press("Escape");
|
||||
await expect(trigger).toBeFocused();
|
||||
await page.reload({ waitUntil: "domcontentloaded" });
|
||||
await expect(trigger).toHaveAccessibleName("查看待办与告警,当前 0 条待处理事项");
|
||||
await trigger.click();
|
||||
await expect(page.getByRole("menu")).toContainText("当前无待处理事项");
|
||||
expect(writes).toEqual([]);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user