AgentSkillsCN

e2e-tests

使用Playwright结合“given/should”的散文式语法,生成端到端测试。在为用户流程、页面交互,或涉及完整应用栈的集成场景编写e2e测试时,此方法尤为适用。

SKILL.md
--- frontmatter
name: e2e-tests
description: Generates end-to-end tests using Playwright with the "given/should" prose format. Use when writing e2e tests for user flows, page interactions, or integration scenarios that exercise the full application stack.

E2E Tests

Act as a top-tier software engineer with serious testing skills.

Write e2e tests for: $ARGUMENTS

Each test must answer these 5 questions:

  1. What is the user flow under test? (test should be in a named describe block)
  2. What is the expected behavior? ($given and $should arguments are adequate)
  3. What actions does the user perform? (navigations, clicks, form fills, etc.)
  4. What is the expected outcome? (visible elements, URLs, toasts, database state)
  5. How can we find the bug? (implicitly answered if the above questions are answered correctly)

Rules

  • Use Playwright with test, expect, and test.describe.
  • Tests must use the "given: ..., should: ..." prose format.
  • Test files live in playwright/ directory, organized by feature subdirectories.
  • Test files use the .e2e.ts extension.
  • Prefer accessible locators: getByRole, getByLabel, getByText over CSS selectors.
  • Use getByRole with name option as the primary locator strategy.
  • When accessible locators are insufficient, use data-testid attributes via getByTestId.
  • Never use CSS class selectors for test locators — classes are for styling, not testing.
  • Define data-testid values as named exports in a shared constants file (e.g. app/test/test-ids.ts) and import them in both the component and the test.
  • Use regex with case-insensitive flag for text matching: { name: /submit/i }.
  • Await all Playwright actions and assertions.
  • Use toBeVisible() and toBeHidden() for element presence checks.
  • Use toHaveURL() or a getPath(page) helper for URL assertions.
  • Handle auth setup in helper functions, not inline in every test.
  • Clean up test data in teardown — don't leave state for the next test.
  • Each test should be independent and not depend on other tests' state.
  • Use test.step("description", async () => { ... }) to organize logical phases within a test — never use inline comments like // Open notifications panel as step separators.
  • Block images in performance-sensitive tests via page.route.
  • Use test.describe blocks to group related scenarios.
  • Assert toast notifications via getByRole("region", { name: /notifications/i }).
  • For forms, use getByRole("textbox", { name: /label/i }) and .fill().
  • For dropdowns, use getByRole("combobox") then getByRole("option").
  • For accessibility checks, use @axe-core/playwright with expect(results.violations).toEqual([]).
  • Create reusable setup/teardown helpers for common flows (login, org creation, etc.).
  • Use factories from the codebase to create test data — never hardcode full objects.
  • Verify database state after mutations using model functions from infrastructure layer.