import { expect, type Locator, test } from "@playwright/test"; import { CONTACT_HEADING, clientProjectNames, DESKTOP } from "./helpers"; /** * (e) Com JavaScript desligado, a home mostra o texto do contato e o nome dos clientes: no HTML, visíveis e com * opacidade calculada acima de 0,5 (um texto "visível" mas a 0,1 de opacidade, à espera de uma animação que não * roda sem JavaScript, não serve a quem lê). */ const MIN_OPACITY = 0.5; test.use({ viewport: DESKTOP, javaScriptEnabled: false }); /** Opacidade efetiva: o produto das opacidades calculadas do elemento e de todos os seus ancestrais. */ function effectiveOpacity(locator: Locator) { return locator.evaluate((element) => { let opacity = 1; for (let node: Element | null = element; node; node = node.parentElement) opacity *= Number.parseFloat(getComputedStyle(node).opacity); return opacity; }); } /** * Leva o texto ao meio da janela, como quem lê rolando (a passagem entre seções é um fade ligado à rolagem, em CSS * puro: antes de a seção chegar à janela o conteúdo espera a 0, e isso não depende de JavaScript) e espera a * opacidade passar de MIN_OPACITY: as animações de entrada em CSS levam um instante para terminar. */ async function expectReadable(locator: Locator, what: string) { await locator.evaluate((element) => element.scrollIntoView({ block: "center", behavior: "instant" }), ); await expect .poll(() => effectiveOpacity(locator), { message: `opacidade de ${what}`, timeout: 5_000, }) .toBeGreaterThan(MIN_OPACITY); } test("sem JavaScript a home mostra o contato e os nomes dos 5 clientes, legíveis", async ({ page, }) => { const clients = clientProjectNames(); expect(clients, "clientes em public/portfolio-data.json").toHaveLength(5); const response = await page.goto("/", { waitUntil: "load" }); expect(response?.status()).toBe(200); const heading = page.getByRole("heading", { level: 2, name: CONTACT_HEADING, }); await expect(heading).toBeVisible(); await expectReadable(heading, "o texto do contato"); for (const name of clients) { const text = page.getByText(name, { exact: false }).first(); await expect(text, `cliente "${name}"`).toBeVisible(); await expectReadable(text, `o cliente "${name}"`); } // o texto está no HTML entregue, não só na tela: vale também para quem lê sem renderizar const html = await (await page.request.get("/")).text(); expect(html).toContain(CONTACT_HEADING); for (const name of clients) expect(html).toContain(name); });