159 lines
6.3 KiB
TypeScript
159 lines
6.3 KiB
TypeScript
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 page.getByRole("button", { name: "放大", exact: true }).click();
|
|
await expect
|
|
.poll(async () => (await research.boundingBox())!.height)
|
|
.toBeGreaterThan(initialHeight);
|
|
await page.getByRole("button", { name: "适应画布", exact: true }).click();
|
|
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 page.getByRole("button", { name: "撤销", exact: true }).click();
|
|
await expect(competitor.locator("..")).toHaveAttribute("data-depth", "2");
|
|
await page.getByRole("button", { name: "重做", exact: true }).click();
|
|
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 page.getByRole("button", { name: "撤销", exact: true }).click();
|
|
await expect(
|
|
outline.getByLabel("大纲主题 竞争分析", { exact: true })
|
|
).toBeVisible();
|
|
await page.getByRole("button", { name: "归档", exact: true }).click();
|
|
await expect(
|
|
outline.getByLabel("大纲主题 历史记录", { exact: true })
|
|
).toBeVisible();
|
|
await page.getByRole("button", { name: "项目", exact: true }).click();
|
|
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 page.getByRole("button", { name: "备注", exact: true }).click();
|
|
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([]);
|
|
});
|