- 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
10 KiB
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 ensessionStoragepara 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.jso un servidor Browserless accesible (WSS) paravalidate-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 Studiomock_server.js— servidor Express mock (dev) que emula endpoints/api/sessiony/studio/:id(útil para pruebas offline)run_e2e_with_mock.js— helper que arranca el mock en proceso y ejecuta el validador localvalidate-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 BrowserlessCHROME_HOST/CHROME_WS— host:port (p.ej.host:9222) o websocket de Chrome remotoBROADCAST_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
- Prueba local rápida (usa la página de prueba
e2e/test-pages/broadcast.html)
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
- Usar el mock server (arranca servidor y valida fluxo realista)
# 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/
- Ejecutar contra Browserless remoto
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
- Ejecutar contra Chrome remoto (remote debugging, puerto 9222)
# 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/sessionenVITE_BACKEND_TOKENS_URL(ohttps://avanzacast-servertokens.bfzqqk.easypanel.hostpor defecto) para crear una sesión. - Abre
BROADCAST_URL/:id(usandoBROWSER_WS/BROWSERLESS_WS) y verifica quesessionStoragecontiene la sesión. - Llama a
/api/session/:id/tokeny guarda el resultado en JSON + captura.
Ejecución (Browserless):
cd e2e
BROWSERLESS_WS="wss://browserless.bfzqqk.easypanel.host" \
BROWSERLESS_TOKEN="<token>" \
node validate-session-id-flow.js
Ejecución (Chrome remoto):
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.jsone2e/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:
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— actualizaLIVEKIT_API_KEYyLIVEKIT_API_SECRETen el archivo.envdel token-server y recrea el servicio (docker-compose). Uso seguro: hace backup del archivo.envantes de modificarlo.scripts/verify_token_server_after_update.sh— crea una sesión de prueba en el token-server, obtiene el token y (si tieneswebsocatinstalado) 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
- Actualiza las claves en el
.envdel token-server y recrea el servicio (ajusta paths y nombre del servicio según tu despliegue):
./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>
- Verifica que el token-server crea sesiones y devuelve token:
./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
.envantes de editarlo.
Si quieres, puedo aplicar (probar) estas acciones en tu entorno si me indicas:
- el path al
.envy aldocker-compose.ymlque controlatoken-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— timestampsconsole— 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
assertionsmuestrasessionStorage_has_token: ok: trueystudio_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.jsovalidate-flow-browserless.jsy añade comprobaciones en el bloque que ejecutastudioPage.evaluate(...)o consultasessionStorageen la página broadcast. - Patrón de aserción:
results.assertions.push({ name: 'my_assertion', ok: boolean, detail: 'mensaje' })
- Re-run el script y revisar
results.assertionsen el JSON.
Integración en CI (recomendación)
- Usa el workflow
/.github/workflows/validate-studio-flow-browserless.yml(ya incluido). El workflow requiere los inputsbrowserless_wsybrowserless_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
.woffo 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")