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 (Stage 4 decide).
Registro de Componentes + IDs @atc. Se consulta ANTES de proponer nada (Critical Rule #12).
Para cambios de alto riesgo (fixtures nuevos, bases compartidas). Nunca automático.
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.
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.
Branch test/*, PR, merge. Luego /regression-testing (Stage 6) en CI.
Cada fase del mapa = una sección de este deck, en el mismo orden.
antes de nada — qué entra y a qué tamaño
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.
| 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 |
| Regression-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 |
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 → /adapt-framework (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 |
| 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, <1 minuto
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 / StepsFixture. Sin registro = inalcanzable.
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
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.
craft del code · la arquitectura — nunca colapses capas (T3)
Config, logger, faker, accesores de entorno. Nada de Playwright ni HTTP aquí.
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.
Orquestan ATCs en escenarios. Validan FLUJOS, no propiedades sueltas.
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 (../../../).
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 } | Depende | 3+ ATCs repetidos en 3+ archivos |
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. GET de lectura = helper (@step); acción que muta estado = ATC.
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.
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.
después del accept — git y ciclo de vida del TC
Local gate green. Ready for /git-flow-master: cut test/UPEX-411-checkout from the integration trunk, push, Sanity-CI, PR, merge --no-ff.
cierre — cómo invocarlo y qué deja
/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.
spec.md + automation-plan.md + atc/*.md · componentes y tests en tests/** · kata-manifest.json regenerado · sesión archivada.
← /test-documentation (Stage 4, veredictos Candidate) · → /git-flow-master (branch + PR) · → /regression-testing (Stage 6, 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