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

110 lines
6.9 KiB
TypeScript

import { expect, test, type Page } from "@playwright/test";
import JSZip from "jszip";
import { clickXmindAction } from "./editor-actions";
async function openMap(page: Page, markers = false) {
await page.goto("/dev/flow-board-preview", { waitUntil: "commit" });
const zip = new JSZip();
zip.file("content.json", JSON.stringify([{ title: "标记验证", rootTopic: {
id: "root", title: "项目", children: { attached: [
{ id: "a", title: "设计", ...(markers ? { markers: [{ markerId: "priority-1" }] } : {}) },
{ id: "b", title: "开发", ...(markers ? { markers: [{ markerId: "priority-2" }, { markerId: "unknown-marker" }] } : {}) },
] },
} }]));
await page.locator("input[accept*=xmind]").setInputFiles({ name: "markers.xmind", mimeType: "application/octet-stream", buffer: await zip.generateAsync({ type: "nodebuffer" }) });
await expect(page.locator(".drawnix").getByText("设计", { exact: true })).toBeVisible();
await page.getByRole("button", { name: "标记", exact: true }).click();
}
const markerImages = (page: Page, id?: string) => page.locator(`.drawnix .xmind-topic-marker${id ? `[data-marker-id="${id}"]` : ""}`);
const markerButton = (page: Page, id: string) => page.getByLabel("标记面板", { exact: true }).locator(`button[data-marker-id="${id}"]`);
test("native marker palette fits the panel and adds, replaces, toggles, clears and undoes", async ({ page }) => {
const errors: string[] = [];
page.on("pageerror", error => errors.push(error.message));
await openMap(page);
const panel = page.getByLabel("标记面板", { exact: true });
await expect(page.getByRole("button", { name: "标记", exact: true })).toHaveAttribute("aria-pressed", "true");
await expect(panel.locator("button[data-marker-id]")).toHaveCount(58);
await expect(panel).toHaveCSS("width", "240px");
expect(await panel.evaluate(element => element.scrollWidth <= element.clientWidth)).toBe(true);
await page.mouse.click(130, 150);
await expect(markerButton(page, "priority-1")).toBeDisabled();
await page.locator(".drawnix").getByText("设计", { exact: true }).click();
await markerButton(page, "priority-1").click();
await expect(markerImages(page, "priority-1")).toHaveCount(1);
await expect(markerButton(page, "priority-1")).toHaveAttribute("aria-pressed", "true");
await expect.poll(() => markerImages(page, "priority-1").evaluate((image: HTMLImageElement) => image.complete && image.naturalWidth > 0)).toBe(true);
await markerButton(page, "priority-2").click();
await expect(markerImages(page, "priority-1")).toHaveCount(0);
await expect(markerImages(page, "priority-2")).toHaveCount(1);
await markerButton(page, "task-half").click();
await markerButton(page, "flag-green").click();
await expect(markerImages(page)).toHaveCount(3);
await markerButton(page, "flag-green").click();
await expect(markerImages(page)).toHaveCount(2);
await panel.getByRole("button", { name: "清空所选节点标记", exact: true }).click();
await expect(markerImages(page)).toHaveCount(0);
await clickXmindAction(page, "撤销");
await expect(markerImages(page)).toHaveCount(2);
await expect(markerButton(page, "priority-2")).toHaveAttribute("aria-pressed", "true");
await expect(markerButton(page, "task-half")).toHaveAttribute("aria-pressed", "true");
await page.setViewportSize({ width: 800, height: 700 });
expect(await panel.evaluate(element => element.scrollWidth <= element.clientWidth)).toBe(true);
await page.setViewportSize({ width: 1440, height: 900 });
await expect(markerImages(page, "priority-2")).toBeVisible();
await page.screenshot({ path: "test-results/flow-board-ui/marker-panel.png" });
expect(errors).toEqual([]);
});
test("mixed multi-selection applies one value consistently and undo restores the batch", async ({ page }) => {
await openMap(page, true);
const canvas = page.locator(".drawnix");
await canvas.getByText("设计", { exact: true }).click();
await canvas.getByText("开发", { exact: true }).click({ modifiers: ["Shift"] });
await expect(page.getByLabel("标记面板", { exact: true }).getByRole("status")).toHaveText("已选中 2 个主题");
await expect(markerButton(page, "priority-1")).toHaveAttribute("aria-pressed", "mixed");
await markerButton(page, "priority-1").click();
await expect(markerImages(page, "priority-1")).toHaveCount(2);
await expect(markerImages(page, "priority-2")).toHaveCount(0);
await clickXmindAction(page, "撤销");
await expect(markerImages(page, "priority-1")).toHaveCount(1);
await expect(markerImages(page, "priority-2")).toHaveCount(1);
await clickXmindAction(page, "重做");
await expect(markerImages(page, "priority-1")).toHaveCount(2);
await expect(markerButton(page, "priority-1")).toHaveAttribute("aria-pressed", "true");
await page.getByRole("button", { name: "清空所选节点标记", exact: true }).click();
await expect(markerImages(page)).toHaveCount(0);
const downloadPending = page.waitForEvent("download");
await page.getByRole("button", { name: "导出 XMind", exact: true }).click();
const stream = await (await downloadPending).createReadStream();
const chunks: Buffer[] = [];
for await (const chunk of stream!) chunks.push(chunk);
const zip = await JSZip.loadAsync(Buffer.concat(chunks));
const sheets = JSON.parse(await zip.file("content.json")!.async("string"));
expect(sheets[0].rootTopic.children.attached.every((topic: { markers?: unknown }) => !topic.markers)).toBe(true);
await clickXmindAction(page, "撤销");
await expect(markerImages(page, "priority-1")).toHaveCount(2);
await expect(markerButton(page, "priority-1")).toHaveAttribute("aria-pressed", "true");
});
test("search, group collapse and additional installed marker resources are usable", async ({ page }) => {
await openMap(page);
const panel = page.getByLabel("标记面板", { exact: true });
await page.locator(".drawnix").getByText("设计", { exact: true }).click();
await panel.getByRole("button", { name: "标签 7", exact: true }).click();
await expect(markerButton(page, "tag-red")).toHaveCount(0);
await panel.getByLabel("搜索标记").fill("priority-9");
await expect(panel.locator("button[data-marker-id]")).toHaveCount(1);
await markerButton(page, "priority-9").click();
await expect(markerImages(page, "priority-9")).toHaveCount(1);
await panel.getByLabel("搜索标记").fill("没有这个标记");
await expect(panel.getByText("没有匹配的标记", { exact: true })).toBeVisible();
await panel.getByLabel("搜索标记").fill("");
await panel.getByRole("button", { name: "标签 7", exact: true }).click();
await panel.getByRole("button", { name: "更多标记", exact: true }).click();
await expect(panel.locator("button[data-marker-id]")).toHaveCount(219);
await page.getByRole("button", { name: "关闭标记面板", exact: true }).click();
await expect(panel).toHaveCount(0);
await expect(page.getByLabel("格式面板", { exact: true })).toBeVisible();
});