Раскладка карточки: в одну колонку (уже 900 px) колонки растягиваются на всю ширину (align-items: stretch), порог — 899.98px. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
79 lines
4.6 KiB
TypeScript
79 lines
4.6 KiB
TypeScript
import { expect, test, type Page } from "@playwright/test";
|
||
import { login } from "./hub.ts";
|
||
|
||
// то, что в jsdom не проверить: реальная геометрия, ширины и поведение при смене фильтров
|
||
|
||
function watchErrors(page: Page): string[] {
|
||
const errs: string[] = [];
|
||
page.on("pageerror", (e) => errs.push("pageerror: " + e.message));
|
||
page.on("console", (m) => { if (m.type() === "error") errs.push("console: " + m.text()); });
|
||
return errs;
|
||
}
|
||
|
||
test("высота карточек берётся по содержимому из слоя измерения, а не 120px", async ({ page }) => {
|
||
await login(page);
|
||
await expect(page.locator(".board .card[data-key]").first()).toBeVisible();
|
||
const rows = await page.evaluate(() => [...document.querySelectorAll<HTMLElement>(".board .card[data-key]")].map((e) => ({
|
||
key: e.dataset.key!, h: e.offsetHeight, fits: e.scrollHeight <= e.clientHeight + 1,
|
||
})));
|
||
expect(rows.length).toBeGreaterThan(0);
|
||
for (const r of rows) {
|
||
expect(r.fits, `${r.key}: содержимое не помещается`).toBe(true);
|
||
expect(r.h % 8, `${r.key}: высота не на сетке 8`).toBe(0);
|
||
}
|
||
// на фикстуре hub-basic содержимое пяти карточек одной высоты, поэтому «разные высоты» не проверяем (отклонение от плана):
|
||
// высота не равна прежней фиксированной 120px
|
||
expect(rows.some((r) => r.h !== 120), "все карточки по 120px — высота не по содержимому").toBe(true);
|
||
});
|
||
|
||
test("при открытой панели «Проблемы» полоса дат по ширине равна обёртке холста", async ({ page }) => {
|
||
await login(page);
|
||
await page.getByRole("button", { name: "▥ по датам" }).click();
|
||
await expect(page.locator(".dates-in")).toBeVisible();
|
||
for (const open of [false, true]) {
|
||
if (open) {
|
||
await page.getByRole("button", { name: /^Проблемы/ }).click();
|
||
await expect(page.locator(".drawer")).toBeVisible();
|
||
}
|
||
await expect.poll(async () => {
|
||
const a = (await page.locator(".dates-in").boundingBox())!.width, b = (await page.locator(".stage .wrap").boundingBox())!.width;
|
||
return Math.abs(a - b);
|
||
}, `панель ${open ? "открыта" : "закрыта"}`).toBeLessThanOrEqual(1);
|
||
}
|
||
});
|
||
|
||
test("смена спринта и исполнителя, убирающая карточки, не даёт ошибок и белого экрана", async ({ page }) => {
|
||
const errs = watchErrors(page);
|
||
await login(page);
|
||
await expect(page.locator(".board .card[data-key]").first()).toBeVisible();
|
||
const total = await page.locator(".board .card[data-key]").count();
|
||
const dd = (i: number) => page.locator(".bar .dd-btn").nth(i); // 0 — спринты, 1 — исполнители
|
||
for (const [i, name] of [[0, "Спринт 3"], [1, "Сидорова"]] as const) {
|
||
await dd(i).click();
|
||
await page.getByRole("button", { name: "Снять выбор" }).click();
|
||
await page.locator(".dd-item", { hasText: name }).first().locator("input").check();
|
||
await page.keyboard.press("Escape");
|
||
await expect(page.locator("h1")).toHaveText("Доска связей");
|
||
await expect(page.locator(".top")).toBeVisible();
|
||
await expect(page.locator(".board")).toBeVisible();
|
||
await expect.poll(() => page.locator(".board .card[data-key]:not(.dim)").count(), `фильтр «${name}»`).toBeLessThan(total);
|
||
await dd(i).click();
|
||
await page.getByRole("button", { name: "Снять выбор" }).click();
|
||
await page.keyboard.press("Escape");
|
||
}
|
||
await page.getByRole("button", { name: "▥ по датам" }).click();
|
||
await expect(page.locator(".top")).toBeVisible();
|
||
expect(errs).toEqual([]);
|
||
});
|
||
|
||
test("h1 на страницах доски и задач, h2 в окне карточки", async ({ page }) => {
|
||
await login(page);
|
||
await expect(page.locator("h1")).toHaveText("Доска связей");
|
||
await page.getByRole("link", { name: "Задачи" }).click();
|
||
await expect(page.getByRole("heading", { level: 1, name: "Задачи" })).toBeVisible();
|
||
await page.getByRole("link", { name: "AURORA-9002" }).click();
|
||
// карточка — окно поверх списка: её заголовок h2 (тема задачи), h1 остаётся у страницы под окном
|
||
await expect(page.getByRole("dialog").getByRole("heading", { level: 2, name: "API свода" })).toBeVisible();
|
||
await expect(page.locator("h1")).toHaveCount(1);
|
||
});
|