docs: enterprise refactor plan with ralph specs
This commit is contained in:
124
.ralph/specs/legacy/visual-regression.md
Normal file
124
.ralph/specs/legacy/visual-regression.md
Normal file
@@ -0,0 +1,124 @@
|
||||
# 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
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user