Ir al contenido

Tests automatizados end-to-end usando Playwright para verificar flujos completos de la aplicación bilingüe (ES/EN).

e2e-tests/
├── tests/ # Archivos de tests
│ ├── accountSecurityTests.spec.ts # Exportar datos GDPR + eliminar cuenta (12 tests) ✨
│ ├── adminTests.spec.ts # Tests del panel de administración (33 tests)
│ ├── adminCrudTests.spec.ts # Tests CRUD completos de admin (43 tests) ✨
│ ├── authTests.spec.ts # Tests de autenticación (18 tests)
│ ├── certificateTests.spec.ts # Tests de certificados (28 tests)
│ ├── commentsTests.spec.ts # Tests de comentarios (bilingüe)
│ ├── courseTests.spec.ts # Tests de cursos (20 tests)
│ ├── demoAppTests.spec.ts # Tests de la demo app
│ ├── emailVerificationTests.spec.ts # Tests de verificación de email (23 tests) ✨
│ ├── enrollmentTests.spec.ts # Tests de inscripción
│ ├── fileUploadTests.spec.ts # Tests de subida de archivos (bilingüe)
│ ├── instructorTests.spec.ts # Tests de instructores (30 tests) ✨
│ ├── landingPageTests.spec.ts # Tests de landing page (14 tests)
│ ├── lessonResourcesTests.spec.ts # Tests de recursos de lecciones (56 tests) ✨
│ ├── navigationTests.spec.ts # Tests de navegación (34 tests)
│ ├── passwordResetTests.spec.ts # Tests de recuperación de contraseña (bilingüe)
│ ├── paymentTests.spec.ts # Tests de pagos Stripe (13 tests)
│ ├── pricingPageTests.spec.ts # Tests de página de precios
│ ├── promoCodeTests.spec.ts # Tests de códigos promocionales (bilingüe)
│ ├── publicProfileTests.spec.ts # Tests de perfiles públicos
│ ├── quizTests.spec.ts # Tests de quizzes (bilingüe)
│ ├── referralTests.spec.ts # Tests de sistema de referidos (22 tests)
│ ├── reviewsTests.spec.ts # Tests de reseñas CRUD (69 tests) ✨
│ ├── socialAuthTests.spec.ts # Tests de OAuth social (30 tests) ✨
│ ├── teamsTests.spec.ts # Tests de Teams/Enterprise (37 tests) ✨
│ ├── userProfileTests.spec.ts # Tests de perfil de usuario (33 tests)
│ └── utils.ts # Utilidades y helpers compartidos
├── playwright.config.ts # Configuración de Playwright
├── package.json # Scripts y dependencias
└── README.md # Documentación técnica

✨ = Tests nuevos añadidos recientemente

Ventana de terminal
cd e2e-tests
npm install
npx playwright install chromium
Ventana de terminal
# Terminal 1 - Base de datos
cd app
wasp db start
# Terminal 2 - Servidor de desarrollo
cd app
wasp start
# Terminal 3 - Stripe webhook listener (solo para tests de pago)
stripe listen --forward-to localhost:3001/payments-webhook

En app/.env.server:

