import { clickXmindAction, clickXmindSheet } from "./editor-actions"; import { expect, test } from "@playwright/test"; import JSZip from "jszip"; test("outline edits, creates, nests and deletes topics with shared canvas history", async ({ page, }) => { const errors: string[] = []; page.on("pageerror", (error) => errors.push(error.message)); await page.goto("/dev/flow-board-preview", { waitUntil: "commit" }); const zip = new JSZip(); zip.file( "content.json", JSON.stringify([ { title: "项目", rootTopic: { id: "r", title: "项目计划", children: { attached: [ { id: "a", title: "市场调研", notes: { plain: { content: "调研备注" } }, }, { id: "b", title: "产品设计", children: { attached: [{ id: "c", title: "设计评审" }] }, }, ], }, }, }, { title: "归档", rootTopic: { id: "other", title: "历史记录" } }, ]) ); await page.locator("input[accept*=xmind]").setInputFiles({ name: "大纲测试.xmind", mimeType: "application/octet-stream", buffer: await zip.generateAsync({ type: "nodebuffer" }), }); await page.getByRole("button", { name: "切换到大纲", exact: true }).click(); const outline = page.getByRole("region", { name: "大纲视图", exact: true }); await expect( outline.getByLabel("大纲主题 项目计划", { exact: true }) ).toBeVisible(); const research = outline.getByLabel("大纲主题 市场调研", { exact: true }); const initialHeight = (await research.boundingBox())!.height; await clickXmindAction(page, "放大"); await expect .poll(async () => (await research.boundingBox())!.height) .toBeGreaterThan(initialHeight); await clickXmindAction(page, "适应画布"); await research.fill("用户研究"); await research.press("Enter"); await expect( outline.getByLabel("大纲主题 新主题", { exact: true }) ).toBeFocused(); const newTopic = outline.getByLabel("大纲主题 新主题", { exact: true }); await newTopic.fill("竞争分析"); await newTopic.press("Tab"); const competitor = outline.getByLabel("大纲主题 竞争分析", { exact: true }); await expect(competitor.locator("..")).toHaveAttribute("data-depth", "2"); await competitor.press("Shift+Tab"); await expect(competitor.locator("..")).toHaveAttribute("data-depth", "1"); await clickXmindAction(page, "撤销"); await expect(competitor.locator("..")).toHaveAttribute("data-depth", "2"); await clickXmindAction(page, "重做"); await expect(competitor.locator("..")).toHaveAttribute("data-depth", "1"); await outline .getByRole("button", { name: "折叠 产品设计", exact: true }) .click(); await expect( outline.getByLabel("大纲主题 设计评审", { exact: true }) ).toHaveCount(0); await outline .getByRole("button", { name: "展开 产品设计", exact: true }) .click(); await expect( outline.getByLabel("大纲主题 设计评审", { exact: true }) ).toBeVisible(); await page .getByRole("button", { name: "切换到思维导图", exact: true }) .click(); const canvas = page.locator(".drawnix"); await expect(canvas.getByText("用户研究", { exact: true })).toBeVisible(); await expect(canvas.getByText("竞争分析", { exact: true })).toBeVisible(); await canvas.getByText("产品设计", { exact: true }).dblclick(); await page.keyboard.press("ControlOrMeta+A"); await page.keyboard.insertText("方案设计"); await page .locator(".flow-board-canvas-shell") .click({ position: { x: 100, y: 100 } }); await page.getByRole("button", { name: "切换到大纲", exact: true }).click(); await expect( outline.getByLabel("大纲主题 方案设计", { exact: true }) ).toBeVisible(); await outline.getByLabel("大纲主题 竞争分析", { exact: true }).click(); await outline .getByRole("button", { name: "大纲删除主题", exact: true }) .click(); await expect( outline.getByLabel("大纲主题 竞争分析", { exact: true }) ).toHaveCount(0); await clickXmindAction(page, "撤销"); await expect( outline.getByLabel("大纲主题 竞争分析", { exact: true }) ).toBeVisible(); await page.getByRole("button", { name: "归档", exact: true }).click(); await expect( outline.getByLabel("大纲主题 历史记录", { exact: true }) ).toBeVisible(); await clickXmindSheet(page, "项目"); await expect( outline.getByLabel("大纲主题 用户研究", { exact: true }) ).toBeVisible(); const renamedResearch = outline.getByLabel("大纲主题 用户研究", { exact: true, }); await renamedResearch.fill("取消这次改名"); await renamedResearch.press("Escape"); await expect(renamedResearch).toHaveValue("用户研究"); await outline.getByLabel("大纲主题 用户研究", { exact: true }).click(); await clickXmindAction(page, "备注"); await expect(page.getByLabel("主题备注", { exact: true })).toHaveValue( "调研备注" ); await outline .getByLabel("拖动 设计评审", { exact: true }) .dragTo( outline.getByLabel("大纲主题 用户研究", { exact: true }).locator("..") ); await expect .poll(() => outline .locator("[data-outline-input]") .evaluateAll((nodes) => nodes.map((node) => (node as HTMLInputElement).value) ) ) .toEqual(["项目计划", "用户研究", "设计评审", "竞争分析", "方案设计"]); await page.screenshot({ path: test.info().outputPath("outline-preview.png"), }); await page.getByRole("button", { name: "新增画布", exact: true }).click(); await outline .getByRole("button", { name: "添加中心主题", exact: true }) .click(); await expect( outline.getByLabel("大纲主题 中心主题", { exact: true }) ).toBeVisible(); await outline.getByLabel("大纲主题 中心主题", { exact: true }).press("Enter"); await expect( outline.getByLabel("大纲主题 新主题", { exact: true }) ).toBeFocused(); expect(errors).toEqual([]); });