test: migrate workbench fixtures to persistent event streams
Static fulfilled SSE bodies closed immediately and made ordinary UI cases reconnect. Serve persistent fixture streams, retain outage and cursor recovery coverage, and update legacy approval and investigation assertions for current disclosures and SVG diagrams. Validation: 12 related browser scenarios, 877 unit tests, type checking, scoped ESLint, and diff checks. Unrelated SCADA replay changes remain outside this commit.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
import { expect, test, type Locator } from "@playwright/test";
|
||||
import { mockWorkbenchEventStream } from "./support/mock-workbench-event-stream";
|
||||
import type {
|
||||
OperationalTask,
|
||||
OperationalTaskAction,
|
||||
@@ -207,9 +208,7 @@ test("审批动作展示中文参数和证据,viewer 不可审批,冲突后
|
||||
generated_at: "2026-09-23T08:30:00Z"
|
||||
} });
|
||||
});
|
||||
await page.route("http://server.test/api/v1/workbench/events**", (route) =>
|
||||
route.fulfill({ contentType: "text/event-stream", body: ": test keepalive\n\n" })
|
||||
);
|
||||
const eventStream = await mockWorkbenchEventStream(page);
|
||||
|
||||
await page.route("http://server.test/api/v1/operational-task-notifications**", (route) =>
|
||||
route.fulfill({ json: { items: [], limit: 100, offset: 0, next_offset: null } })
|
||||
@@ -254,6 +253,10 @@ test("审批动作展示中文参数和证据,viewer 不可审批,冲突后
|
||||
return route.fulfill({ status: 404, json: {} });
|
||||
});
|
||||
|
||||
const openAction = async (panel: Locator) => {
|
||||
const disclosure = panel.locator(`[data-review-action="${actionId}"]`);
|
||||
if (await disclosure.getAttribute("open") === null) await disclosure.locator("summary").first().click();
|
||||
};
|
||||
const openTask = async () => {
|
||||
await page.getByRole("button", { name: "工况任务", exact: true }).click();
|
||||
const conditionPanel = page.getByRole("region", { name: "工况任务", exact: true });
|
||||
@@ -261,6 +264,7 @@ test("审批动作展示中文参数和证据,viewer 不可审批,冲突后
|
||||
if (await expandButton.isVisible()) await expandButton.click();
|
||||
await conditionPanel.getByRole("button", { name: /调查任务/ }).click();
|
||||
await conditionPanel.getByText("阀门调节审批", { exact: true }).first().click();
|
||||
await openAction(conditionPanel);
|
||||
return conditionPanel;
|
||||
};
|
||||
|
||||
@@ -273,17 +277,8 @@ test("审批动作展示中文参数和证据,viewer 不可审批,冲突后
|
||||
await expect(page.getByText("当前无待处理事项", { exact: true }).first()).toBeVisible();
|
||||
await expect(page.getByText("业务告警来源:未配置", { exact: true })).toBeVisible();
|
||||
await page.keyboard.press("Escape");
|
||||
const reconnectNotice = page.locator("[data-sonner-toast]").filter({
|
||||
hasText: "业务同步正在重连"
|
||||
});
|
||||
await expect(reconnectNotice).toBeVisible();
|
||||
await expect(reconnectNotice).toContainText("当前数据可能陈旧,连接恢复后将自动更新。");
|
||||
await expect(page.getByText("正在重连,业务数据可能陈旧", { exact: true })).toHaveCount(0);
|
||||
await page.evaluate(() => document.fonts.ready);
|
||||
await testInfo.attach("workbench-reconnect-notice", {
|
||||
body: await page.screenshot({ path: testInfo.outputPath("workbench-reconnect-notice.png") }),
|
||||
contentType: "image/png"
|
||||
});
|
||||
await expect.poll(() => eventStream.cursors.length).toBe(1);
|
||||
await expect(page.getByText("业务同步正在重连", { exact: true })).toHaveCount(0);
|
||||
let conditionPanel = await openTask();
|
||||
await expect(conditionPanel.getByRole("navigation", { name: "工况任务分类" })).toBeVisible();
|
||||
await expect(conditionPanel.getByRole("button", { name: /定时任务/ })).toContainText("模拟数据");
|
||||
@@ -299,6 +294,7 @@ test("审批动作展示中文参数和证据,viewer 不可审批,冲突后
|
||||
await refreshingButton.evaluate((button: HTMLButtonElement) => button.click());
|
||||
expect(snapshotRequests).toBe(2);
|
||||
await expect(conditionRefreshButton).toBeEnabled({ timeout: 4_000 });
|
||||
expect(eventStream.cursors).toEqual(["0"]);
|
||||
expect(Date.now() - refreshStartedAt).toBeGreaterThanOrEqual(2_900);
|
||||
await expect(conditionPanel.getByRole("button", { name: "配置定时流程" })).toHaveCount(0);
|
||||
await expect(conditionPanel.getByRole("button", { name: "创建定时流程" })).toHaveCount(0);
|
||||
@@ -317,13 +313,15 @@ test("审批动作展示中文参数和证据,viewer 不可审批,冲突后
|
||||
await expect(appointmentDetail.getByText("联调测试点东侧", { exact: true })).toBeVisible();
|
||||
await expect(conditionPanel.getByText("编辑后的预约维修说明", { exact: true })).toBeVisible();
|
||||
await expect(conditionPanel.getByText("预约 09/23 18:00 由北片区维修组处理", { exact: true })).toHaveCount(0);
|
||||
await page.waitForTimeout(3_500);
|
||||
await page.addStyleTag({ content: "[data-sonner-toaster] { display: none !important; }" });
|
||||
await page.evaluate(() => document.fonts.ready);
|
||||
await page.screenshot({ path: "/tmp/tjwater-operational-ui-review/task-categories-desktop.png" });
|
||||
await testInfo.attach("task-categories-desktop", {
|
||||
body: await conditionPanel.screenshot(), contentType: "image/png"
|
||||
});
|
||||
await conditionPanel.getByRole("button", { name: /调查任务/ }).click();
|
||||
expect(scheduleRequests).toBe(0);
|
||||
await expect(conditionPanel.getByText("上一轮报告,当前任务待人工", { exact: true })).toBeVisible();
|
||||
await expect(conditionPanel.getByRole("region", { name: "任务报告", exact: true }).getByText("上一轮报告", { exact: true })).toBeVisible();
|
||||
await expect(conditionPanel.getByText("待人工审核", { exact: true })).toBeVisible();
|
||||
await openAction(conditionPanel);
|
||||
await expect(conditionPanel.getByText(/第\s*[12]\s*代|generation/i)).toHaveCount(0);
|
||||
const actionCard = conditionPanel.locator(`[data-action-id="${actionId}"]`);
|
||||
await expect(actionCard.getByText("命令类型", { exact: true })).toBeVisible();
|
||||
@@ -372,7 +370,9 @@ test("审批动作展示中文参数和证据,viewer 不可审批,冲突后
|
||||
const reconcileButton = conditionPanel.getByRole("button", { name: "核对执行回执" });
|
||||
await expect(reconcileButton).toBeVisible();
|
||||
await reconcileButton.click();
|
||||
const receipt = conditionPanel.getByRole("region", { name: "执行回执" });
|
||||
const progress = conditionPanel.getByRole("region", { name: "处置进展", exact: true });
|
||||
await progress.locator("summary").filter({ hasText: "设备命令 · 执行成功" }).click();
|
||||
const receipt = progress.getByRole("region", { name: "执行回执" });
|
||||
await expect(receipt).toContainText("SCADA-RECEIPT-20260923-01");
|
||||
await expect(receipt).toContainText("已完成");
|
||||
await expect(receipt).toContainText("V-102 开度已调整至 35%");
|
||||
@@ -420,9 +420,7 @@ test("后端没有调查任务时显示空态,分类标签按压不缩放", as
|
||||
tasks: [], notifications: [], generated_at: "2026-09-23T08:30:00Z"
|
||||
} })
|
||||
);
|
||||
await page.route("http://server.test/api/v1/workbench/events**", (route) =>
|
||||
route.fulfill({ contentType: "text/event-stream", body: ": test keepalive\n\n" })
|
||||
);
|
||||
await mockWorkbenchEventStream(page);
|
||||
await page.route("http://map.test/**", (route) => route.fulfill({ status: 204 }));
|
||||
|
||||
await page.goto("/");
|
||||
|
||||
Reference in New Issue
Block a user