AGENTIC QA · WORKFLOW SKILL
Planifica, escribe y revisa tests automatizados KATA sobre Playwright + TypeScript — tres fases en orden estricto, Plan → Code → Review, nunca directo al código.
el mapa — índice mental del deck
Manual y Deferred son terminales — jamás se automatizan (Documentation decide).
Registro de Componentes + IDs @atc. Se consulta ANTES de proponer nada (Critical Rule #12).
Automation es el único stage con verificador separado obligatorio antes del merge. Lo opcional es cuál de los dos, no si lo hay.
Framework adaptado, toolchain, env + creds, browsers. STOP en RED.
.session/… → resume / restart / abort. Scope: module · ticket · regression.
spec.md + automation-plan.md. TÚ apruebas antes de codear.
TCs a In Automation, luego types → componente → fixture → test file → bun run test.
3 Verifiers paralelos: test · types:check · lint:check.
Checkpoint + archivo de sesión. La skill se detiene aquí — sin git.
Reporte fallido verbatim; re-despachar Code SOLO con tu aprobación. Bug real → confirma y crea el bug.
Lee el código y deja un HTML con cada assertion. Sin Plan → Code → Review, sin sesión, sin Jira.
Branch test/* y PR contra la base que declara git_strategy:. El merge lo hace la persona. Luego /regression-testing (Regression) en CI.
Cada fase del mapa = una sección de este deck, en el mismo orden.
mode routing: se resuelve antes del preflight
| Modo | Cuándo | Qué hace |
|---|---|---|
| automate (default) | Cualquier pedido de planear, escribir o revisar tests KATA | Todo el resto del deck: preflight, Phase 0, Plan → Code → Review |
| explain | Primer token explain, la frase "break-down-tests" o un pedido explícito de explicar tests existentes | Lee solo references/explain-tests.md, traza el código y escribe .context/reports/test-breakdown/<scope>.json; bun run tests:explain:render genera el .html al lado. Luego se detiene |
> /test-automation <KEY> # automate > /test-automation explain <scope> # explain
No tienen slash commands: se pide en prosa. "Carga la skill test-automation, modo explain, sobre <scope>". El primer token que coincide con un modo ES el modo y el resto se reenvía; sin coincidencia aplica automate, y si el pedido puede ser cualquiera de los dos, la skill pregunta.
Sus únicas escrituras son esos dos archivos de reporte (gitignored). Sin estado de sesión, sin editar tests ni código de producto, sin regenerar kata-manifest.json, sin Jira ni TMS. Nunca se infiere implementación desde un pedido de explicación.
antes de nada — qué entra y a qué tamaño
Solo los TCs con veredicto Candidate firmado por una persona llegan a automation: antes de planear, el gate de origen de TCs lee cada TC del TMS, y si falta o no está firmado la sesión se detiene y manda el scope a /test-documentation. Este skill nunca crea un Test ni puntúa ROI. Manual y Deferred son terminales. Los dos skills usan los mismos nombres de scope: el nombre dice el ORIGEN y Macro / Medium / Micro solo dicen el tamaño. module-driven (Macro) · ticket-driven (Medium) · bug-driven (Micro) · discovery-driven (según la brecha) · ad-hoc → donde encaje.
| Scope | Entrada | Salida | Úsalo cuando |
|---|---|---|---|
| Module-driven (Macro) | Un módulo + lista de TCs candidatos | 1 spec de módulo + N specs de ATC | Lote de 10+ tests; primera pasada sobre un área nueva |
| Ticket-driven (Medium) | Un Story ID con escenarios | 1 plan de implementación del ticket | Una user story completa — default del trabajo de sprint |
| Bug-driven (Micro) | Un TC concreto (post-bugfix) | 1 plan de implementación de ATC | Un test de regresión tras un fix: unidad mínima (antes se llamaba Regression-driven) |
| Discovery-driven (Macro por módulo; Medium o Micro por brecha) | Los TCs Candidate firmados de una Tech Story de cobertura, sin Story detrás (una brecha sola no es entrada) | Lo mismo que el tamaño que le toque | Cubrir comportamiento que ya está en producción y que ninguna Story especificó |
Ante la duda, PREGUNTA al usuario. Nunca asumas "module" solo porque aparecen varios IDs de TC en el briefing.
gate 0 · readiness preflight — MANDATORY, corre antes que todo
| Capacidad | Nivel | Por qué aquí |
|---|---|---|
| Framework adaptado | REQUIRED | Sin ATCs contra los scaffolds Example*. Genérico? STOP → el usuario corre /project-discovery → /test-framework-adaptation (el gate nunca los auto-ejecuta) |
| Toolchain + manifest | REQUIRED | bun run test / types:check / lint:check resuelven en t=0; kata:manifest:check limpio antes de proponer componentes |
| Env activo + credenciales | REQUIRED | Los tests corren en vivo: URL alcanzable + test users en .env (por rol si aplica) + browsers Playwright (bun run pw:install) |
| OpenAPI MCP + api/schemas/ | SCOPE · API | Se necesita ya en PLAN-time: explorar endpoints para diseñar ATCs y clasificar datos |
| DBHub MCP | SCOPE · datos | PLAN-time también: explorar el schema para diseñar fixtures de datos |
| Mapa de negocio por nivel tocado | REQUIRED | E2E → business-e2e-context, API → business-api-context, datos → business-data-context: bun run context:map <slug> --list debe listar secciones. Placeholder? STOP → project-context modo e2e / api / data |
| Issue tracker | SCOPE · ticket | Lecturas de ATP + ACs vía bun run jira:sync-issues |
args-as-answers — lo que ya diste (scope, ticket, API vs E2E) no se re-pregunta. probe, don't assume — se verifica, no se supone. Gaps + REDs → UN solo checklist de preguntas; STOP ante cualquier RED bloqueante.
phase 0 · resume check, inline y sin subagente
Ticket key, TC de regresión o module slug — según la invocación.
.session/test-automation/<scope>/progress.md — existe?
Sesión nueva → scope picker + Phase 1 (Plan).
Lee plan.md + cola de progress.md → informa última fase completada → ofrece resume / restart / abort.
El plan.md de sesión es un índice DELGADO que cita los artefactos canónicos — spec.md, automation-plan.md, atc/*.md — bajo .context/PBI/epics/EPIC-<KEY>-<slug>/test-specs/<scope>/. El dominio vive UNA vez, nunca duplicado. Con restart, la sesión vieja se archiva en .session/.archive/ antes de empezar.
phase 1 · plan — lo que se lee, en este orden
phase 1 · plan — lo que se escribe, y el gate humano
.context/PBI/epics/EPIC-<KEY>-<slug>/test-specs/<scope>/
→ spec.md · automation-plan.md · atc/*.md
Hand-authored, NO-Jira. Distinto del implementation-plan.md del Story (plan DEV, sincronizado, read-only).
.session/test-automation/<scope>/plan.md — Goal, Inputs, Approach, fases, riesgos, verificación. Cita los canónicos; no los duplica. Tras aprobar: checkpoint en progress.md.
Un subagente Plan (patrón Single) produce los artefactos; el orquestador te presenta el plan y ESPERA tu aprobación. Phase 2 jamás arranca sin ella (anti-pattern T2: nunca saltar el Plan, ni para un test "simple").
craft del plan · test-design doctrine — binding
Un AC → varios ATCs. EP-merge colapsa SOLO dentro de una partición (mismo comportamiento → un ATC parametrizado) — nunca entre particiones, límites o estados.
Donde haya rango / límite / longitud / ventana de fecha: casos de borde explícitos (min−1 · min · min+1 …). El merge esconde el off-by-one.
Inputs inválidos, rutas de auth/error, transiciones de estado y anomalías que el AC calla también entran al set de ATCs.
| Disparador en el AC | Técnica obligatoria | Produce |
|---|---|---|
| Cualquier input (siempre) | Equivalence Partitioning | Un ATC parametrizado por partición; particiones distintas → ATCs separados |
| Rango / límite / longitud | BVA | Bordes + cero / vacío / null |
| Campo de estado | State-Transition | Cada transición válida + cada inválida |
| 2+ condiciones que interactúan | Decision Table | Un ATC por regla superviviente |
| 3+ factores combinables | Pairwise | Set all-pairs (registra la reducción) |
Canon: agentic-qa-core/references/test-design-doctrine.md — carga MANDATORY antes de derivar ATCs desde ACs. Nunca reportes "% de ACs verificados" como completitud.
craft del plan · estrategia de datos — se clasifica al PLANEAR
Busca datos ya en el estado requerido. Cero impacto en DB. Preferido.
Toma datos existentes y mútalos vía API al estado requerido. Una mutación.
Crea desde cero: faker + POST. Último recurso — contamina el entorno.
Ningún patrón viable → NO automatizable; documenta el gap y escala.
Usa Generate aunque los datos pudieran descubrirse SI el test muta estado — evita dependencias de orden. Cada test genera sus PROPIOS datos (DataFactory / faker): sin estado compartido entre tests.
Nunca expect() dentro de beforeAll — una assertion fallida mata TODO el describe y oculta la causa. beforeAll solo descubre; cada test resguarda su precondición: test.skip(!order, 'No order available'). Así el reporte distingue "skipped — faltan datos" de "failed — bug real".
phase 2 · code — orden de construcción innegociable
Payloads, responses y DTOs al tope del archivo del componente.
Extiende ApiBase / UiBase. Helpers primero (sin decorator), ATCs después (@atc('TICKET-ID')).
En ApiFixture / UiFixture. Sin registro = inalcanzable. Los Steps NO se registran: se instancian directo.
tests/e2e/{module}/ o tests/integration/{module}/, con el fixture correcto.
Los tres comandos, en orden — si algo falla, se arregla ANTES del Review.
$ bun run test tests/e2e/checkout/processCheckout.test.ts # pasa? (0 retries) $ bun run types:check # tsc --noEmit, sin errores $ bun run lint:check # ESLint, sin errores $ bun allure:agent # opcional: reporte markdown por bloque @atc
Cada TC del scope sale de Candidate: start_automation → In Automation. Un TC que sigue en Candidate mientras se escribe su código le dice al equipo que nadie lo tomó. Slug sin mapear? Fallback de artifact-lifecycle.md §4: se pregunta, nunca se salta en silencio.
Dispatch Sequential: un subagente de Code por unidad de scope (module: 1 por TC · ticket: 1 total). Cada uno carga /playwright-best-practices junto a esta skill y retorna archivos cambiados + resumen (el orquestador nunca lee diffs). Si además necesita manejar un browser real (snapshot, trace, record), suma /playwright-cli, el único camino de browser, con sesión con nombre según agentic-qa-core/references/browser-sessions.md.
craft del code · la arquitectura — nunca colapses capas (T3)
Drivers de Playwright (page, request), config, entorno y DataFactory. Sin helpers HTTP ni de UI.
Helpers HTTP (retornos de tupla tipados) y helpers de Playwright. Todo lo genérico vive aquí, una sola vez.
@atc vive aquí. Un componente por archivo: {Resource}Api.ts / {Page}Page.ts.
Cadenas de ATCs reusables para preconditions. NO se decoran con @atc.
Inyección de dependencias. Los tests piden el fixture y reciben los componentes. Los Steps no tienen fixture: se importan e instancian directo.
tests/e2e/** y tests/integration/** orquestan ATCs en escenarios y validan FLUJOS: consumen los Fixtures (L4), no son una quinta capa. Son cuatro capas nombradas, más Steps opcional.
Una capa superior usa una inferior — nunca al revés. Imports SIEMPRE por alias (los de tsconfig.base.json, p. ej. @api/ @ui/) — el lint rechaza los relativos (../../../).
craft del code · selección de fixture — carga estructural
| Tipo de test | Fixture | Browser? | Úsalo cuando |
|---|---|---|---|
| Solo API (integration) | { api } | No (lazy) | API puro — default para tests/integration/** |
| Solo UI | { ui } | Sí | Centrado en UI, sin setup de backend vía API |
| Híbrido | { test } | Sí | Setup de datos vía API, flujo vía UI, verificación vía API |
| Cadenas de precondición | Steps (import directo) | Depende | 3+ ATCs repetidos en 3+ archivos — se instancia la clase Steps, nunca vía fixture |
Nunca pidas { ui } para un test que jamás toca la UI — abre un browser para nada. E2E usa { ui } si no necesita setup por API; si lo necesita, { test }.
craft del code · las reglas que deciden el review
clickLoginButton() NO es un ATC; loginWithValidCredentials(data) SÍ. Si envuelve en una línea un page.click(), bórralo.
Todos los resultados esperados de la misma precondición + acción son assertions del MISMO TC — no lo dividas por paneles ni endpoints.
Tres ATCs que devuelven 401 están mal: un solo loginWithInvalidCredentials(payload) parametrizado.
Cadenas reusables → módulo Steps (tests/components/steps/), sin @atc.
Sin locators/*.ts: el selector vive en el ATC; 2+ usos → private readonly arrow. acción que muta estado = ATC; un GET cuya respuesta ES el resultado que se prueba (datos, 401, 403, 404) también es ATC; un GET que solo prepara datos = helper (@step opcional).
Máx 2 params posicionales (3+ → objeto). Sin waitForTimeout — espera condiciones. retries: 0: un pass en retry es un bug. Ticket-ID en cada test().
phase 2 · code — la forma de un componente API (L3)
export class OrdersApi extends ApiBase { private readonly baseEndpoint = '/api/v1/orders'; @step // helper — read-only, sin @atc async getOrderById(id: string): Promise<[APIResponse, Order]> { return this.apiGET<Order>(`${this.baseEndpoint}/${id}`); } @atc('UPEX-411') // ATC — muta estado, trazado al TMS async createOrderSuccessfully(payload: CreateOrderRequest) { const [response, body, sent] = await this.apiPOST(this.baseEndpoint, payload); expect(response.status()).toBe(201); // assertion FIJA — vive en el ATC expect(body.id).toBeDefined(); return [response, body, sent]; // 3-tupla: permite encadenar } }
GET / DELETE retornan 2-tuplas; POST / PUT / PATCH retornan 3-tuplas (comparar lo enviado vs lo recibido). Test files: {verb}{Feature}.test.ts e importan de @TestFixture, nunca de @playwright/test.
phase 3 · review — el gate de merge
| Verifier (paralelo) | Comando | Debe dar |
|---|---|---|
| Tests | bun run test {path} | Todo verde, cero retries usados |
| Types | bun run types:check | Sin errores |
| Lint | bun run lint:check | Sin errores |
| + Checklist KATA (visual) | references/review-checklists.md | Fixture registrado · @atc ↔ TC real del TMS · naming — cada ítem fallido es un blocker |
STOP: el reporte fallido se te muestra verbatim. Sin auto-fix, sin re-despachar Code sin tu aprobación. La sesión NO se archiva — queda para debug.
Checkpoint final en progress.md → sesión archivada en .session/.archive/ → bun run kata:manifest + git add para el gate de husky.
El contrato de Automation exige un verificador separado en contexto limpio, para cualquier cambio y no solo los de alto riesgo: /pr-review-lead (review de QA lead anclado en la doctrina KATA) o /judgment-day (dos jueces ciegos en paralelo, aprueba solo si ambos coinciden). Eliges el que encaje con el cambio; saltarlo es una falla del DoD. Es el único stage con esta obligación, a cambio de más autonomía a la entrada (de 2 a 3 dentro del plan aprobado).
después del accept: quién hace el git, y contra qué base
En la etapa Automation, /test-automation termina en una revisión local en verde (tests, tipos, lint) y deja el handoff explícito; el PR lo abre /git-flow-master, nunca /test-automation por su cuenta, contra la base que declara el bloque git_strategy: de .agents/project.yaml.
El repo trae solo-main como default heredado; cada proyecto declara el suyo. /git-flow-master lo lee, corta la branch test/*, hace push y abre el PR hacia esa base. Se detiene al crear el PR: el merge es el siguiente paso explícito de la persona.
Cada ticket corta test/{KEY}-{slug} desde el integration trunk, pasa Sanity CI y abre su PR hacia el trunk; el trunk llega a main en un único PR final. El gate local pasa en local Y staging antes del push, y el Git Ledger se apendiza a progress.md tras cada acción de branch.
Local gate green. Ready for /git-flow-master: cut test/UPEX-411-checkout from the integration trunk, push, Sanity-CI, PR into the trunk, merge --no-ff.
Después, en el pipeline: /regression-testing (Regression) corre las suites en CI y emite GO / CAUTION / NO-GO.
tres transiciones que esta skill es dueña
| Momento | Transición | Estado después |
|---|---|---|
| Abre Phase 2 · Code | start_automation | In Automation |
| Abre el PR del ticket (bajo sdet, hacia el trunk) | create_pr | Pull Request |
| El código llega a la rama de producción (git_strategy.branches.production; bajo sdet, el PR final de la suite) con CI verde ahí | merged | Automated |
No existe un Test "automatizado" separado: @atc('<TC_KEY>') es la clave del TC, y cada corrida queda registrada en el TC mismo. No se crea un segundo Test ni se enlaza uno.
+ automated y − automation-candidate en el Test: son mutuamente excluyentes. Se cambian en merged, cuando el TC llega de verdad a Automated, nunca en un merge al trunk o a la rama de integración.
Las transiciones salen por /test-documentation + [ISSUE_TRACKER_TOOL], con cada slug resuelto contra .agents/jira-workflows.json. Slug sin mapear? El fallback de artifact-lifecycle.md §4: lista las transiciones vivas, pregunta una vez, dispara el id vivo con tu OK. Nunca se salta en silencio.
a escala · batch fleet, segundo ejecutor opcional
Por defecto un batch corre en esta sesión, un Work Package a la vez, Plan → Code → Review cada uno. La flota se ofrece solo si la pides o si el lote tiene 3+ Work Packages sobre módulos disjuntos; nunca se entra en silencio.
Su spec.md + automation-plan.md + atc/*.md. Un lote es una lista de WPs, nunca de archivos ni de TCs. Sin spec.md, el WP no se despacha.
Un worker es dueño de los componentes de un módulo; los WPs del mismo módulo corren en serie dentro de él. Nunca dos workers en un módulo: comparten Pages, Apis y fixtures.
Esta skill escribe código, y dos sesiones en un checkout pelean por el índice de git. El conductor crea el worktree y lo provisiona (bun run worktree:provision) antes de lanzar al worker.
api:login, api:sync, las escrituras en Jira/TMS (transiciones, labels, links) y bun run kata:manifest en cada integración: el manifest se regenera, nunca se mergea a mano. Integra una branch a la vez y re-corre la suite sobre el estado mergeado.
El conductor siempre escribe launch.txt: una línea autocontenida por worker. Con orquestador esas líneas se lanzan solas; sin él, la persona las pega en terminales. La ausencia del orquestador no se reporta en ninguna parte. Sin conductor vivo, el lote corre aquí, WP por WP, en el orden que daría la partición.
light stage verifier · cierra el stage Automation
Artefactos por KEY · links presentes · estados esperados (con la transición disparada) · assignee en lo creado · parent QA epic + components · campos y comments escritos · checkpoint en progress.md · session footer en el chat.
Ligero = se responde con lo que el stage ya hizo, más como máximo UNA lectura extra. Cada línea es YES o un N/A con su motivo; una línea en blanco es una falla. Cualquier NO = NEEDS REVISION.
[ ] TCs del scope en in_automation o más allá (start_automation disparado) [ ] Cada ATC lleva la clave de su TC; ningún Test automatizado aparte [ ] Labels cambiados en su estado: +automated -automation-candidate en merged, nunca en el merge al trunk [ ] Ningún TC en candidate con código ya escrito [ ] Slug sin mapear pasó por el fallback §4 (se preguntó), nunca un salto silencioso
Canon: agentic-qa-core/references/artifact-lifecycle.md §5. Va después del ACCEPT de Phase 3 y del verificador separado; con REJECT no se llega aquí.
session footer · gate de calidad del cierre, solo en el chat
Cada captura se anuncia con su ruta relativa al repo en el mismo turno en que aparece, y al cierre va la lista consolidada: anotaciones de bugs primero, solo archivos verificados en disco. En esta skill suelen ser pocas; si no hay, el bloque no lleva encabezados vacíos.
Skills cargadas, MCPs realmente llamados, CLIs invocadas, niveles de testing tocados con un "none" explícito para cada nivel esperado que no se tocó, y la línea Refinements proposed:.
Testing levels touched: - API: cobertura automatizada nueva en OrdersApi (L3 component) + spec - E2E/UI: none (fuera del scope de este ticket) - Unit: none Refinements proposed: 0
"Niveles tocados" significa qué niveles recibieron cobertura automatizada nueva (Unit, API, E2E/UI) y en qué capa KATA aterrizó el código (L2 base, L3 component, Steps, fixture, spec). Nunca va en un comment de Jira ni en un ATR. Las lecciones se proponen en .session/test-automation/<scope>/refinements.md, nunca se aplican a la skill viva.
quién decide qué — el contrato de Automation
Feedforward y feedback se compensan: más cuerda a la entrada se paga con un control más duro a la salida. El plan aprobado antes del código es el feedforward; el verificador separado antes del merge es el feedback.
cierre — cómo invocarlo y qué deja
/test-automation (modo automate) o /test-automation explain en Claude Code; en OpenCode y Codex, en prosa: "carga la skill test-automation, modo explain". También por frases como "automate ticket", "create API test", "break-down-tests". Siempre se carga ANTES de escribir código de test.
spec.md + automation-plan.md + atc/*.md · componentes y tests en tests/** · kata-manifest.json regenerado · sesión archivada.
← /test-documentation (Documentation, veredictos Candidate) · → /git-flow-master (branch + PR) · → /regression-testing (Regression, CI).
1 · Un ATC = un test case atómico, trazado con @atc('TICKET-ID'). 2 · Plan → Code → Review, siempre en orden y con tu aprobación en medio. 3 · La estabilidad es disciplina: retries: 0, sin waits fijos, datos propios por test.
← → navegar · O resumen · S presentador · N notas · F pantalla completa