Guía de usuario — Full Testing Web (FTW)
Esta guía explica cómo usar Full Testing Web, el panel de control web que orquesta el framework de automatización Full Testing AI contra la aplicación de ejemplo Banco Americano. Está pensada para el equipo de QA: qué hace cada pantalla, cómo se crean pruebas con IA, qué reglas exactas siguen la automatización en lenguaje natural y la autosanación, y dónde encontrar cada artefacto.
La misma guía existe en inglés (user-guide.en.md) y se puede leer dentro de
la propia aplicación en la página User Guide del menú lateral.
1. Qué es FTW y cómo encaja en el ecosistema
FTW es una aplicación FastAPI + Jinja + htmx que corre en local
(http://localhost:9000). No ejecuta pruebas por sí misma: coordina tres
piezas:
┌──────────────────────────────────────────────┐
│ FPD — Full Project Director (puerto 8000) │
│ · Sirve la app bajo prueba: Banco Americano │
│ (/playground/banco-americano) │
lee casos de prueba │ · API de casos de prueba (GET /api/tcs) │
(GET /api/tcs) │ · Puerta de enlace LLM │
┌──────────────────┐ │ (POST /api/ai/complete, task=generation) │
│ │ ─▶ └──────────────────────────────────────────────┘
│ Full Testing │ ▲
│ Web (FTW) │ ───────────────┘ todas las llamadas a la IA pasan
│ puerto 9000 │ llamadas LLM por FPD con el token FTW_FPD_TOKEN
│ │
│ FastAPI + htmx │ ┌──────────────────────────────────────────────┐
│ │ │ Full Testing AI (framework, repo aparte) │
│ Lanza procesos │ ─▶│ Java 21 · Maven · JUnit 5 · Playwright │
│ Maven y lee los │ │ Patrón POM + Flow Objects │
│ resultados │ │ Toolchain portable: ../.tools/jdk, │
└───────┬──────────┘ │ ../.tools/maven │
│ └───────────────┬──────────────────────────────┘
│ push a main solo cuando │ push (siempre decisión humana)
│ un humano pulsa Publicar ▼
│ ┌──────────────────┐
└────────────────────▶│ GitHub (repo │
│ full-testing-ai, │
│ Actions CI) │
└──────────────────┘
- FPD (Full Project Director) — la aplicación anfitriona. Sirve el Banco
Americano (la app bajo prueba), la API de lectura de casos de prueba (TC) y
la única puerta de enlace hacia el LLM:
POST /api/ai/completecontask: "generation". FTW nunca habla con el proveedor de IA directamente. - Full Testing AI (FTA) — el framework de pruebas, un repo independiente
en Java 21 / Maven / JUnit 5 / Playwright con patrón híbrido
POM + Flow Objects (tres capas: page objects con localizadores y
acciones atómicas; flow objects con flujos de negocio reutilizables como
login; tests con orquestación y aserciones). Los tests ejecutados son
código determinista: la IA solo participa en la creación y en la
sanación, nunca dentro de
mvn test. - GitHub — el repo
JulioCOropeza/full-testing-aicon GitHub Actions (tests.yml, disparo manualworkflow_dispatch). Nada se ejecuta en servidores propios.
La filosofía de publicación (regla de oro)
El repo del framework se trata como de solo lectura. FTW lee archivos (registro de cobertura, fuentes, reportes surefire) y ejecuta los comandos Maven del propio framework, pero nunca escribe en el repo hasta que un humano pulsa un botón de publicar:
- Push to main en un scaffold o en una automatización verificada.
- Apply & push to main en un refactor terminado.
- En la autosanación, main nunca se toca: el arreglo se empuja a una rama
heal/...y se sugiere un PR para revisión humana.
Además, los botones de publicar solo versionan exactamente los archivos que
generó ese trabajo (nunca git add -A): cambios no relacionados que tengas
en el working tree del framework jamás se tocan. La única excepción
deliberada: un coverage/coverage.json con cambios (regenerado por la corrida
de verificación) viaja en el mismo commit de publicación, para que el registro
@Covers llegue a main junto con el código.
Puertas de verificación: nada llega a main sin verificar. La ruta de
automatización NL solo habilita Push to main en estado verified (corrida
headless en verde); la ruta de refactor tiene la misma puerta desde
2026-08-04 — Apply & push to main permanece bloqueado hasta que Verify
before publish termine en verde, y el servidor rechaza la publicación en
caso contrario (HTTP 409).
Cerrar el ciclo: tras un push exitoso, FTW publica de inmediato el
registro de cobertura en FPD (POST /api/tcs/automations/coverage), así que
el botón "Run automated" de FPD se entera al momento de la nueva
automatización — sin esperar un GitHub Actions. La sincronización es
soft-fail: nunca bloquea una publicación.
Rollback: cada publicación queda registrada (ver Publishes en la
página Run) y se puede deshacer con un clic. El rollback es un
git revert --no-edit + push — el historial conserva tanto la publicación
como su revert, nunca un reset ni force-push — seguido de la misma
sincronización de cobertura, para que FPD quede consistente con el estado
revertido. Si el revert tiene conflictos (commits posteriores tocaron esos
archivos), se aborta y se reporta para resolución manual; nada se
fuerza.
2. Puesta en marcha
Prerrequisitos: Python 3.12+, el repo full-testing-ai clonado con su
toolchain portable (TestProjects/.tools/jdk y .tools/maven), y FPD
corriendo en el puerto 8000.
cd /c/Users/JulioAI/TestProjects/full-testing-web
.venv/Scripts/python -m uvicorn app.main:app --port 9000
Para habilitar el TC Explorer y todas las funciones con IA necesitas un token
de API de FPD (en FPD: Profile → API tokens, empieza por fpd_). Se
configura con la variable FTW_FPD_TOKEN o en el archivo .env (ver
.env.example). Sin token la app arranca igual, pero el TC Explorer queda
deshabilitado y las funciones con IA no pueden llamar al LLM.
3. Tour por las pantallas
3.1 Dashboard (/)
Panel de salud del entorno:
- Framework: si el directorio
full-testing-aiexiste y si contienecoverage/coverage.json(el registro de cobertura). - Banco Americano: si la app bajo prueba responde (GET a la página de login del banco).
- FPD API: si
GET /api/tcsresponde (un 401 anónimo ya cuenta como "arriba"). - Coverage: cuántas claves TC hay en el registro y, con token configurado, cuántos TC de FPD están automatizados vs. sin automatizar.
- Discovered test classes: tabla de todas las clases
*Test.javaencontradas en el framework con sus anotaciones@Covers("TC-KEY")(se omiten las clases base abstractas).
3.2 TC Explorer (/tcs)
Lista los casos de prueba de FPD (GET /api/tcs, con búsqueda q en el
servidor). Cada fila muestra:
- Clave, título y carpeta del TC.
- Estado de cobertura: badge verde Automated → Clase#método (la clave
está en el registro
coverage/coverage.jsondel framework tal como está commiteado en origin/main), badge ámbar Automated (unpublished) cuando la entrada de cobertura existe solo en el registro local — generada por una corrida de verificación local y aún no empujada a main (tooltip: "generated locally, not pushed to main yet") — o badge ámbar Not automated. La comparación leegit show origin/main:coverage/coverage.json(con fallback aHEAD, y al comportamiento local de siempre si git falla). - Expand: carga el spec completo del TC (precondición + tabla de pasos
acción → resultado esperado) y dos botones de autoría con IA:
Scaffold test y Automate with AI (con casilla
headless). Si el TC ya está cubierto se muestra un aviso ámbaralready covered by ...para evitar duplicar cobertura. Cuando el TC está Automated (unpublished), aparece además un botón Push to main: commitea y empuja exactamente los archivos generados para ese TC (recuperados de los registros de automatización persistidos — las páginas de trabajo de automatización son en memoria y desaparecen al reiniciar) junto con el registro de cobertura local pendiente, y re-sincroniza la cobertura con FPD — la vía de recuperación cuando el push no se hizo al momento de automatizar.
Los dos botones se explican en detalle en la sección 4.
3.3 Run (/run)
Lanza la suite del framework como un trabajo en segundo plano (mvn -B test).
El formulario ofrece:
- Scope:
All tests,Bank UI only(TransferFlowTest + DepositVariationsTest),FPD API only(FpdTcsApiTest) o una clase individual de las descubiertas. - Headless browser: navegador sin ventana (se pasa como
FTA_HEADLESS). - Auto-heal with AI on failure: autosanación automática para esta ejecución — marcada por defecto; es el opt-out por corrida (ver la sección 5).
- Device: perfil de emulación (Desktop, iPhone 13, Pixel 7, iPad; se pasa
como
FTA_DEVICEcon viewport, user-agent y touch). - Base URL: contra qué servidor correr (se pasa como
FTA_BASE_URL; por defecto el FPD local).
Mientras corre, la página del trabajo (/run/{id}) se actualiza sola cada 2
segundos (htmx) mostrando el log de Maven en vivo. Al terminar muestra:
- Tarjetas resumen: tests, passed, failures, errors, skipped y tiempo.
- Por cada fallo: clase#método, mensaje, stack trace, captura de pantalla
en línea y enlace al HTML de la página en el momento del fallo
(artefactos servidos desde
target/artifacts/del framework). - Botón Allure report: genera (o regenera) el sitio estático de Allure
de esa corrida a partir de sus resultados guardados y lo abre en una URL
permanente por corrida (
/reports/allure/<id-de-corrida>/index.html) — cada corrida conserva su propio reporte, no el de la última generada. - Las secciones de autosanación (ver sección 5): la de ejecuciones automáticas con su clasificación y la de botones manuales Heal ... with AI por cada clase fallida.
Las páginas de corrida son persistentes: cada corrida queda registrada en
recordings/runs.json (scope, opciones, estado, resumen y decisiones de
autosanación) y su página sigue renderizando tras reiniciar FTW (el log de
Maven en vivo solo vive en memoria). Una corrida que estaba en vuelo cuando
FTW se reinició vuelve como interrupted (server restarted mid-run).
Debajo del formulario, la sección Recent runs lista las últimas corridas persistidas (más recientes primero: hora de inicio, scope, badge de estado, passed/total y las clasificaciones de auto-heal si las hubo), cada una con enlace a su página de corrida.
Debajo del formulario, la sección Publishes lista los pushes a
origin main hechos desde este panel (más recientes primero: sha corto,
origen — scaffold / refactor / automate —, clave TC, mensaje y fecha). Cada
entrada aún vigente ofrece un botón Rollback: git revert --no-edit +
push (el historial conserva ambos commits — nunca un reset ni force-push)
seguido de una re-sincronización de cobertura a FPD, para que el estado
revertido quede consistente en todas partes. Un revert en conflicto con
commits posteriores se aborta y se reporta como "conflict — resolve
manually". Las entradas ya revertidas muestran un badge gris con su commit
de revert.
Limitaciones conocidas de esta pantalla:
- El log de Maven en vivo no se retiene entre reinicios: las páginas de corridas pasadas muestran resumen, fallos y Allure, pero no el log.
- Las listas que se renderizan al cargar la página (como la de grabaciones de Record & Play) no se refrescan solas: usa F5 para ver entradas nuevas.
3.4 Record & Play (/record)
Graba un flujo manual y lo convierte en código Java crudo de Playwright:
- Elige el TC: un desplegable alimentado por FPD (con badge de cobertura) si hay token, o un campo de texto libre para la clave.
- System under test: un desplegable alimentado por el registro de
sistemas (
config/apps.json, ver §3.5) que muestranombre — start_url; la grabación empieza en la URL configurada de la app. La opción Custom URL… revela el antiguo campo de texto libre como vía de escape — solo URLs http(s) sin&ni espacios (lista blanca de seguridad de shell), y toda URL, configurada o libre, pasa la misma lista blanca antes de llegar a la línea de comandos. - Device: viewport de grabación (la emulación completa se aplica luego en
tiempo de ejecución vía
FTA_DEVICE). - Start recording: se abre una ventana de navegador real en esta
máquina (Playwright codegen vía
mvn exec:java). Realiza el flujo con normalidad; el código se va volcando al archivo de salida mientras grabas. - Para terminar, cierra la ventana del navegador: es la forma limpia y
conserva todo lo grabado. El botón Stop mata la sesión
(
taskkill /T /F) y puede perder las últimas acciones aún no volcadas — la propia UI lo advierte.
La página del trabajo muestra el log del codegen y el Java capturado.
Al terminar, el archivo se guarda en
recordings/<tc-key>-<yyyymmdd-HHMMSS>.java (carpeta ignorada por git) y
aparece en el panel Saved recordings de la derecha. Las grabaciones se
agrupan por clave de TC (extraída del nombre del archivo; las que no
coinciden con el patrón caen en Other), cada grupo es una sección
plegable que muestra el número de grabaciones y la fecha de la más reciente,
con las más nuevas primero dentro. Acciones por grabación:
View / Download / Refactor / Delete — Delete es permanente (no hay
papelera) y pide confirmación antes. La lista se genera al cargar la página:
si terminas una grabación con la página abierta, pulsa F5 para verla.
3.5 Systems (/systems)
El registro de sistemas bajo prueba — el panel de config/apps.json:
- Lista: cada app configurada con su clave, nombre,
start_urly los nombres de rol de sus usuarios (las credenciales nunca se muestran). - Add / Edit / Delete: nombre y
start_urlson obligatorios; la URL debe ser http(s) y pasar la misma lista blanca de seguridad de shell que Record & Play. La clave de un sistema nuevo se deriva de su nombre (slug en minúsculas, con sufijo si colisiona). Edit conserva intacto el bloqueusersde la app — las credenciales se gestionan editandoconfig/apps.jsondirectamente. - Sin reinicio: el archivo se recarga en caliente, así que los cambios se
aplican al instante. La página reescribe el archivo como JSON canónico con
indentación de 2 espacios, preservando su estructura
(
{clave: {name, start_url, users{rol: creds}}}).
Este registro es compartido: el desplegable de Record & Play lo lista (§3.4) y Automate with AI lee la misma entrada para su URL inicial y sus credenciales de login (§4.3).
4. Creación de pruebas con IA
Las tres funciones de autoría comparten el mismo modelo: la IA genera código siguiendo las convenciones vivas del framework, el resultado se guarda fuera del repo para revisión, y solo un humano lo publica con un botón.
4.1 Scaffold test (andamiaje desde un TC)
Qué hace: ejecuta la herramienta TestScaffolder del framework
(mvn -q test-compile exec:java) para crear el esqueleto de una clase de test
a partir de la clave del TC.
Pasos: TC Explorer → fila del TC → Expand → botón Scaffold test (puede tardar un minuto: es Maven).
Qué escribe y dónde: un archivo *.java nuevo bajo el directorio de tests
de la app en el repo del framework, con @Covers("<clave>"), el javadoc con
el título del spec y un único método @Disabled con un comentario
// TODO(step n): <acción> -> <esperado> por cada paso del TC. Compila pero
no se ejecuta hasta que se implemente. Nunca sobrescribe un archivo
existente.
Reglas de decisión:
- La comprobación de duplicados va primero: si la clave ya está en
coverage/coverage.json, no se escribe nada y se muestra un cuadro ámbarALREADY COVERED by ...(hay que extender el test existente, no crear uno nuevo). - Conflicto (el archivo ya existe): se aborta sin escribir.
Publicación: el resultado ofrece un botón Push to main que commitea y
empuja a origin main únicamente el archivo generado (más un
coverage/coverage.json con cambios, si existe). Tras el push, FTW sincroniza
el registro de cobertura a FPD de inmediato y la página de resultado ofrece un
botón Rollback (revert + push, nunca un reset). Una vez publicado, el
botón se renderiza deshabilitado con el tooltip Already pushed (\<sha
corta>) (un rollback lo rehabilita). También puedes revisarlo
en el repo y borrarlo si no lo quieres.
4.2 Refactor with AI (sobre una grabación)
Qué hace: reescribe el Java crudo de Playwright codegen en las convenciones del framework (POM + Flow Objects, Allure, DataFactory) usando el LLM de FPD.
Pasos: Record & Play → termina una grabación → botón Refactor (en la página del trabajo terminado o en la lista de grabaciones guardadas). La página del refactor se actualiza sola cada 2 segundos mientras la IA trabaja.
Cómo funciona: el Java crudo se envía a POST {FPD}/api/ai/complete con
un prompt enriquecido con las convenciones reales del framework: inventario de
pages/flows existentes (escaneados de bank/pages y bank/flows), las
plantillas del scaffolder, un test real como ancla de estilo y el estado de
cobertura del TC. La IA responde JSON estricto
{files: [{kind, class_name, package, code}], notes} que se valida en forma
(máx. 8 archivos, 60 000 caracteres por archivo, nombres de clase y paquete
válidos).
Qué escribe y dónde: los archivos validados se guardan en
recordings/<base>.refactored/ para revisión — el repo del framework sigue
intacto.
Verify before publish (la puerta): un refactor terminado no se puede
publicar directamente. El botón Verify before publish aplica los archivos
en el checkout del framework (todo-o-nada, la misma semántica del publish) y
corre la clase de test producida en headless (mvn test -Dtest=<Clase>); la
página se actualiza sola mientras corre. En verde, el trabajo muestra un
badge Verified con el resumen de la corrida y el botón de publicar se
desbloquea. En fallo, la página muestra el resumen del fallo (errores de
compilación o casos fallidos con enlaces a captura / HTML de página), no se
commitea ni empuja nada, y el botón de publicar sigue bloqueado: corrige el
código en el checkout del framework y pulsa Re-verify — la nueva
corrida prueba el checkout tal cual, así que lo que se verifica son tus
correcciones manuales. El servidor impone la misma regla: publicar un
refactor no verificado se rechaza con HTTP 409.
Publicación: Apply & push to main en un trabajo verificado commitea
el estado del checkout de los archivos generados (lo que quedó verificado en
verde, correcciones manuales incluidas) — pages y flows viven bajo
src/main/java, tests bajo src/test/java — más el
coverage/coverage.json regenerado, y empuja a origin main. Si algún
destino ya existe con contenido distinto, se aborta todo el publish (no
se sobrescribe nada): hay que reconciliar a mano en el repo. Tras el push,
FTW sincroniza de inmediato el registro de cobertura a FPD (soft-fail) y la
página de resultado ofrece un botón Rollback.
4.3 Automate with AI (automatización en lenguaje natural)
Qué hace: convierte un TC manual de FPD (pasos + resultados esperados en lenguaje natural) en un test Java determinista, verde y verificado, con un solo clic.
Pasos: TC Explorer → fila del TC → Expand → botón Automate with AI
(casilla headless marcada por defecto). Se abre la página del trabajo, que
se actualiza cada 2 segundos y encadena automáticamente todas las etapas:
discovery → generating → applied → verifying ⇄ healing → verified.
Etapa 1 — Discovery (exploración)
Un agente conduce un navegador Chromium real mediante Python Playwright nativo (sin Node.js: el plan original preveía Playwright MCP, pero el host no tiene Node; la técnica es la misma — snapshot aria + referencias — y el dueño aceptó la desviación tras comprobar que todos los fallos de aceptación estaban en la generación Java, nunca en la conducción del navegador).
En cada iteración el bucle:
- Etiqueta los elementos interactivos visibles con atributos
data-fta-ref(máx. 80 referencias) y toma un snapshot aria de la página (máx. 12 000 caracteres). - Envía a FPD (
/api/ai/complete, taskgeneration) el spec del TC (pasos y esperados), la config de la app (URL y usuarios/roles deconfig/apps.json), el snapshot, la tabla de referencias y el historial de acciones. - Recibe una única acción JSON estricta
(
click | fill | press | navigate | assert_text | assert_visible | done | fail), la ejecuta en el navegador y registra el resultado. Los errores se devuelven al siguiente prompt, así que el bucle se autocorrige en línea.
El resultado es un action log: pasos ordenados con estrategias de
localización concretas (prioridad data-testid > role+nombre > css > texto),
valores tecleados y éxito/fallo por paso. Se persiste en
recordings/automations/<TC>-<timestamp>.json.
Guardarraíles del discovery: máx. 40 pasos por defecto (tope 200), tope de
15 minutos de reloj, timeout de página 8 s, y aborto tras 3 fallos
consecutivos de llamada al LLM (endpoint caído o token inválido). El modelo
declara done solo cuando ejecutó todos los pasos y verificó todos los
resultados esperados; fail cuando el caso no se puede completar.
Etapa 2 — Generating (conversión a Java)
El action log se convierte a Java reutilizando el perfil de Refactor with
AI más reglas de endurecimiento aprendidas en las corridas de aceptación:
firmas exactas de DataFactory/Money, patrón de precondición con admin,
aserciones por subcadena (nunca igualdad exacta para assert_text), preferencia
por componer Flow classes, paquete correcto de TestConfig, anotaciones en su
sitio (@Covers/@Feature/@Story a nivel de clase; @Description/@Test en el
método) y prohibido inventar aserciones no vistas en el discovery. Se
generan archivos completos y compilables bajo las convenciones POM + Flows
(pages en bank/pages, flows en bank/flows, test en bank/tests), y se
dejan "stageados" en recordings/automations/<stem>.generated/.
Etapa 3 — Applied (escritura en el framework)
Los archivos staged se escriben en el checkout del framework con política todo o nada: si algún destino existe con contenido distinto, la etapa falla sin escribir nada y hay que reconciliar a mano (la UI lo explica y ofrece re-ejecutar el pipeline).
Etapa 4 — Verifying (y auto-reparación)
Se ejecuta mvn test -Dtest=<ClaseGenerada> headless. "Verified" significa
exactamente: la corrida terminó bien, el reporte surefire existe para esa
clase y tiene 0 fallos y 0 errores.
Si falla, entra el bucle de auto-reparación (badge naranja healing),
hasta un máximo de 2 rondas:
- Se destila la evidencia del fallo (líneas
[ERROR]de javac/surefire o detalle de los casos fallidos, acotada a ~6-8 mil caracteres) junto con el contenido actual de los archivos. - El LLM propone archivos corregidos (mismos nombres de clase).
- Se re-aplican con guarda estricta: solo se pueden sobrescribir los archivos que este mismo trabajo generó.
- Se re-verifica headless. Si sigue en rojo, segunda y última ronda.
Publicación — Push to main
El botón Push to main solo se habilita en estado verified. Es una
decisión humana: commitea únicamente los archivos que el trabajo aplicó
(mensaje NL automation of <TC> into POM/Flows (job <id>), más el
coverage/coverage.json regenerado cuando la corrida de verificación lo deja
con cambios) y los empuja a origin main. Justo después del push, FTW
publica el registro de cobertura en FPD (soft-fail), así que el TC pasa a
automated en FPD sin esperar un GitHub Actions, y el resultado de la
publicación ofrece un botón Rollback (revert + push, nunca un reset). A
partir de ese momento el botón se renderiza deshabilitado con el tooltip
Already pushed (\<sha corta>) — FTW registra cada publicación y bloquea el
botón contra dobles pushes; un rollback lo rehabilita.
El objetivo económico del dueño: el primer pase paga el discovery y la
generación; todas las re-ejecuciones posteriores son mvn test plano — 0
coste de IA, totalmente deterministas.
Reglas de decisión, resumen exacto:
| Pregunta | Regla |
|---|---|
| ¿Cuándo reintenta una acción del discovery? | Cuando la acción falla o la respuesta no es JSON válido, el error se devuelve al siguiente prompt (mismo paso consume 1 del presupuesto de pasos). |
| ¿Cuándo aborta el discovery? | 3 fallos LLM seguidos, 40 pasos agotados (tope 200), 15 min de reloj, o el modelo declara fail. |
| ¿Cuántas rondas de reparación? | Máximo 2 (MAX_REPAIR_ROUNDS), cada una re-verificada. |
| ¿Qué es "verified"? | Corrida mvn terminada OK + surefire de la clase generada con 0 fallos y 0 errores. |
| ¿Cuándo se empuja a main? | Nunca automáticamente: solo si un humano pulsa Push to main en estado verified. |
| ¿Qué pasa si hay conflicto al aplicar? | Todo o nada: no se escribe nada; el humano reconcilia en el repo y re-ejecuta el pipeline. |
5. Autosanación (self-healing) — el conjunto completo de reglas
La autosanación arregla tests que fallan al re-ejecutarse porque la aplicación cambió (típicamente un localizador), y propone el arreglo como PR para revisión humana. Es la pieza con reglas más estrictas del módulo.
5.1 Disparo automático en CUALQUIER corrida fallida
El autosanado se dispara automáticamente al terminar cualquier corrida con fallos (hook del runner), siempre que concurran dos condiciones:
- el interruptor maestro
FTW_AUTO_HEAL(por defecto activado), y - la casilla por corrida Auto-heal with AI on failure del formulario Run (marcada por defecto — desmárcala para excluir esa corrida, p. ej. en demos).
El botón Heal ... with AI de la página de resultados es solo el camino manual; nunca es el único mecanismo. Las corridas de verificación internas del pipeline de automatización nunca disparan autosanado (tienen su propio bucle de reparación).
5.2 Clasificador de fallos
Cada caso fallido se clasifica con la heurística del FailureAnalyzer del
framework (mismo orden de precedencia), usando el mensaje del fallo y el texto
visible del HTML capturado:
| Categoría | Firma | ¿Autosana? |
|---|---|---|
LOCATOR_DRIFT |
TimeoutError / "timeout" / "waiting for ..." en la salida (el elemento ya no aparece) |
Sí — única categoría elegible |
BEHAVIOR_MISMATCH |
Fallo de aserción (AssertionFailedError, expected...) — la app responde pero no como dice el spec |
No, nunca: es un bug real candidato y se reporta |
APP_ERROR |
La página capturada es un 5xx (internal server error, bad gateway, etc.) | No, nunca: bug de la aplicación, se reporta |
UNKNOWN |
Ninguna de las anteriores | Solo si conserva firma de timeout/"waiting for"; en caso contrario no |
Regla fundamental: BEHAVIOR_MISMATCH y APP_ERROR jamás se autosanan —
enmascararían bugs reales de la aplicación. En la página de resultados cada
fallo muestra su clasificación y, cuando no es autosanable, la nota
not online-healable — review as a likely app bug.
5.3 Guardas y límites
- Máximo 2 rondas de sanación por clase de test (
HEAL_ROUNDS = 2), cada una verificada antes de intentar la siguiente. - Máximo 3 autosanados por corrida (
MAX_AUTO_HEALS_PER_RUN = 3); a partir del cuarto fallo elegible la entrada queda con la notaauto-heal cap reached — use the manual button. - Un trabajo de sanación por clase+método a la vez (se rechazan duplicados en curso).
- Opt-out por corrida con la casilla del formulario (por defecto ON) e
interruptor global
FTW_AUTO_HEAL.
5.4 Qué hace un trabajo de sanación
- Evidencia (máx. 8 000 caracteres): del último surefire XML de la clase, el stack trace y la línea del localizador que hizo timeout ("waiting for ..."); más el snapshot HTML más reciente del paso fallido (título y texto visible de la página actual).
- Contexto: contenido actual de la clase de test y de los pages/flows que importa.
- LLM (mismo canal
/api/ai/complete, timeout de 600 s): prompt de modo HEAL — diff mínimo, arreglar solo lo que la evidencia señala (típicamente un localizador obsoleto en un page object), prohibido debilitar aserciones, renombrar o crear clases; solo puede devolver versiones corregidas de los archivos dados. Un arreglo de solo page object es válido. - Aplicación con la guarda más estricta: sobrescritura únicamente de
archivos existentes directamente bajo
bank/tests|pages|flows, todo o nada, guardando el contenido previo de cada archivo. - Re-verificación headless (
mvn test -Dtest=<Clase>). Si sigue en rojo, una segunda y última ronda con la evidencia nueva. Hay un reintento extra en la misma ronda ante errores de transporte (p. ej. un timeout de lectura no consume una ronda).
5.5 Resultados posibles
- Sanado y verificado (verde): se crea la rama
heal/<Clase>-<timestamp>, se commitean solo los archivos sanados, se empuja y la UI muestra el enlace de compare para abrir el PR (/compare/main...<rama>). El merge es siempre humano — jamás se commitea enmain. El checkout vuelve amainal terminar. - Verde pero sin diff vs main (el "fallo" venía de cambios locales sin
commitear, no de deriva real): no se crea rama y el trabajo queda con la
nota
healed — no diff vs main, nothing to PR. - Fallo (sin rondas o error): reversión completa — cada archivo sobrescrito vuelve a su contenido previo; el árbol del framework nunca queda sucio.
- Si la sugerencia de PR falla (p. ej. git sin credenciales) pero el arreglo
verificó, el trabajo queda
healedcon el error anotado (pr_error) — el arreglo sigue en el working tree.
Puedes seguir cualquier sanación en vivo en su página (/heal/{id}, se
actualiza cada 2 s) con el detalle de intentos, evidencia, archivos
modificados, rama y enlace al PR.
5.6 Advertencia operativa conocida
Las llamadas LLM de sanación pueden chocar con el techo de ~240 s del
upstream de IA de FPD cuando el proveedor está degradado (observado: 28 s
incluso para respuestas de una palabra, y 502 en generaciones de archivos
completos), aunque el canal de sanación espera hasta 600 s. Síntoma típico:
trabajos de sanación que fallan con ReadTimeout/502 en días de degradación.
En el backlog está endurecer el prompt (mapear el localizador fallido al
archivo que lo contiene para enviar solo el test + los archivos relevantes) y,
del lado de FPD, un timeout de upstream más amplio o un modelo dedicado más
barato/rápido para sanaciones.
6. Referencia de configuración
Toda la configuración son variables de entorno con valores por defecto
orientados al demo local (ver app/config.py). También se puede usar un
archivo .env en la raíz del proyecto (copia de .env.example; las variables
de entorno reales tienen precedencia).
| Variable | Defecto | Significado |
|---|---|---|
FTW_FRAMEWORK_DIR |
C:\Users\JulioAI\TestProjects\full-testing-ai |
Raíz del repo del framework (solo lectura salvo publicación) |
FTW_JAVA_HOME |
C:\Users\JulioAI\TestProjects\.tools\jdk |
JDK portable (Temurin 21) para los subprocesos Maven |
FTW_MVN |
C:\Users\JulioAI\TestProjects\.tools\maven\bin\mvn.cmd |
Lanzador Maven portable (3.9.16) |
FTW_FPD_BASE_URL |
http://localhost:8000 |
Servidor FPD (app banco + API de TC + gateway LLM) |
FTW_FPD_TOKEN |
(vacío) | Token Bearer de FPD; vacío = TC Explorer e IA deshabilitados |
FTW_PORT |
9000 |
Puerto de esta aplicación |
FTW_AUTO_HEAL |
true |
Interruptor maestro de la autosanación automática |
Configuración adicional:
config/apps.json— el registro de sistemas bajo prueba:start_urly usuarios/roles con credenciales por app. Editable a mano o desde la página Systems (§3.5); se recarga en caliente, sin reinicio. Alimenta por igual el desplegable de Record & Play y la automatización NL. Hoy solo definebanco-americano.- Constantes de código (no son variables de entorno): rondas de reparación
del pipeline
MAX_REPAIR_ROUNDS = 2y presupuestos del discovery (40 pasos, 15 min) enapp/services/automate_service.py; rondas de sanaciónHEAL_ROUNDS = 2y timeout LLM de sanaciónHEAL_LLM_TIMEOUT = 600 senapp/services/heal_service.py; tope de autosanados por corridaMAX_AUTO_HEALS_PER_RUN = 3enapp/config.py. - Toolchain portable: no hace falta Java/Maven de sistema; FTW pasa
JAVA_HOMEy elmvn.cmdportable a cada subproceso, envolviendo las llamadas encmd.exe /c(Windows no ejecuta batch files directamente) con validación estricta de todo lo que llega a la línea de comandos.
7. Solución de problemas y FAQ
El TC Explorer dice "FPD token required".
Crea un token en FPD (Profile → API tokens, empieza por fpd_) y arranca
FTW con FTW_FPD_TOKEN=fpd_... o ponlo en .env.
Una corrida se queda "encolada" y no pasa nada.
Mientras ejecutan, las corridas son hilos en memoria: si FTW se reinició a
media corrida, el trabajo murió y su página muestra el estado interrupted
(las corridas terminadas sí sobreviven el reinicio con su resumen y su
Allure). Comprueba el log de FTW (la salida de uvicorn; en el
arranque actual con nohup, /tmp/ftw-9000.log), que el framework exista en
FTW_FRAMEWORK_DIR y que el toolchain portable esté en .tools/. Las
corridas Maven grandes tardan: la verificación interna del pipeline espera
hasta 15 min antes de declarar timeout.
Síntomas de degradación del proveedor de IA.
Respuestas lentas (decenas de segundos para cualquier llamada), 502 del
upstream de FPD (~240 s de techo), discovery que aborta con "LLM endpoint
failed 3 times in a row", refactor/automatización que fallan en la llamada al
LLM, sanaciones que mueren con ReadTimeout. No es un bug de FTW: espera a
que el proveedor se recupere y reintenta (los pipelines fallidos se pueden
re-ejecutar desde su página).
¿Dónde están los logs y artefactos?
| Qué | Dónde |
|---|---|
| Reportes surefire (XML) | full-testing-ai/target/surefire-reports/ |
| Capturas y HTML de fallos | full-testing-ai/target/artifacts/<Clase>/ |
| Resultados Allure | full-testing-ai/target/allure-results/ (sitio: target/site/allure-maven-plugin/) |
| Registro de corridas (Recent runs) | full-testing-web/recordings/runs.json |
| Resultados + sitios Allure por corrida | full-testing-web/recordings/runs/<id>/{results,report}/ |
| Reporte de triage del framework | full-testing-ai/target/triage/triage-report.md |
| Grabaciones | full-testing-web/recordings/ |
| Resultados de discovery (action logs) | full-testing-web/recordings/automations/*.json |
| Java generado (staging) | full-testing-web/recordings/automations/<stem>.generated/ |
| Salidas de refactor | full-testing-web/recordings/<base>.refactored/ |
| Staging de sanaciones | full-testing-web/recordings/heals/ |
| Log de FTW | salida de uvicorn (hoy /tmp/ftw-9000.log) |
¿Cómo evito que la autosanación intervenga en una demo?
Desmarca la casilla Auto-heal with AI on failure en el formulario Run para
esa corrida (es el opt-out por ejecución), o arranca FTW con
FTW_AUTO_HEAL=false para apagar el interruptor maestro.
Una automatización falló en la etapa applied por conflicto.
Alguien ya creó esos archivos en el repo con contenido distinto. Reconcilia a
mano en full-testing-ai (quédate con la versión del repo o reemplázala por
la staged que indica la UI) y pulsa Re-run pipeline en la página del
trabajo.
La automatización generó un nombre de clase raro (p. ej. ...DiscoveryTest).
Es inofensivo y conocido (está en el backlog de pulido). El test es válido
igualmente.
¿La IA interviene al re-ejecutar tests ya automatizados?
No. Las re-ejecuciones son mvn test deterministas, sin coste de IA. La única
excepción es la autosanación: se dispara solo si la corrida falla, solo para
fallos de tipo LOCATOR_DRIFT, con los límites de la sección 5, y su arreglo
llega a main únicamente tras revisión humana del PR.
Record & Play perdió las últimas acciones al parar. Conocido: el botón Stop mata el proceso y puede perder lo no volcado. Cierra la ventana del navegador para terminar limpiamente (el archivo se va escribiendo mientras grabas).
8. Lecturas relacionadas
full-testing-web/README.md— arquitectura técnica, notas de Windows y filosofía de solo-lectura/publicación.full-testing-ai/docs/decisions.md— registro vivo de decisiones aprobadas y guardarraíles (la especificación autoritativa de las reglas).full-testing-ai/docs/ai-authoring.md— el bucle de autoría dentro del repo del framework (scaffolder, triage, cobertura).
Source: docs/user-guide.es.md — rendered at request time.