feat(workbench): integrate runtime data and map tooling
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import { expect, test, type Locator } from "@playwright/test";
|
||||
import { expect, test, type Locator, type Page } from "@playwright/test";
|
||||
import { mockHierarchicalWorkOrder } from "./support/mock-hierarchical-work-order";
|
||||
|
||||
test("scheduled conditions keep acrylic blur outside transformed ancestors", async ({ page }) => {
|
||||
await page.goto("/", { waitUntil: "domcontentloaded" });
|
||||
await page.getByRole("button", { name: "工况任务", exact: true }).click();
|
||||
await openConditionFeed(page);
|
||||
|
||||
const panel = page.getByRole("region", { name: "工况任务", exact: true });
|
||||
await expect(panel).toBeVisible();
|
||||
@@ -75,14 +76,12 @@ test("scheduled conditions keep acrylic blur outside transformed ancestors", asy
|
||||
test("narrow desktop keeps Agent and expanded conditions from overlapping", async ({ page }) => {
|
||||
await page.setViewportSize({ width: 1024, height: 768 });
|
||||
await page.goto("/", { waitUntil: "domcontentloaded" });
|
||||
await page.getByRole("button", { name: "工况任务", exact: true }).click();
|
||||
await page.getByRole("button", { name: /展开 Agent 助手面板/ }).click();
|
||||
await openConditionFeed(page);
|
||||
|
||||
const panel = page.getByRole("region", { name: "工况任务", exact: true });
|
||||
const agentPanel = page.locator('aside[aria-label="Agent 命令面板"]');
|
||||
const resizeHandle = page.getByRole("separator", { name: "调整 Agent 面板宽度" });
|
||||
await resizeHandle.focus();
|
||||
await page.keyboard.press("End");
|
||||
await expect(agentPanel).toHaveCSS("width", "484px");
|
||||
await expect(agentPanel).toHaveCSS("width", "500px");
|
||||
|
||||
const compactAgentBox = await agentPanel.boundingBox();
|
||||
const compactConditionBox = await panel.boundingBox();
|
||||
@@ -112,7 +111,7 @@ test("narrow desktop keeps Agent and expanded conditions from overlapping", asyn
|
||||
|
||||
test("switching conditions keeps the detail viewport fully expanded", async ({ page }) => {
|
||||
await page.goto("/", { waitUntil: "domcontentloaded" });
|
||||
await page.getByRole("button", { name: "工况任务", exact: true }).click();
|
||||
await openConditionFeed(page);
|
||||
|
||||
const panel = page.getByRole("region", { name: "工况任务", exact: true });
|
||||
await panel.getByRole("button", { name: "展开工况任务" }).click();
|
||||
@@ -161,7 +160,7 @@ test("switching conditions keeps the detail viewport fully expanded", async ({ p
|
||||
.getByRole("button", { name: /SCADA 数据诊断/ })
|
||||
.first()
|
||||
.click();
|
||||
const workflowTitle = panel.getByText("SCADA 诊断流程", { exact: true });
|
||||
const workflowTitle = panel.getByText("演示执行流程 · SCADA 诊断流程", { exact: true });
|
||||
await expect(workflowTitle).toBeVisible();
|
||||
await expect(workflowTitle.locator("..").locator("svg")).toHaveCount(0);
|
||||
});
|
||||
@@ -169,8 +168,9 @@ test("switching conditions keeps the detail viewport fully expanded", async ({ p
|
||||
test("keeps execution spinners without breathing badges after selecting timeline tasks", async ({
|
||||
page
|
||||
}) => {
|
||||
await mockHierarchicalWorkOrder(page, "execution");
|
||||
await page.goto("/", { waitUntil: "domcontentloaded" });
|
||||
await page.getByRole("button", { name: "工况任务", exact: true }).click();
|
||||
await openConditionFeed(page);
|
||||
|
||||
const panel = page.getByRole("region", { name: "工况任务", exact: true });
|
||||
await panel.getByRole("button", { name: "展开工况任务" }).click();
|
||||
@@ -182,14 +182,14 @@ test("keeps execution spinners without breathing badges after selecting timeline
|
||||
.first();
|
||||
const executingWorkOrder = timeline
|
||||
.locator('button[aria-pressed]')
|
||||
.filter({ hasText: "系统工单:北辰分区阀门开度调整" });
|
||||
.filter({ hasText: "演示工单:北辰分区阀门开度调整" });
|
||||
|
||||
await expectRunningStatusAnimations(runningCondition);
|
||||
await runningCondition.click();
|
||||
await expectRunningStatusAnimations(runningCondition);
|
||||
await expect(
|
||||
panel
|
||||
.getByText("SCADA 诊断流程", { exact: true })
|
||||
.getByText("演示执行流程 · SCADA 诊断流程", { exact: true })
|
||||
.locator("..")
|
||||
.locator(".status-badge .status-dot")
|
||||
).toHaveCount(0);
|
||||
@@ -198,18 +198,26 @@ test("keeps execution spinners without breathing badges after selecting timeline
|
||||
await expect(executingWorkOrder.getByText("执行中", { exact: true })).toBeVisible();
|
||||
await executingWorkOrder.click();
|
||||
await expectRunningStatusAnimations(executingWorkOrder);
|
||||
const detail = panel.getByTestId("scheduled-condition-detail-scroll");
|
||||
await expect(detail.getByText("子任务", { exact: true })).toBeVisible();
|
||||
await expect(detail.getByText("1/3 完成", { exact: true })).toBeVisible();
|
||||
await expect(detail.getByText(/上传阀门操作前后照片/).first()).toBeVisible();
|
||||
const activeSubtask = detail.locator("details").filter({ hasText: "记录最终开度" });
|
||||
await expect(activeSubtask).toHaveAttribute("open", "");
|
||||
await expect(activeSubtask.getByText("执行中", { exact: true })).toBeVisible();
|
||||
});
|
||||
|
||||
test("shows completed field work as a static waiting-for-reply state", async ({ page }) => {
|
||||
await mockHierarchicalWorkOrder(page, "reply");
|
||||
await page.goto("/", { waitUntil: "domcontentloaded" });
|
||||
await page.getByRole("button", { name: "工况任务", exact: true }).click();
|
||||
await openConditionFeed(page);
|
||||
|
||||
const panel = page.getByRole("region", { name: "工况任务", exact: true });
|
||||
await panel.getByRole("button", { name: "展开工况任务" }).click();
|
||||
const awaitingReplyWorkOrder = panel
|
||||
.getByTestId("scheduled-condition-timeline")
|
||||
.locator('button[aria-pressed]')
|
||||
.filter({ hasText: "系统工单:泵站边界复核复令" });
|
||||
.filter({ hasText: "演示工单:泵站边界复核复令" });
|
||||
|
||||
await expect(awaitingReplyWorkOrder.getByText("待复令", { exact: true })).toBeVisible();
|
||||
await expect(awaitingReplyWorkOrder.locator(".status-icon")).toHaveAttribute(
|
||||
@@ -225,7 +233,8 @@ test("shows completed field work as a static waiting-for-reply state", async ({
|
||||
);
|
||||
|
||||
await awaitingReplyWorkOrder.click();
|
||||
await expect(panel.getByText("当前阶段:待复令", { exact: true })).toBeVisible();
|
||||
await expect(panel.getByText("2/3 完成", { exact: true })).toBeVisible();
|
||||
await expect(panel.getByText("确认模型边界已同步更新 · 待复令", { exact: true })).toBeVisible();
|
||||
await expect(
|
||||
panel
|
||||
.getByTestId("scheduled-condition-detail-scroll")
|
||||
@@ -253,7 +262,19 @@ async function readScrollbarPresentation(locator: Locator) {
|
||||
});
|
||||
}
|
||||
|
||||
async function openConditionFeed(page: Page) {
|
||||
const button = page.getByRole("button", { name: "工况任务", exact: true });
|
||||
await button.focus();
|
||||
await page.keyboard.press("Enter");
|
||||
}
|
||||
|
||||
async function expectAcrylicComposition(panel: Locator) {
|
||||
await expect.poll(() => panel.evaluate((element) => getComputedStyle(element).transform)).toBe(
|
||||
"none"
|
||||
);
|
||||
await expect.poll(() => panel.evaluate((element) => getComputedStyle(element).willChange)).toBe(
|
||||
"auto"
|
||||
);
|
||||
const composition = await panel.evaluate((element) => {
|
||||
const rootStyle = getComputedStyle(element);
|
||||
const blockingAncestors: string[] = [];
|
||||
|
||||
Reference in New Issue
Block a user