Ventana de terminal
# CRÍTICO - Desactiva verificación de email en desarrollo
SKIP_EMAIL_VERIFICATION_IN_DEV=true
# Stripe (modo test) - para tests de pago
STRIPE_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
# SendGrid (opcional - si no está, emails se imprimen en consola)
SENDGRID_API_KEY=...
Ventana de terminal
cd e2e-tests
# Interfaz de Playwright + Stripe webhook (recomendado)
npm run local:e2e:start
# Solo tests principales (ignora opcionales)
npm run local:e2e:useful-ui
# Todos los tests en modo headless
npm run e2e:playwright
# Tests específicos
npx playwright test authTests.spec.ts
npx playwright test paymentTests.spec.ts --headed
ScriptDescripción
e2e:playwrightEjecuta todos los tests en modo headless
e2e:useful-onlyTests principales (ignora comentarios, quizzes, referidos, archivos, promo codes)
local:e2e:startRecomendado: Playwright UI + inicia Stripe webhook listener
local:e2e:useful-uiPlaywright UI solo con tests principales
local:e2e:playwright:uiPlaywright UI con SKIP_EMAIL_VERIFICATION_IN_DEV=true
test:validationValida que todas las variables de entorno requeridas estén presentes
ArchivoTestsCoberturaComando
accountSecurityTests.spec.ts12Exportar datos GDPR, eliminar cuenta, confirmación con frase, post-deletion loginnpx playwright test accountSecurityTests.spec.ts
adminCrudTests.spec.ts43CRUD usuarios, cursos, lecciones, quizzes desde el panel adminnpx playwright test adminCrudTests.spec.ts
adminTests.spec.ts33Panel de administración, métricas, gestión de usuarios y cursosnpx playwright test adminTests.spec.ts
authenticationTests.spec.ts18Registro, login, logout, sesiones, soporte bilingüenpx playwright test authenticationTests.spec.ts
certificateTests.spec.ts28Generación, descarga, verificación pública, compartir en redesnpx playwright test certificateTests.spec.ts
commentsTests.spec.ts~30Q&A en lecciones, respuestas, votos, marcar soluciónnpx playwright test commentsTests.spec.ts
courseTests.spec.ts20Listado, filtros, búsqueda, detalles, categoríasnpx playwright test courseTests.spec.ts
demoAppTests.spec.ts~10Demo de IA, uso de créditos, respuestas GPTnpx playwright test demoAppTests.spec.ts
emailVerificationTests.spec.ts23Flujo de verificación, tokens, reenvío, modo devnpx playwright test emailVerificationTests.spec.ts
enrollmentTests.spec.ts19Inscripción en cursos, progreso de lecciones, certificadosnpx playwright test enrollmentTests.spec.ts
fileUploadTests.spec.ts~15Subida de archivos, validación de tipo y tamaño, descarganpx playwright test fileUploadTests.spec.ts
instructorTests.spec.ts30Perfiles de instructor, CRUD admin, asignación a cursosnpx playwright test instructorTests.spec.ts
landingPageTests.spec.ts14Hero, features, FAQ, CTA, language switchernpx playwright test landingPageTests.spec.ts
lessonResourcesTests.spec.ts56Recursos descargables, S3, validación, permisos por rolnpx playwright test lessonResourcesTests.spec.ts
navigationTests.spec.ts34Header, footer, rutas protegidas, menú de usuario, i18nnpx playwright test navigationTests.spec.ts
passwordResetTests.spec.ts~15Solicitud de reset, tokens, nueva contraseña, bilingüenpx playwright test passwordResetTests.spec.ts
paymentTests.spec.ts13Checkout Stripe, suscripciones, créditos, portal de clientenpx playwright test paymentTests.spec.ts
pricingPageTests.spec.ts~10Planes de precios, toggle mensual/anual, CTAnpx playwright test pricingPageTests.spec.ts
promoCodeTests.spec.ts~15Crear, aplicar, validar y eliminar códigos promocionalesnpx playwright test promoCodeTests.spec.ts
publicProfileTests.spec.ts22Perfiles públicos, privacidad, username úniconpx playwright test publicProfileTests.spec.ts
quizTests.spec.ts~20Quizzes por lección, examen final, score, intentosnpx playwright test quizTests.spec.ts
referralTests.spec.ts22Generación de códigos, tracking, recompensas, leaderboardnpx playwright test referralTests.spec.ts
reviewsTests.spec.ts69CRUD reseñas, ratings 1-5, promedio, distribuciónnpx playwright test reviewsTests.spec.ts
socialAuthTests.spec.ts30OAuth Google y GitHub, URLs, flujo, accesibilidadnpx playwright test socialAuthTests.spec.ts
teamsTests.spec.ts37Landing /teams, formulario demo, secciones, responsivenpx playwright test teamsTests.spec.ts
twoFactorTests.spec.ts~8Setup 2FA, TOTP, backup codes, desactivar 2FAnpx playwright test twoFactorTests.spec.ts
userProfileTests.spec.ts33Editar perfil, avatar, bio, links sociales, privacidadnpx playwright test userProfileTests.spec.ts
Ventana de terminal
# Solo los tests de seguridad de cuenta (GDPR)
npx playwright test accountSecurityTests.spec.ts twoFactorTests.spec.ts
# Solo los tests de autenticación
npx playwright test authenticationTests.spec.ts emailVerificationTests.spec.ts socialAuthTests.spec.ts passwordResetTests.spec.ts
# Solo los tests de cursos y aprendizaje
npx playwright test courseTests.spec.ts enrollmentTests.spec.ts certificateTests.spec.ts quizTests.spec.ts lessonResourcesTests.spec.ts
# Solo los tests de monetización
npx playwright test paymentTests.spec.ts pricingPageTests.spec.ts promoCodeTests.spec.ts referralTests.spec.ts
# Solo los tests de admin
npx playwright test adminTests.spec.ts adminCrudTests.spec.ts
# Tests con un patrón en el nombre
npx playwright test --grep "Export my data"
npx playwright test --grep "Delete my account"
npx playwright test --grep "Danger Zone"
export default defineConfig({
testDir: "./tests",
fullyParallel: true, // Permite paralelización
workers: process.env.CI ? 1 : 4, // Múltiples workers en local
reporter: "html",
use: {
baseURL: "http://localhost:3000",
trace: "on-first-retry",
screenshot: "only-on-failure",
video: "retain-on-failure",
},
timeout: 60000, // 60 segundos por test
});

