ai-chatbot/tests/flow-board/annotations.spec.ts

107 lines
4.7 KiB
TypeScript

import { expect, type Locator, type Page, test } from "@playwright/test";
async function importMap(page: Page) {
// Exercise the actual Markdown importer with a test-only cloud response.
await page.route("**/api/flow-board/files", async (route) => {
await route.fulfill({
json: {
data: {
...route.request().postDataJSON(),
id: "test-map",
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
},
},
});
});
await page.goto("/dev/flow-board-preview", { waitUntil: "commit" });
await page.locator("input[type=file][accept*=md]").setInputFiles({
name: "项目计划.md",
mimeType: "text/markdown",
buffer: Buffer.from(
"# 项目计划\n## 产品调研\n### 用户访谈\n### 竞品分析\n## 设计方案\n### 视觉设计\n### 交互设计\n## 开发实现\n### 前端开发\n### 质量验证"
),
});
await expect(page.getByText("用户访谈", { exact: true })).toBeVisible();
}
function bounds(locator: Locator) {
return locator.evaluate((element) => {
const box = (element as unknown as SVGGraphicsElement).getBBox();
return { x: box.x, y: box.y, width: box.width, height: box.height };
});
}
test("annotations follow layout and collapse, persist across sheets, and undo with deleted topics", async ({
page,
}) => {
const errors: string[] = [];
page.on("pageerror", (error) => errors.push(error.message));
await importMap(page);
await page.getByText("用户访谈", { exact: true }).click();
await page.getByRole("button", { name: "联系", exact: true }).click();
await expect(
page.getByRole("status").filter({ hasText: "点击另一个主题" })
).toBeVisible();
await page.getByText("视觉设计", { exact: true }).click();
await page.getByLabel("联系文字", { exact: true }).fill("调研驱动设计");
const relationText = page
.locator(".drawnix")
.getByText("调研驱动设计", { exact: true });
await expect(relationText).toBeVisible();
await expect(page.locator("[plait-arrow-line=true]")).toHaveCount(1);
await page.getByText("产品调研", { exact: true }).click();
await page.getByRole("button", { name: "外框", exact: true }).click();
await page.getByLabel("外框留白").selectOption("24");
const boundary = page.locator("[plait-geometry=true]");
const originalBounds = await bounds(boundary);
await page.locator(".drawnix").getByText("项目计划", { exact: true }).click();
await page.getByRole("button", { name: "向下逻辑", exact: true }).click();
await expect.poll(() => bounds(boundary)).not.toEqual(originalBounds);
await page.getByRole("button", { name: "向右逻辑", exact: true }).click();
await expect.poll(() => bounds(boundary)).toEqual(originalBounds);
await page.getByText("产品调研", { exact: true }).click();
const expanded = await bounds(boundary);
await page.keyboard.press("ControlOrMeta+/");
await expect(page.getByText("用户访谈", { exact: true })).toHaveCount(0);
await expect
.poll(async () => (await bounds(boundary)).width)
.toBeLessThan(expanded.width);
await expect(relationText).toBeVisible();
await page.keyboard.press("ControlOrMeta+/");
await expect(page.getByText("用户访谈", { exact: true })).toBeVisible();
await expect.poll(() => bounds(boundary)).toEqual(expanded);
await page.getByRole("button", { name: "新增画布", exact: true }).click();
await expect(relationText).toHaveCount(0);
await page.getByRole("button", { name: "画布 1", exact: true }).click();
await expect(relationText).toBeVisible();
await expect(boundary).toHaveCount(1);
await page.getByText("视觉设计", { exact: true }).click();
await page.keyboard.press("Backspace");
await expect(relationText).toHaveCount(0);
await page.getByRole("button", { name: "撤销", exact: true }).click();
await expect(relationText).toBeVisible();
await page.getByRole("button", { name: "重做", exact: true }).click();
await expect(relationText).toHaveCount(0);
expect(errors).toEqual([]);
});
test("summary uses selected branches and relationship creation can be cancelled", async ({
page,
}) => {
await importMap(page);
await page.getByText("开发实现", { exact: true }).click();
await page.getByRole("button", { name: "概要", exact: true }).click();
await expect(
page.locator(".drawnix").getByText("摘要", { exact: true })
).toBeVisible();
await page.getByText("用户访谈", { exact: true }).click();
await page.getByRole("button", { name: "联系", exact: true }).click();
await page.keyboard.press("Escape");
await page.getByText("视觉设计", { exact: true }).click();
await expect(page.locator("[plait-arrow-line=true]")).toHaveCount(0);
});