# 0022 — Tests E2E con Playwright contra Element Web ## Objetivo Crear una suite de tests E2E que use Playwright para controlar Element Web (headless) y verificar que los agentes Matrix responden correctamente. Los tests simulan un usuario real: login, verificacion E2EE, enviar mensajes a los bots y validar respuestas. ## Contexto - Los agentes corren en una VPS sin entorno grafico — Playwright debe operar en modo headless - Element Web se levanta como servicio estatico (o Docker) apuntando al homeserver `matrix-af2f3d.organic-machine.com` - El login requiere usuario, contraseña y recovery key (cross-signing) — todo desde `.env` - Actualmente no hay tests que verifiquen el flujo completo usuario→bot→respuesta por Matrix - Playwright descarga sus propios browsers y necesita deps del sistema (`npx playwright install-deps`) ## Arquitectura ``` e2e/ NEW — proyecto Node.js independiente ├── package.json NEW — playwright + dependencias ├── playwright.config.ts NEW — config headless, timeouts, base URL ├── .env.example NEW — template de variables E2E ├── fixtures/ │ ├── element-auth.ts NEW — login + verificacion cross-signing │ └── matrix-room.ts NEW — helpers para navegar a rooms, enviar mensajes, esperar respuestas ├── tests/ │ ├── login.spec.ts NEW — test basico: login + E2EE verification funciona │ ├── assistant-bot.spec.ts NEW — tests del assistant-bot │ └── asistente-2.spec.ts NEW — tests del asistente-2 (con tools) └── scripts/ └── setup-element.sh NEW — descargar/levantar Element Web local ``` ``` dev-scripts/ └── e2e/ ├── run.sh NEW — levantar Element + ejecutar tests + teardown └── install.sh NEW — instalar Node, Playwright, deps del sistema ``` ### Patron pure core / impure shell Este issue es 100% infraestructura de testing, no modifica codigo Go. - `pkg/` — sin cambios - `shell/` — sin cambios - `agents/` — sin cambios - `e2e/` — proyecto Node.js aislado, no forma parte del modulo Go ## Desglose multi-issue Este issue se implementa en 3 sub-issues independientes, cada uno en su propia rama. | Sub-issue | Rama | Alcance | Estado | |-----------|------|---------|--------| | 0022a-e2e-infra | issue/0022a-e2e-infra | Proyecto Node.js, Playwright config, scripts install/setup Element | pendiente | | 0022b-e2e-auth-helpers | issue/0022b-e2e-auth-helpers | Fixtures de login E2EE, storageState, helpers de rooms | pendiente | | 0022c-e2e-agent-tests | issue/0022c-e2e-agent-tests | Specs de agentes, run.sh, verificacion, docs | pendiente | ### Nota sobre feature flags Este issue no requiere feature flag porque es infraestructura de testing externa (proyecto Node.js aislado). No hay codigo de produccion que activar/desactivar — cada sub-issue produce artefactos funcionales e independientes que no afectan al runtime Go. ### Progreso por tarea **Fase 1: Infraestructura base** — sub-issue 0022a - [ ] **1.1** Crear `e2e/` con `package.json` (playwright, @playwright/test, dotenv) - [ ] **1.2** Crear `playwright.config.ts` configurado para headless, timeouts 30s, screenshot on failure - [ ] **1.3** Crear `e2e/.env.example` con variables necesarias - [ ] **1.4** Crear `e2e/scripts/setup-element.sh` — descarga Element Web, config.json, servidor estatico - [ ] **1.5** Crear `dev-scripts/e2e/install.sh` — instala Node.js, npm ci, Playwright chromium + deps **Fase 2: Fixtures de autenticacion** — sub-issue 0022b - [ ] **2.1** Crear fixture `element-auth.ts` — flujo login completo + cross-signing - [ ] **2.2** Implementar `storageState` para cachear sesion autenticada - [ ] **2.3** Crear `global-setup.ts` que ejecute login una vez **Fase 3: Helpers de interaccion** — sub-issue 0022b - [ ] **3.1** Crear fixture `matrix-room.ts` con helpers (goToRoom, sendMessage, waitForBotReply, getLastMessage) - [ ] **3.2** Manejar mensajes encriptados — validar que no aparece "Unable to decrypt" **Fase 4: Tests de los agentes** — sub-issue 0022c - [ ] **4.1** `login.spec.ts` — smoke test: login, rooms visibles, E2EE verificado - [ ] **4.2** `assistant-bot.spec.ts` — saludo, pregunta, !help, !ping - [ ] **4.3** `asistente-2.spec.ts` — saludo, !tools, pregunta con tool use, !help **Fase 5: Script de ejecucion** — sub-issue 0022c - [ ] **5.1** Crear `dev-scripts/e2e/run.sh` — verificar agentes, levantar Element, ejecutar tests, teardown - [ ] **5.2** Agregar opcion `--headed` para debug local **Fase 6: Verificacion** — sub-issue 0022c - [ ] **6.1** Verificar que `npx playwright test` pasa en headless - [ ] **6.2** Verificar screenshots on failure - [ ] **6.3** Verificar login cacheado funciona **Fase 7: Cleanup y docs** — sub-issue 0022c - [ ] **7.1** Documentar en `e2e/README.md` - [ ] **7.2** Agregar `e2e/node_modules/` y `e2e/test-results/` a `.gitignore` - [ ] **7.3** Actualizar `CLAUDE.md` con seccion de E2E tests ## Ejemplo de uso ```bash # Primera vez: instalar todo ./dev-scripts/e2e/install.sh # Configurar credenciales cp e2e/.env.example e2e/.env # editar e2e/.env con usuario, password, recovery key # Asegurar que los agentes estan corriendo ./dev-scripts/server/start.sh # Ejecutar tests ./dev-scripts/e2e/run.sh # Output esperado: # ✓ login.spec.ts — login y verificacion E2EE (12s) # ✓ assistant-bot.spec.ts — responde a saludo (8s) # ✓ assistant-bot.spec.ts — responde a pregunta (15s) # ✓ assistant-bot.spec.ts — comando !help (3s) # ✓ asistente-2.spec.ts — responde con tool use (20s) # 5 passed (58s) ``` ## Decisiones de diseno - **Proyecto Node.js separado**: Playwright es ecosistema Node. Mantenerlo en `e2e/` aislado del modulo Go evita contaminar el proyecto principal. - **Element Web local**: servir Element localmente en vez de usar app.element.io para tener control total del config.json y no depender de servicios externos. - **storageState para cachear login**: el login + cross-signing es lento (~10s). Cachearlo evita repetirlo en cada test y hace la suite mas rapida. - **Solo Chromium**: en headless server no necesitamos multi-browser. Chromium es suficiente y reduce el tamaño de la instalacion. - **Recovery key via .env**: las palabras de seguridad (recovery key) son necesarias para verificar cross-signing y poder desencriptar mensajes E2EE. Sin esto los tests verian "Unable to decrypt". - **Timeouts generosos**: los bots dependen de LLMs externos (OpenAI), que pueden tardar 5-20s en responder. Timeout de 30s por defecto. - **Sin feature flag**: al ser infra de testing aislada (no modifica codigo Go), no hay codigo de produccion que proteger con un flag. ## Prerequisitos - Node.js v18+ instalado en la VPS (o el install.sh lo instala) - Los agentes deben estar corriendo contra el homeserver - Un usuario de test registrado en el homeserver con cross-signing configurado - El usuario de test debe estar en los rooms de los bots (o los bots aceptan DMs) ## Riesgos - **Selectores de Element Web inestables**: Element cambia su UI entre versiones. Mitigacion: fijar una version de Element en `setup-element.sh`, usar selectores por role/testid cuando sea posible. - **Timeouts por LLM lento**: si OpenAI esta lento, los tests fallan por timeout. Mitigacion: timeouts generosos (30s), retry con `test.retry(1)` en la config. - **Cross-signing verification UI**: el flujo de verificacion en Element puede variar. Mitigacion: documentar la version exacta de Element, usar screenshots on failure para debug. - **Deps del sistema en VPS**: `npx playwright install-deps` necesita sudo. Mitigacion: documentar en install.sh, ejecutar con permisos adecuados. - **Mensajes E2EE**: si el cross-signing no se completa correctamente, los mensajes aparecen como "Unable to decrypt". Mitigacion: el smoke test (login.spec.ts) verifica E2EE antes de los tests de agentes.