primer commit
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
# 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
|
||||
<figure class="screenshot-frame">
|
||||
<img src="artifacts/01-login.png" alt="Pantalla de inicio de sesión" />
|
||||
<ol class="annotations" data-annotations='[
|
||||
{"x": 62, "y": 58, "n": 1, "label": "Botón Iniciar sesión"},
|
||||
{"x": 50, "y": 74, "n": 2, "label": "Campo contraseña"}
|
||||
]'></ol>
|
||||
<figcaption>Inicio de sesión con credenciales de prueba.</figcaption>
|
||||
</figure>
|
||||
```
|
||||
|
||||
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.
|
||||
Reference in New Issue
Block a user