import { expect, test, type Page } from "@playwright/test"; import { login } from "./hub.ts"; type Box = { left: string; top: string; width: string; height: string }; const boxes = (page: Page) => page.locator(".board .card").evaluateAll((els) => Object.fromEntries(els.map((e) => { const el = e as HTMLElement; return [el.querySelector("a.key")?.textContent ?? "", { left: el.style.left, top: el.style.top, width: el.style.width, height: el.style.height }]; })) as Record); const lanes = (page: Page) => page.locator(".board .lane-name").allTextContents(); test("раскладка новой доски совпадает со старой страницей", async ({ page }) => { await login(page); // токен в localStorage общий для /app и /links for (const mode of ["обычная", "по датам"]) { if (mode === "по датам") await page.getByRole("button", { name: "▥ по датам" }).click(); await expect(page.locator(".board .card").first()).toBeVisible(); const fresh = { boxes: await boxes(page), lanes: await lanes(page), edges: await page.locator("svg.edges path").count() }; await page.screenshot({ path: `test-results/compare/new-${mode}.png`, fullPage: true }); await page.goto("/links"); await expect(page.locator(".board .card").first()).toBeVisible(); const old = { boxes: await boxes(page), lanes: await lanes(page), edges: await page.locator("#edges path").count() }; await page.screenshot({ path: `test-results/compare/old-${mode}.png`, fullPage: true }); expect(fresh.lanes).toEqual(old.lanes); expect(fresh.edges).toBe(old.edges); expect(Object.keys(fresh.boxes).sort()).toEqual(Object.keys(old.boxes).sort()); for (const k of Object.keys(old.boxes)) { for (const p of ["left", "top", "width", "height"] as const) { expect(Math.abs(parseFloat(fresh.boxes[k][p]) - parseFloat(old.boxes[k][p])), `${mode} ${k}.${p}`).toBeLessThanOrEqual(1); } } await page.goto("/app/board"); } });