Saltar al contenido principal

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 errores
  • getConsoleErrors() - Obtiene errores capturados
  • assertNoConsoleErrors() - Falla si hay errores
  • clearConsoleErrors() - 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 red
  • getNetworkLogs() - Obtiene todos los logs
  • getFailedRequests() - 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ón
  • stopManualVideoRecording(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 snapshot
    • screenshot: true - Captura screenshot
    • html: true - Loguea preview de HTML
    • elements: true - Loguea elementos con data-testid
    • network: 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ágina
  • waitForURLPattern(page, pattern, timeout) - Espera patrón de URL
  • waitForCustomCondition(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 detallada
  • assertElementVisibleAndInteractable(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 completa
  • pause() - 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]
ModeDescripciónEjemplo
headedNavegador visible/test e2e debug login-test.spec.ts headed
debugPlaywright Inspector interactivo/test e2e debug login-test.spec.ts debug
uiUI interactiva completa/test e2e debug login-test.spec.ts ui
traceTraces completas/test e2e debug login-test.spec.ts trace
videoGrabación de video/test e2e debug login-test.spec.ts video
consoleErrores de consola/test e2e debug login-test.spec.ts console
networkLogging de red/test e2e debug login-test.spec.ts network
snapshotSnapshots visuales/test e2e debug login-test.spec.ts snapshot
demoTodos 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

Featureagent-browserDebugHelpers
Console errorsagent-browser errorscaptureConsoleErrors()
Network loggingagent-browser network requestssetupNetworkDebugging()
Video recordingagent-browser record start/stopstartManualVideoRecording()
JavaScript execagent-browser evalevaluateAndLog()
Snapshotagent-browser snapshottakeSnapshot()
Wait conditionsagent-browser wait --text/--urlwaitForText/URL/Condition()
Integration❌ Requiere setup externo✅ Integrado en Playwright
Stability⚠️ Alpha/Experimental✅ Estable
Documentation⚠️ Parcial✅ Completa
CommunityPequeña (6k forks)Grande (60k forks)

📚 Recursos Adicionales

Documentación

Skills

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