IMPORTANTE: Los tests NO inician automáticamente el servidor. Debes tener wasp start corriendo.

TODOS los tests soportan español e inglés usando regex patterns:

// ✅ Correcto: Soporta ES + EN
await page.getByRole("button", { name: /Buy Plan|Comprar Plan/i });
await page.getByRole("link", { name: /Log in|Iniciar sesión/i });
const error = page.locator("text=/error|declined|rechazado/i");
// ❌ Incorrecto: Solo inglés
await page.getByRole("button", { name: "Buy Plan" });

Email verification está habilitada por defecto en la app. Los tests manejan esto:

// Pattern usado en TODOS los tests autenticados
await page.goto("/ruta-protegida");
await page.waitForTimeout(1000);
// Si redirigido a /login o /check-email, el usuario no está autenticado
if (page.url().includes("/login") || page.url().includes("/check-email")) {
test.skip(); // Skip test - esperado con email verification
return;
}
// Continuar con el test...

Alternativa: Usar SKIP_EMAIL_VERIFICATION_IN_DEV=true en .env.server

El componente LanguageSwitcher usa aria-label, no texto visible:

// ✅ Correcto: Usa aria-label (más estable)
const languageSwitcher = page.getByRole("button", { name: /Switch to/i });
if ((await languageSwitcher.count()) > 0 && (await languageSwitcher.isVisible())) {
await languageSwitcher.click();
await page.waitForTimeout(500);
}
// ❌ Incorrecto: Usa texto visible (frágil)
const languageSwitcher = page.locator('button:has-text("EN")');

Implementado en utils.ts:

export const createRandomUser = (): User => ({
email: `test-${Date.now()}-${Math.random().toString(36)}@test.com`,
password: "TestPassword123!",
username: `testuser${Date.now()}`,
});

Cada test crea un usuario único para evitar colisiones.

// Wait corto - verificar estado de página
await page.waitForTimeout(500);
// Wait estándar - permitir animaciones/transiciones
await page.waitForTimeout(1000);
// Tests lentos - marcar explícitamente
test("Stripe payment flow", async () => {
test.slow(); // Multiplica timeout por 3
await makeStripePayment({ test, page, planId: "hobby" });
});

El botón de logout está en un dropdown que debe abrirse primero:

// Navegar a home para asegurar nav completo
await page.goto("/");
await page.waitForTimeout(500);
// Abrir dropdown de usuario
const userButtons = page.locator("nav button").filter({ hasText: /@/ });
if ((await userButtons.count()) > 0) {
await userButtons.first().click();
await page.waitForTimeout(500);
}
// Ahora hacer logout
const logoutBtn = page.getByRole("button", { name: /logout|cerrar sesión/i });
await logoutBtn.click();
Ventana de terminal
npx playwright test --headed
npx playwright test authTests.spec.ts --headed
Ventana de terminal
npm run local:e2e:start
# O
npx playwright test --ui

