Debugging Avanzado de Tests E2E
Sistema completo de debugging para tests end-to-end en Floutic, inspirado en patrones de agent-browser (Vercel Labs) pero implementado con Playwright.
Última actualización: 28 Enero 2026
Documentación principal: frontend/tests/DEBUGGING_GUIDE.md
Demo interactiva: frontend/tests/debug-helpers-demo.spec.ts
Script de debugging: scripts/debug_e2e.sh
🚀 Quick Start
Ejecutar Demo Completa
/test e2e demo
Este comando ejecuta frontend/tests/debug-helpers-demo.spec.ts con:
- Navegador visible
- Grabación de video
- Snapshots visuales
- Captura de errores de consola
- Debugging de red
Debug Interactivo
/test e2e debug login-test.spec.ts
Abre el Playwright Inspector para debugging paso a paso.
📦 Módulo DebugHelpers
El módulo DebugHelpers en frontend/tests/utils/debug-helpers.ts proporciona 12 métodos estáticos para debugging avanzado.
1. Captura de Errores de Consola
Detecta automáticamente errores de consola durante la ejecución del test.
import { DebugHelpers } from '../tests/utils/debug-helpers';
test('test sin errores de consola', async ({ page }) => {
DebugHelpers.captureConsoleErrors(page);
// ... acciones del test
DebugHelpers.assertNoConsoleErrors(); // Falla si hay errores
});
Métodos disponibles:
captureConsoleErrors(page)- Inicia captura de erroresgetConsoleErrors()- Obtiene errores capturadosassertNoConsoleErrors()- Falla si hay erroresclearConsoleErrors()- Limpia errores capturados
Ejecutar: /test e2e debug [test_file] console
Similar a: agent-browser errors
2. Debugging de Red
Analiza todas las requests HTTP para detectar fallos y lentitud.
test('verificar requests de red', async ({ page }) => {
DebugHelpers.setupNetworkDebugging(page);
// ... acciones del test
const failedRequests = DebugHelpers.getFailedRequests();
expect(failedRequests.length).toBe(0);
const slowRequests = DebugHelpers.getSlowRequests(2000);
if (slowRequests.length > 0) {
console.warn(`Requests lentas: ${slowRequests.length}`);
}
});
Métodos disponibles:
setupNetworkDebugging(page)- Inicia logging de redgetNetworkLogs()- Obtiene todos los logsgetFailedRequests()- Filtra requests fallidas (status >= 400)getSlowRequests(threshold)- Filtra requests lentas
Ejecutar: /test e2e debug [test_file] network
Similar a: agent-browser network requests
3. Grabación de Video Manual
Graba videos manualmente para demos y documentación.
test('grabar demo de login', async ({ context }) => {
const videoPage = await DebugHelpers.startManualVideoRecording(context, 'videos');
try {
await videoPage.goto('/login');
// ... acciones
} finally {
await DebugHelpers.stopManualVideoRecording(videoPage);
}
});
Métodos disponibles:
startManualVideoRecording(context, outputPath, size)- Inicia grabaciónstopManualVideoRecording(page)- Detiene y guarda video
Ejecutar: /test e2e debug [test_file] video
Similar a: agent-browser record start/stop
4. Ejecución de JavaScript
Ejecuta JavaScript en el contexto del navegador para inspeccionar el estado.
test('ejecutar JavaScript', async ({ page }) => {
await TestUtils.loginAsExperto(page);
const title = await DebugHelpers.evaluateAndLog(page, () => document.title);
expect(title).toContain('Dashboard');
const authState = await DebugHelpers.evaluateAndLog(page, () => {
const authService = (window as any).secureAuthService;
return {
isAuthenticated: authService?.isAuthenticated?.() ?? false,
hasAccessToken: !!authService?.getAccessToken?.(),
};
});
});
Métodos disponibles:
evaluateAndLog(page, script, args, description)- Ejecuta y loguea
Similar a: agent-browser eval
5. Snapshots Visuales
Captura el estado visual de la página en cualquier momento.
test('snapshots visuales', async ({ page }) => {
await page.goto('/login');
await DebugHelpers.takeSnapshot(page, '01-inicial', {
screenshot: true,
html: false,
elements: true,
network: false,
});
await page.fill('[data-testid="username-input"]', 'user');
await DebugHelpers.takeSnapshot(page, '02-formulario-lleno');
await page.click('[data-testid="submit-button"]');
await DebugHelpers.takeSnapshot(page, '03-dashboard');
});
Métodos disponibles:
takeSnapshot(page, name, options)- Captura snapshotscreenshot: true- Captura screenshothtml: true- Loguea preview de HTMLelements: true- Loguea elementos con data-testidnetwork: true- Loguea requests de red
Similar a: agent-browser snapshot
6. Esperas Avanzadas
Múltiples estrategias de espera para diferentes escenarios.
test('esperas avanzadas', async ({ page }) => {
await TestUtils.loginAsAdmin(page);
// Esperar texto específico
await DebugHelpers.waitForText(page, 'Dashboard');
// Esperar patrón de URL
await DebugHelpers.waitForURLPattern(page, '**/dashboard/admin**');
// Esperar condición personalizada
await DebugHelpers.waitForCustomCondition(page, async () => {
const isAuthenticated = await page.evaluate(() => {
return fetch('/api/users/me', { credentials: 'include' })
.then(r => r.ok)
.catch(() => false);
});
return isAuthenticated;
}, 'User authenticated', 10000);
});
Métodos disponibles:
waitForText(page, text, options)- Espera texto en la páginawaitForURLPattern(page, pattern, timeout)- Espera patrón de URLwaitForCustomCondition(page, condition, description, timeout)- Espera condición custom
Similar a: agent-browser wait --text/--url/--fn
7. Información de Elementos
Obtiene información detallada de elementos para debugging.
test('info de elementos', async ({ page }) => {
await TestUtils.loginAsEmpresa(page);
const dashboardTitle = page.locator('[data-testid="empresa-dashboard-title"]');
const info = await DebugHelpers.getElementInfo(page, dashboardTitle);
console.log('Dashboard Title:', info);
// {
// visible: true,
// text: 'Dashboard Empresa',
// tagName: 'h1',
// className: 'text-2xl font-bold',
// boundingBox: { x: 0, y: 0, width: 800, height: 40 },
// attributes: { 'data-testid': 'empresa-dashboard-title', ... }
// }
});
Métodos disponibles:
getElementInfo(page, selector)- Obtiene información detalladaassertElementVisibleAndInteractable(page, selector, description)- Verifica visibilidad
8. Información Completa de la Página
Muestra un resumen completo del estado de la página.
test('info completa', async ({ page }) => {
await page.goto('/login');
await DebugHelpers.showPageInfo(page);
// Output:
// 📊 Page Info:
// URL: http://localhost:3000/login
// Title: Login - Floutic
// Cookies: 2
// LocalStorage: [cookies-accepted, ...]
// SessionStorage: []
// Viewport: 1280x720
// Console Errors: 0
});
Métodos disponibles:
showPageInfo(page)- Muestra información completapause()- Pausa ejecución (solo en modo debug)
🎬 Script de Debugging
El script scripts/debug_e2e.sh facilita la ejecución de tests con debugging.
Modos Disponibles
./scripts/debug_e2e.sh [test_file] [mode]
| Mode | Descripción | Ejemplo |
|---|---|---|
headed | Navegador visible | /test e2e debug login-test.spec.ts headed |
debug | Playwright Inspector interactivo | /test e2e debug login-test.spec.ts debug |
ui | UI interactiva completa | /test e2e debug login-test.spec.ts ui |
trace | Traces completas | /test e2e debug login-test.spec.ts trace |
video | Grabación de video | /test e2e debug login-test.spec.ts video |
console | Errores de consola | /test e2e debug login-test.spec.ts console |
network | Logging de red | /test e2e debug login-test.spec.ts network |
snapshot | Snapshots visuales | /test e2e debug login-test.spec.ts snapshot |
demo | Todos los features | /test e2e demo |
Características del Script
- ✅ Verificación automática de Docker
- ✅ Preparación de directorios (snapshots/, videos/)
- ✅ Opción de resetear base de datos
- ✅ Post-ejecución: ver reportes, snapshots, videos
- ✅ Colores para mejor UX
- ✅ Ayuda integrada
📂 Directorios de Output
Snapshots Visuales
Ubicación: frontend/snapshots/
Contiene screenshots de los tests cuando se usan DebugHelpers.takeSnapshot().
ls -lh frontend/snapshots/
# 01-login-page.png
# 02-form-filled.png
# 03-dashboard-loaded.png
Videos de Tests
Ubicación: frontend/videos/
Contiene videos de ejecución de tests cuando se habilita la grabación.
ls -lh frontend/videos/
# demo-login.webm
# dashboard-test.webm
Reportes HTML
Ubicación: frontend/playwright-report/
Reportes HTML de los tests ejecutados.
cd frontend
npx playwright show-report
🎯 Patrones de Debugging Comunes
Pattern 1: Debug de Login Fallido
test('debug login fallido', async ({ page }) => {
DebugHelpers.captureConsoleErrors(page);
DebugHelpers.setupNetworkDebugging(page);
await DebugHelpers.takeSnapshot(page, '01-inicial');
await page.goto('/login');
await page.fill('[data-testid="username-input"]', 'wrong');
await page.fill('[data-testid="password-input']', 'wrong');
await DebugHelpers.takeSnapshot(page, '02-formulario-lleno');
await page.click('[data-testid="submit-button"]');
await DebugHelpers.takeSnapshot(page, '03-error-mostrado');
await DebugHelpers.showPageInfo(page);
});
Pattern 2: Debug de API Requests
test('debug API requests', async ({ page }) => {
DebugHelpers.setupNetworkDebugging(page);
await TestUtils.loginAsEmpresa(page);
await page.goto('/proyectos');
await page.click('[data-testid="create-project-button"]');
const logs = DebugHelpers.getNetworkLogs();
const apiRequests = logs.filter(log => log.url.includes('/api/'));
console.log('API requests:', apiRequests);
const failed = DebugHelpers.getFailedRequests();
expect(failed.length).toBe(0);
});
Pattern 3: Debug de Estado de Autenticación
test('debug auth state', async ({ page }) => {
await TestUtils.loginAsExperto(page);
const authState = await DebugHelpers.evaluateAndLog(page, () => {
const authService = (window as any).secureAuthService;
return {
isAuthenticated: authService?.isAuthenticated?.() ?? false,
hasAccessToken: !!authService?.getAccessToken?.(),
hasRefreshToken: !!authService?.getRefreshToken?.(),
userRole: authService?.getUser?.()?.role,
};
});
expect(authState.isAuthenticated).toBe(true);
expect(authState.hasAccessToken).toBe(true);
expect(authState.userRole).toBe('experto');
});
Pattern 4: Debug de UI Invisible
test('debug elemento invisible', async ({ page }) => {
await page.goto('/dashboard');
const element = page.locator('[data-testid="hidden-element"]');
const isVisible = await element.isVisible();
console.log('Is visible:', isVisible);
const info = await DebugHelpers.getElementInfo(page, element);
console.log('Element info:', info);
const styles = await page.evaluate(selector => {
const el = document.querySelector(selector);
if (!el) return null;
const computed = getComputedStyle(el);
return {
display: computed.display,
visibility: computed.visibility,
opacity: computed.opacity,
};
}, '[data-testid="hidden-element"]');
console.log('Computed styles:', styles);
});
🆚 Comparación: Agent-Browser vs DebugHelpers
| Feature | agent-browser | DebugHelpers |
|---|---|---|
| Console errors | ✅ agent-browser errors | ✅ captureConsoleErrors() |
| Network logging | ✅ agent-browser network requests | ✅ setupNetworkDebugging() |
| Video recording | ✅ agent-browser record start/stop | ✅ startManualVideoRecording() |
| JavaScript exec | ✅ agent-browser eval | ✅ evaluateAndLog() |
| Snapshot | ✅ agent-browser snapshot | ✅ takeSnapshot() |
| Wait conditions | ✅ agent-browser wait --text/--url | ✅ waitForText/URL/Condition() |
| Integration | ❌ Requiere setup externo | ✅ Integrado en Playwright |
| Stability | ⚠️ Alpha/Experimental | ✅ Estable |
| Documentation | ⚠️ Parcial | ✅ Completa |
| Community | Pequeña (6k forks) | Grande (60k forks) |
📚 Recursos Adicionales
Documentación
- Guía completa de debugging - Referencia completa con ejemplos
- Test de demo - 11+ ejemplos de debugging
- Resumen de implementación - Todos los cambios realizados
Skills
- Playwright Skill - Patrones de testing
- Comando /test - Comando unificado
Documentación de Playwright
🎓 Cómo Empezar
Paso 1: Ejecutar Demo
/test e2e demo
Paso 2: Leer Guía
cat frontend/tests/DEBUGGING_GUIDE.md
Paso 3: Usar en un Test Existente
import { test, expect } from '@playwright/test';
import { DebugHelpers } from '../tests/utils/debug-helpers';
test('mi test con debugging', async ({ page }) => {
DebugHelpers.captureConsoleErrors(page);
DebugHelpers.setupNetworkDebugging(page);
await DebugHelpers.takeSnapshot(page, '01-inicio');
// ... acciones del test
DebugHelpers.assertNoConsoleErrors();
await DebugHelpers.takeSnapshot(page, '02-fin');
});
Paso 4: Debug con Script
# Debug interactivo
/test e2e debug mi-test.spec.ts
# Solo console errors
/test e2e debug mi-test.spec.ts console
# Full debugging
/test e2e debug mi-test.spec.ts demo
Implementación completada: 28 Enero 2026 Métodos de DebugHelpers: 12 Ejemplos de debugging: 11+ Modos de debugging: 9 Total de líneas de código: ~2,100