import { expect, test } from "@playwright/test"; import { DESKTOP } from "./helpers"; /** * (f) No computador, nenhuma das paradas a cada 10 % da rolagem da home tem tela vazia: sempre há ao menos um * elemento de texto visível na janela. Cabeçalho, avisos, leitores de tela e itens ocultos não contam * (o cabeçalho fixo estaria em todas as paradas e esconderia uma tela vazia). */ test.use({ viewport: DESKTOP }); test("nenhuma parada a cada 10 % da home tem tela vazia", async ({ page }) => { await page.goto("/", { waitUntil: "load" }); await page.waitForTimeout(1500); const empty: string[] = []; const stops: string[] = []; for (let step = 0; step <= 10; step++) { await page.evaluate((fraction) => { const max = document.documentElement.scrollHeight - innerHeight; window.scrollTo({ top: Math.round(max * fraction), behavior: "instant" }); }, step / 10); // a rolagem suave, as animações ligadas à rolagem e as imagens preguiçosas assentam await page.waitForTimeout(700); const result = await page.evaluate(() => { const ignored = "header, footer [aria-hidden], [aria-hidden='true'], [role='dialog'], .sr-only, .skip-link, script, style, noscript"; const effectiveOpacity = (element: Element | null) => { let opacity = 1; for (let node = element; node; node = node.parentElement) opacity *= Number.parseFloat(getComputedStyle(node).opacity); return opacity; }; const visible: string[] = []; const walker = document.createTreeWalker( document.body, NodeFilter.SHOW_TEXT, ); for (let node = walker.nextNode(); node; node = walker.nextNode()) { const text = node.textContent?.trim() ?? ""; const parent = node.parentElement; if (text.length < 3 || !parent || parent.closest(ignored)) continue; const style = getComputedStyle(parent); if (style.visibility !== "visible" || style.display === "none") continue; if (effectiveOpacity(parent) < 0.2) continue; const range = document.createRange(); range.selectNodeContents(node); const rect = range.getBoundingClientRect(); const inside = rect.width > 1 && rect.height > 1 && rect.bottom > 0 && rect.top < innerHeight && rect.right > 0 && rect.left < innerWidth; if (inside) visible.push(text.slice(0, 40)); } return { count: visible.length, sample: visible.slice(0, 2) }; }); const label = `${step * 10}%`; stops.push(`${label}: ${result.count} trecho(s) de texto`); if (result.count === 0) empty.push(label); } expect( empty, `paradas com tela vazia (nenhum texto visível):\n${stops.join("\n")}`, ).toEqual([]); });