import { expect, test } from "@playwright/test"; import { CW } from "../src/board/constants.ts"; import { agentServeRefresh, login } from "./hub.ts"; test.beforeEach(async ({ page }) => { await login(page); }); test("перетаскивание за рамку двигает карточку и переживает перезагрузку", async ({ page }) => { const card = page.locator('.board .card[data-key="AURORA-9001"]'); const before = await card.boundingBox(); const grip = card.locator(".grip.t"); const g = (await grip.boundingBox())!; await page.mouse.move(g.x + g.width / 2, g.y + g.height / 2); await page.mouse.down(); await page.mouse.move(g.x + g.width / 2 + 160, g.y + g.height / 2 + 40, { steps: 8 }); await page.mouse.up(); const after = (await card.boundingBox())!; expect(Math.round(after.x - before!.x)).toBeGreaterThan(100); await page.reload(); const reloaded = (await page.locator('.board .card[data-key="AURORA-9001"]').boundingBox())!; expect(Math.abs(reloaded.x - after.x)).toBeLessThan(2); expect(Math.abs(reloaded.y - after.y)).toBeLessThan(2); }); test("растяжка за уголок и возврат размера двойным щелчком", async ({ page }) => { const card = page.locator('.board .card[data-key="AURORA-9002"]'); const rsz = (await card.locator(".rsz").boundingBox())!; const w0 = (await card.boundingBox())!.width; await page.mouse.move(rsz.x + 2, rsz.y + 2); await page.mouse.down(); await page.mouse.move(rsz.x + 82, rsz.y + 42, { steps: 6 }); await page.mouse.up(); await expect.poll(async () => (await card.boundingBox())!.width).toBeGreaterThan(w0 + 60); await card.locator(".rsz").dblclick(); await expect.poll(async () => Math.round((await card.boundingBox())!.width)).toBe(CW); }); test("«по датам» — колонки дат, подписи и стрелки", async ({ page }) => { await page.getByRole("button", { name: "▥ по датам" }).click(); await expect(page.locator(".dcol").first()).toBeVisible(); await expect(page.locator(".dates-track .dlabel").first()).toBeVisible(); await expect(page.locator("svg.edges path")).not.toHaveCount(0); }); test("«Обновить из Jira» с учебным агентом доходит до конца", async ({ page }) => { const btn = page.getByRole("button", { name: "Обновить из Jira" }); await btn.click(); await expect(btn).toBeDisabled(); await expect(page.getByRole("status")).toContainText(/пакет #\d+/); await agentServeRefresh(); await expect(page.getByRole("status")).toContainText(/пакет #\d+ выполнен/, { timeout: 15_000 }); await expect(btn).toBeEnabled(); await expect(page.getByText(/^Хаб · данные на /)).toBeVisible(); await expect(page.locator(".board .card[data-key]")).not.toHaveCount(0); }); test("ⓘ открывает карточку задачи в приложении", async ({ page }) => { await page.locator('.board .card[data-key="AURORA-9001"]').getByRole("link", { name: "Открыть карточку AURORA-9001" }).click(); await expect(page).toHaveURL(/\/app\/issues\/AURORA-9001$/); await expect(page.getByRole("heading", { name: /AURORA-9001/ })).toBeVisible(); }); test("M-3: прокрутка доски после возврата из карточки задачи", async ({ page }) => { await page.setViewportSize({ width: 1600, height: 600 }); await expect(page.locator(".board .card[data-key]").first()).toBeVisible(); const y = await page.evaluate(() => { window.scrollTo(0, document.documentElement.scrollHeight); return window.scrollY; }); expect(y).toBeGreaterThan(100); // реальный щелчок по ⓘ карточки, видимой в окне после прокрутки (иначе Playwright сам сдвинет страницу) const key = await page.evaluate(() => { const vh = window.innerHeight; const a = [...document.querySelectorAll(".board .card[data-key] a.open-card")] .find((e) => { const r = e.getBoundingClientRect(); return r.top > 200 && r.bottom < vh - 20; }); return a?.closest(".card")?.dataset.key ?? null; }); expect(key).not.toBeNull(); const link = page.locator(`.board .card[data-key="${key}"] a.open-card`); await link.click(); await expect(page).toHaveURL(/\/app\/issues\//); await page.getByRole("link", { name: "Доска", exact: true }).click(); await expect.poll(() => page.evaluate(() => window.scrollY)).toBeGreaterThan(y - 2); });