merge: quick/e2e-issues — comando create-issue y issues E2E 0022

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-08 13:57:41 +00:00
6 changed files with 698 additions and 0 deletions
+154
View File
@@ -0,0 +1,154 @@
# Command: create issue
Crea un issue nuevo en `dev/issues/` siguiendo **estrictamente** la regla `create_issue.md`. Si el issue es grande, lo desglosa automaticamente en sub-issues con feature flags.
## Inputs
Se necesitan los datos del issue. Si no se proporcionan, preguntar.
- `titulo`: titulo corto y descriptivo (ej: "Hot reload de configuracion")
- `descripcion`: objetivo/descripcion de lo que se quiere lograr
- `dependencias` (opcional): issues de los que depende (ej: "Requiere issue 0010")
## Flujo obligatorio
### 1. Determinar el numero del issue
Buscar el numero mas alto en `dev/issues/` y `dev/issues/completed/` y usar el siguiente.
Formato: 4 digitos con ceros a la izquierda (`0023`, `0024`, etc.).
```bash
ls dev/issues/ dev/issues/completed/ | grep -oP '^\d{4}' | sort -rn | head -1
```
### 2. Generar slug
A partir del titulo:
- Lowercase
- Palabras separadas por guiones
- Conciso (2-4 palabras)
- Ejemplo: "Hot reload de configuracion" → `hot-reload`
### 3. Evaluar tamano del issue
Antes de escribir el issue, analizar el alcance y determinar si cabe en **una sola rama corta (horas)**.
**Criterios para desglosar en sub-issues:**
- Toca mas de 2 capas del patron (pkg/ + shell/ + agents/ + tools/)
- Requiere mas de ~3 fases de implementacion
- El usuario lo indica explicitamente
- La descripcion implica multiples componentes independientes
**Si es un issue simple** (cabe en una rama):
- Crear un solo archivo `dev/issues/<NNNN>-<slug>.md`
- Seguir directo al paso 4
**Si es un issue grande** (necesita desglose):
- Crear el issue principal `dev/issues/<NNNN>-<slug>.md` con seccion `## Desglose multi-issue`
- Crear cada sub-issue como `dev/issues/<NNNN><letra>-<sub-slug>.md` (ej: `0023a-types`, `0023b-client`)
- Cada sub-issue es autocontenido: debe compilar, pasar tests, no romper master
- Agregar feature flag en la descripcion del issue principal
- Registrar todos los sub-issues en `dev/issues/README.md`
### 4. Crear el issue desde el template
Copiar `.claude/templates/issue.md` y rellenar **todas** las secciones:
- **Objetivo**: 1-3 frases claras
- **Contexto**: que existe, que falta, dependencias
- **Arquitectura**: archivos afectados (marcar `NEW` los nuevos). Explicar que va en `pkg/` (puro) vs `shell/` (impuro)
- **Tareas**: fases con tareas numeradas (`1.1`, `1.2`, etc.). Cada tarea concreta y verificable. Siempre incluir fase de tests y fase de cleanup/docs
- **Ejemplo de uso**: flujo concreto
- **Decisiones de diseno**: justificaciones clave
- **Prerequisitos**: que debe existir antes
- **Riesgos**: problemas potenciales y mitigacion
### 5. Para issues multi-issue — contenido adicional
En el issue principal, agregar despues de las tareas:
```markdown
## Desglose multi-issue
Este issue se implementa en sub-issues independientes, cada uno en su propia rama.
| Sub-issue | Rama | Alcance | Estado |
|-----------|------|---------|--------|
| <NNNN>a-<slug> | issue/<NNNN>a-<slug> | <que cubre> | pendiente |
| <NNNN>b-<slug> | issue/<NNNN>b-<slug> | <que cubre> | pendiente |
| ...
### Feature flag
Nombre: `<nombre-del-flag>`
Se activa en el ultimo sub-issue cuando todo esta integrado.
### Progreso por tarea
- [ ] **1.1** <tarea> — sub-issue <NNNN>a
- [ ] **1.2** <tarea> — sub-issue <NNNN>a
- [ ] **2.1** <tarea> — sub-issue <NNNN>b
...
```
Cada sub-issue individual debe tener su propio archivo con:
- Objetivo especifico del sub-issue
- Tareas que le corresponden del issue principal
- Nota de que es parte de un issue mayor
### 6. Registrar feature flag (solo multi-issue)
Actualizar `dev/feature_flags.json`:
```json
{
"<nombre-del-flag>": {
"enabled": false,
"issue": "<NNNN>",
"description": "<descripcion breve>",
"added": "<YYYY-MM-DD>"
}
}
```
### 7. Actualizar el indice
En `dev/issues/README.md`, agregar filas al final de la tabla.
**Issue simple:**
```markdown
| <N> | <Titulo> | [<NNNN>-<slug>.md](<NNNN>-<slug>.md) | pendiente |
```
**Issue multi-issue (agregar fila por cada sub-issue tambien):**
```markdown
| <N> | <Titulo> | [<NNNN>-<slug>.md](<NNNN>-<slug>.md) | pendiente |
| <N>a | <Titulo> (parte a) | [<NNNN>a-<slug>.md](<NNNN>a-<slug>.md) | pendiente |
| <N>b | <Titulo> (parte b) | [<NNNN>b-<slug>.md](<NNNN>b-<slug>.md) | pendiente |
```
### 8. Verificar
- [ ] Archivo(s) creado(s) en `dev/issues/`
- [ ] Todas las secciones del template rellenadas
- [ ] Fila(s) agregada(s) en `dev/issues/README.md`
- [ ] Numero de issue es consecutivo (sin saltos ni duplicados)
- [ ] Si es multi-issue: sub-issues creados, feature flag en `dev/feature_flags.json`, seccion de desglose en issue principal
### 9. Reportar al usuario
Mostrar resumen:
- Numero y titulo del issue
- Si fue desglosado: listar sub-issues con su alcance
- Recordar: usar `/fix-issue <NNNN>` (o `/fix-issue <NNNN>a`, `<NNNN>b`, etc.) para implementar
## Reglas criticas
- Seguir `create_issue.md` de forma estricta
- **Patron pure core / impure shell**: toda feature debe explicar que va en `pkg/` vs `shell/`
- **Tareas atomicas**: cada tarea debe ser implementable de forma independiente
- **Numeracion continua**: nunca reusar numeros
- **Estado**: issues nuevos siempre `pendiente`
- **Issues grandes**: desglosar en sub-issues con feature flags, nunca dejar una rama abierta por dias
- **Feature flag != WIP**: un flag protege codigo terminado y testeado, no codigo a medias
- **No commitear**: este comando solo crea archivos en `dev/issues/`. No hace commits ni crea ramas
+147
View File
@@ -0,0 +1,147 @@
# 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.
+119
View File
@@ -0,0 +1,119 @@
# 0022a — E2E Tests: Infraestructura base
> Parte de [0022 — Tests E2E con Playwright](0022-e2e-tests-playwright.md)
## Objetivo
Crear el proyecto Node.js base para tests E2E con Playwright: estructura de directorios, configuracion, scripts de instalacion y setup de Element Web local.
## Contexto
- Primer sub-issue del desglose de 0022. Establece la base sobre la que 0022b y 0022c construyen.
- Playwright necesita un proyecto Node.js independiente con sus propias dependencias
- Element Web se sirve localmente para control total del entorno
- La VPS no tiene entorno grafico — todo headless
## Arquitectura
```
e2e/ NEW — proyecto Node.js independiente
├── package.json NEW — playwright, @playwright/test, dotenv
├── playwright.config.ts NEW — config headless, timeouts, base URL
├── .env.example NEW — template de variables E2E
├── fixtures/ NEW — directorio vacio (se llena en 0022b)
├── tests/ NEW — directorio vacio (se llena en 0022c)
└── scripts/
└── setup-element.sh NEW — descargar/levantar Element Web local
dev-scripts/e2e/
├── install.sh NEW — instalar Node, Playwright, deps
└── run.sh NEW — placeholder (se completa en 0022c)
```
### Patron pure core / impure shell
100% infra de testing, sin cambios al codigo Go.
## Tareas
### Fase 1: Proyecto Node.js
- [ ] **1.1** Crear `e2e/package.json` con dependencias: `@playwright/test`, `dotenv`
- [ ] **1.2** Crear `e2e/playwright.config.ts`:
- Headless por defecto
- Timeout de 30s para acciones (LLMs son lentos)
- Screenshot on failure
- Base URL desde env (`ELEMENT_URL`)
- Solo proyecto Chromium
- `globalSetup` apuntando a `global-setup.ts` (se creara en 0022b)
- [ ] **1.3** Crear `e2e/.env.example`:
```
ELEMENT_URL=http://localhost:8080
MATRIX_HOMESERVER=https://matrix-af2f3d.organic-machine.com
MATRIX_USER=@test-user:matrix-af2f3d.organic-machine.com
MATRIX_PASSWORD=
MATRIX_RECOVERY_KEY=
```
### Fase 2: Scripts
- [ ] **2.1** Crear `e2e/scripts/setup-element.sh`:
- Descargar Element Web release (version fijada)
- Generar `config.json` apuntando al homeserver
- Servir con `python3 -m http.server` o `npx serve` en puerto 8080
- Opcion para detener el servidor
- [ ] **2.2** Crear `dev-scripts/e2e/install.sh`:
- Verificar/instalar Node.js v18+
- `npm ci` en `e2e/`
- `npx playwright install chromium`
- `npx playwright install-deps` (necesita sudo)
- [ ] **2.3** Crear `dev-scripts/e2e/run.sh` como placeholder:
- Verificar que `e2e/node_modules/` existe
- Verificar que `e2e/.env` existe
- Mensaje indicando que los tests se agregan en 0022c
### Fase 3: Gitignore y verificacion
- [ ] **3.1** Agregar a `.gitignore`: `e2e/node_modules/`, `e2e/test-results/`, `e2e/.auth/`, `e2e/.env`
- [ ] **3.2** Verificar que `npm ci` y `npx playwright install chromium` funcionan en la VPS
- [ ] **3.3** Verificar que Element Web se levanta y es accesible en `localhost:8080`
---
## Ejemplo de uso
```bash
# Instalar todo
./dev-scripts/e2e/install.sh
# Configurar credenciales
cp e2e/.env.example e2e/.env
vim e2e/.env
# Levantar Element Web
./e2e/scripts/setup-element.sh start
# → Element Web serving at http://localhost:8080
# Verificar que carga
curl -s http://localhost:8080 | head -5
# → <!doctype html>...
# Detener
./e2e/scripts/setup-element.sh stop
```
## Decisiones de diseno
- **Version fijada de Element**: evita que cambios de UI rompan selectores. Se actualiza manualmente.
- **python3 http.server como fallback**: disponible en cualquier VPS sin instalar nada extra. `npx serve` como alternativa si esta disponible.
- **Directorios vacios con .gitkeep**: `fixtures/` y `tests/` se crean vacios para que la estructura exista desde el primer sub-issue.
## Prerequisitos
- Acceso a la VPS con sudo (para `playwright install-deps`)
- Conectividad al homeserver Matrix
## Riesgos
- **Node.js no instalado**: `install.sh` debe manejarlo con instrucciones claras o instalacion automatica via nvm/nodesource.
- **Playwright deps del sistema**: varian por distro. `playwright install-deps` lo maneja pero necesita sudo.
+125
View File
@@ -0,0 +1,125 @@
# 0022b — E2E Tests: Auth fixtures y helpers de interaccion
> Parte de [0022 — Tests E2E con Playwright](0022-e2e-tests-playwright.md)
> Depende de: [0022a — Infraestructura base](0022a-e2e-infra.md)
## Objetivo
Implementar los fixtures de Playwright para autenticacion en Element Web (login + cross-signing E2EE) y los helpers de interaccion con rooms Matrix (enviar mensajes, esperar respuestas de bots).
## Contexto
- Element Web requiere login + verificacion de dispositivo con recovery key para desencriptar mensajes E2EE
- El flujo de login es lento (~10s) — se cachea con `storageState` de Playwright para reutilizar entre tests
- Los helpers de room abstraen la interaccion con la UI de Element para que los tests sean legibles
- Depende de 0022a: el proyecto Node.js y Element Web local ya deben estar configurados
## Arquitectura
```
e2e/
├── global-setup.ts NEW — ejecuta login una vez, guarda storageState
├── fixtures/
│ ├── element-auth.ts NEW — flujo de login + cross-signing
│ └── matrix-room.ts NEW — goToRoom, sendMessage, waitForBotReply, getLastMessage
└── .auth/
└── state.json NEW (generado) — sesion autenticada cacheada
```
### Patron pure core / impure shell
100% infra de testing, sin cambios al codigo Go.
## Tareas
### Fase 1: Fixture de autenticacion
- [ ] **1.1** Crear `e2e/fixtures/element-auth.ts` con el flujo completo:
1. Navegar a Element Web
2. Click "Sign in"
3. Configurar homeserver URL si no esta preset
4. Ingresar usuario y contraseña
5. Manejar prompt de verificacion de dispositivo
6. Ingresar recovery key para cross-signing
7. Verificar login exitoso (lista de rooms visible)
- [ ] **1.2** Crear `e2e/global-setup.ts`:
- Lanzar browser
- Ejecutar flujo de login de `element-auth.ts`
- Guardar sesion con `page.context().storageState({ path: 'e2e/.auth/state.json' })`
- Cerrar browser
- [ ] **1.3** Actualizar `playwright.config.ts` para usar `globalSetup` y `storageState`
### Fase 2: Helpers de interaccion
- [ ] **2.1** Crear `e2e/fixtures/matrix-room.ts` con helpers:
- `goToRoom(page, roomName)` — buscar y navegar a un room por nombre
- `sendMessage(page, text)` — escribir mensaje en el composer y enviar
- `waitForBotReply(page, options?)` — esperar respuesta de un bot con timeout configurable, filtrar por sender si se especifica
- `getLastMessage(page)` — obtener texto del ultimo mensaje del timeline
- [ ] **2.2** Implementar deteccion de "Unable to decrypt" — si aparece, el test debe fallar con mensaje claro indicando problema de E2EE
### Fase 3: Tests de validacion
- [ ] **3.1** Crear `e2e/tests/login.spec.ts` — smoke test:
- Login funciona (usa storageState cacheado)
- Se ven rooms en el sidebar
- No aparece "Unable to decrypt" en mensajes recientes
- [ ] **3.2** Verificar que el segundo run reutiliza la sesion cacheada (no repite login)
- [ ] **3.3** Verificar que los helpers navegan correctamente a rooms de los bots
---
## Ejemplo de uso
```typescript
// global-setup.ts
import { chromium } from '@playwright/test';
import { loginToElement } from './fixtures/element-auth';
async function globalSetup() {
const browser = await chromium.launch();
const page = await browser.newPage();
await loginToElement(page, {
url: process.env.ELEMENT_URL!,
user: process.env.MATRIX_USER!,
password: process.env.MATRIX_PASSWORD!,
recoveryKey: process.env.MATRIX_RECOVERY_KEY!,
});
await page.context().storageState({ path: 'e2e/.auth/state.json' });
await browser.close();
}
export default globalSetup;
```
```typescript
// Uso de helpers en un test (preview de 0022c)
import { goToRoom, sendMessage, waitForBotReply } from '../fixtures/matrix-room';
test('bot responde', async ({ page }) => {
await goToRoom(page, 'Assistant Bot');
await sendMessage(page, 'Hola');
const reply = await waitForBotReply(page, { timeout: 30_000 });
expect(reply).toBeTruthy();
});
```
## Decisiones de diseno
- **storageState global**: el login + cross-signing se hace una sola vez en `globalSetup`. Todos los tests arrancan ya autenticados.
- **Helpers como funciones puras de page**: reciben `page` como argumento en vez de extender fixtures de Playwright, para simplicidad y reusabilidad.
- **Deteccion explicita de E2EE fallido**: en vez de timeouts silenciosos, detectar "Unable to decrypt" y fallar con mensaje descriptivo.
## Prerequisitos
- 0022a completado (proyecto Node.js, Element Web local funcionando)
- Usuario de test con cross-signing configurado en el homeserver
- `.env` con credenciales validas
## Riesgos
- **UI de cross-signing cambia entre versiones de Element**: mitigacion con version fijada en 0022a y screenshots on failure.
- **Recovery key formato inconsistente**: las palabras pueden tener espacios. Asegurarse de que el input acepta el formato tal cual esta en `.env`.
- **Sesion expirada**: si el token caduca entre runs, `globalSetup` debe re-autenticar. Implementar deteccion de sesion invalida.
+148
View File
@@ -0,0 +1,148 @@
# 0022c — E2E Tests: Tests de agentes, ejecucion y docs
> Parte de [0022 — Tests E2E con Playwright](0022-e2e-tests-playwright.md)
> Depende de: [0022b — Auth fixtures y helpers](0022b-e2e-auth-helpers.md)
## Objetivo
Escribir los tests E2E para cada agente (assistant-bot, asistente-2), completar el script de ejecucion `run.sh`, y documentar todo el sistema E2E.
## Contexto
- Los fixtures de auth y helpers de room ya estan implementados (0022b)
- Cada agente tiene comportamiento distinto: assistant-bot es basico, asistente-2 tiene tools
- Los tests dependen de LLMs externos (OpenAI) que pueden tardar 5-20s en responder
- El script `run.sh` orquesta todo: verifica agentes, levanta Element, ejecuta tests, teardown
## Arquitectura
```
e2e/tests/
├── login.spec.ts EXISTENTE (de 0022b, se puede extender)
├── assistant-bot.spec.ts NEW — tests del assistant-bot
└── asistente-2.spec.ts NEW — tests del asistente-2 (con tools)
e2e/README.md NEW — documentacion del sistema E2E
dev-scripts/e2e/
└── run.sh MODIFICAR — completar el placeholder de 0022a
```
### Patron pure core / impure shell
100% infra de testing, sin cambios al codigo Go.
## Tareas
### Fase 1: Tests de agentes
- [ ] **1.1** Crear `e2e/tests/assistant-bot.spec.ts`:
- Enviar saludo en DM → bot responde (no timeout, no error)
- Enviar pregunta → respuesta coherente (no vacia, longitud > 10 chars)
- Enviar `!help` → respuesta contiene lista de comandos
- Enviar `!ping` → respuesta contiene "pong" o similar
- [ ] **1.2** Crear `e2e/tests/asistente-2.spec.ts`:
- Enviar saludo → respuesta
- Enviar `!tools` → lista de herramientas disponibles
- Enviar pregunta que active una tool (ej: "que hora es?") → respuesta con resultado
- Enviar `!help` → comandos incluyendo los especificos del agente
### Fase 2: Script de ejecucion
- [ ] **2.1** Completar `dev-scripts/e2e/run.sh`:
1. Verificar que los agentes estan corriendo (`dev-scripts/server/ps.sh`)
2. Levantar Element Web si no esta corriendo (`e2e/scripts/setup-element.sh start`)
3. Ejecutar `npx playwright test` con reporte en consola
4. Generar reporte HTML en `e2e/test-results/` para debug
5. Teardown de Element Web (`e2e/scripts/setup-element.sh stop`)
6. Retornar exit code de playwright
- [ ] **2.2** Agregar opcion `--headed` para debug local (si hay DISPLAY disponible)
### Fase 3: Verificacion completa
- [ ] **3.1** Ejecutar `npx playwright test` en la VPS (headless) — todos los tests pasan
- [ ] **3.2** Verificar que screenshots on failure se generan en `e2e/test-results/`
- [ ] **3.3** Verificar que el login cacheado funciona (segundo run no repite login)
- [ ] **3.4** Verificar que `dev-scripts/e2e/run.sh` orquesta todo correctamente
### Fase 4: Cleanup y docs
- [ ] **4.1** Crear `e2e/README.md` con:
- Como instalar (`dev-scripts/e2e/install.sh`)
- Como configurar `.env`
- Como ejecutar tests (`dev-scripts/e2e/run.sh`)
- Como debuggear fallos (screenshots, `--headed`, reporte HTML)
- Estructura del proyecto
- [ ] **4.2** Actualizar `.gitignore` si faltan entradas de 0022a
- [ ] **4.3** Actualizar `CLAUDE.md` con seccion de E2E tests
---
## Ejemplo de uso
```typescript
// assistant-bot.spec.ts
import { test, expect } from '@playwright/test';
import { goToRoom, sendMessage, waitForBotReply } from '../fixtures/matrix-room';
test.describe('assistant-bot', () => {
test('responde a un saludo', async ({ page }) => {
await goToRoom(page, 'Assistant Bot');
await sendMessage(page, 'Hola, como estas?');
const reply = await waitForBotReply(page, { timeout: 30_000 });
expect(reply).toBeTruthy();
expect(reply!.length).toBeGreaterThan(10);
});
test('!help muestra comandos', async ({ page }) => {
await goToRoom(page, 'Assistant Bot');
await sendMessage(page, '!help');
const reply = await waitForBotReply(page, { timeout: 5_000 });
expect(reply).toContain('help');
expect(reply).toContain('ping');
});
test('!ping responde', async ({ page }) => {
await goToRoom(page, 'Assistant Bot');
await sendMessage(page, '!ping');
const reply = await waitForBotReply(page, { timeout: 5_000 });
expect(reply).toBeTruthy();
});
});
```
```bash
# Ejecucion completa
./dev-scripts/e2e/run.sh
# ✓ login.spec.ts — login y verificacion E2EE (12s)
# ✓ assistant-bot.spec.ts — responde a saludo (8s)
# ✓ assistant-bot.spec.ts — !help muestra comandos (3s)
# ✓ assistant-bot.spec.ts — !ping responde (3s)
# ✓ asistente-2.spec.ts — responde con tool use (20s)
# 5 passed (46s)
# Debug con browser visible
./dev-scripts/e2e/run.sh --headed
```
## Decisiones de diseno
- **Assertions flexibles**: no validar contenido exacto de respuestas LLM (son no-deterministicas). Solo verificar que responde, que no esta vacio, y longitud razonable.
- **Commands con assertions estrictas**: los `!help` y `!ping` tienen respuestas deterministicas — se pueden validar con mayor precision.
- **Test retry**: `test.retry(1)` en la config para manejar timeouts ocasionales por LLM lento.
- **Tests secuenciales**: los tests de un mismo agente se ejecutan en serie (fullyParallel: false) para evitar race conditions en el timeline de Matrix.
## Prerequisitos
- 0022a y 0022b completados
- Agentes corriendo contra el homeserver
- `.env` configurado con credenciales validas
## Riesgos
- **LLM timeout**: respuestas de GPT-4o pueden tardar >30s bajo carga. Mitigacion: retry + timeout generoso.
- **Race conditions en timeline**: si dos tests envian mensajes al mismo bot simultaneamente, las respuestas pueden mezclarse. Mitigacion: tests secuenciales por agente.
- **Tool use no deterministico**: el LLM puede decidir no usar una tool. Mitigacion: prompt de test claro (ej: "que hora es?" para current_time), retry si falla.
+5
View File
@@ -25,3 +25,8 @@ afectados y notas de implementacion.
| 18 | Shared knowledge | [0018-shared-knowledge.md](0018-shared-knowledge.md) | pendiente |
| 19 | Prompt injection hardening | [0019-prompt-injection-hardening.md](completed/0019-prompt-injection-hardening.md) | completado |
| 20 | Aislar claude -p del repo | [0020-claude-code-sandbox.md](completed/0020-claude-code-sandbox.md) | completado |
| 21 | Threads default config | (completado via branch) | completado |
| 22 | Tests E2E con Playwright | [0022-e2e-tests-playwright.md](0022-e2e-tests-playwright.md) | pendiente |
| 22a | E2E: Infraestructura base | [0022a-e2e-infra.md](0022a-e2e-infra.md) | pendiente |
| 22b | E2E: Auth fixtures y helpers | [0022b-e2e-auth-helpers.md](0022b-e2e-auth-helpers.md) | pendiente |
| 22c | E2E: Tests de agentes + docs | [0022c-e2e-agent-tests.md](0022c-e2e-agent-tests.md) | pendiente |