- Add Next.js app structure with base configs, linting, and formatting - Implement LiveKit Meet page, types, and utility functions - Add Docker, Compose, and deployment scripts for backend and token server - Provide E2E and smoke test scaffolding with Puppeteer and Playwright helpers - Include CSS modules and global styles for UI - Add postMessage and studio integration utilities - Update package.json with dependencies and scripts for development and testing
188 lines
10 KiB
Markdown
188 lines
10 KiB
Markdown
# E2E — Validación del flujo Broadcast → Studio
|
|
|
|
Este README recoge cómo ejecutar, depurar e interpretar las pruebas E2E del flujo Broadcast Panel → StudioPortal (activación de sesión LiveKit). Está pensado para desarrolladores e infra-ops que deben validar el flujo tanto localmente como contra entornos remotos (Browserless / Chrome remoto).
|
|
|
|
Resumen rápido
|
|
- Objetivo: validar que al crear una sesión (POST /api/session) el Broadcast Panel abra el Studio y que el Studio reciba el token (vía postMessage o `?token=`) y lo persista en `sessionStorage` para que el cliente LiveKit se conecte.
|
|
- Ubicación de los scripts: `e2e/`
|
|
- Artefactos de salida: JSON y capturas PNG en `e2e/`
|
|
|
|
Prerequisitos
|
|
- Node.js (v16+ recomendado)
|
|
- npm
|
|
- Chrome local o un Chrome remoto con remote-debugging habilitado (puerto 9222) para ejecución con `validate-flow-remote-chrome.js` o un servidor Browserless accesible (WSS) para `validate-flow-browserless.js`.
|
|
|
|
Archivos principales en `e2e/`
|
|
- `validate-flow-domains-local.js` — validador local (usa file:// o URLs HTTP locales)
|
|
- `validate-flow-browserless.js` — validador que se conecta a Browserless (puppeteer-core)
|
|
- `validate-flow-remote-chrome.js` — validador que se conecta a Chrome remoto (debug port / ws)
|
|
- `simulate_token_query_browserless.js` — prueba que inyecta `?token=` y abre el Studio
|
|
- `mock_server.js` — servidor Express mock (dev) que emula endpoints `/api/session` y `/studio/:id` (útil para pruebas offline)
|
|
- `run_e2e_with_mock.js` — helper que arranca el mock en proceso y ejecuta el validador local
|
|
- `validate-flow-remote-chrome-result.json` (y otros JSON) — resultados de ejecución con consola, navigations y assertions
|
|
|
|
Variables de entorno usadas (ejemplos)
|
|
- `BROWSERLESS_WS` — WebSocket endpoint a Browserless (ej. `wss://...`)
|
|
- `BROWSERLESS_TOKEN` — token del servicio Browserless
|
|
- `CHROME_HOST` / `CHROME_WS` — host:port (p.ej. `host:9222`) o websocket de Chrome remoto
|
|
- `BROADCAST_URL` — URL del Broadcast Panel (ej: `https://avanzacast-broadcastpanel.bfzqqk.easypanel.host`)
|
|
- `STUDIO_URL` — URL base del Studio (ej: `https://avanzacast-studio.bfzqqk.easypanel.host`)
|
|
- `TOKEN` — token de prueba (opcional, para forzar `?token=` fallback)
|
|
|
|
Comandos (rápidos) — ejecuciones locales y remotas
|
|
|
|
1) Prueba local rápida (usa la página de prueba `e2e/test-pages/broadcast.html`)
|
|
```bash
|
|
cd e2e
|
|
BROADCAST_URL="file://$(pwd)/test-pages/broadcast.html" \
|
|
TOKEN="testtoken123" STUDIO_URL="about:blank" \
|
|
node validate-flow-domains-local.js
|
|
```
|
|
Salida: `e2e/studio-flow-domains-result.json` + `e2e/studio_flow_result.png`
|
|
|
|
2) Usar el mock server (arranca servidor y valida fluxo realista)
|
|
```bash
|
|
# en una terminal
|
|
cd e2e
|
|
node mock_server.js
|
|
# en otra terminal
|
|
BROADCAST_URL="http://localhost:4001/broadcast" \
|
|
TOKEN="local-mock-token" STUDIO_URL="http://localhost:4001/studio" \
|
|
node validate-flow-domains-local.js
|
|
```
|
|
Salida: JSON + capturas en `e2e/`
|
|
|
|
3) Ejecutar contra Browserless remoto
|
|
```bash
|
|
cd /path/to/repo
|
|
BROWSERLESS_WS="wss://browserless.example" \
|
|
BROWSERLESS_TOKEN="your_token" \
|
|
BROADCAST_URL="https://avanzacast-broadcastpanel.bfzqqk.easypanel.host" \
|
|
STUDIO_URL="https://avanzacast-studio.bfzqqk.easypanel.host" \
|
|
node validate-flow-browserless.js
|
|
```
|
|
Salida: `e2e/validate-flow-browserless-result.json` + screenshot
|
|
|
|
4) Ejecutar contra Chrome remoto (remote debugging, puerto 9222)
|
|
```bash
|
|
# obtener websocket URL (ejemplo local) y ejecutar
|
|
WS=$(curl -s http://localhost:9222/json/version | python3 -c "import sys,json;print(json.load(sys.stdin).get('webSocketDebuggerUrl',''))")
|
|
cd e2e
|
|
CHROME_WS="$WS" \
|
|
BROADCAST_URL="https://avanzacast-broadcastpanel.bfzqqk.easypanel.host" \
|
|
STUDIO_URL="https://avanzacast-studio.bfzqqk.easypanel.host" \
|
|
TOKEN="e2e098863b912f6a178b68e71ec3c58d" \
|
|
node validate-flow-remote-chrome.js
|
|
```
|
|
Salida: `e2e/validate-flow-remote-chrome-result.json` + screenshot
|
|
|
|
### Validar flujo `/:id` (session id stored in DB -> broadcast panel)
|
|
|
|
Hemos añadido un test E2E específico que valida el flujo en el que el token-server crea una sesión y el Broadcast Panel la consume a través de la ruta `/:id`.
|
|
|
|
Script: `e2e/validate-session-id-flow.js`
|
|
Qué hace:
|
|
- POST `/api/session` en `VITE_BACKEND_TOKENS_URL` (o `https://avanzacast-servertokens.bfzqqk.easypanel.host` por defecto) para crear una sesión.
|
|
- Abre `BROADCAST_URL/:id` (usando `BROWSER_WS` / `BROWSERLESS_WS`) y verifica que `sessionStorage` contiene la sesión.
|
|
- Llama a `/api/session/:id/token` y guarda el resultado en JSON + captura.
|
|
|
|
Ejecución (Browserless):
|
|
```bash
|
|
cd e2e
|
|
BROWSERLESS_WS="wss://browserless.bfzqqk.easypanel.host" \
|
|
BROWSERLESS_TOKEN="<token>" \
|
|
node validate-session-id-flow.js
|
|
```
|
|
|
|
Ejecución (Chrome remoto):
|
|
```bash
|
|
WS=$(curl -s http://localhost:9222/json/version | python3 -c "import sys,json;print(json.load(sys.stdin).get('webSocketDebuggerUrl',''))")
|
|
cd e2e
|
|
BROWSER_WS="$WS" node validate-session-id-flow.js
|
|
```
|
|
|
|
Salida:
|
|
- `e2e/validate-session-id-flow-result.json`
|
|
- `e2e/validate-session-id-flow.png`
|
|
|
|
Diagnóstico y debugging (token-server y 502)
|
|
- Si ves errores `Failed to load resource: 502`, verifica el token-server y el reverse-proxy:
|
|
```bash
|
|
curl -i 'https://avanzacast-servertokens.bfzqqk.easypanel.host/health'
|
|
curl -i -X POST 'https://avanzacast-servertokens.bfzqqk.easypanel.host/api/session' -H 'Content-Type: application/json' -d '{"room":"diag","username":"diag"}'
|
|
# script de diagnóstico (recopila headers y logs)
|
|
node ../scripts/check_token_server_node.mjs https://avanzacast-servertokens.bfzqqk.easypanel.host testroom e2euser
|
|
```
|
|
- Si el POST/GET token responde 200 con JSON y token -> backend OK; si no, revisa logs del proxy (nginx/EasyPanel) y del contenedor del token-server.
|
|
|
|
Infra: Alinear claves LiveKit (token-server ↔ LiveKit)
|
|
|
|
Si las pruebas E2E fallan con errores 401 al conectar a LiveKit, normalmente significa que el token-server está firmando tokens con una clave (API key / secret) distinta a la que LiveKit espera. He incluido dos helpers en `scripts/` para actualizar y verificar la configuración del token-server:
|
|
|
|
- `scripts/update_token_server_env.sh` — actualiza `LIVEKIT_API_KEY` y `LIVEKIT_API_SECRET` en el archivo `.env` del token-server y recrea el servicio (docker-compose). Uso seguro: hace backup del archivo `.env` antes de modificarlo.
|
|
- `scripts/verify_token_server_after_update.sh` — crea una sesión de prueba en el token-server, obtiene el token y (si tienes `websocat` instalado) intenta una conexión WebSocket básica a la URL reportada por el token-server (esto es un sanity-check, no un handshake RTC completo).
|
|
|
|
Comandos de ejemplo
|
|
|
|
1) Actualiza las claves en el `.env` del token-server y recrea el servicio (ajusta paths y nombre del servicio según tu despliegue):
|
|
```bash
|
|
./scripts/update_token_server_env.sh \
|
|
--env-file /path/to/token-server/.env \
|
|
--compose-file /path/to/docker-compose.yml \
|
|
--service token-server \
|
|
--livekit-key <LIVEKIT_API_KEY> \
|
|
--livekit-secret <LIVEKIT_API_SECRET>
|
|
```
|
|
|
|
2) Verifica que el token-server crea sesiones y devuelve token:
|
|
```bash
|
|
./scripts/verify_token_server_after_update.sh \
|
|
--session-room e2e_room \
|
|
--session-user e2e_user \
|
|
--token-server-url https://avanzacast-servertokens.bfzqqk.easypanel.host
|
|
```
|
|
|
|
Notas de seguridad
|
|
- No guardes secretos en repositorios públicos.
|
|
- El script hace backup del `.env` antes de editarlo.
|
|
|
|
Si quieres, puedo aplicar (probar) estas acciones en tu entorno si me indicas:
|
|
- el path al `.env` y al `docker-compose.yml` que controla `token-server`, o
|
|
- si prefieres que prepare los comandos para que el administrador los ejecute por SSH (yo te doy el playbook exacto).
|
|
|
|
Estructura del JSON de resultados
|
|
- `startedAt` / `endedAt` — timestamps
|
|
- `console` — array de mensajes capturados de consola (type, text)
|
|
- `navigations` — array con pasos realizados (ej: `broadcast_loaded`, `studio_opened`, `direct_studio`)
|
|
- `assertions` — (cuando se configuraron) array con { name, ok, detail }
|
|
- `screenshot` — ruta absoluta del PNG generado
|
|
|
|
Ejemplo de interpretación rápida
|
|
- Si `assertions` muestra `sessionStorage_has_token: ok: true` y `studio_page_shows_token: ok: true` → flujo verificado (la sesión fue creada o inyectada y el Studio la recibió).
|
|
- Si hay 502 en `console` → probable problema infra (proxy / token-server) o asset roto; ejecutar scripts de diagnóstico.
|
|
|
|
Cómo añadir nuevas aserciones
|
|
- Edita `e2e/validate-flow-remote-chrome.js` o `validate-flow-browserless.js` y añade comprobaciones en el bloque que ejecuta `studioPage.evaluate(...)` o consulta `sessionStorage` en la página broadcast.
|
|
- Patrón de aserción:
|
|
```js
|
|
results.assertions.push({ name: 'my_assertion', ok: boolean, detail: 'mensaje' })
|
|
```
|
|
- Re-run el script y revisar `results.assertions` en el JSON.
|
|
|
|
Integración en CI (recomendación)
|
|
- Usa el workflow `/.github/workflows/validate-studio-flow-browserless.yml` (ya incluido). El workflow requiere los inputs `browserless_ws` y `browserless_token`. Configura secrets y ejecútalo desde Actions para runs periódicos o en PRs.
|
|
|
|
Preguntas frecuentes / troubleshooting
|
|
- Q: ¿Por qué el test abre el Studio directamente (`direct_studio`) en lugar de simular el click? A: Si el popup está bloqueado o el selector no se encuentra, el script hace fallback y navega directamente con `?token=`. Aumenta timeouts o agrega selectores más específicos si quieres forzar la simulación del click.
|
|
- Q: Veo OTS parsing errors en consola (fuentes). ¿Importa? A: No para la E2E funcional; afecta sólo la carga de un archivo `.woff` o la validación visual. Revisa la fuente y el servidor que la sirve.
|
|
|
|
Contacto / notas finales
|
|
- Los scripts y la lógica han sido añadidos para que puedas automatizar y auditar la activación del StudioPortal. Si quieres, puedo:
|
|
- añadir aserciones adicionales específicas (ej. TTL, usuario, room),
|
|
- crear el README en `e2e/README.md` (este archivo),
|
|
- añadir tests en CI que fallen si alguna aserción no pasa.
|
|
|
|
---
|
|
|
|
Si quieres que genere además un archivo `e2e/LOG.md` o un registro más formal por cada ejecución (con timestamp, link a artifact, resultado de aserciones), lo creo ahora y lo integro automáticamente cuando corre el validador. ¿Lo añado? (responde "Sí, crea LOG.md")
|