QA visual com Playwright CLI
Regra de ouro: sem saída de comando fresca não há veredito. Nada de "deveria estar bem".
Setup mínimo
- Playwright como devDependency do projeto;
playwright.config.tscom viewport explícito de 375px (nãodevices['Pixel 7'], que são 412px) e projetosdesktop-chromeemobile-chrome. - Scripts de captura em
scripts/shot.mjs(não usar MCP para isso: o CLI é mais rápido e reproduzível). - Para axe:
@axe-core/playwright. - Servir o build de produção (
npm run build && npm run start) para medir desempenho real; usar dev apenas para depuração.
Checagens por página e por locale
- Console e rede:
page.on('console'),page.on('pageerror'),page.on('requestfailed')e respostas ≥400. Falha = vermelho. - Overflow: em cada viewport verificar
document.documentElement.scrollWidth <= clientWidth + 1; se houver transbordo, listar os elementos culpados (getBoundingClientRect().right > innerWidth). - Acessibilidade: axe sem violações
critical/serious; um únicoh1;img[alt]completo; foco visível em todo elemento interativo (verificar:focus-visiblecom teclado real, não CSS a olho); ordem de tabulação lógica. - Reduced motion:
page.emulateMedia({ reducedMotion: 'reduce' }); não deve haver pin, autoplay nem animação de mais de 200ms. - Links: extrair todos os
href, validar os internos (200) e marcar externos como informativos; 0href="#"sem controlador. - SEO:
title,meta description, canonical, OG,hreflangpor locale, JSON-LD parseável,sitemap.xmlerobots.txt200. - Desempenho: medir LCP/CLS com PerformanceObserver após carregar; objetivo LCP < 2.5s e CLS < 0.1 em desktop; medir jank de scroll contando frames longos (>50ms) com rAF durante 5s de scroll automatizado.
- Canvas/scroll: como o canvas pode sair preto em headless, verificar por DOM: elementos com opacidade/transform esperados, textos dos beats presentes e visíveis nos ranges corretos, e estado exposto em
windowse existir.
Loop
- Após cada execução: relatório com tabela gate/comando/resultado/estado e lista de bloqueantes com evidência (seletor, log ou captura).
- Se um gate falhar: corrigir (testes/scripts próprios) ou propor o fix concreto de
src/com evidência; repetir o ciclo completo. - Salvar capturas datadas em
docs/qa/(desktop + mobile por locale principal) e baseline para comparar regressões. - Não declarar PRONTO com um gate vermelho ou não executado.
Limites honestos
- Não é possível validar uma sequência de frames em iOS real a partir de headless: deixar isso escrito no relatório.
- Lighthouse via
npx lighthouseé opcional mas recomendado no build de produção; se não puder ser executado, dizer isso em vez de estimar.