Pruebas E2E con Playwright¶
Hardhat Flow usa Playwright para pruebas de extremo a extremo en el navegador. Las pruebas se ejecutan contra cada rol de la aplicación para verificar navegación, permisos y acceso a funciones.
Requisitos previos¶
- Node.js >= 22.12
- Navegador Chromium instalado vía Playwright (ver abajo)
- Aplicación en ejecución (Docker o servidor de desarrollo local)
- Usuarios de prueba Auth0 (uno por rol)
Instalación¶
cd frontend
npm install
npx playwright install --with-deps chromium
Configuración de usuarios de prueba Auth0¶
Necesita 7 usuarios Auth0, uno por cada rol. Deben crearse en su inquilino Auth0 y asignarse el rol correcto mediante la administración de roles de Auth0.
Paso 1: Crear usuarios en Auth0¶
En el panel de Auth0 → User Management → Users, cree estos usuarios:
| Email (sugerido) | Role | Notes |
|---|---|---|
[email protected] |
badged |
Acceso mínimo — solo Bids, Jobs, búsqueda |
[email protected] |
supervisor |
Puede crear Bids, convertir a Jobs, ve KPIs de gestión |
[email protected] |
accounting |
Puede crear Bids, convertir a Jobs, KPIs de gestión y contabilidad |
[email protected] |
project_manager |
Ve navegación Clients/Contacts, no puede crear Bids |
[email protected] |
owner |
Acceso total al inquilino — Bids, aprobaciones, conversiones, todos los KPIs |
[email protected] |
admin |
Todo lo del owner + páginas de administración (Tenants, Users, Access Requests) |
[email protected] |
platform_admin |
Solo páginas de administración — sin creación de Bids, sin nav Clients/Contacts |
Paso 2: Asignar roles¶
En Auth0 → User Management → Roles, asegúrese de que cada rol exista y mapee al reclamo personalizado https://hardhatpro.com/roles. Asigne a cada usuario de prueba exactamente un rol.
Si un usuario tuviera más de un rol en el JWT, la aplicación trata los permisos y la visibilidad de KPI del panel como la unión de esos roles (por ejemplo, aparecen KPI de gestión y de contabilidad si cualquier rol asignado califica). Mantener un solo rol por usuario E2E sigue siendo lo recomendado para que las expectativas de Playwright sean predecibles.
Paso 3: Agregar usuarios a un inquilino¶
Cada usuario de prueba (excepto platform_admin) debe pertenecer a un inquilino en Hardhat Flow para que la aplicación resuelva su contexto. El usuario platform_admin opera a nivel de plataforma.
Paso 4: Configurar variables de entorno¶
Copie el archivo de ejemplo y complete credenciales:
cp .env.e2e.example .env.e2e
Edite .env.e2e:
[email protected]
E2E_BADGED_PASSWORD=<password>
[email protected]
E2E_SUPERVISOR_PASSWORD=<password>
[email protected]
E2E_ACCOUNTING_PASSWORD=<password>
[email protected]
E2E_PROJECT_MANAGER_PASSWORD=<password>
[email protected]
E2E_OWNER_PASSWORD=<password>
[email protected]
E2E_ADMIN_PASSWORD=<password>
[email protected]
E2E_PLATFORM_ADMIN_PASSWORD=<password>
Warning
Nunca confirme .env.e2e al control de versiones. Ya está cubierto por el patrón gitignore .env*.
Ejecutar pruebas¶
Inicie la aplicación primero:
# Opción A: Docker
docker compose up -d
# Opción B: Desarrollo local
cd frontend && npm run dev # en una terminal
cd .. && python manage.py runserver # en otra
Luego ejecute las pruebas:
# Todas las pruebas por rol
npm run test:e2e
# Pruebas para un rol específico
npx playwright test --project=owner
npx playwright test --project=badged
# Modo UI interactivo
npm run test:e2e:ui
# Modo headed (ver el navegador)
npm run test:e2e:headed
# Informe HTML
npx playwright show-report
Estructura de pruebas¶
frontend/
playwright.config.ts # Config con proyectos por rol
.env.e2e # Credenciales (gitignored)
.env.e2e.example # Plantilla
.auth/ # Estado de auth guardado por rol (gitignored)
badged.json
supervisor.json
accounting.json
project_manager.json
owner.json
admin.json
platform_admin.json
e2e/
auth.setup.ts # Inicia sesión en los 7 roles, guarda storageState
badged.spec.ts # Pruebas Badge Worker
supervisor.spec.ts # Pruebas Supervisor
accounting.spec.ts # Pruebas Accounting
project-manager.spec.ts # Pruebas Project Manager
owner.spec.ts # Pruebas Owner
admin.spec.ts # Pruebas Admin
platform-admin.spec.ts # Pruebas Platform Admin
Cómo funciona la autenticación en las pruebas¶
- El archivo
auth.setup.tsse ejecuta primero como proyecto "setup" de Playwright. - Para cada rol navega a
/login/, completa el inicio de sesión hospedado en Auth0 y guarda el estado del navegador (cookies + localStorage) en.auth/<role>.json. - El proyecto de pruebas de cada rol carga su archivo
storageState, así las pruebas comienzan ya autenticadas. - La configuración solo corre una vez por invocación
playwright test— todas las pruebas de un rol comparten la misma sesión.
Qué prueba cada rol¶
| Role | Tests |
|---|---|
| badged | Nav: solo Dashboard/Bids/Jobs/Search. Sin botón New Bid. Sin acceso admin. |
| supervisor | Nav: igual que badged. Botón New Bid visible. KPIs de gestión. Los KPI de facturas solo aparecen si el JWT incluye un rol con capacidad contable (semántica de unión). |
| accounting | Nav: igual que badged. Botón New Bid visible. KPIs de gestión y contabilidad. |
| project_manager | Nav: agrega Clients/Contacts. Sin botón New Bid. Puede abrir páginas de cliente/contacto. |
| owner | Nav: agrega Clients/Contacts. Botón New Bid. Todos los KPIs. Sin acceso admin. |
| admin | Nav completa incluyendo sección admin. Todos los KPIs + botón Tenants. Puede abrir todas las páginas admin. |
| platform_admin | Nav admin pero sin Clients/Contacts. Sin botón New Bid. Botón Tenants visible. Páginas admin accesibles. |
Prueba de ciclo completo¶
El archivo lifecycle.spec.ts cubre el flujo completo Bid → Job → Invoice → Payment
entre cuatro roles en secuencia dentro de una sola prueba, verificando la cadena de entrega de punta a punta.
Qué verifica¶
| Phase | Role | Mechanism | What is verified |
|---|---|---|---|
| 1 | PM | UI — formulario /bids/new |
Se crea el Bid |
| 2 | PM | API — POST /bids/{id}/submit/ |
El Bid pasa a awaiting_po |
| 3 | Owner | UI — botón Approve | El Bid pasa a approved; Job auto-creado |
| 4 | PM | API — start + complete | El Job pasa por in_progress → needs_invoice |
| 5 | Accounting | API — crear Invoice + 2 pagos | El Invoice pasa a paid |
| 6 | Accounting | API — cerrar Invoice | El estado llega a workflow_complete |
| 7 | Owner | UI — dashboard | KPI Invoice Paid visible |
| 8 | — | API — activity feed | Entradas ActivityLog para las transiciones |
| 9 | Supervisor, Badge Worker | API | 403 en transiciones de gestión |
Configuración única del inquilino E2E¶
Antes de ejecutar la prueba de ciclo de vida necesita un inquilino E2E dedicado al que pertenezcan sus 7 usuarios de prueba. Es independiente de cualquier inquilino demo que ya tenga.
Provisionar una vez (desarrollo local):
python manage.py seed_e2e_tenant --provision --slug=e2e
Reiniciar + volver a sembrar antes de cada ejecución (automático vía globalSetup):
python manage.py seed_e2e_tenant --reset --slug=e2e
El comando:
- Crea la base del inquilino e2e si no existe (con --provision)
- Elimina todos los bids, jobs, invoices y pagos de la base del inquilino (con --reset)
- Siembra un cliente (E2E Construction Co.) y un contacto
- Asocia cada usuario E2E (por correo desde variables E2E_<ROLE>_EMAIL) al inquilino E2E
Ejecutar la prueba de ciclo de vida¶
# Solo la prueba de ciclo de vida
npx playwright test --project=lifecycle
# Con navegador visible
npx playwright test --project=lifecycle --headed
# Omitir el re-seed automático del inquilino (usar datos existentes)
E2E_SKIP_SEED=true npx playwright test --project=lifecycle
Comportamiento de globalSetup¶
playwright.config.ts registra e2e/global-setup.ts como gancho globalSetup.
Antes de cualquier proyecto de prueba ejecuta seed_e2e_tenant --reset para asegurar estado limpio.
En CI llama a Django vía docker compose exec -T web uv run python manage.py ….
En local (DEBUG=True) llama python manage.py … desde la raíz del repositorio.
Establezca E2E_SKIP_SEED=true en .env.e2e para omitir la siembra al iterar la lógica de prueba.
Estructura de la prueba¶
frontend/e2e/
global-setup.ts # Ejecuta seed_e2e_tenant antes de todas las pruebas
lifecycle.spec.ts # Prueba completa Bid → Payment
helpers/
contexts.ts # contextFor(browser, role) y captureToken(page)
ids.ts # uniqueScope() para datos de prueba sin colisiones
Resolución de problemas¶
El inicio de sesión Auth0 agota el tiempo de espera: Asegúrese de que el usuario de prueba exista en Auth0 y las credenciales sean correctas. Verifique que la página Universal Login de Auth0 no haya cambiado etiquetas de campos.
Las pruebas fallan con "not authenticated": Elimine .auth/ y vuelva a ejecutar para regenerar el estado de autenticación. Los tokens pueden haber expirado.
El puerto 3000 ya está en uso: La configuración usa reuseExistingServer: true, así que si el servidor de desarrollo ya corre, Playwright lo usará. Si no, inicia npm run dev automáticamente.