Files
Autonomous-Bug-Explorer/.ralph/specs/legacy/visual-regression.md

125 lines
3.9 KiB
Markdown

# ABE — Visual Regression Testing Specification
## Concepto
ABE toma screenshots durante la exploración. En vez de solo guardarlos,
los compara contra una baseline aprobada para detectar cambios visuales
inesperados entre ejecuciones. Inspirado en Percy y Chromatic,
pero integrado directamente en el flujo de exploración autónoma.
## Cómo funciona
### Primera ejecución (sin baseline)
1. ABE explora el app, toma screenshots de cada estado descubierto
2. Todos los screenshots se marcan como "pending review" en la UI
3. El usuario aprueba o rechaza cada uno desde la GUI
4. Los aprobados se convierten en la BASELINE
### Ejecuciones posteriores
1. ABE explora el app, toma screenshots de cada estado
2. Para cada screenshot, busca la baseline correspondiente por state_id (hash DOM+URL)
3. Si no hay baseline: marcar como "new state", notificar
4. Si hay baseline: comparar usando pixelmatch (npm library)
5. Si diff > threshold (default 0.1%): crear anomalía tipo visual_regression
6. Si diff <= threshold: marcar como "passed"
## Librería de comparación
Usar `pixelmatch` (npm) para comparación pixel a pixel.
Usar `sharp` para resize y normalización de imágenes antes de comparar.
```typescript
import pixelmatch from 'pixelmatch';
import sharp from 'sharp';
async function compareScreenshots(
baselinePath: string,
currentPath: string,
diffOutputPath: string,
threshold: number = 0.1
): Promise<{ diffPixels: number; diffPercent: number; hasDiff: boolean }> {
// resize both to same dimensions, compare, generate diff image
}
```
## Modelo de datos — añadir a SQLite
### Table: visual_baselines
```sql
CREATE TABLE IF NOT EXISTS visual_baselines (
id TEXT PRIMARY KEY,
state_id TEXT NOT NULL,
url TEXT NOT NULL,
screenshot_path TEXT NOT NULL,
approved_at INTEGER NOT NULL,
approved_by TEXT DEFAULT 'user',
width INTEGER NOT NULL,
height INTEGER NOT NULL
);
```
### Table: visual_comparisons
```sql
CREATE TABLE IF NOT EXISTS visual_comparisons (
id TEXT PRIMARY KEY,
session_id TEXT NOT NULL,
state_id TEXT NOT NULL,
baseline_id TEXT,
current_screenshot_path TEXT NOT NULL,
diff_screenshot_path TEXT,
diff_pixels INTEGER,
diff_percent REAL,
status TEXT NOT NULL, -- 'passed' | 'failed' | 'new_state' | 'pending'
created_at INTEGER NOT NULL
);
```
## Nuevo tipo de anomalía
Añadir a AnomalyDetector:
- type: `visual_regression`
- severity: calculado por diff_percent:
- < 1% → low
- 1-5% → medium
- 5-15% → high
- > 15% → critical
- description: "Visual regression detected: X% of pixels changed"
- evidence: baseline screenshot + current screenshot + diff image (highlighted in red)
## Nuevo endpoint de API
### GET /api/visual/comparisons
Lista todas las comparaciones de la sesión más reciente.
Query: ?status=failed&sessionId=xxx
### POST /api/visual/baselines/:comparisonId/approve
Aprueba un screenshot como nueva baseline.
### POST /api/visual/baselines/:comparisonId/reject
Rechaza (anomalía confirmada, no actualizar baseline).
### POST /api/visual/baselines/approve-all
Aprueba todos los "new_state" pendientes de una sesión.
## Frontend — nueva sección Visual Review
Nueva página /visual-review:
- Grid de cards, cada una muestra: URL del estado, thumbnail del screenshot actual
- Filtros: passed | failed | new_state | pending
- Click en una card abre modal con:
- Vista lado a lado: baseline izquierda, actual derecha
- Vista diff: imagen con píxeles cambiados en rojo
- Porcentaje de cambio
- Botones: Approve as new baseline | Mark as bug | Ignore
- Bulk actions: "Approve all new states", "Mark all failed as bugs"
## Configuración
Añadir a ExplorationConfig:
```typescript
visualRegression: {
enabled: boolean; // default: true
threshold: number; // default: 0.001 (0.1%)
screenshotFullPage: boolean; // default: false (solo viewport)
ignoreSelectors: string[]; // e.g. [".timestamp", ".ad-banner"] — excluir zonas dinámicas
}
```