Files
portifolio-evandrodevbr/e2e/sev-poster.spec.ts
T
Evandro Fonseca Junior 2cd4a98c55 test: e2e mais rígida e .gitattributes
Zero telas sem texto no computador e no celular; atalho de teclado em até 4 Tabs e linear em até 36 com o inventário das paradas; ciclo de foco do menu com a barra de cookies; oferta e cabeçalho levando ao formulário; foco vindo de outra página; separador da faixa de clientes; contagem de pôsteres da SEV. .gitattributes com eol=lf.
2026-10-14 19:14:49 -03:00

81 lines
2.9 KiB
TypeScript

import { expect, type Page, test } from "@playwright/test";
import { DESKTOP, PHONE } from "./helpers";
/**
* (j) O pôster da SEV Moda Íntima não se repete: em /servicos e em /cases ele aparece no máximo 2 vezes (meta da
* rodada 4), contando todo elemento que o mostra ao navegador (<img>, <video poster>, fundo CSS) e que não esteja
* dentro da própria página do case. Conta o que está no HTML, visível ou não, porque o que está no HTML é o que o
* navegador baixa. O mesmo vale nas duas larguras.
*/
const SEV_ASSETS = "/videos/sev-modaintima/";
const MAX_SEV_POSTERS = 2;
const PAGES = ["/servicos", "/cases"] as const;
const VIEWPORTS = [
{ name: "computador 1440x900", size: DESKTOP },
{ name: "celular 390x844", size: PHONE },
] as const;
/** Elementos que mostram um arquivo de /videos/sev-modaintima/, descritos em texto. */
function sevPosters(page: Page) {
return page.evaluate((assets) => {
const decoded = (value: string | null) => {
try {
return decodeURIComponent(value ?? "");
} catch {
return value ?? "";
}
};
const found: string[] = [];
for (const element of document.querySelectorAll("*")) {
const sources = [
element.getAttribute("src"),
element.getAttribute("srcset"),
element.getAttribute("poster"),
element instanceof HTMLElement ? element.style.backgroundImage : null,
];
if (element instanceof HTMLElement && element.tagName !== "HTML")
sources.push(getComputedStyle(element).backgroundImage);
const hit = sources.find((value) => decoded(value).includes(assets));
if (hit)
found.push(
`<${element.tagName.toLowerCase()}> ${decoded(hit).slice(0, 110)}`,
);
}
return found;
}, SEV_ASSETS);
}
for (const { name, size } of VIEWPORTS) {
test.describe(`pôster da SEV, ${name}`, () => {
test.use({ viewport: size });
// o detector enxerga o pôster onde ele certamente está (o hero da home e o próprio case): sem isso, "0 imagens"
// poderia ser só um seletor que não acha nada
for (const path of ["/", "/cases/sev-modaintima"]) {
test(`${path}: o detector acha o pôster da SEV`, async ({ page }) => {
await page.goto(path, { waitUntil: "load" });
await page.waitForTimeout(1000);
expect((await sevPosters(page)).length).toBeGreaterThan(0);
});
}
for (const path of PAGES) {
test(`${path}: no máximo ${MAX_SEV_POSTERS} imagens da SEV fora do próprio case`, async ({
page,
}) => {
await page.goto(path, { waitUntil: "load" });
await page.waitForTimeout(1000);
const posters = await sevPosters(page);
expect(
posters.length,
`${path}: ${posters.length} elemento(s) mostram arquivos da SEV (meta: no máximo ${MAX_SEV_POSTERS}):\n${posters.join("\n")}`,
).toBeLessThanOrEqual(MAX_SEV_POSTERS);
});
}
});
}