Permite:

  • Ver tests en tiempo real
  • Pausar/reanudar ejecución
  • Inspeccionar DOM en cada paso
  • Ver screenshots y traces
  • Time travel debugging
Ventana de terminal
npx playwright test --debug

Abre Playwright Inspector para debugging línea por línea.

En caso de fallo, Playwright captura:

  • Screenshots: test-results/
  • Videos: test-results/
  • Traces: test-results/

Ver reporte HTML:

Ventana de terminal
npx playwright show-report

❌ Error: “Connection refused at localhost:3000”

Sección titulada «❌ Error: “Connection refused at localhost:3000”»

Causa: El servidor Wasp no está corriendo.

Solución:

Ventana de terminal
cd app
wasp start

Causa: PostgreSQL no está corriendo.

Solución:

Ventana de terminal
cd app
wasp db start

❌ Tests fallan con redirect a /login o /check-email

Sección titulada «❌ Tests fallan con redirect a /login o /check-email»

Causa: Email verification está habilitada.

Solución 1 (Recomendada):

Ventana de terminal
# En app/.env.server
SKIP_EMAIL_VERIFICATION_IN_DEV=true

Solución 2: Los tests ya manejan esto con test.skip().

Causa: Usando button:has-text("EN") en lugar de aria-label.

Solución:

// Correcto
const languageSwitcher = page.getByRole("button", { name: /Switch to/i });

Causa: No abriste el dropdown del menú de usuario primero.

Solución: Ver patrón de logout en sección 6 arriba.

Causa: Stripe webhook listener no está corriendo.

Solución:

Ventana de terminal
stripe listen --forward-to localhost:3001/payments-webhook

Total: ~788 tests en 27 archivos — Estado actual: ~760+ passing (96%+)

ÁreaArchivosTestsEstado
Seguridad de cuentaaccountSecurityTests, twoFactorTests~20
AutenticaciónauthenticationTests, emailVerificationTests, socialAuthTests, passwordResetTests~84
Cursos y aprendizajecourseTests, enrollmentTests, certificateTests, quizTests, lessonResourcesTests~138
AdminadminTests, adminCrudTests76
Perfiles de usuariouserProfileTests, publicProfileTests, instructorTests85
MonetizaciónpaymentTests, pricingPageTests, promoCodeTests, referralTests~60⚠️ Stripe
Social y contenidoreviewsTests, commentsTests~99
PlataformanavigationTests, landingPageTests, teamsTests, demoAppTests, fileUploadTests~106

Notas:

  • ⚠️ Los tests de pago requieren stripe listen --forward-to localhost:3001/payments-webhook activo
  • Los tests de enrollment con pago previo dependen de que los tests de pago pasen primero
name: E2E Tests
on: [push, pull_request]
jobs:
e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Install Wasp
run: curl -sSL https://get.wasp-lang.dev/installer.sh | sh
- name: Start Database
run: |
cd app
wasp db start &
sleep 10
- name: Start App
run: |
cd app
wasp start &
sleep 30
- name: Install E2E Dependencies
run: |
cd e2e-tests
npm install
npx playwright install chromium
- name: Run E2E Tests
run: |
cd e2e-tests
SKIP_EMAIL_VERIFICATION_IN_DEV=true npm run e2e:playwright
- name: Upload Test Results
if: failure()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: e2e-tests/playwright-report/

Antes de hacer commit de cambios que afecten los tests:

  • Todos los tests pasan localmente (npm run e2e:playwright)
  • Tests nuevos para features nuevos incluyen soporte bilingüe
  • Selectores usan getByRole con regex bilingüe cuando sea posible
  • Language switcher usa aria-label (/Switch to/i)
  • Tests manejan email verification flow (test.skip() si redirige a login)
  • Logout tests abren dropdown primero
  • Timeouts apropiados (500ms para UI, 1000ms para navegación)
  • Tests de pago están marcados con test.slow()
  • Screenshots/videos de fallos revisados
  • Documentación actualizada si es necesario