优化组件选择交互与视图适配时机

This commit is contained in:
ljz committed 2026-08-03 11:59:24 +08:00
1 parent 11093613c5
commit cf249d6c0d
7 files changed
+473 -18

No files matched your search

+112
View File
@@ -44,3 +44,115 @@ test("未知图形元件使用带端口和名称的默认节点,并将动作
await expect(page.locator(".validation-section")).toHaveCount(0);
await expect(page.locator(".properties")).not.toContainText("仿真结果");
});
test("拖入组件后仅选择新组件,变换操作不会继续作用于旧选择", async ({
page,
}) => {
await page.goto("/");
const paletteItem = page.getByRole("button", { name: /通用测试元件/ });
const pane = page.locator(".flow-canvas .react-flow__pane");
await paletteItem.dragTo(pane, { targetPosition: { x: 220, y: 220 } });
const firstNode = page.locator(
'.flow-canvas .react-flow__node[data-id="generic_sensor_1"]',
);
await expect(firstNode).toHaveClass(/selected/);
await expect(firstNode.locator(".sim-node")).toHaveCSS(
"outline-style",
"dashed",
);
await paletteItem.dragTo(pane, { targetPosition: { x: 480, y: 340 } });
const secondNode = page.locator(
'.flow-canvas .react-flow__node[data-id="generic_sensor_2"]',
);
await expect(firstNode).not.toHaveClass(/selected/);
await expect(secondNode).toHaveClass(/selected/);
await expect(firstNode.locator(".sim-node")).toHaveCSS("outline-style", "none");
await expect(secondNode.locator(".sim-node")).toHaveCSS(
"outline-style",
"dashed",
);
await page
.getByRole("button", { name: "顺时针旋转 90° (Ctrl+R)", exact: true })
.click();
await expect(firstNode.locator(".sim-node")).not.toHaveClass(
/orientation-vertical/,
);
await expect(secondNode.locator(".sim-node")).toHaveClass(
/orientation-vertical/,
);
});
test("框选结束后隐藏整体包围框并保留每个组件的虚线选中框", async ({
page,
}) => {
await page.goto("/");
const paletteItem = page.getByRole("button", { name: /通用测试元件/ });
const pane = page.locator(".flow-canvas .react-flow__pane");
await paletteItem.dragTo(pane, { targetPosition: { x: 220, y: 220 } });
await paletteItem.dragTo(pane, { targetPosition: { x: 480, y: 340 } });
const firstNode = page.locator(
'.flow-canvas .react-flow__node[data-id="generic_sensor_1"]',
);
const secondNode = page.locator(
'.flow-canvas .react-flow__node[data-id="generic_sensor_2"]',
);
const [paneBounds, firstBounds, secondBounds] = await Promise.all([
pane.boundingBox(),
firstNode.boundingBox(),
secondNode.boundingBox(),
]);
expect(paneBounds).not.toBeNull();
expect(firstBounds).not.toBeNull();
expect(secondBounds).not.toBeNull();
const startX = Math.max(
paneBounds!.x + 4,
Math.min(firstBounds!.x, secondBounds!.x) - 14,
);
const startY = Math.max(
paneBounds!.y + 4,
Math.min(firstBounds!.y, secondBounds!.y) - 14,
);
const endX = Math.min(
paneBounds!.x + paneBounds!.width - 4,
Math.max(
firstBounds!.x + firstBounds!.width,
secondBounds!.x + secondBounds!.width,
) + 14,
);
const endY = Math.min(
paneBounds!.y + paneBounds!.height - 4,
Math.max(
firstBounds!.y + firstBounds!.height,
secondBounds!.y + secondBounds!.height,
) + 14,
);
await page.mouse.move(startX, startY);
await page.mouse.down();
await page.mouse.move(endX, endY, { steps: 12 });
await page.mouse.up();
await expect(firstNode).toHaveClass(/selected/);
await expect(secondNode).toHaveClass(/selected/);
await expect(firstNode.locator(".sim-node")).toHaveCSS(
"outline-style",
"dashed",
);
await expect(secondNode.locator(".sim-node")).toHaveCSS(
"outline-style",
"dashed",
);
await expect(page.locator(".flow-canvas .react-flow__selection")).toHaveCount(0);
const aggregateSelection = page.locator(
".flow-canvas .react-flow__nodesselection-rect",
);
await expect(aggregateSelection).toHaveCount(1);
await expect(aggregateSelection).toHaveCSS("border-top-width", "0px");
await expect(aggregateSelection).toHaveCSS("pointer-events", "none");
});