test(web): скрипт скриншотов экранов для проверки вида (#65)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andrey Epifancev 2026-10-22 01:34:51 +04:00
parent 7ace847548
commit 3b73bb5ca0
2 changed files with 101 additions and 0 deletions

1
.gitignore vendored
View File

@ -17,3 +17,4 @@ web/test-results/
web/playwright-report/
web/.e2e-hub/
*.tsbuildinfo
web/e2e-screens/

100
web/e2e/screens.spec.ts Normal file
View File

@ -0,0 +1,100 @@
import { expect, test, type Page } from "@playwright/test";
import { mkdirSync } from "node:fs";
import { resolve } from "node:path";
import { agentServeRefresh, login } from "./hub.ts";
// Снимки экранов для проверки вида (запуск: SCREENS=1 npx playwright test e2e/screens.spec.ts).
// Результат — web/e2e-screens/<тема>-<ширина>-<экран>.png, в git не попадает.
test.skip(!process.env.SCREENS, "снимки только по SCREENS=1");
const OUT = resolve(import.meta.dirname, "../e2e-screens");
const SIZES = [{ w: 1920, h: 1080 }, { w: 390, h: 844 }];
for (const theme of ["light", "dark"] as const) {
for (const { w, h } of SIZES) {
test.describe(`${theme} ${w}`, () => {
test.use({ viewport: { width: w, height: h }, colorScheme: theme });
test.beforeEach(async ({ page }) => {
mkdirSync(OUT, { recursive: true });
await page.addInitScript((t) => { localStorage.setItem("graph-theme", t); }, theme);
});
const shot = (page: Page, name: string) =>
page.screenshot({ path: `${OUT}/${theme}-${w}-${name}.png`, fullPage: true });
const settle = async (page: Page) => {
await page.evaluate(() => document.fonts.ready.then(() => undefined));
await page.waitForTimeout(400); // раскладка доски и переходы успокаиваются до снимка
};
test("login", async ({ page }) => {
await page.goto("/app/board");
await expect(page.getByLabel("Клиентский токен хаба")).toBeVisible();
await settle(page);
await shot(page, "login");
});
test("board", async ({ page }) => {
await login(page);
await expect(page.locator(".board .card[data-key]").first()).toBeVisible();
await settle(page);
await shot(page, "board");
});
test("board-bydate", async ({ page }) => {
await login(page);
await page.getByRole("button", { name: "По датам" }).click();
await expect(page.locator(".dcol").first()).toBeVisible();
await settle(page);
await shot(page, "board-bydate");
});
test("board-problems", async ({ page }) => {
await login(page);
await expect(page.locator(".board .card[data-key]").first()).toBeVisible();
await page.getByRole("button", { name: /Проблемы/ }).click();
await settle(page);
await shot(page, "board-problems");
});
test("issues", async ({ page }) => {
await login(page, "/app/issues");
await expect(page.locator("table.issue-table tbody tr").first()).toBeVisible();
await settle(page);
await shot(page, "issues");
});
test("issues-filters", async ({ page }) => {
await login(page, "/app/issues");
await page.getByRole("button", { name: /Фильтры/ }).click();
await page.getByRole("combobox", { name: "Исполнитель" }).selectOption("Петров Пётр Петрович");
await expect(page).toHaveURL(/assignee=/);
await settle(page);
await shot(page, "issues-filters");
});
test("card", async ({ page }) => {
await login(page, "/app/issues/AURORA-9001");
await expect(page.getByRole("dialog").getByRole("heading", { name: "Схема свода" })).toBeVisible();
await settle(page);
await shot(page, "card");
});
test("new-project", async ({ page }) => {
await login(page);
await page.getByLabel("Проект", { exact: true }).selectOption({ label: "+ Новый проект…" });
await expect(page.getByRole("dialog", { name: "Новый проект" })).toBeVisible();
await settle(page);
await shot(page, "new-project");
});
test("refresh", async ({ page }) => {
await login(page);
await page.getByRole("button", { name: "Обновить из Jira" }).click();
await expect(page.getByRole("status")).toContainText(/пакет #\d+/);
await settle(page);
await shot(page, "refresh");
await agentServeRefresh(); // не оставляем пакет в очереди тестового хаба
await expect(page.getByRole("status")).toContainText(/выполнен/, { timeout: 15_000 });
});
});
}
}