TE
test-case-design
Diseñar casos de prueba y generar código Playwright nativo en TypeScript. Sin BDD. Sin Gherkin. Sin Cucumber. **Playwright Test puro con Page Objects.**
Install
mkdir -p .claude/skills/test-case-design && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/15355" && unzip -o skill.zip -d .claude/skills/test-case-design && rm skill.zipInstalls to .claude/skills/test-case-design
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Diseñar casos de prueba y generar código Playwright nativo en TypeScript. Sin BDD. Sin Gherkin. Sin Cucumber. **Playwright Test puro con Page Objects.**152 chars · catalog descriptionno explicit “when” trigger
About this skill
SKILL: test-case-design
Para uso exclusivo de Blu — QA Agent de Yeyu Windecker
🎯 Responsabilidad única
Diseñar casos de prueba y generar código Playwright nativo en TypeScript. Sin BDD. Sin Gherkin. Sin Cucumber. Playwright Test puro con Page Objects.
📥 Cómo se invoca
diseñar-tests [módulo] # solo diseña casos, sin código
diseñar-tests [módulo] --base [KEY] # usa doc base de Jira
automatizar [módulo] # genera .spec.ts + Page Objects
automatizar [módulo] --base [KEY] # usa doc base de Jira
📌 LINEAMIENTOS OBLIGATORIOS
Todo el código generado debe respetar estas convenciones sin excepción.
Prioridad de selectores (orden estricto)
| Prioridad | Método | Cuándo |
|---|---|---|
| 1 | getByTestId() | Existe data-testid |
| 2 | getByRole() | Elementos semánticos |
| 3 | getByLabel() | Inputs con label |
| 4 | getByPlaceholder() | Inputs con placeholder único |
| 5 | getByText() | Textos visibles únicos |
| 6 | getByAltText() | Imágenes con alt |
| 7 | locator('css') | Solo último recurso |
Prefijos de locators (siempre camelCase)
| Prefijo | Elemento |
|---|---|
btn | Botones |
input | Campos de texto |
dropdown | Selectores |
checkbox | Checkboxes |
link | Enlaces |
text | Textos y mensajes |
table | Tablas |
Estructura de archivos
src/playwright/
├── locators/ → [módulo].locator.ts
├── pages/ → [módulo].page.ts
└── tests/ → [módulo].spec.ts
Naming
login.locator.ts
login.page.ts
login.spec.ts
Anti-patrones prohibidos
❌ page.waitForTimeout() → usar expect().toBeVisible()
❌ Locators directos en .spec → siempre via Page Object
❌ URLs hardcodeadas → process.env.BASEURL
❌ CSS/XPath si existe semántico
❌ Datos sensibles en el código
❌ Expects sin mensaje descriptivo
🧪 Modo: diseñar-tests
Solo diseña los casos. No genera código.
Output — tabla de casos
## Casos de prueba: [módulo]
| # | Caso | Tipo | Prioridad | Datos |
|---|------|------|-----------|-------|
| 1 | [descripción] | Happy Path | 🔥 Smoke | [datos] |
| 2 | [descripción] | Unhappy Path | ✅ Regression | [datos] |
| 3 | [descripción] | Edge Case | ✅ Regression | [datos] |
⚙️ Modo: automatizar
Genera los 3 archivos del módulo:
1. [módulo].locator.ts
import { Page } from '@playwright/test';
export class [Módulo]Locator {
readonly page: Page;
constructor(page: Page) {
this.page = page;
}
get input[Campo]() {
return this.page.getByLabel('[label]');
}
get btn[Acción]() {
return this.page.getByRole('button', { name: '[nombre]' });
}
get text[Mensaje]() {
return this.page.getByTestId('[test-id]');
}
}
2. [módulo].page.ts
import { expect, Page } from '@playwright/test';
import { [Módulo]Locator } from '../locators/[módulo].locator';
export class [Módulo]Page {
readonly page: Page;
readonly locator: [Módulo]Locator;
constructor(page: Page) {
this.page = page;
this.locator = new [Módulo]Locator(page);
}
async navigateTo() {
await this.page.goto(`${process.env.BASEURL}/[ruta]`);
}
async [acción]([params]: [tipos]) {
await this.locator.[elemento].[acción]([params]);
}
async verify[Resultado]() {
await expect(
this.locator.[elemento],
'[mensaje descriptivo del assert]'
).[matcher]();
}
}
3. [módulo].spec.ts
import { test, expect } from '@playwright/test';
import { [Módulo]Page } from '../pages/[módulo].page';
test.describe('[Módulo] — [descripción]', () => {
let [módulo]Page: [Módulo]Page;
test.beforeEach(async ({ page }) => {
[módulo]Page = new [Módulo]Page(page);
await [módulo]Page.navigateTo();
});
// ─── SMOKE ───────────────────────────────────────────────
test('[caso happy path]', async () => {
await [módulo]Page.[acción]([datos]);
await [módulo]Page.verify[Resultado]();
});
// ─── REGRESSION ──────────────────────────────────────────
test('[caso unhappy path]', async () => {
await [módulo]Page.[acción]([datos inválidos]);
await [módulo]Page.verify[Error]();
});
// ─── EDGE CASES ───────────────────────────────────────────
test('[caso edge]', async () => {
await [módulo]Page.[acción]([datos límite]);
await [módulo]Page.verify[Resultado]();
});
});
💬 Mensaje final al usuario
✅ Código generado para: [módulo]
Archivos creados:
📄 src/playwright/locators/[módulo].locator.ts
📄 src/playwright/pages/[módulo].page.ts
📄 src/playwright/tests/[módulo].spec.ts
Para ejecutar:
npx playwright test [módulo].spec.ts
npx playwright test --grep "smoke"
npx playwright test --grep "regression"