一键导入
qa-e2e
End-to-end tests with Playwright or Cypress. Trigger when the user wants to create user journey tests, UI integration tests, or browser automation.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
End-to-end tests with Playwright or Cypress. Trigger when the user wants to create user journey tests, UI integration tests, or browser automation.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Multi-agent team orchestration with native Agent Teams. Trigger when the user wants to launch a team of agents, coordinate parallel work with inter-agent communication, or use swarm mode.
Perform a thorough code review. Use when the user requests a review, wants to verify code quality, or before merging a PR.
Context transfer between AI sessions. Trigger when the user wants to save the context, resume a task, or hand off the work to another session.
API mock configuration for tests. Trigger when the user wants to mock APIs, use MSW, or test without a backend.
Debug and resolve problems. Use when the user has a bug, an error, an unexpected behavior, or wants to understand why something is not working.
TDD development with Red-Green-Refactor cycle. Use to implement a feature by writing tests BEFORE the code. Trigger automatically when the user asks for TDD, wants to write tests first, mentions "test first", or asks to implement, add, create, fix, correct code, a new feature, a bugfix, or a functionality.
| name | qa-e2e |
| description | End-to-end tests with Playwright or Cypress. Trigger when the user wants to create user journey tests, UI integration tests, or browser automation. |
| allowed-tools | ["Read","Write","Edit","Bash","Glob","Grep"] |
| context | fork |
This skill activates when the user mentions:
| Framework | Advantages | Use case |
|---|---|---|
| Playwright | Multi-browser, fast, auto-wait | Modern apps |
| Cypress | Excellent DX, easy debugging | Prototyping |
Default recommendation: Playwright
e2e/
├── fixtures/ # Custom fixtures
├── pages/ # Page Objects
│ ├── login.page.ts
│ └── dashboard.page.ts
├── tests/
│ ├── auth/
│ │ └── login.spec.ts
│ └── checkout/
│ └── purchase.spec.ts
├── utils/ # Helpers
└── playwright.config.ts
// e2e/pages/login.page.ts
import { Page, Locator } from '@playwright/test';
export class LoginPage {
readonly page: Page;
readonly emailInput: Locator;
readonly passwordInput: Locator;
readonly submitButton: Locator;
constructor(page: Page) {
this.page = page;
this.emailInput = page.getByLabel('Email');
this.passwordInput = page.getByLabel('Password');
this.submitButton = page.getByRole('button', { name: 'Login' });
}
async goto() {
await this.page.goto('/login');
}
async login(email: string, password: string) {
await this.emailInput.fill(email);
await this.passwordInput.fill(password);
await this.submitButton.click();
}
}
// e2e/tests/auth/login.spec.ts
import { test, expect } from '@playwright/test';
import { LoginPage } from '../../pages/login.page';
test.describe('Authentication', () => {
let loginPage: LoginPage;
test.beforeEach(async ({ page }) => {
loginPage = new LoginPage(page);
await loginPage.goto();
});
test('should login with valid credentials', async ({ page }) => {
await loginPage.login('user@example.com', 'password');
await expect(page).toHaveURL('/dashboard');
});
test('should show error with invalid credentials', async ({ page }) => {
await loginPage.login('user@example.com', 'wrong');
await expect(page.getByRole('alert')).toContainText('Invalid');
});
});
| Journey | Test points |
|---|---|
| Signup | Form validation, email, success |
| Login | Valid/invalid, remember me, forgot |
| Navigation | Menu, breadcrumbs, deep links |
| Search | Query, filters, pagination |
| Checkout | Cart, payment, confirmation |
| Priority | Selector | Example |
|---|---|---|
| 1 | Role | getByRole('button', { name: 'Submit' }) |
| 2 | Label | getByLabel('Email') |
| 3 | Text | getByText('Welcome') |
| 4 | Test ID | getByTestId('submit-btn') |
| 5 | CSS | .btn-primary (avoid) |
# Run the tests
npx playwright test
# Interactive UI mode
npx playwright test --ui
# Headed mode (see the browser)
npx playwright test --headed
# Debug
npx playwright test --debug
# Generate code
npx playwright codegen http://localhost:3000
# Report
npx playwright show-report
Playwright fixtures centralize the setup and inject the Page Objects into the tests:
// e2e/fixtures/index.ts
import { test as base } from '@playwright/test';
import { LoginPage } from '../pages/login.page';
import { DashboardPage } from '../pages/dashboard.page';
type Fixtures = {
loginPage: LoginPage;
dashboardPage: DashboardPage;
};
export const test = base.extend<Fixtures>({
loginPage: async ({ page }, use) => {
await use(new LoginPage(page));
},
dashboardPage: async ({ page }, use) => {
await use(new DashboardPage(page));
},
});
export { expect } from '@playwright/test';
// e2e/tests/auth/login.spec.ts (with fixtures)
import { test, expect } from '../../fixtures';
test('should login with valid credentials', async ({ loginPage, page }) => {
await loginPage.goto();
await loginPage.login('user@example.com', 'password');
await expect(page).toHaveURL('/dashboard');
});
// e2e/fixtures/auth.ts
import { test as base } from '@playwright/test';
export const test = base.extend({
authenticatedPage: async ({ page }, use) => {
await page.goto('/login');
await page.getByLabel('Email').fill('user@example.com');
await page.getByLabel('Password').fill('password');
await page.getByRole('button', { name: 'Login' }).click();
await page.waitForURL('/dashboard');
await use(page);
},
});
| Practice | Description |
|---|---|
| Fresh context | Each test starts in an isolated browser context (no shared state) |
| Auto-waiting | Don't add waitForTimeout - Playwright waits automatically |
| Web-first assertions | Use expect(locator) which retries automatically, not expect(await locator.textContent()) |
| Parallelism | fullyParallel: true in the config for parallel execution |
| Traces | trace: 'on-first-retry' to debug flaky tests |
| Anti-pattern | Alternative |
|---|---|
page.waitForTimeout(3000) | await expect(locator).toBeVisible() |
page.$('.my-class') | page.getByRole('button', { name: '...' }) |
| XPath selectors | role/label/text selectors |
| Tests dependent on each other | Each test is independent |
page.evaluate() for assertions | Web-first assertions with expect |
| Page Objects with business logic | Page Objects = actions + locators only |
IMPORTANT: E2E tests are slow - reserve them for critical journeys (10% of the pyramid).
IMPORTANT: Always use accessible selectors (role, label).
IMPORTANT: Use Playwright fixtures to inject the Page Objects - no new Page() in each test.
YOU MUST implement the Page Object Model for maintainability.
NEVER test implementation details - test user behavior.
NEVER use fragile CSS selectors (classes, dynamic IDs).
NEVER use waitForTimeout - use web-first assertions which retry automatically.
The Microsoft Playwright team publishes their own SKILL.md at microsoft/playwright-cli/skills/playwright-cli (9,978★, last commit 2026-05-04). Authoritative on Playwright API patterns, kept in sync with each Playwright release.
When working on a Playwright project, install the vendor skill alongside this one. This skill captures the opinionated workflow patterns the foundation imposes (TDD, anti-fragility rules, don't-do lists); the vendor skill captures the canonical API patterns that evolve with each Playwright release. Both together is the recommended setup for Playwright users.
Vendor-neutrality disclosure: Microsoft owns Playwright. Per the foundation's vendor curation policy, Microsoft tools that predate the company's deepening OpenAI commercial relationship (e.g. VSCode, GitHub, Playwright created in 2020) are evaluated case-by-case rather than auto-rejected. Playwright remains MIT-licensed and the de-facto standard for E2E testing. We point to the vendor skill because no equivalent vendor-neutral source maintains the API canonically and the community alternative lackeyjb/playwright-skill was 5 months stale at audit time. Re-evaluate this pointer if Microsoft's commercial alignment with OpenAI changes the project's roadmap visibly (e.g. direct OpenAI product integration).
For Cypress users (the other framework this skill covers), no vendor-published Cypress skill was identified at the time of the audit; the framework-agnostic guidance in this skill remains the primary reference.
Install command and full list of validated vendor skills: docs/recipes/recommended-vendor-skills.md. Audit pilot trace: specs/marketplace-audit/qa-skills-pilot-2026-05-06.md.