import { expect, test, type Locator } from "@playwright/test"; import { prepareApp } from "./fixtures"; async function bounds(locator: Locator) { const box = await locator.boundingBox(); expect(box).not.toBeNull(); return { ...box!, cx: box!.x + box!.width / 2, cy: box!.y + box!.height / 2 }; } test("不再提供网格吸附或网格线开关,拖入、微移和粘贴不再对网格取整", async ({ page }) => { await prepareApp(page); await page.goto("/"); await expect(page.getByRole("button", { name: /网格吸附|主网格线/ })).toHaveCount(0); await expect(page.locator('pattern[id$="major-grid-lines"]')).toHaveCount(0); await expect(page.locator('pattern[id$="minor-grid-dots"]')).toHaveCount(1); const pane = page.locator(".flow-canvas .react-flow__pane"); const canvas = await bounds(pane); const drop = { x: 231, y: 197 }; await page.getByRole("button", { name: /通用测试元件/ }).dragTo(pane, { targetPosition: drop }); const node = page.locator('.flow-canvas .react-flow__node[data-id="generic_sensor_1"]'); const initial = await bounds(node); expect(initial.cx).toBeCloseTo(canvas.x + drop.x, 0); expect(initial.cy).toBeCloseTo(canvas.y + drop.y, 0); // 先跨过 React Flow 的拖拽阈值,再移动少于原网格间距的距离。 await page.mouse.move(initial.cx, initial.cy); await page.mouse.down(); await page.mouse.move(initial.cx, initial.cy + 5); const started = await bounds(node); await page.mouse.move(initial.cx + 7, initial.cy + 16); await page.mouse.up(); const moved = await bounds(node); expect(moved.x - started.x).toBeCloseTo(7, 0); expect(moved.y - started.y).toBeCloseTo(11, 0); await page.keyboard.press("Control+c"); await page.keyboard.press("Control+v"); const pointer = { x: canvas.x + 493, y: canvas.y + 371 }; await page.mouse.move(pointer.x, pointer.y); const preview = page.locator(".flow-canvas .pending-paste-node"); await expect(preview).toBeVisible(); const pending = await bounds(preview); expect(pending.cx).toBeCloseTo(pointer.x, 0); expect(pending.cy).toBeCloseTo(pointer.y, 0); await page.mouse.click(pointer.x, pointer.y); await expect(preview).toHaveCount(0); const placed = await bounds(page.locator('.react-flow__node[data-id="generic_sensor_2"]')); expect(placed.cx).toBeCloseTo(pointer.x, 0); expect(placed.cy).toBeCloseTo(pointer.y, 0); }); test("忽略旧版网格线开关并保留网格点偏好", async ({ page }) => { await prepareApp(page); await page.addInitScript(() => localStorage.setItem( "system-simulation-flow:canvas-grid-visibility", JSON.stringify({ lines: true, dots: false }), )); await page.goto("/"); await expect(page.locator(".flow-canvas .react-flow__background")).toHaveCount(0); await expect(page.getByRole("button", { name: /网格吸附|主网格线/ })).toHaveCount(0); await page.getByRole("button", { name: "显示网格点", exact: true }).click(); await expect(page.locator('pattern[id$="minor-grid-dots"]')).toHaveCount(1); await expect(page.locator('pattern[id$="major-grid-lines"]')).toHaveCount(0); await expect.poll(() => page.evaluate(() => JSON.parse(localStorage.getItem( "system-simulation-flow:canvas-grid-visibility", )!))).toEqual({ dots: true }); });