# Capturas de pantalla Cómo producir las capturas que acompañarán a los manuales. Esta guía presupone que tienes instalada la skill `playwright-skill` de lackeyjb. ## Configuración del navegador - **Viewport**: 1440×900 px (escritorio estándar). - **Factor de escala**: 2 (DPR 2). Resultado: imagen a 2880×1800. Reduce al 50% en el CSS con `max-width: 100%` y `image-rendering: -webkit-optimize-contrast`. - **Localización**: `es-ES` (o la del usuario). Forzar la zona horaria de la operación si afecta a la UI. - **User agent**: dejar el de Chromium por defecto. - **Modo headless**: recomendado. Usar `headless: true` para ejecuciones desatendidas. Reservar headed para depuración puntual. Plantilla de configuración para `playwright-skill`: ```bash export PW_HEADLESS=true export PW_ARTIFACT_DIR="$PWD/artifacts" node "$SKILL_DIR/run.js" "$TMP_DIR/capturar-flujo.js" ``` ## Resolución y nombrado - Tamaño final recomendado: entre 1200 y 1600 px de ancho (después del downscale). Más grande no mejora la impresión y aumenta el peso del PDF. - Formato: PNG para capturas con texto nítido. JPEG (`quality: 80`) para pantallas con muchas fotos. - Nombres de archivo: `NN-slug-corto.png` donde `NN` es el número de paso. Ejemplo: `01-login.png`, `02-panel-principal.png`, `03-formulario-cliente.png`. - Guardar todas las capturas dentro de `artifacts/` en la raíz del manual. El build copia esa carpeta al directorio temporal de render. ## Antes de capturar 1. **Sesión limpia**: cierra banners de cookies, notificaciones push y tooltips de onboarding. Si la app tiene un banner de "tour", descártalo. 2. **Datos consistentes**: usa siempre el mismo usuario de pruebas, mismo idioma y mismo conjunto de datos. Cualquier inconsistencia se notará en el manual. 3. **Quita lo accesorio**: oculta elementos beta, flags, datos personales reales, mensajes transitorios. No falsees pantallas: si un paso intermedio no es representativo, no lo fotografíes. 4. **Espera activa**: usa `await page.locator(...).waitFor({ state: 'visible' })` o `await page.getByRole(...).waitFor()` en lugar de `waitForTimeout`. La captura debe hacerse después de que la UI termine de actualizarse. ## Encuadre - Captura la pantalla completa con `fullPage: true` solo si la página entera es el contenido relevante. Para vistas con scroll, prefiere captura del viewport (`fullPage: false`). - Recorta a la zona de interés con `page.locator(selector).screenshot({ path })` cuando solo importa un componente (por ejemplo, un modal). - Deja al menos 16pt de margen visual alrededor del elemento principal. - Incluye en la captura el contexto suficiente para que el lector se ubique: la barra de navegación, el breadcrumb o el encabezado de sección son válidos. - Evita capturas con scrollbars visibles a menos que sea indispensable. ## Privacidad y seguridad - **Nunca** incluyas contraseñas, tokens, claves API, datos personales reales o números de identificación reales. Sustituye por placeholders tipográficos como `usuario@ejemplo.com`, `••••••••`, `1234567X` o cuentas de prueba claramente ficticias. - Antes de capturar, valida que la vista no contenga datos sensibles: usa cuentas de test y datos sintéticos. - Si necesitas capturar un error real, anonimiza la URL y los IDs antes de pegarla en el manual. - Revisa el fondo de la captura: pueden aparecer datos de otras pestañas sincronizadas, notificaciones del sistema o fechas de la máquina. ## Anotaciones Las anotaciones se aplican en el HTML con la clase `.annotations` y el atributo `data-annotations`. Cada elemento del array es un marcador posicionado en porcentaje respecto a la imagen: ```html
Pantalla de inicio de sesión
    Inicio de sesión con credenciales de prueba.
    ``` Convenciones: - `x` y `y` son porcentajes sobre el ancho y alto de la imagen. 0/0 es la esquina superior izquierda, 100/100 la inferior derecha. - `n` es el número que se muestra en el círculo. Debe coincidir con el orden lógico del paso (1, 2, 3…). - `label` es texto accesible (lectores de pantalla) y se usa como tooltip al pasar el cursor. - En el manual impreso, los marcadores se muestran en blanco con borde primary, número primary. ## Plantilla de script Playwright ```javascript const { chromium } = require('playwright'); const path = require('node:path'); const fs = require('node:fs'); const TARGET = process.env.TARGET_URL || 'http://localhost:3000'; const ART = process.env.PW_ARTIFACT_DIR || path.join(process.cwd(), 'artifacts'); fs.mkdirSync(ART, { recursive: true }); (async () => { const browser = await chromium.launch({ headless: true }); const context = await browser.newContext({ viewport: { width: 1440, height: 900 }, deviceScaleFactor: 2, locale: 'es-ES', timezoneId: 'Europe/Madrid', }); const page = await context.newPage(); // Paso 1: login await page.goto(`${TARGET}/login`); await page.getByLabel('Email').waitFor(); await page.screenshot({ path: path.join(ART, '01-login.png'), fullPage: false }); // Paso 2: panel principal await page.getByLabel('Email').fill('demo@factorpesca.com'); await page.getByLabel('Contraseña').fill('Demo-2025!'); await page.getByRole('button', { name: 'Iniciar sesión' }).click(); await page.getByRole('heading', { name: /panel/i }).waitFor(); await page.screenshot({ path: path.join(ART, '02-panel.png'), fullPage: false }); await browser.close(); })(); ``` Guarda el script como `scripts/capturar.js` y ejecútalo a través de la skill `playwright-skill` con `node "$SKILL_DIR/run.js" capturar.js`. ## Verificación rápida Antes de pasar al redactor, ejecuta este checklist: - [ ] Las capturas se ven nítidas a tamaño real (sin pixelado al 100%). - [ ] El texto de la UI es legible. - [ ] No hay datos personales reales. - [ ] El número de capturas coincide con el número de pasos previstos. - [ ] Los nombres de archivo siguen el patrón `NN-slug.png`. - [ ] Cada captura muestra el estado final del paso anterior, no un estado intermedio de carga. - [ ] Los banners de cookies, tooltips de onboarding y notificaciones de "tour" están cerrados.