import { test, expect } from "@playwright/test" for (const width of [320, 390, 1024, 1440]) { test(`шапка ${width}px: заголовок, действия и меню доступны без обрезки`, async ({ page }) => { await page.setViewportSize({ width, height: 900 }) const errors: string[] = [] page.on("pageerror", error => errors.push(error.message)) await page.route("**/health", route => route.fulfill({ json: { ok: true } })) await page.route("**/api/**", route => { const path = new URL(route.request().url()).pathname return route.fulfill({ json: path === "/api/recursive-routes" ? { routes: [] } : path === "/api/recursive-routes/gateways" ? { gateways: [] } : path === "/api/auth/config" ? { required: false } : path === "/api/servers" ? [{ id: 1, name: "Роутер", host: "192.0.2.100", type: "exit-node", site: "TEST", country: "RU", asn: "64512", enabled: true, status: "online", latency: 1 }] : path === "/api/evobgp/settings" ? { enabled: false, baseUrl: "", secretConfigured: false } : {} }) }) await page.goto("/recursive-routes") const header = page.locator("header").filter({ has: page.getByRole("navigation", { name: "Путь страницы" }) }) const current = header.locator('[aria-current="page"]') await expect(current).toHaveText("Рекурсивные маршруты") await expect(header.getByRole("button", { name: "Обновить", exact: true })).toBeEnabled() // Check the actual visible controls, not just document scrollWidth: a clipped // child in an overflow-hidden application shell can otherwise pass unnoticed. const visibleBounds = await header.evaluate(element => { const parent = element.getBoundingClientRect() return [...element.querySelectorAll('button, [aria-current="page"]')] .filter(child => child.getClientRects().length > 0) .map(child => { const rect = child.getBoundingClientRect() return { label: child.textContent, inside: rect.left >= parent.left && rect.right <= Math.min(parent.right, window.innerWidth) + 1 && rect.top >= parent.top && rect.bottom <= parent.bottom + 1 } }) }) expect(visibleBounds.filter(control => !control.inside)).toEqual([]) expect(await header.locator("ol").evaluate(list => [...list.children].every(child => child.tagName === "LI"))).toBe(true) const apps = header.getByRole("button", { name: "Приложения", exact: true }) await apps.focus() await page.keyboard.press("Enter") await expect(page.getByRole("menu")).toBeVisible() await page.keyboard.press("Escape") await expect(apps).toBeFocused() if (width < 768) { const sidebar = header.getByRole("button", { name: "Боковое меню", exact: true }) await sidebar.press("Enter") await expect(page.getByRole("dialog")).toBeVisible() await page.keyboard.press("Escape") await expect(sidebar).toBeFocused() } await page.screenshot({ path: `test-results/page-header-${width}.png`, fullPage: true, animations: "disabled" }) expect(errors).toEqual([]) }) }