110 lines
6.9 KiB
TypeScript
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();
|
|
});
|