feat(workbench): refine dynamic task collaboration

This commit is contained in:
2026-09-24 16:36:12 +08:00
parent b64d2b78bb
commit 87cc7785da
25 changed files with 1216 additions and 470 deletions
+46 -11
View File
@@ -109,7 +109,9 @@ test.describe("外围工单测试", () => {
await expect(workOrderList).toContainText("待处理");
await expect(workOrderList).toContainText("处理中");
await expect(workOrderList).toContainText("已完成");
await expect(workOrderList.getByText("暂无活动记录;不根据工单状态推测处置过程。", { exact: true })).toHaveCount(3);
await expect(workOrderList.getByText("工单报告", { exact: true })).toHaveCount(3);
await expect(workOrderList.getByText("暂无现场反馈", { exact: true })).toHaveCount(3);
await expect(workOrderList.getByText("活动记录", { exact: true })).toHaveCount(0);
expect(requestedPaths).toEqual(expect.arrayContaining([
"/api/sample/v1/context",
"/api/sample/v1/work-orders"
@@ -240,6 +242,7 @@ test.describe("外围工单测试", () => {
const projectId = "324ff7ee-c2d4-5184-a84b-48fb14a2933e";
let workOrders: Record<string, unknown>[] = [];
const writes: Record<string, unknown>[] = [];
let deleteRequests = 0;
await page.route("**/runtime-config.js", (route) => route.fulfill({
contentType: "text/javascript",
body: `globalThis.__TJWATER_CONFIG__=${JSON.stringify({ TJWATER_AUTH_MODE: "disabled", TJWATER_SERVER_API_BASE_URL: "http://server.test", TJWATER_PERIPHERAL_SAMPLE_API_BASE_URL: "http://peripheral.test" })}`
@@ -269,7 +272,7 @@ test.describe("外围工单测试", () => {
workOrders = [next];
return route.fulfill({ json: workOrders[0] });
}
if (path.includes("/work-orders/") && request.method() === "DELETE") { workOrders = []; return route.fulfill({ json: { resource_type: "work_order", resource_id: path.split("/").at(-1), revision: 3, deleted: true } }); }
if (path.includes("/work-orders/") && request.method() === "DELETE") { deleteRequests += 1; workOrders = []; return route.fulfill({ json: { resource_type: "work_order", resource_id: path.split("/").at(-1), revision: 3, deleted: true } }); }
return route.fulfill({ status: 404, json: { code: "NOT_FOUND", message: "not found", effect: "none", request_id: null } });
});
@@ -299,6 +302,12 @@ test.describe("外围工单测试", () => {
await panel.getByRole("button", { name: "编辑工单 合成预约维修" }).click();
editor = panel.getByRole("region", { name: "编辑工单 合成预约维修" });
await expect(panel.getByLabel("工单列表").getByRole("region", { name: "编辑工单 合成预约维修" })).toBeVisible();
await expect(editor.locator("xpath=ancestor::article")).toContainText("合成预约维修");
await expect(editor.getByRole("textbox", { name: "标题" })).toBeFocused();
await expect(panel.getByRole("button", { name: "编辑工单 合成预约维修" })).toHaveCount(0);
await expect(panel.getByRole("button", { name: "删除工单 合成预约维修" })).toHaveCount(0);
expect(await editor.getByRole("textbox", { name: "标题" }).evaluate((input) => getComputedStyle(input).outlineWidth)).toBe("0px");
await editor.getByRole("textbox", { name: "标题" }).fill("合成预约维修(已对齐)");
await editor.getByRole("textbox", { name: "负责人", exact: true }).fill("测试班组乙");
await editor.getByRole("textbox", { name: "位置", exact: true }).fill("联调测试点东侧");
@@ -323,13 +332,14 @@ test.describe("外围工单测试", () => {
await expect(panel.getByText("外部系统更新后的预约维修", { exact: true })).toBeVisible();
await panel.getByRole("button", { name: "编辑工单 外部系统更新后的预约维修" }).click();
const refreshedEditor = panel.getByRole("region", { name: "编辑工单 外部系统更新后的预约维修" });
await expect(refreshedEditor.locator("xpath=ancestor::article")).toContainText("外部系统更新后的预约维修");
await expect(refreshedEditor.getByRole("textbox", { name: "负责人", exact: true })).toHaveValue("测试班组乙");
await expect(refreshedEditor.getByRole("textbox", { name: "位置", exact: true })).toHaveValue("联调测试点东侧");
await expect(refreshedEditor.getByRole("textbox", { name: "回执要求(每行一项)" })).toHaveValue("回传现场处理结果\n上传照片");
for (const width of [1280, 375, 320]) {
await page.setViewportSize({ width, height: 780 });
await refreshedEditor.scrollIntoViewIfNeeded();
await refreshedEditor.locator("xpath=ancestor::article").evaluate((element) => element.scrollIntoView({ block: "start" }));
expect(await page.evaluate(() => document.documentElement.scrollWidth)).toBeLessThanOrEqual(width);
await testInfo.attach(`peripheral-work-order-process-${width}`, {
body: await page.screenshot({ path: `/tmp/tjwater-operational-ui-review/peripheral-work-order-edit-${width}.png` }),
@@ -338,7 +348,34 @@ test.describe("外围工单测试", () => {
}
await page.setViewportSize({ width: 1280, height: 780 });
await refreshedEditor.getByRole("button", { name: "关闭编辑表单" }).click();
await expect(panel.getByRole("button", { name: "编辑工单 外部系统更新后的预约维修" })).toBeFocused();
await expect(panel.getByRole("button", { name: "删除工单 外部系统更新后的预约维修" })).toBeVisible();
await panel.getByRole("button", { name: "删除工单 外部系统更新后的预约维修" }).click();
const deletePrompt = panel.getByRole("group", { name: "确认删除工单 外部系统更新后的预约维修" });
await expect(deletePrompt).toBeVisible();
await expect(deletePrompt).toContainText("对应的工况任务将在后台同步后移出任务列表");
expect(deleteRequests).toBe(0);
await deletePrompt.getByRole("button", { name: "取消" }).click();
await expect(deletePrompt).toHaveCount(0);
expect(deleteRequests).toBe(0);
await panel.getByRole("button", { name: "删除工单 外部系统更新后的预约维修" }).click();
await page.keyboard.press("Escape");
await expect(deletePrompt).toHaveCount(0);
expect(deleteRequests).toBe(0);
await panel.getByRole("button", { name: "删除工单 外部系统更新后的预约维修" }).click();
for (const width of [1280, 375, 320]) {
await page.setViewportSize({ width, height: 780 });
await deletePrompt.scrollIntoViewIfNeeded();
expect(await page.evaluate(() => document.documentElement.scrollWidth)).toBeLessThanOrEqual(width);
await testInfo.attach(`peripheral-work-order-delete-prompt-${width}`, {
body: await page.screenshot(),
contentType: "image/png"
});
}
await deletePrompt.getByRole("button", { name: "确认删除" }).click();
expect(deleteRequests).toBe(1);
await expect(panel.getByText("外部系统更新后的预约维修", { exact: true })).toBeHidden();
await page.route("http://server.test/api/v1/operational-tasks", (route) =>
@@ -526,8 +563,8 @@ test.describe("外围工单测试", () => {
await expect(conditionPanel.getByText("调查处理流程", { exact: true })).toBeVisible();
await expect(conditionPanel.getByText(/已完成 5 项 · 执行中 3 项 · 待人工或资料 3 项/)).toBeVisible();
await expect(conditionPanel.locator('[data-execution-node]')).toHaveCount(13);
await expect(conditionPanel.getByLabel("并行分枝 4 项")).toBeVisible();
await expect(conditionPanel.getByLabel("并行分枝 2 项")).toBeVisible();
await expect(conditionPanel.getByText(/历史流程按原始依赖展示/)).toBeVisible();
await expect(conditionPanel.getByText(/并行处理/)).toHaveCount(0);
await expect(conditionPanel.getByRole("button", { name: "完整工程图" })).toHaveCount(0);
await expect(conditionPanel.getByText("节点与执行记录", { exact: true })).toHaveCount(0);
await expect(conditionPanel.getByLabel("计划版本", { exact: true })).toHaveCount(0);
@@ -549,7 +586,7 @@ test.describe("外围工单测试", () => {
body: await conditionPanel.screenshot({ path: testInfo.outputPath("execution-plan-desktop.png") }),
contentType: "image/png"
});
await conditionPanel.getByLabel("并行分枝 2 项").scrollIntoViewIfNeeded();
await conditionPanel.locator('[data-execution-node="conclusion"]').scrollIntoViewIfNeeded();
await testInfo.attach("water-quality-condition-task-second-fork-1280", {
body: await conditionPanel.screenshot({ path: testInfo.outputPath("execution-plan-second-fork-desktop.png") }),
contentType: "image/png"
@@ -572,8 +609,7 @@ test.describe("外围工单测试", () => {
await expect(responsiveWorkflowStep).toBeVisible();
await responsiveConditionPanel.getByText("调查处理流程", { exact: true }).scrollIntoViewIfNeeded();
await expect(responsiveConditionPanel.locator('[data-execution-node]')).toHaveCount(13);
await expect(responsiveConditionPanel.getByLabel("并行分枝 4 项")).toBeVisible();
await expect(responsiveConditionPanel.getByLabel("并行分枝 2 项")).toBeVisible();
await expect(responsiveConditionPanel.getByText(/历史流程按原始依赖展示/)).toBeVisible();
await expect(responsiveConditionPanel.getByRole("button", { name: "放大流程图" })).toHaveCount(0);
await page.waitForTimeout(350);
expect(await page.evaluate(() => document.documentElement.scrollWidth)).toBeLessThanOrEqual(width);
@@ -581,7 +617,7 @@ test.describe("外围工单测试", () => {
body: await page.screenshot({ path: testInfo.outputPath(`execution-plan-${width}.png`) }),
contentType: "image/png"
});
await responsiveConditionPanel.getByLabel("并行分枝 2 项").scrollIntoViewIfNeeded();
await responsiveConditionPanel.locator('[data-execution-node="conclusion"]').scrollIntoViewIfNeeded();
await page.evaluate(() => document.fonts.ready);
await testInfo.attach(`water-quality-condition-task-second-fork-${width}`, {
body: await page.screenshot({ path: testInfo.outputPath(`execution-plan-second-fork-${width}.png`) }),
@@ -618,8 +654,7 @@ test.describe("外围工单测试", () => {
await recovered.getByRole("button", { name: /调查任务/ }).click();
const taskRow = recovered.getByRole("button", { name: /水质投诉调查/ }).first();
await taskRow.click();
await expect(recovered.getByLabel("并行分枝 4 项")).toBeVisible();
await expect(recovered.getByLabel("并行分枝 2 项")).toBeVisible();
await expect(recovered.getByText(/历史流程按原始依赖展示/)).toBeVisible();
expect(agentRequests.filter((body) => "trigger_context" in body)).toHaveLength(0);
});