name: web-qa-visual description: Verifica webs con Playwright CLI antes de darlas por terminadas: errores de consola, requests fallidas, overflow responsive a 375/414/768/1280/1440, accesibilidad axe, teclado y foco, reduced-motion, enlaces, SEO/meta y métricas de carga. Úsala al testear una web, tras cada cambio grande o para validar un deploy.
QA visual con Playwright CLI
Regla de oro: sin salida de comando fresca no hay veredicto. Nada de "debería verse bien".
Setup mínimo
- Playwright como devDependency del proyecto;
playwright.config.tscon viewport explícito de 375px (nodevices['Pixel 7'], que son 412px) y proyectosdesktop-chromeymobile-chrome. - Scripts de captura en
scripts/shot.mjs(no usar MCP para esto: el CLI es más rápido y reproducible). - Para axe:
@axe-core/playwright. - Servir el build de producción (
npm run build && npm run start) para medir rendimiento real; usar dev solo para depurar.
Chequeos por página y por locale
- Consola y red:
page.on('console'),page.on('pageerror'),page.on('requestfailed')y respuestas ≥400. Fallo = rojo. - Overflow: en cada viewport comprobar
document.documentElement.scrollWidth <= clientWidth + 1; si hay desborde, listar los elementos culpables (getBoundingClientRect().right > innerWidth). - Accesibilidad: axe sin violaciones
critical/serious; un soloh1;img[alt]completo; foco visible en todo elemento interactivo (comprobar:focus-visiblecon teclado real, no CSS a ojo); orden de tabulación lógico. - Reduced motion:
page.emulateMedia({ reducedMotion: 'reduce' }); no debe haber pin, autoplay ni animación de más de 200ms. - Enlaces: extraer todos los
href, validar los internos (200) y marcar externos como informativos; 0href="#"sin controlador. - SEO:
title,meta description, canonical, OG,hreflangpor locale, JSON-LD parseable,sitemap.xmlyrobots.txt200. - Rendimiento: medir LCP/CLS con PerformanceObserver tras cargar; objetivo LCP < 2.5s y CLS < 0.1 en desktop; medir jank de scroll contando frames largos (>50ms) con rAF durante 5s de scroll automatizado.
- Canvas/scroll: como el canvas puede salir negro en headless, verificar por DOM: elementos con opacidad/transform esperados, textos de los beats presentes y visibles en los rangos correctos, y estado expuesto en
windowsi existe.
Loop
- Tras cada ejecución: informe con tabla gate/comando/resultado/estado y lista de bloqueantes con evidencia (selector, log o captura).
- Si un gate falla: arreglar (tests/scripts propios) o proponer el fix concreto de
src/con evidencia; repetir el ciclo completo. - Guardar capturas fechadas en
docs/qa/(desktop + móvil por locale principal) y baseline para comparar regresiones. - No declarar LISTO con un gate en rojo o sin ejecutar.
Límites honestos
- No se puede validar una secuencia de frames en iOS real desde headless: dejarlo escrito en el informe.
- Lighthouse vía
npx lighthousees opcional pero recomendable en el build de producción; si no se puede ejecutar, decirlo en vez de estimar.