Cesar Mendivil 8b458a3ddf feat: add initial LiveKit Meet integration with utility scripts, configs, and core components
- 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
2025-11-20 12:50:38 -07:00
..

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)
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

  1. 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/

  1. 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

  1. 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/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):

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.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:
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):
./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>
  1. 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 .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:
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")