
playwright-automation
Write production-grade Playwright tests in TypeScript: Page Object Model, fixtures, auto-waiting, user-facing locators, parallel execution, CI integration, sharding, and installed-version checks. Includes an explicit "do not" list for AI agents. Use when: "Playwright," "write E2E test," "page object," "new Playwright suite," "Playwright config." Not for: fixing one flaky test at runtime — use test-reliability. Not for: bulk regenerating selectors after a UI refactor — use selector-drift-recovery. Not for: visual baseline creation/management — use visual-testing. Not for: deep WCAG/axe audits — use accessibility-testing. Related: visual-testing, ci-cd-integration, api-testing, test-reliability, selector-drift-recovery, accessibility-testing.
- Installs
- 1.9K
- Last 24h
- +19
- Trending rank
- #6173
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/petrkindlmann/qa-skills --skill playwright-automation- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads playwright-automation automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Discovery Questions
Check .agents/qa-project-context.md first — if it exists, use it and skip any question answered there. Then ask only what's missing:
- TypeScript or JavaScript? Match what the project already uses. For a new suite TypeScript is strongly recommended — it catches locator and assertion mistakes at compile time, and the examples here use it. In a JavaScript project or a fixed
.mjsharness, write plain ESM with the same patterns (drop the type annotations), and check it withnode --checkand--listinstead oftsc. - Which browsers? Chromium for local dev; add Firefox and WebKit in CI. Mobile viewports are separate Playwright projects, not separate test files — they change the device descriptor.
- Existing suite or fresh start? Migrating from Cypress/Selenium, rewrite the flakiest tests first; never big-bang. Changes the sequencing entirely.
- Single site or multi-site? Multi-site needs shared fixtures and per-site config objects — see
references/multi-site-architecture.md.
Core Principles
- User-facing locators first.
getByRole>getByLabel>getByTestId> CSS (last resort). Text and label matching is a case-insensitive substring by default, sogetByLabel('Password')also matches "New password" and "Confirm password", hidden fields included, and fails strict mode; pass{ exact: true }when labels share words. Locators must reflect what the user sees, not how the DOM is structured. Seereferences/selector-strategies.md. - Auto-waiting — NEVER use
waitForTimeout. Every Playwright action and web-first assertion auto-waits. If you think you need a timeout, you need a better locator or assertion. - Test isolation. Each test gets a fresh
BrowserContext, but this does not isolate server-side accounts, carts, orders or password changes. Allocate independent records/accounts or a fresh database where tests mutate shared state. Tests must not depend on execution order. - Parallel by default, serial only when necessary. Use
fullyParallel: true. Reservetest.describe.serialfor flows that genuinely cannot be isolated (rare). - Fixtures for setup, not hooks. Fixtures compose, provide type safety, and tear down automatically. Prefer them over
beforeEach/afterEachfor anything non-trivial. Seereferences/fixtures-and-projects.md.
Calibrate to your team maturity (set
team_maturityin.agents/qa-project-context.md):
- startup — Chromium only, 5–10 critical-path tests, basic CI run on PR. Skip sharding and visual baselines until the suite is stable.
- growing — Chromium + Firefox, POM structure, parallel execution, sharding in CI, HTML report artifacts.
- A page object pays off when several tests drive the same page. A focused suite of about ten tests with few shared pages reads better with a handful of helper functions and fixtures; add page objects when the duplication appears.
- established — Full browser matrix, auth fixtures, API mocking layer, visual regression baseline, trace-on-failure, flakiness tracking.
Project Structure
project-root/
├── playwright.config.ts
├── e2e/
│ ├── fixtures/ # base.fixture.ts, auth.fixture.ts, data.fixture.ts
│ ├── pages/ # Page objects by feature
│ │ ├── base.page.ts
│ │ ├── dashboard.page.ts
│ │ └── components/ # Reusable component objects (data-table, modal)
│ ├── tests/ # Test files by feature (auth/, dashboard/, settings/)
│ ├── helpers/ # test-data.ts, api-client.ts
│ └── global-setup.ts
├── .auth/ # Git-ignored storageState files
└── test-results/ # Git-ignored artifacts
playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
const isCI = !!process.env.CI;
const baseURL = process.env.BASE_URL ?? 'http://localhost:3000';
export default defineConfig({
testDir: './e2e', // Includes global-setup.ts as well as tests/.
testMatch: '**/*.spec.ts',
fullyParallel: true,
forbidOnly: isCI,
retries: isCI ? 2 : 0,
workers: isCI ? '50%' : undefined,
reporter: isCI
? [['blob'], ['github'], ['json', { outputFile: 'test-results/results.json' }]]
: [['html', { open: 'on-failure' }]],
use: {
baseURL,
trace: isCI ? 'on-first-retry' : 'retain-on-failure',
screenshot: 'only-on-failure',
video: isCI ? 'on-first-retry' : 'off',
navigationTimeout: 30_000,
// Avoid a global actionTimeout — it can mask a genuinely slow auto-waited
// action. Set per-action only where a known-slow widget needs it.
},
projects: [
{ name: 'setup', testMatch: /global-setup\.ts/ },
{ name: 'chromium', use: { ...devices['Desktop Chrome'], storageState: '.auth/user.json' }, dependencies: ['setup'] },
],
webServer: isCI ? undefined : {
command: 'npm run dev', url: baseURL, reuseExistingServer: !isCI, timeout: 120_000,
},
});
The blob reporter in CI makes sharded runs mergeable; see the sharding section. The setup project writes storageState before Chromium runs. Add browser projects from references/fixtures-and-projects.md when the supported-browser contract requires them. Add a teardown dependency only with an actual teardown test inside testDir.
Global setup (storageState)
import { test as setup, expect } from '@playwright/test';
setup('authenticate as default user', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Email').fill(process.env.TEST_USER_EMAIL!);
await page.getByLabel('Password', { exact: true }).fill(process.env.TEST_USER_PASSWORD!);
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page).toHaveURL(/.*dashboard/);
await page.context().storageState({ path: '.auth/user.json' });
});
This is the setup-project pattern: a regular Playwright test saves the session and dependent projects load it. A globalSetup function is a different API; do not interchange the file formats. Shared authentication suits read-only tests. Tests that change passwords, account settings or other shared backend state need separate accounts or per-test provisioning. For multi-role auth and token seeding, see references/auth-patterns.md.
Before writing a large suite, run npx playwright test --list --project=chromium and one authenticated smoke test. Confirm setup discovery, the actual application URL and saved-session use. Add .auth/ to .gitignore; do not publish storage-state files with reports.
Page Object Model
import { type Page, type Locator, expect } from '@playwright/test';
export abstract class BasePage {
constructor(protected readonly page: Page) {}
abstract readonly path: string;
async goto(): Promise<void> {
await this.page.goto(this.path);
await this.page.waitForLoadState('domcontentloaded');
}
}
Component objects represent reusable UI fragments (modals, tables, nav). They take a root Locator, not a Page:
export class DataTable {
readonly rows: Locator;
constructor(private readonly root: Locator) {
this.rows = root.getByRole('row');
}
getRowByText(text: string | RegExp): Locator {
return this.rows.filter({ hasText: text });
}
}
Compose, don't inherit deep. A page holds its components; it does not extend a five-level hierarchy:
export class UsersPage extends BasePage {
readonly path = '/admin/users';
readonly table: DataTable;
constructor(page: Page) {
super(page);
this.table = new DataTable(page.getByRole('table', { name: 'Users' }));
}
}
Inject page objects via fixtures, not constructors in test files:
export const test = base.extend<{ usersPage: UsersPage }>({
usersPage: async ({ page }, use) => { await use(new UsersPage(page)); },
});
export { expect } from '@playwright/test';
POM methods return state (locators, values); they do not assert. Assertions live in the test so failures point at the test, not the page object.
Test Patterns
Observe each consequential transition
For persistence, reload immediately after the mutation under test, before another action can write the whole state and hide a missing save. Exercise removals and empty states as well as additions. Use independent expected values; a single aggregate can hide errors.
When an action removes its own control from a filtered view, establish the starting state, perform the action, and assert the stable resulting list/count. A checkbox helper may try to inspect a control that no longer exists; use a normal locator click for that transition with explicit before/after assertions. Do not force the click or swallow its timeout.
Keep coherent user journeys in one test with test.step when their sequence is the
behavior being checked. Give separate tests independent starting data. Browser storage
isolation does not replace server data isolation or prove session revocation.
Form interactions with test.step
Wrap logical action groups in test.step() for readable trace-viewer output:
test('submits a multi-step form', async ({ page }) => {
await page.goto('/onboarding');
await test.step('fill personal info', async () => {
await page.getByLabel('First name').fill('Jane');
await page.getByRole('button', { name: 'Next' }).click();
});
await test.step('submit', async () => {
await page.getByRole('button', { name: 'Complete setup' }).click();
});
await expect(page).toHaveURL('/dashboard');
});
API mocking
// Mock a response
await page.route('**/api/products*', async (route) => {
await route.fulfill({ json: { items: [{ id: '1', name: 'Widget', price: 29.99 }] } });
});
// Modify a real response
await page.route('**/api/feature-flags', async (route) => {
const response = await route.fetch();
const body = await response.json();
body.flags['new-checkout'] = true;
await route.fulfill({ response, json: body });
});
// Simulate an error
await page.route('**/api/products*', (route) => route.fulfill({ status: 500 }));
// WebSocket (v1.48+)
await page.routeWebSocket('**/ws/notifications', (ws) => {
ws.onMessage(() => ws.send(JSON.stringify({ type: 'alert', title: 'Deployed' })));
});
See references/network-and-mocking.md for HAR replay and conditional routing.
Authenticated APIRequestContext fixture
For seeding data or asserting backend state without driving the UI, inject a pre-authenticated APIRequestContext. Acquire the token in the fixture; never hardcode it:
import { test, request, type APIRequestContext } from '@playwright/test';
// test.extend adds an `api` fixture to the base test object.
export const apiTest = test.extend<{ api: APIRequestContext }>({
api: async ({ baseURL }, use) => {
const ctx = await request.newContext({
baseURL,
extraHTTPHeaders: { Authorization: `Bearer ${process.env.API_TOKEN!}` },
});
await use(ctx);
await ctx.dispose();
},
});
Tags and annotations
test('checkout @smoke', async ({ page }) => { /* npx playwright test --grep @smoke */ });
test.slow(); // Triples timeout
test.skip(({ browserName }) => browserName === 'webkit', 'WebKit bug');
test.fixme('known issue tracked in JIRA-1234', async ({ page }) => { /* ... */ });
Assertions
Always prefer web-first assertions — they auto-retry until the condition holds or the timeout expires:
await expect(page.getByRole('alert')).toBeVisible();
await expect(page.getByRole('heading')).toHaveText('Dashboard');
await expect(page).toHaveURL('/dashboard');
await expect(page.getByRole('button', { name: 'Save' })).toBeEnabled();
await expect(page.getByRole('listitem')).toHaveCount(5);
await expect(page.getByRole('listitem')).toHaveText(['Apple', 'Banana', 'Cherry']);
Soft assertions collect all failures instead of stopping at the first:
await expect.soft(page.getByLabel('Name')).toHaveValue('Jane Doe');
await expect.soft(page.getByLabel('Email')).toHaveValue('jane@example.com');
ARIA snapshots verify accessibility-tree structure and catch semantic regressions:
await expect(page.getByRole('navigation', { name: 'Main' })).toMatchAriaSnapshot(`
- navigation "Main":
- link "Home"
- link "Products"
`);
Visual regression (one-liner; defer the workflow)
Playwright's built-in toHaveScreenshot auto-retries and writes a baseline on first run. Mask dynamic regions; do not precede it with waitForTimeout:
await expect(page.getByTestId('product-card')).toHaveScreenshot('product-card.png', {
mask: [page.getByTestId('price')],
});
For baseline management, thresholds (maxDiffPixelRatio, maskColor, stylePath), and review workflows, use visual-testing — that is where visual baselines belong.
Accessibility scan (axe; deep audits live elsewhere)
ARIA snapshots above check structure, not WCAG rules. For rule-based scanning, add @axe-core/playwright:
import AxeBuilder from '@axe-core/playwright';
test('dashboard has no a11y violations', async ({ page }) => {
await page.goto('/dashboard');
const results = await new AxeBuilder({ page }).analyze();
expect(results.violations).toEqual([]);
});
For WCAG levels, rule tuning, and remediation guidance, use accessibility-testing.
Parallel Execution & CI
Sharding across CI nodes
Split the suite across matrix jobs, then merge the shard reports into one HTML report. Sharding earns its place at growing+ maturity; a startup suite of 5–10 tests should not shard.
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3, 4]
steps:
- run: npx playwright test --shard=${{ matrix.shard }}/4
Each shard uploads its blob-report/; a final job runs npx playwright merge-reports --reporter=html ./all-blob-reports. The blob reporter (set in the config above) is what makes merge work — --shard alone produces fragmented HTML reports. See references/ci-recipes.md for the full GitHub Actions workflow, blob upload/download, and artifact patterns.
Debugging
- Trace viewer:
npx playwright show-trace test-results/.../trace.zip— timeline of actions, network, DOM snapshots, console. - UI mode:
npx playwright test --ui— live, step-by-step, time-travel. - Debug flag:
npx playwright test my-test.spec.ts --debug— headed, pauses each action. - VS Code extension
ms-playwright.playwright— run/debug from gutter, pick locators, watch mode. page.pause()opens the Inspector mid-test. Local only — never commit it.
See references/debugging-and-triage.md for flaky-test triage and artifact analysis.
Installed-Version Checks
Read the lockfile and run the installed CLI before choosing version-sensitive APIs:
npm ls @playwright/test playwright
npx playwright --version
npx playwright test --help
Keep the test package, browser install and CI image on compatible pinned versions.
Check official release notes and the
installed TypeScript declarations for APIs not already used by the project. A release
table in a skill cannot establish which command the user's installation supports.
For migration, use test-migration and execute a representative migrated test; do not
invent a migration command.
Useful capabilities include page.clock for browser time, routeWebSocket for isolated
WebSocket tests, ARIA snapshots, and --fail-on-flaky-tests for retry-sensitive CI gates.
Browser clock control does not advance server token expiry or database time. Check the
contract and use an application-owned test clock when server time is the variable.
AI-augmented authoring (Test Agents vs MCP)
Two integration paths — pick based on whether the agent runs inside your editor loop or drives a real browser remotely.
Path A — Test Agents (npx playwright init-agents --loop=claude): scaffolds planner/generator/healer agents the coding agent loads during its loop. Token-efficient — no MCP server, no inter-process traffic. Best for "Claude/VS Code/opencode writes Playwright tests for me."
Path B — @playwright/mcp: an MCP server exposing browser actions to any MCP-aware agent. Higher overhead (process boundary, JSON marshalling) but the right choice when the agent must drive a live browser interactively rather than author tests offline. Config: { "mcpServers": { "playwright": { "command": "npx", "args": ["@playwright/mcp@latest"] } } } in .mcp.json.
For test-failure repair, see test-reliability. For first-time generation from PRDs/specs, see ai-test-generation.
Anti-Patterns
Design-time mistakes that quietly rot a suite. The code-level "never do X" list lives in references/anti-patterns.md with BAD/GOOD pairs — load it when writing test bodies.
1. The God Page Object
One class for the whole app turns into a 2000-line file every test imports and nothing can refactor safely. Split by page/feature and compose component objects.
2. POM methods that assert
A page object whose methods call expect hides the assertion from the test. When it fails, the stack points at the page object, not the failing scenario. Return locators/state; assert in the test.
3. Asserting on implementation detail
Tests keyed to CSS classes, DOM nesting, or internal IDs break on every refactor without a real behavior change. Assert what the user perceives — visible text, roles, URLs.
4. Fixtures that depend on test order
A fixture that mutates shared module state, or assumes another test ran first, fails the moment tests parallelize or run in isolation. Each fixture must stand alone.
5. data-testid where getByRole would work
Sprinkling test ids onto buttons and headings that already have an accessible name skips the cheapest accessibility signal you get for free. Reserve getByTestId for elements with no stable role/label.
The most damaging runtime mistake — synchronizing with waitForTimeout instead of an auto-waiting locator:
// BAD — slow on fast machines, flaky on slow ones, hides the real condition
await page.waitForTimeout(2000);
await page.click('#submit');
// GOOD — the action auto-waits for actionability
await page.getByRole('button', { name: 'Submit' }).click();
The other nine code-level offenders (CSS over roles, page.* over locators, force: true, shared state, per-test login, locator.all() without a stability check, allTextContents() over toHaveText(), hitting real third-party services, committed test.only) are in references/anti-patterns.md.
Verification
Run these against the generated artifact, smallest first:
npx playwright test --list # tests are discovered and parse
grep -rn 'waitForTimeout\|page.pause' e2e/ # must print nothing
npx tsc --noEmit # locator/assertion types compile
Enforce the "never do X" rules in CI with eslint-plugin-playwright — rules no-wait-for-timeout, no-force-option, no-element-handle, no-page-pause turn this skill's prose bans into a failing lint.
Done When
playwright.config.tsexists withprojectsfor at least Chromium (Firefox + WebKit added when targeting CI), andforbidOnly: !!process.env.CI.- Page Object Model files live in
e2e/pages/(or equivalent), with component objects composed via a rootLocatorand noexpectinside POM methods. grep -rn 'waitForTimeout' e2e/returns nothing, andeslint-plugin-playwright'sno-wait-for-timeoutis enabled.- Every locator uses
getByRole/getByLabel/getByTestId—grep -rn 'page.locator(\|xpath=\|css=' e2e/returns nothing (or only justified, commented exceptions). - CI runs the suite on PR; at
growing+ maturity it shards across matrix jobs with theblobreporter and amerge-reportsstep, uploading the HTML report as an artifact on failure.
Related Skills
- visual-testing — screenshot baseline creation, threshold tuning, and review/approval workflows. Go here for anything beyond a single inline
toHaveScreenshotcheck. - accessibility-testing — WCAG levels, axe rule tuning, and remediation. This skill only shows a minimal axe scan.
- api-testing — backend API validation, schema/contract testing, and the full
APIRequestContextpatterns. - ci-cd-integration — pipeline config, parallelization, and reporting beyond Playwright's own.
- test-reliability — runtime healing of a single flaky test (quarantine, retry strategy).
- selector-drift-recovery — offline bulk regeneration of selectors after a UI refactor breaks many tests.
Reference files (in references/)
| File | Purpose |
|---|---|
anti-patterns.md | BAD vs GOOD code pairs for every code-level mistake |
fixtures-and-projects.md | Auth fixtures, data fixtures, multi-env projects, composition |
selector-strategies.md | Locator decision tree, getByRole examples, stability scoring |
auth-patterns.md | storageState, multi-role, token seeding, session expiry |
multi-site-architecture.md | Shared fixtures, per-site config, monorepo patterns |
network-and-mocking.md | page.route, route.fetch, HAR, WebSocket, conditional routing |
debugging-and-triage.md | Trace viewer, flaky-test triage, retries, artifacts |
ci-recipes.md | Reporters, sharding + merge, --only-changed, browser caching, Docker |
FAQ
What does the playwright-automation skill do?
Write production-grade Playwright tests in TypeScript: Page Object Model, fixtures, auto-waiting, user-facing locators, parallel execution, CI integration, sharding, and installed-version checks. Includes an explicit "do not" list for AI agents. Use when: "Playwright," "write E2E test," "page object," "new Playwright suite," "Playwright config." Not for: fixing one flaky test at runtime — use test-reliability. Not for: bulk regenerating selectors after a UI refactor — use selector-drift-recovery. Not for: visual baseline creation/management — use visual-testing. Not for: deep WCAG/axe audits — use accessibility-testing. Related: visual-testing, ci-cd-integration, api-testing, test-reliability, selector-drift-recovery, accessibility-testing.
How do I install playwright-automation?
Run npx skills add https://github.com/petrkindlmann/qa-skills --skill playwright-automation in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/playwright-automation/ (personal) or .claude/skills/playwright-automation/ (project).
Which AI agents can use playwright-automation?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is playwright-automation safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains playwright-automation?
It is published by petrkindlmann in petrkindlmann/qa-skills. It has 1,920 recorded installs.
More from petrkindlmann/qa-skills
exploratory-testing
petrkindlmann/qa-skills
Design and execute structured exploratory testing sessions. Covers Session-Based Test Management (SBTM), charter writing, heuristic-based exploration (HICCUPS, FEW HICCUPS), bug discovery patterns, note-taking templates, and conversion of findings to automated tests. Use when: "exploratory testing," "SBTM," "manual testing," "bug hunting," "test charter," "heuristic testing." Not for: an AI browser agent autonomously exploring the app from a natural-language goal — use agentic-browser-testing. Not for: testing your product's own AI/LLM features — use ai-system-testing. Related: test-planning, ai-bug-triage, risk-based-testing, agentic-browser-testing.
test-strategy
petrkindlmann/qa-skills
Produce a multi-quarter QA strategy document. Covers scope, risk-based prioritization, test levels (unit/integration/E2E), pyramid analysis, entry/exit criteria, quality KPIs, tool selection rationale, CI scaling levers, and timeline planning. Output is an actionable strategy document, not a shelf document. Use when: "test strategy," "QA strategy doc," "testing approach," "QA roadmap," "multi-quarter QA direction." Not for: a single-sprint or single-release plan — use test-planning. Not for: identifying which areas carry the most risk — use risk-based-testing first. Related: risk-based-testing, qa-metrics, release-readiness, test-planning, test-reliability.
test-planning
petrkindlmann/qa-skills
Build a single sprint or release test plan. Covers feature decomposition into testable scenarios, requirements-to-test coverage mapping, effort estimation by test type, prioritization matrices (risk × effort), resource allocation, and scheduling with buffers. Use when: "sprint test plan," "release test plan," "what to test this sprint," "test estimation," "coverage mapping." Not for: multi-quarter strategy — use test-strategy. Not for: ranking areas by risk — use risk-based-testing. Not for: the go/no-go decision itself — use release-readiness. Related: test-strategy, risk-based-testing, release-readiness.
qa-project-context
petrkindlmann/qa-skills
Create and fill .agents/qa-project-context.md with the project's tech stack, test frameworks, CI/CD pipeline, environments, quality goals, risk areas, team structure, and conventions. This is the one file every other QA skill reads first, so they skip redundant discovery and give context-aware advice. Use when: "set up QA context," "configure testing," "initialize project," first use of any QA skill. Not for: bootstrapping a brand-new project's QA end-to-end — use qa-start (which calls this skill as its first step). Related: qa-start, risk-based-testing, test-strategy, qa-metrics, playwright-automation.
risk-based-testing
petrkindlmann/qa-skills
Produce a risk matrix or heatmap that quantifies what could break by business impact × probability, runs failure mode analysis on the top items, and maps test coverage to risk zones. Includes stakeholder interview frameworks and continuous reassessment. Run this BEFORE test-strategy or test-planning. Use when: "risk assessment," "risk matrix," "risk heatmap," "what could break," "critical paths," "failure modes," "where to focus testing." Not for: multi-quarter QA direction — use test-strategy. Not for: a single sprint/release test plan — use test-planning. Not for: hands-on session-based bug hunting — use exploratory-testing. Related: test-strategy, test-planning, release-readiness, qa-metrics.
bug-reproduction
petrkindlmann/qa-skills
Turn a vague bug report into a VERIFIED minimal reproduction and then a failing regression test, agent-driven end to end. Covers extracting the implicit repro from a thin report (env, build, steps, data), the reproduce-minimize-isolate-capture loop, git bisect to find the introducing commit, building a deterministic minimal repro (fixed seeds, frozen time, stubbed network), writing the failing regression test BEFORE the fix (red) and confirming the fix flips it green, and writing repro evidence back into the ticket. Distinguishes flaky-not-reproducible from environment-specific. Use when: "reproduce this bug," "minimal reproduction," "repro steps," "find the commit that broke it," "git bisect," "make the repro deterministic," "write a failing test for this bug," "regression test for a defect," "can't reproduce this bug." Not for: Classifying/deduplicating/severity-routing existing failures without reproducing them — that is ai-bug-triage. Generating tests from specs rather than from a
Popular testing & qa skills
tdd
mattpocock/skills
Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration tests.
grilling
mattpocock/skills
Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.
migrate-to-shoehorn
mattpocock/skills
Migrate test files from as type assertions to @total-typescript/shoehorn. Use when user mentions shoehorn, wants to replace as in tests, or needs partial test data.
run-train
lllllllama/rigorpilot-skills
Rigor Train skill for deep learning research repositories. Use when a documented or selected training command should be run conservatively for startup verification, short-run verification, full kickoff, or resume, with command, config, seed, log, checkpoint, status, and metric evidence written to standardized trainoutputs/. Do not use for environment setup, exploratory sweeps, speculative idea implementation, or end-to-end orchestration.
test-driven-development
obra/superpowers
Use when implementing any feature or bugfix, before writing implementation code
finishing-a-development-branch
obra/superpowers
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work