by thetestingacademy
Teach AI coding agents to use the Playwright CLI and debug loop efficiently with last-failed runs, locator probing, trace evidence, and safe healing.
npx @qaskills/cli add playwright-cli-agent-loopAuto-detects your AI agent and installs the skill. Works with Claude Code, Cursor, Copilot, and more.
You are an AI coding agent that uses the Playwright CLI as a tight evidence loop: run the smallest useful test, inspect traces, probe locators, fix code, and rerun only what proves the change.
Install Playwright and create predictable scripts.
npm install --save-dev @playwright/test
npx playwright install --with-deps
npm pkg set scripts.test:e2e='playwright test'
npm pkg set scripts.test:e2e:debug='PWDEBUG=1 playwright test --debug'
npm pkg set scripts.test:e2e:last='playwright test --last-failed'
npm pkg set scripts.test:e2e:report='playwright show-report'
Use a config that retains failure evidence.
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests/e2e',
retries: process.env.CI ? 2 : 0,
reporter: [['html'], ['list']],
use: {
baseURL: process.env.BASE_URL || 'http://127.0.0.1:3000',
trace: 'retain-on-failure',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
],
});
Follow this loop for every Playwright failure.
--last-failed.Use commands that keep output readable.
npx playwright test tests/e2e/login.spec.ts --project=chromium --reporter=line
npx playwright test -g 'valid user can sign in' --project=chromium --reporter=line
npx playwright test --last-failed --reporter=line
npx playwright show-trace test-results/login-valid-user-chromium/trace.zip
Use Playwright locators to understand what the browser can actually see.
// tests/e2e/probe.spec.ts
import { test } from '@playwright/test';
test('probe accessible names', async ({ page }) => {
await page.goto('/login');
const buttons = await page.getByRole('button').evaluateAll((nodes) =>
nodes.map((node) => ({
text: node.textContent?.trim(),
aria: node.getAttribute('aria-label'),
})),
);
console.log(JSON.stringify(buttons, null, 2));
});
Use debug mode when static logs are not enough.
PWDEBUG=console npx playwright test tests/e2e/checkout.spec.ts -g 'submits order'
npx playwright test tests/e2e/checkout.spec.ts --debug --project=chromium
npx playwright codegen http://127.0.0.1:3000/checkout
When the inspector is open, check these items.
When repairing a locator, improve the contract.
// Before
await page.locator('.btn-primary').click();
// Better
await page.getByRole('button', { name: 'Create project' }).click();
// Also acceptable when the design system owns the accessible name
await page.getByTestId('create-project-button').click();
| Problem | First Command | Follow-Up |
|---|---|---|
| One failing test | playwright test path -g name | Open trace |
| Multiple failures | playwright test --last-failed | Group by root cause |
| Locator timeout | --debug | Probe roles and names |
| Mobile-only failure | --project mobile project | Check viewport assumptions |
| Suspected flake | Repeat exact test | Inspect network and timing |
| Unknown page state | Add temporary probe | Remove probe before final |
waitForTimeout instead of identifying the wait condition.--last-failed after a fix.--last-failed passed after the fix.- name: Install QA Skills
run: npx @qaskills/cli add playwright-cli-agent-loop12 of 29 agents supported
Go from zero to Playwright pro: Page Object Model, fixtures, and CI/CD on real projects.
Use code PROMODE at checkout