import { test, expect } from "@playwright/test"; import { expandSimulationConsole, prepareApp, wideProject } from "./fixtures"; const latestKey = "system-simulation-flow:autosave"; test.beforeEach(async ({ page }) => { await prepareApp(page); }); test("刷新恢复最新工程名称,初始空画布及忽略提示不会覆盖最新存档", async ({ page }) => { await page.goto("/"); const project = { ...wideProject, name: "持久化 工程名称.v2" }; await page.evaluate(({ key, project }) => localStorage.setItem(key, JSON.stringify(project)), { key: latestKey, project }); await page.clock.install(); await page.reload(); await expect(page.getByRole("textbox", { name: "工程", exact: true })).toHaveValue(project.name); await page.getByRole("button", { name: "忽略", exact: true }).click(); await page.clock.runFor(6000); await expect(page.locator(".flow-canvas .react-flow__node")).toHaveCount(0); expect(await page.evaluate(key => JSON.parse(localStorage.getItem(key)!), latestKey)).toEqual(project); await page.getByRole("button", { name: "加载工程", exact: true }).click(); await expect(page.locator(".flow-canvas .react-flow__node")).toHaveCount(4); await expect(page.getByRole("textbox", { name: "工程", exact: true })).toHaveValue(project.name); }); test("自动保存和手动保存共用最新入口,哪个后完成就加载哪个", async ({ page }) => { await page.goto("/"); await expect(page.getByRole("button", { name: /通用测试元件/ })).toBeVisible(); for (const [name, count, manual] of [["手动 A", 4, true], ["自动 B", 2, false], ["手动 C", 3, true]] as const) { await page.locator('input[type="file"]').setInputFiles({ name: `${name}.json`, mimeType: "application/json", buffer: Buffer.from(JSON.stringify({ ...wideProject, nodes: wideProject.nodes.slice(0, count), edges: [] })) }); if (manual) await page.getByRole("button", { name: "保存工程", exact: true }).click(); await expect.poll(() => page.evaluate(key => JSON.parse(localStorage.getItem(key) || "null")?.name, latestKey)).toBe(name); await page.getByRole("button", { name: "加载工程", exact: true }).click(); await expect(page.locator(".flow-canvas .react-flow__node")).toHaveCount(count); await expect(page.getByRole("textbox", { name: "工程", exact: true })).toHaveValue(name); } }); test("没有最新存档时不猜选历史命名工程,也不改动画布", async ({ page }) => { await page.goto("/"); await page.evaluate(project => localStorage.setItem("system-simulation-flow:project:demo-system", JSON.stringify(project)), wideProject); await page.getByRole("button", { name: "加载工程", exact: true }).click(); await expandSimulationConsole(page); await expect(page.getByRole("complementary", { name: "仿真控制台", exact: true })).toContainText("尚无自动保存或保存到浏览器的工程"); await expect(page.locator(".flow-canvas .react-flow__node")).toHaveCount(0); }); test("明确保存的空工程也是最新工程,不回退到旧的非空副本", async ({ page }) => { await page.goto("/"); const empty = { ...wideProject, name: "已清空工程", nodes: [], edges: [] }; await page.evaluate(({ key, empty, old }) => { localStorage.setItem(key, JSON.stringify(empty)); localStorage.setItem("system-simulation-flow:pending-recovery", JSON.stringify(old)); }, { key: latestKey, empty, old: wideProject }); await page.reload(); await expect(page.getByRole("textbox", { name: "工程", exact: true })).toHaveValue(empty.name); await page.getByRole("button", { name: "加载工程", exact: true }).click(); await expect(page.locator(".flow-canvas .react-flow__node")).toHaveCount(0); await expect(page.getByRole("textbox", { name: "工程", exact: true })).toHaveValue(empty.name); });