1
19import { test, expect } from "../fixtures";
20
21interface WhiteboardPageDto {
22 id: string;
23 kind?: string;
24}
25
26interface CanvasElement {
27 id: string;
28 type: string;
29 text?: string;
30}
31
32test.describe("Whiteboard — P5 (T-168/T-169/T-170)", () => {
33 test("renders the canvas, adds a sticky + rect, edits text, and autosaves to the API", async ({
34 authPage,
35 api,
36 freshWorkspace
37 }) => {
38 const ws = await freshWorkspace("Whiteboard Space");
39
40
41
42
43 const createRes = await api.post(`/api/v1/workspaces/${ws.id}/pages`, {
44 data: { title: "Team Wall", type: "whiteboard" }
45 });
46 expect(createRes.status(), await createRes.text()).toBe(201);
47 const page = (await createRes.json()) as WhiteboardPageDto;
48 expect(page.id).toBeTruthy();
49
50 await authPage.goto(`/w/${ws.slug}/page/${page.id}`);
51
52
53 const root = authPage.getByTestId("wb-root");
54 await expect(root).toBeVisible({ timeout: 20_000 });
55 await expect(authPage.getByTestId("wb-canvas")).toBeVisible();
56
57
58
59
60 const canvas = authPage.getByTestId("wb-canvas");
61 const box = await canvas.boundingBox();
62 if (!box) throw new Error("wb-canvas has no bounding box");
63 await authPage.getByTestId("wb-tool-sticky").click();
64 await authPage.mouse.click(box.x + box.width / 2, box.y + box.height / 3);
65 await expect(authPage.getByTestId("wb-sticky")).toHaveCount(1, { timeout: 10_000 });
66 await expect(authPage.getByTestId("wb-tool-select")).toHaveClass(/active/);
67
68
69
70
71
72
73
74
75 const LABEL = "E2E sticky text";
76 await authPage.getByTestId("wb-sticky").dblclick();
77 const editor = authPage.getByTestId("wb-editor-input");
78 await expect(editor).toBeVisible({ timeout: 10_000 });
79 await editor.fill(LABEL);
80 await editor.press("Escape");
81 await expect(editor).toHaveCount(0);
82 await expect(authPage.getByTestId("wb-label").first()).toContainText(LABEL, {
83 timeout: 10_000
84 });
85
86
87 await authPage.getByTestId("wb-tool-rect").click();
88 await authPage.mouse.move(box.x + box.width / 2 + 120, box.y + box.height * 0.6);
89 await authPage.mouse.down();
90 await authPage.mouse.move(box.x + box.width / 2 + 220, box.y + box.height * 0.75, {
91 steps: 5
92 });
93 await authPage.mouse.up();
94 await expect(authPage.getByTestId("wb-rect")).toHaveCount(1, { timeout: 10_000 });
95
96
97
98
99
100
101
102
103
104 await expect
105 .poll(
106 async () => {
107 const res = await api.get(`/api/v1/pages/${page.id}/whiteboard`);
108 const body = (await res.json()) as { canvas?: { elements?: Record<string, CanvasElement> } };
109 const els = Object.values(body.canvas?.elements ?? {});
110 const sticky = els.find((e) => e.type === "sticky");
111 return !!sticky && sticky.text === LABEL && els.some((e) => e.type === "rect");
112 },
113 { timeout: 15_000 }
114 )
115 .toBe(true);
116 });
117});
118