AGENTIC QA · WORKFLOW SKILL

/test-automation

Planifica, escribe y revisa tests automatizados KATA sobre Playwright + TypeScript — tres fases en orden estricto, Plan → Code → Review, nunca directo al código.

Stage 5 — Test Automation Plan → Code → Review KATA · Playwright · TypeScript
Encuadre: esta skill convierte los veredictos Candidate de test-documentation en tests automatizados atómicos y trazables. KATA reescribe el Page Object clásico: si escribes tests "a la manera estándar", el review los rechaza.

el mapa — índice mental del deck

Plan → Code → Review, con sus gates

← /test-documentation

Solo veredictos Candidate

Manual y Deferred son terminales — jamás se automatizan (Stage 4 decide).

gate anti-duplicación

kata-manifest.json

Registro de Componentes + IDs @atc. Se consulta ANTES de proponer nada (Critical Rule #12).

/judgment-day · opcional

Doble juez ciego

Para cambios de alto riesgo (fixtures nuevos, bases compartidas). Nunca automático.

Gate 0 · Preflight

Readiness

Framework adaptado, toolchain, env + creds, browsers. STOP en RED.

Phase 0

Resume + scope

.session/… → resume / restart / abort. Scope: module · ticket · regression.

Phase 1

Plan ✋

spec.md + automation-plan.md. TÚ apruebas antes de codear.

Phase 2

Code

Types → componente → fixture → test file → bun run test.

Phase 3

Review

3 Verifiers paralelos: test · types:check · lint:check.

Accept

Handoff

Checkpoint + archivo de sesión. La skill se detiene aquí — sin git.

reject

STOP — sin auto-fix

Reporte fallido verbatim; re-despachar Code SOLO con tu aprobación. Bug real → confirma y crea el bug.

Cada fase del mapa = una sección de este deck, en el mismo orden.

Camino principal: Preflight → Phase 0 → Plan → Code → Review → Handoff. Adyacentes: la entrada desde test-documentation, el gate del manifest en Plan, judgment-day opcional en Review, el loop de REJECT y el handoff a git-flow-master + regression-testing.

antes de nada — qué entra y a qué tamaño

Elige el scope primero, una sola vez

La entrada viene de /test-documentation (Stage 4)

Solo los TCs con veredicto Candidate llegan a automation. Manual y Deferred son terminales. Mapeo: Module ← module-driven · Ticket ← ticket-driven · Regression ← bug-driven · ad-hoc → donde encaje.

ScopeEntradaSalidaÚsalo cuando
Module-driven (Macro)Un módulo + lista de TCs candidatos1 spec de módulo + N specs de ATCLote de 10+ tests; primera pasada sobre un área nueva
Ticket-driven (Medium)Un Story ID con escenarios1 plan de implementación del ticketUna user story completa — default del trabajo de sprint
Regression-driven (Micro)Un TC concreto (post-bugfix)1 plan de implementación de ATCUn test de regresión tras un fix — unidad mínima

Ante la duda, PREGUNTA al usuario. Nunca asumas "module" solo porque aparecen varios IDs de TC en el briefing.

El scope dicta cuánta ceremonia de planificación se produce y cuántos subagentes de Code se despachan después. Elegirlo mal es programar el alcance equivocado.

gate 0 · readiness preflight — MANDATORY, corre antes que todo

¿Está todo listo para escribir y correr código?

CapacidadNivelPor qué aquí
Framework adaptadoREQUIREDSin ATCs contra los scaffolds Example*. ¿Genérico? STOP → el usuario corre /project-discovery/adapt-framework (el gate nunca los auto-ejecuta)
Toolchain + manifestREQUIREDbun run test / types:check / lint:check resuelven en t=0; kata:manifest:check limpio antes de proponer componentes
Env activo + credencialesREQUIREDLos 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 · APISe necesita ya en PLAN-time: explorar endpoints para diseñar ATCs y clasificar datos
DBHub MCPSCOPE · datosPLAN-time también: explorar el schema para diseñar fixtures de datos
Issue trackerSCOPE · ticketLecturas de ATP + ACs vía bun run jira:sync-issues

Dos leyes

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.

Distinto del pre-flight anti-duplicación de Phase 1 (ese cruza el manifest buscando reuso): este gate va de tools y entorno listos. Evita descubrir a mitad del Code que faltaba una credencial o que el framework seguía genérico.

phase 0 · resume check — inline, <1 minuto

¿Hay una sesión previa? Retómala, no la repitas

1

Determina el scope

Ticket key, TC de regresión o module slug — según la invocación.

2

Busca la sesión

.session/test-automation/<scope>/progress.md — ¿existe?

3

No existe

Sesión nueva → scope picker + Phase 1 (Plan).

4

Existe

Lee plan.md + cola de progress.md → informa última fase completada → ofrece resume / restart / abort.

La sesión es un índice, no el contenido

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 0 corre inline (sin subagente). Para module-driven, el resume a mitad de lote lee los checkpoints de progress.md y salta los ATCs ya codificados.

phase 1 · plan — lo que se lee, en este orden

El manifest primero; la Story completa, después

Saltarse el manifest produce Pages duplicadas, IDs @atc repetidos y reuso perdido — todo rechazado en review. Leer solo un campo de la Story produce ATCs incompletos: los comments suelen contener el contexto que cambia el plan.

phase 1 · plan — lo que se escribe, y el gate humano

Un plan que responde 5 preguntas — y espera tu sí

Artefactos canónicos (git)

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

Índice de sesión

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

Gate de fase

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

El subagente único de Plan protege el contexto del orquestador de las lecturas KATA pesadas. El briefing SIEMPRE incluye kata-manifest.json como context doc.

craft del plan · test-design doctrine — binding

Cubrir los ACs es el piso, no la meta

1 : N por defecto

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.

EP no reemplaza BVA

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.

El riesgo vive fuera del AC

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 ACTécnica obligatoriaProduce
Cualquier input (siempre)Equivalence PartitioningUn ATC parametrizado por partición; particiones distintas → ATCs separados
Rango / límite / longitudBVABordes + cero / vacío / null
Campo de estadoState-TransitionCada transición válida + cada inválida
2+ condiciones que interactúanDecision TableUn ATC por regla superviviente
3+ factores combinablesPairwiseSet 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.

Un AC es la afirmación de negocio; un ATC es su exploración concreta (precondición + acción + aserciones). Colapsar a 1:1 exige una justificación escrita "trivially atomic".

craft del plan · estrategia de datos — se clasifica al PLANEAR

Discover → Modify → Generate (prioridad estricta)

1

Discover

Busca datos ya en el estado requerido. Cero impacto en DB. Preferido.

2

Modify

Toma datos existentes y mútalos vía API al estado requerido. Una mutación.

3

Generate

Crea desde cero: faker + POST. Último recurso — contamina el entorno.

4

Blocker

Ningún patrón viable → NO automatizable; documenta el gap y escala.

Override

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.

La trampa del beforeAll

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

Esta clasificación ocurre en el plan, jamás diferida al código. Cleanup: Discover no necesita; Modify restaura en afterAll; Generate borra en afterEach.

phase 2 · code — orden de construcción innegociable

Types → componente → fixture → test → verificar

1

Types

Payloads, responses y DTOs al tope del archivo del componente.

2

Componente

Extiende ApiBase / UiBase. Helpers primero (sin decorator), ATCs después (@atc('TICKET-ID')).

3

Registrar

En ApiFixture / UiFixture / StepsFixture. Sin registro = inalcanzable.

4

Test file

tests/e2e/{module}/ o tests/integration/{module}/, con el fixture correcto.

5

Run + verify

Los tres comandos, en orden — si algo falla, se arregla ANTES del Review.

local validation loop
$ 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

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; retorna archivos cambiados + resumen — el orquestador nunca lee diffs.

Checkpoint en progress.md tras cada subagente de Code — el resume a mitad de lote salta lo ya codificado. Allure 3 vive como devDep: bunx allure resuelve local, sin instalar global.

craft del code · la arquitectura — nunca colapses capas (T3)

Las capas KATA, de abajo hacia arriba

L1

TestContext

Config, logger, faker, accesores de entorno. Nada de Playwright ni HTTP aquí.

L2

ApiBase / UiBase

Helpers HTTP (retornos de tupla tipados) y helpers de Playwright. Todo lo genérico vive aquí, una sola vez.

L3

Componentes de dominio — UsersApi, LoginPage

@atc vive aquí. Un componente por archivo: {Resource}Api.ts / {Page}Page.ts.

L3.5

Steps — AuthSteps, CheckoutSteps

Cadenas de ATCs reusables para preconditions. NO se decoran con @atc.

L4

Fixtures — TestFixture, ApiFixture, UiFixture, StepsFixture

Inyección de dependencias. Los tests piden el fixture y reciben los componentes.

Tests

tests/e2e/** · tests/integration/**

Orquestan ATCs en escenarios. Validan FLUJOS, no propiedades sueltas.

Dos reglas duras

Una capa superior usa una inferior — nunca al revés. Imports SIEMPRE por alias (@api/ @ui/ @utils/ @variables @TestContext @schemas/) — el lint rechaza los relativos (../../../).

Aplanar capas es rechazo automático en Review (anti-pattern T3). La separación permite que helpers HTTP, helpers UI y utilidades agnósticas tengan un solo hogar cada uno.

craft del code · selección de fixture — carga estructural

El fixture decide si se abre un browser

Tipo de testFixture¿Browser?Úsalo cuando
Solo API (integration){ api }No (lazy)API puro — default para tests/integration/**
Solo UI{ ui }Centrado en UI, sin setup de backend vía API
Híbrido{ test }Setup de datos vía API, flujo vía UI, verificación vía API
Cadenas de precondición{ steps }Depende3+ ATCs repetidos en 3+ archivos

Regla de oro

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

Playwright instancia lazy solo lo que el test pide. El fixture equivocado significa un browser lento innecesario o un contexto faltante.

craft del code · las reglas que deciden el review

Reglas ATC — los rechazos más comunes

ATC = test case completo

clickLoginButton() NO es un ATC; loginWithValidCredentials(data) SÍ. Si envuelve en una línea un page.click(), bórralo.

Identidad: precondición + acción = 1 TC

Todos los resultados esperados de la misma precondición + acción son assertions del MISMO TC — no lo dividas por paneles ni endpoints.

Mismo output → un ATC parametrizado

Tres ATCs que devuelven 401 están mal: un solo loginWithInvalidCredentials(payload) parametrizado.

Un ATC nunca llama a otro ATC

Cadenas reusables → módulo Steps (tests/components/steps/), sin @atc.

Locators inline · helpers vs ATCs

Sin locators/*.ts: el selector vive en el ATC; 2+ usos → private readonly arrow. GET de lectura = helper (@step); acción que muta estado = ATC.

Disciplina anti-flake

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

Assertions fijas (status, campos, redirect) van DENTRO del ATC; las de flujo, en el test file. Internalizar estas seis tarjetas hace que la mayoría del código pase el review a la primera.

phase 2 · code — la forma de un componente API (L3)

Helper sin decorator, ATC con @atc

tests/components/api/OrdersApi.ts
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.

Orden interno del archivo: types, baseEndpoint, constructor, helpers, ATCs. En UI el patrón es igual: locators inline con getByTestId como primer peldaño, assertions fijas dentro del ATC, retorno void.

phase 3 · review — el gate de merge

Tres Verifiers en paralelo; cero blockers para aceptar

Verifier (paralelo)ComandoDebe dar
Testsbun run test {path}Todo verde, cero retries usados
Typesbun run types:checkSin errores
Lintbun run lint:checkSin errores
+ Checklist KATA (visual)references/review-checklists.mdFixture registrado · @atc ↔ TC real del TMS · naming — cada ítem fallido es un blocker

REJECT — protocolo de error

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.

ACCEPT — cierre limpio

Checkpoint final en progress.md → sesión archivada en .session/.archive/bun run kata:manifest + git add para el gate de husky.

Gate adversarial opcional — /judgment-day

Para cambios de alto riesgo (fixtures nuevos, modificaciones a bases Page/Api compartidas, refactors multi-ATC): dos jueces ciegos en paralelo; solo aprueba si ambos coinciden. Opt-in por ticket, nunca automático.

La agregación es inline: el orquestador lee los 3 reportes y decide. Si un test falla por un bug REAL de producto: busca bug existente, anota test.fail('Blocked by {BUG-KEY}') o crea el bug con tu confirmación — un test rojo sin bug key nunca es override aceptable.

después del accept — git y ciclo de vida del TC

La skill se detiene en un review local limpio

handoff
Local gate green. Ready for /git-flow-master:
cut test/UPEX-411-checkout from the integration trunk, push, Sanity-CI, PR, merge --no-ff.
Los PRs de test siguen la convención test/* con título {type}({ISSUE-KEY}): {description}. Nunca mezclar código de producto y de test en el mismo PR (anti-pattern T8).

cierre — cómo invocarlo y qué deja

/test-automation — planéalo, codéalo por capas, pásalo en verde

Cómo se invoca

/test-automation o frases como "write test", "automate ticket", "create API test", "KATA", "review test code". Siempre se carga ANTES de escribir código de test.

Artefactos clave

spec.md + automation-plan.md + atc/*.md · componentes y tests en tests/** · kata-manifest.json regenerado · sesión archivada.

En el pipeline

/test-documentation (Stage 4, veredictos Candidate) · → /git-flow-master (branch + PR) · → /regression-testing (Stage 6, CI).

Las tres reglas para llevarte

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

Cierre: la skill no reemplaza la metodología — ejecuta exactamente esta metodología, más rápido, con el humano aprobando el plan y revisando las fallas.