@athenaflow/plugin-e2e-test-builder 2.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/.claude-plugin/plugin.json +20 -0
  2. package/.codex-plugin/plugin.json +15 -0
  3. package/dist/2.0.8/.agents/plugins/marketplace.json +14 -0
  4. package/dist/2.0.8/claude/plugin/.claude-plugin/plugin.json +20 -0
  5. package/dist/2.0.8/claude/plugin/package.json +9 -0
  6. package/dist/2.0.8/claude/plugin/skills/add-e2e-tests/SKILL.md +217 -0
  7. package/dist/2.0.8/claude/plugin/skills/add-e2e-tests/agents/claude.yaml +1 -0
  8. package/dist/2.0.8/claude/plugin/skills/add-e2e-tests/agents/openai.yaml +10 -0
  9. package/dist/2.0.8/claude/plugin/skills/add-e2e-tests/references/authentication.md +8 -0
  10. package/dist/2.0.8/claude/plugin/skills/add-e2e-tests/references/error-recovery.md +43 -0
  11. package/dist/2.0.8/claude/plugin/skills/add-e2e-tests/references/scaffolding.md +12 -0
  12. package/dist/2.0.8/claude/plugin/skills/add-e2e-tests/references/tracker-template.md +53 -0
  13. package/dist/2.0.8/claude/plugin/skills/analyze-test-codebase/SKILL.md +142 -0
  14. package/dist/2.0.8/claude/plugin/skills/analyze-test-codebase/agents/claude.yaml +3 -0
  15. package/dist/2.0.8/claude/plugin/skills/analyze-test-codebase/agents/openai.yaml +4 -0
  16. package/dist/2.0.8/claude/plugin/skills/fix-flaky-tests/SKILL.md +160 -0
  17. package/dist/2.0.8/claude/plugin/skills/fix-flaky-tests/agents/claude.yaml +3 -0
  18. package/dist/2.0.8/claude/plugin/skills/fix-flaky-tests/agents/openai.yaml +10 -0
  19. package/dist/2.0.8/claude/plugin/skills/fix-flaky-tests/references/fix-patterns.md +91 -0
  20. package/dist/2.0.8/claude/plugin/skills/generate-test-cases/SKILL.md +184 -0
  21. package/dist/2.0.8/claude/plugin/skills/generate-test-cases/agents/claude.yaml +3 -0
  22. package/dist/2.0.8/claude/plugin/skills/generate-test-cases/agents/openai.yaml +10 -0
  23. package/dist/2.0.8/claude/plugin/skills/generate-test-cases/references/scenario-categories.md +36 -0
  24. package/dist/2.0.8/claude/plugin/skills/plan-test-coverage/SKILL.md +116 -0
  25. package/dist/2.0.8/claude/plugin/skills/plan-test-coverage/agents/claude.yaml +3 -0
  26. package/dist/2.0.8/claude/plugin/skills/plan-test-coverage/agents/openai.yaml +10 -0
  27. package/dist/2.0.8/claude/plugin/skills/review-test-cases/SKILL.md +147 -0
  28. package/dist/2.0.8/claude/plugin/skills/review-test-cases/agents/claude.yaml +3 -0
  29. package/dist/2.0.8/claude/plugin/skills/review-test-cases/agents/openai.yaml +10 -0
  30. package/dist/2.0.8/claude/plugin/skills/review-test-code/SKILL.md +189 -0
  31. package/dist/2.0.8/claude/plugin/skills/review-test-code/agents/claude.yaml +3 -0
  32. package/dist/2.0.8/claude/plugin/skills/review-test-code/agents/openai.yaml +10 -0
  33. package/dist/2.0.8/claude/plugin/skills/write-test-code/SKILL.md +227 -0
  34. package/dist/2.0.8/claude/plugin/skills/write-test-code/agents/claude.yaml +3 -0
  35. package/dist/2.0.8/claude/plugin/skills/write-test-code/agents/openai.yaml +10 -0
  36. package/dist/2.0.8/claude/plugin/skills/write-test-code/references/anti-patterns.md +88 -0
  37. package/dist/2.0.8/claude/plugin/skills/write-test-code/references/api-setup-teardown.md +83 -0
  38. package/dist/2.0.8/claude/plugin/skills/write-test-code/references/auth-patterns.md +63 -0
  39. package/dist/2.0.8/claude/plugin/skills/write-test-code/references/mapping-tables.md +56 -0
  40. package/dist/2.0.8/claude/plugin/skills/write-test-code/references/network-interception.md +56 -0
  41. package/dist/2.0.8/codex/plugin/.codex-plugin/plugin.json +15 -0
  42. package/dist/2.0.8/codex/plugin/package.json +9 -0
  43. package/dist/2.0.8/codex/plugin/skills/add-e2e-tests/SKILL.md +217 -0
  44. package/dist/2.0.8/codex/plugin/skills/add-e2e-tests/agents/claude.yaml +1 -0
  45. package/dist/2.0.8/codex/plugin/skills/add-e2e-tests/agents/openai.yaml +10 -0
  46. package/dist/2.0.8/codex/plugin/skills/add-e2e-tests/references/authentication.md +8 -0
  47. package/dist/2.0.8/codex/plugin/skills/add-e2e-tests/references/error-recovery.md +43 -0
  48. package/dist/2.0.8/codex/plugin/skills/add-e2e-tests/references/scaffolding.md +12 -0
  49. package/dist/2.0.8/codex/plugin/skills/add-e2e-tests/references/tracker-template.md +53 -0
  50. package/dist/2.0.8/codex/plugin/skills/analyze-test-codebase/SKILL.md +142 -0
  51. package/dist/2.0.8/codex/plugin/skills/analyze-test-codebase/agents/claude.yaml +3 -0
  52. package/dist/2.0.8/codex/plugin/skills/analyze-test-codebase/agents/openai.yaml +4 -0
  53. package/dist/2.0.8/codex/plugin/skills/fix-flaky-tests/SKILL.md +160 -0
  54. package/dist/2.0.8/codex/plugin/skills/fix-flaky-tests/agents/claude.yaml +3 -0
  55. package/dist/2.0.8/codex/plugin/skills/fix-flaky-tests/agents/openai.yaml +10 -0
  56. package/dist/2.0.8/codex/plugin/skills/fix-flaky-tests/references/fix-patterns.md +91 -0
  57. package/dist/2.0.8/codex/plugin/skills/generate-test-cases/SKILL.md +184 -0
  58. package/dist/2.0.8/codex/plugin/skills/generate-test-cases/agents/claude.yaml +3 -0
  59. package/dist/2.0.8/codex/plugin/skills/generate-test-cases/agents/openai.yaml +10 -0
  60. package/dist/2.0.8/codex/plugin/skills/generate-test-cases/references/scenario-categories.md +36 -0
  61. package/dist/2.0.8/codex/plugin/skills/plan-test-coverage/SKILL.md +116 -0
  62. package/dist/2.0.8/codex/plugin/skills/plan-test-coverage/agents/claude.yaml +3 -0
  63. package/dist/2.0.8/codex/plugin/skills/plan-test-coverage/agents/openai.yaml +10 -0
  64. package/dist/2.0.8/codex/plugin/skills/review-test-cases/SKILL.md +147 -0
  65. package/dist/2.0.8/codex/plugin/skills/review-test-cases/agents/claude.yaml +3 -0
  66. package/dist/2.0.8/codex/plugin/skills/review-test-cases/agents/openai.yaml +10 -0
  67. package/dist/2.0.8/codex/plugin/skills/review-test-code/SKILL.md +189 -0
  68. package/dist/2.0.8/codex/plugin/skills/review-test-code/agents/claude.yaml +3 -0
  69. package/dist/2.0.8/codex/plugin/skills/review-test-code/agents/openai.yaml +10 -0
  70. package/dist/2.0.8/codex/plugin/skills/write-test-code/SKILL.md +227 -0
  71. package/dist/2.0.8/codex/plugin/skills/write-test-code/agents/claude.yaml +3 -0
  72. package/dist/2.0.8/codex/plugin/skills/write-test-code/agents/openai.yaml +10 -0
  73. package/dist/2.0.8/codex/plugin/skills/write-test-code/references/anti-patterns.md +88 -0
  74. package/dist/2.0.8/codex/plugin/skills/write-test-code/references/api-setup-teardown.md +83 -0
  75. package/dist/2.0.8/codex/plugin/skills/write-test-code/references/auth-patterns.md +63 -0
  76. package/dist/2.0.8/codex/plugin/skills/write-test-code/references/mapping-tables.md +56 -0
  77. package/dist/2.0.8/codex/plugin/skills/write-test-code/references/network-interception.md +56 -0
  78. package/dist/2.0.8/release.json +18 -0
  79. package/dist/2.0.9/.agents/plugins/marketplace.json +14 -0
  80. package/dist/2.0.9/claude/plugin/.claude-plugin/plugin.json +20 -0
  81. package/dist/2.0.9/claude/plugin/package.json +9 -0
  82. package/dist/2.0.9/claude/plugin/skills/add-e2e-tests/SKILL.md +215 -0
  83. package/dist/2.0.9/claude/plugin/skills/add-e2e-tests/agents/claude.yaml +3 -0
  84. package/dist/2.0.9/claude/plugin/skills/add-e2e-tests/agents/openai.yaml +10 -0
  85. package/dist/2.0.9/claude/plugin/skills/add-e2e-tests/references/authentication.md +8 -0
  86. package/dist/2.0.9/claude/plugin/skills/add-e2e-tests/references/error-recovery.md +43 -0
  87. package/dist/2.0.9/claude/plugin/skills/add-e2e-tests/references/scaffolding.md +12 -0
  88. package/dist/2.0.9/claude/plugin/skills/add-e2e-tests/references/tracker-template.md +53 -0
  89. package/dist/2.0.9/claude/plugin/skills/analyze-test-codebase/SKILL.md +142 -0
  90. package/dist/2.0.9/claude/plugin/skills/analyze-test-codebase/agents/claude.yaml +3 -0
  91. package/dist/2.0.9/claude/plugin/skills/analyze-test-codebase/agents/openai.yaml +4 -0
  92. package/dist/2.0.9/claude/plugin/skills/fix-flaky-tests/SKILL.md +160 -0
  93. package/dist/2.0.9/claude/plugin/skills/fix-flaky-tests/agents/claude.yaml +3 -0
  94. package/dist/2.0.9/claude/plugin/skills/fix-flaky-tests/agents/openai.yaml +10 -0
  95. package/dist/2.0.9/claude/plugin/skills/fix-flaky-tests/references/fix-patterns.md +91 -0
  96. package/dist/2.0.9/claude/plugin/skills/generate-test-cases/SKILL.md +184 -0
  97. package/dist/2.0.9/claude/plugin/skills/generate-test-cases/agents/claude.yaml +3 -0
  98. package/dist/2.0.9/claude/plugin/skills/generate-test-cases/agents/openai.yaml +10 -0
  99. package/dist/2.0.9/claude/plugin/skills/generate-test-cases/references/scenario-categories.md +36 -0
  100. package/dist/2.0.9/claude/plugin/skills/plan-test-coverage/SKILL.md +117 -0
  101. package/dist/2.0.9/claude/plugin/skills/plan-test-coverage/agents/claude.yaml +3 -0
  102. package/dist/2.0.9/claude/plugin/skills/plan-test-coverage/agents/openai.yaml +10 -0
  103. package/dist/2.0.9/claude/plugin/skills/review-test-cases/SKILL.md +147 -0
  104. package/dist/2.0.9/claude/plugin/skills/review-test-cases/agents/claude.yaml +3 -0
  105. package/dist/2.0.9/claude/plugin/skills/review-test-cases/agents/openai.yaml +10 -0
  106. package/dist/2.0.9/claude/plugin/skills/review-test-code/SKILL.md +189 -0
  107. package/dist/2.0.9/claude/plugin/skills/review-test-code/agents/claude.yaml +3 -0
  108. package/dist/2.0.9/claude/plugin/skills/review-test-code/agents/openai.yaml +10 -0
  109. package/dist/2.0.9/claude/plugin/skills/write-test-code/SKILL.md +227 -0
  110. package/dist/2.0.9/claude/plugin/skills/write-test-code/agents/claude.yaml +3 -0
  111. package/dist/2.0.9/claude/plugin/skills/write-test-code/agents/openai.yaml +10 -0
  112. package/dist/2.0.9/claude/plugin/skills/write-test-code/references/anti-patterns.md +88 -0
  113. package/dist/2.0.9/claude/plugin/skills/write-test-code/references/api-setup-teardown.md +83 -0
  114. package/dist/2.0.9/claude/plugin/skills/write-test-code/references/auth-patterns.md +63 -0
  115. package/dist/2.0.9/claude/plugin/skills/write-test-code/references/mapping-tables.md +56 -0
  116. package/dist/2.0.9/claude/plugin/skills/write-test-code/references/network-interception.md +56 -0
  117. package/dist/2.0.9/codex/plugin/.codex-plugin/plugin.json +15 -0
  118. package/dist/2.0.9/codex/plugin/package.json +9 -0
  119. package/dist/2.0.9/codex/plugin/skills/add-e2e-tests/SKILL.md +215 -0
  120. package/dist/2.0.9/codex/plugin/skills/add-e2e-tests/agents/claude.yaml +3 -0
  121. package/dist/2.0.9/codex/plugin/skills/add-e2e-tests/agents/openai.yaml +10 -0
  122. package/dist/2.0.9/codex/plugin/skills/add-e2e-tests/references/authentication.md +8 -0
  123. package/dist/2.0.9/codex/plugin/skills/add-e2e-tests/references/error-recovery.md +43 -0
  124. package/dist/2.0.9/codex/plugin/skills/add-e2e-tests/references/scaffolding.md +12 -0
  125. package/dist/2.0.9/codex/plugin/skills/add-e2e-tests/references/tracker-template.md +53 -0
  126. package/dist/2.0.9/codex/plugin/skills/analyze-test-codebase/SKILL.md +142 -0
  127. package/dist/2.0.9/codex/plugin/skills/analyze-test-codebase/agents/claude.yaml +3 -0
  128. package/dist/2.0.9/codex/plugin/skills/analyze-test-codebase/agents/openai.yaml +4 -0
  129. package/dist/2.0.9/codex/plugin/skills/fix-flaky-tests/SKILL.md +160 -0
  130. package/dist/2.0.9/codex/plugin/skills/fix-flaky-tests/agents/claude.yaml +3 -0
  131. package/dist/2.0.9/codex/plugin/skills/fix-flaky-tests/agents/openai.yaml +10 -0
  132. package/dist/2.0.9/codex/plugin/skills/fix-flaky-tests/references/fix-patterns.md +91 -0
  133. package/dist/2.0.9/codex/plugin/skills/generate-test-cases/SKILL.md +184 -0
  134. package/dist/2.0.9/codex/plugin/skills/generate-test-cases/agents/claude.yaml +3 -0
  135. package/dist/2.0.9/codex/plugin/skills/generate-test-cases/agents/openai.yaml +10 -0
  136. package/dist/2.0.9/codex/plugin/skills/generate-test-cases/references/scenario-categories.md +36 -0
  137. package/dist/2.0.9/codex/plugin/skills/plan-test-coverage/SKILL.md +117 -0
  138. package/dist/2.0.9/codex/plugin/skills/plan-test-coverage/agents/claude.yaml +3 -0
  139. package/dist/2.0.9/codex/plugin/skills/plan-test-coverage/agents/openai.yaml +10 -0
  140. package/dist/2.0.9/codex/plugin/skills/review-test-cases/SKILL.md +147 -0
  141. package/dist/2.0.9/codex/plugin/skills/review-test-cases/agents/claude.yaml +3 -0
  142. package/dist/2.0.9/codex/plugin/skills/review-test-cases/agents/openai.yaml +10 -0
  143. package/dist/2.0.9/codex/plugin/skills/review-test-code/SKILL.md +189 -0
  144. package/dist/2.0.9/codex/plugin/skills/review-test-code/agents/claude.yaml +3 -0
  145. package/dist/2.0.9/codex/plugin/skills/review-test-code/agents/openai.yaml +10 -0
  146. package/dist/2.0.9/codex/plugin/skills/write-test-code/SKILL.md +227 -0
  147. package/dist/2.0.9/codex/plugin/skills/write-test-code/agents/claude.yaml +3 -0
  148. package/dist/2.0.9/codex/plugin/skills/write-test-code/agents/openai.yaml +10 -0
  149. package/dist/2.0.9/codex/plugin/skills/write-test-code/references/anti-patterns.md +88 -0
  150. package/dist/2.0.9/codex/plugin/skills/write-test-code/references/api-setup-teardown.md +83 -0
  151. package/dist/2.0.9/codex/plugin/skills/write-test-code/references/auth-patterns.md +63 -0
  152. package/dist/2.0.9/codex/plugin/skills/write-test-code/references/mapping-tables.md +56 -0
  153. package/dist/2.0.9/codex/plugin/skills/write-test-code/references/network-interception.md +56 -0
  154. package/dist/2.0.9/release.json +18 -0
  155. package/package.json +13 -0
  156. package/skills/add-e2e-tests/SKILL.md +215 -0
  157. package/skills/add-e2e-tests/agents/claude.yaml +3 -0
  158. package/skills/add-e2e-tests/agents/openai.yaml +10 -0
  159. package/skills/add-e2e-tests/references/authentication.md +8 -0
  160. package/skills/add-e2e-tests/references/error-recovery.md +43 -0
  161. package/skills/add-e2e-tests/references/scaffolding.md +12 -0
  162. package/skills/add-e2e-tests/references/tracker-template.md +53 -0
  163. package/skills/analyze-test-codebase/SKILL.md +142 -0
  164. package/skills/analyze-test-codebase/agents/claude.yaml +3 -0
  165. package/skills/analyze-test-codebase/agents/openai.yaml +4 -0
  166. package/skills/fix-flaky-tests/SKILL.md +160 -0
  167. package/skills/fix-flaky-tests/agents/claude.yaml +3 -0
  168. package/skills/fix-flaky-tests/agents/openai.yaml +10 -0
  169. package/skills/fix-flaky-tests/references/fix-patterns.md +91 -0
  170. package/skills/generate-test-cases/SKILL.md +184 -0
  171. package/skills/generate-test-cases/agents/claude.yaml +3 -0
  172. package/skills/generate-test-cases/agents/openai.yaml +10 -0
  173. package/skills/generate-test-cases/references/scenario-categories.md +36 -0
  174. package/skills/plan-test-coverage/SKILL.md +117 -0
  175. package/skills/plan-test-coverage/agents/claude.yaml +3 -0
  176. package/skills/plan-test-coverage/agents/openai.yaml +10 -0
  177. package/skills/review-test-cases/SKILL.md +147 -0
  178. package/skills/review-test-cases/agents/claude.yaml +3 -0
  179. package/skills/review-test-cases/agents/openai.yaml +10 -0
  180. package/skills/review-test-code/SKILL.md +189 -0
  181. package/skills/review-test-code/agents/claude.yaml +3 -0
  182. package/skills/review-test-code/agents/openai.yaml +10 -0
  183. package/skills/write-test-code/SKILL.md +227 -0
  184. package/skills/write-test-code/agents/claude.yaml +3 -0
  185. package/skills/write-test-code/agents/openai.yaml +10 -0
  186. package/skills/write-test-code/references/anti-patterns.md +88 -0
  187. package/skills/write-test-code/references/api-setup-teardown.md +83 -0
  188. package/skills/write-test-code/references/auth-patterns.md +63 -0
  189. package/skills/write-test-code/references/mapping-tables.md +56 -0
  190. package/skills/write-test-code/references/network-interception.md +56 -0
@@ -0,0 +1,227 @@
1
+ ---
2
+ name: write-test-code
3
+ description: >
4
+ This skill should be used when writing, refactoring, or modifying Playwright E2E test code.
5
+ It covers creating test files from TC-ID specs, converting browser exploration results to
6
+ executable tests, refactoring locators or fixtures, adding API mocking, test data
7
+ setup/teardown, and parallel-safe isolation. Includes locator strategy hierarchy, auth setup
8
+ patterns, fixture design, teardown strategies, and network interception recipes.
9
+ Triggers: "write a test for", "add a test case", "refactor this locator", "add error path
10
+ tests", "convert specs to code", "add API mocking", "set up auth for tests".
11
+ NOT for: full pipeline from scratch (use add-e2e-tests), exploring live sites (use
12
+ agent-web-interface-guide), generating specs without code (use plan-test-coverage or
13
+ generate-test-cases), diagnosing flaky tests (use fix-flaky-tests).
14
+ allowed-tools: Read Write Edit Bash Glob Grep Task
15
+ ---
16
+
17
+ # Write E2E Tests
18
+
19
+ Write, refactor, or fix Playwright E2E tests. Convert browser exploration results or test case specifications into executable, stable test code.
20
+
21
+ ## Input
22
+
23
+ Parse the test description or spec file path from: $ARGUMENTS
24
+
25
+ ## Workflow
26
+
27
+ ### 1. Understand the Request
28
+ - Identify the user journey to test and success criteria
29
+ - Identify preconditions (auth, seeded data, feature flags, env)
30
+ - If a test case spec file path is provided, read it for TC-IDs and expected behaviors
31
+
32
+ ### 2. Inspect Repo Conventions (CRITICAL — before writing any code)
33
+ - Search for `playwright.config.ts` / `playwright.config.js` — extract `baseURL`, `testDir`, projects
34
+ - Search for existing tests, fixtures, page objects, locator patterns, test data modules
35
+ - Read 2-3 existing test files to match the project's naming, structure, and locator strategy
36
+ - Check for custom fixtures, POM patterns, auth setup (storageState, global setup)
37
+ - Follow the project's existing style unless it clearly causes flakiness
38
+
39
+ ### 3. Verify Key Selectors Against the Live Site
40
+ - If a test case spec file includes **Selectors observed**, use those as your starting point
41
+ - If no spec or selectors are available, browse the target page using `agent-web-interface-guide` to discover the actual selectors before writing code — do not guess
42
+ - Spot-check 2-3 critical selectors with `find` or `get_element` to confirm they resolve to the intended elements
43
+
44
+ ### 4. Implement Tests
45
+ - Add/adjust fixtures and page objects first (if needed)
46
+ - Write tests in a story-like flow with AAA structure: Arrange → Act → Assert
47
+ - Add assertions that represent user outcomes
48
+ - **For large suites:** Use subagents (Task tool) to write individual test files in parallel.
49
+ Pass each subagent the test case spec path, codebase conventions from Step 2, and the
50
+ operating principles from this skill. Only split when files have independent responsibilities.
51
+
52
+ ### 5. Stabilize
53
+ - Replace any sleeps with meaningful waits
54
+ - Tighten locators to avoid ambiguity
55
+ - For network-driven flows, use `page.waitForResponse` for critical checkpoints
56
+
57
+ ### 6. Verify
58
+ - Run the smallest relevant test command: `npx playwright test <file> --reporter=list 2>&1`
59
+ - In CI or headless environments (no display), never use `--headed` — it will fail silently or hang
60
+ - Use `--headed` only during local interactive debugging when you need to visually observe the test
61
+ - Fix root causes rather than extending timeouts
62
+
63
+ ### 7. Summarize
64
+ Return:
65
+ 1. **What I changed** (bullets)
66
+ 2. **Test case IDs added** (list all new TC-IDs with brief description)
67
+ 3. **Why it's stable** (locator/wait strategy used)
68
+ 4. **How to run** (exact commands)
69
+ 5. **Notes / follow-ups** (optional)
70
+
71
+ ## Operating Principles (Non-Negotiable)
72
+
73
+ ### Test User Outcomes
74
+ Assert what the user sees — visible text, URL changes, enabled/disabled states — not internal state, CSS classes, or component hierarchy.
75
+
76
+ ### No Arbitrary Sleeps
77
+ Avoid `page.waitForTimeout()` except as a last-resort debug aid — remove before finishing.
78
+
79
+ ### Locator Strategy
80
+ | Priority | Method | When to Use |
81
+ |----------|--------|-------------|
82
+ | 1 | `getByRole('role', { name })` | Buttons, links, headings, form controls |
83
+ | 2 | `getByLabel()` | Form fields with visible labels |
84
+ | 3 | `getByPlaceholder()` | Inputs with placeholder text |
85
+ | 4 | `getByTestId()` | When data-testid is available |
86
+ | 5 | `getByText()` | Short, stable text (avoid marketing copy) |
87
+ | 6 | CSS selectors | Last resort, always scoped tightly |
88
+
89
+ Avoid `.first()` / `.nth()` unless a strong, documented reason exists — scope locators to a container instead.
90
+
91
+ **Within-file consistency:** Every test file must use ONE locator approach for equivalent elements. Do not mix `getByPlaceholder('Email')` in one test with `page.locator('input[placeholder="Email"]')` in another test within the same file. When adding tests to an existing file, match the locator style already in use. If the existing style is suboptimal, refactor all locators in the file together — do not create inconsistency.
92
+
93
+ ### Waiting Strategy
94
+ - Prefer Playwright auto-waits via actions and `expect(...)` assertions
95
+ - If explicit waiting needed, wait for meaningful state: visibility, enabled, URL, specific network response, spinner gone
96
+
97
+ ### Test Case IDs
98
+ - Every test MUST have a unique TC-ID: `TC-<FEATURE>-<NUMBER>`
99
+ - Include in test title: `test('TC-LOGIN-001: User can log in with valid credentials', ...)`
100
+ - Sequential within feature area, never reused
101
+ - When adding to existing file, check existing IDs and continue the sequence
102
+
103
+ ### POM + Fixtures
104
+ - If the project has a `pages/` directory or BasePage class, ALL new tests MUST use Page Objects for interactions
105
+ - Page Objects contain HOW (locators + interactions)
106
+ - Tests contain WHAT (behavior/outcome to verify)
107
+ - Keep page objects thin and composable
108
+ - If the boilerplate shipped a BasePage that no tests reference, either extend it for your feature or flag it for removal — do not leave dead infrastructure
109
+
110
+ ### Determinism and Isolation
111
+ - Tests must not depend on execution order
112
+ - Use unique test data per test or suite
113
+ - **Parallel-safe mutations:** When `fullyParallel: true` is configured, tests run concurrently across workers. A test that creates a record (e.g., a ticket) and then asserts it appears in a list WILL race with other tests creating records. Solutions: (a) assert on the specific record you created (filter/search by the unique ID from your API setup), not on list position or count; (b) use `test.describe.serial` for flows that genuinely require sequence (create-then-verify); (c) scope list assertions with `.filter({ hasText: uniqueIdentifier })` to avoid seeing other workers' data.
114
+
115
+ ### Assertions
116
+ - Use Playwright `expect` matchers (auto-retry, better error messages)
117
+ - Avoid `isVisible()` + `expect(true)` pattern
118
+
119
+ ### Configuration Hygiene
120
+ - Use `baseURL` and relative navigation (`page.goto('/')`)
121
+ - Avoid hardcoded domains/URLs in tests
122
+ - Configure `trace: 'on-first-retry'`, `screenshot: 'only-on-failure'`, `video: 'on-first-retry'` for CI debugging
123
+ - Set `retries: process.env.CI ? 2 : 0` — retries in CI only
124
+ - View traces with `npx playwright show-trace trace.zip` to time-travel through failures
125
+ - If `tsconfig.json` defines path aliases (e.g., `@pages/*`, `@fixtures/*`, `@utils/*`), use them in imports instead of relative paths. Check tsconfig paths before writing any import statement.
126
+
127
+ ### Authentication Setup
128
+ Use `storageState` for most projects (log in once in global setup, reuse across tests).
129
+ For parallel workers needing separate accounts, use worker-scoped fixtures.
130
+ For multi-role tests (admin + user), create separate browser contexts.
131
+ Per-test login is only for testing the login flow itself.
132
+ Never hardcode tokens — use environment variables or `.env.test`.
133
+
134
+ See [references/auth-patterns.md](references/auth-patterns.md) for full patterns with code examples.
135
+
136
+ ### API-Driven Test Setup and Teardown
137
+ Use API calls (not UI clicks) to seed test data — 10-50x faster and more reliable.
138
+ Use UI setup only when the creation flow IS the test. Tests that create persistent data
139
+ MUST clean up: use `afterEach` API deletion, fixture-with-cleanup, or bulk `globalTeardown`.
140
+ If no cleanup endpoint exists, document the gap with a TODO.
141
+
142
+ See [references/api-setup-teardown.md](references/api-setup-teardown.md) for full patterns with code examples.
143
+
144
+ ### Network Interception and Error Paths
145
+ Use `page.route()` to mock server errors, patch responses, assert backend calls, or block
146
+ heavy resources. Every feature needs error path tests: server error (500), network timeout,
147
+ and empty state at minimum.
148
+
149
+ See [references/network-interception.md](references/network-interception.md) for full patterns with code examples.
150
+
151
+ ### Custom Fixtures (test.extend)
152
+
153
+ Use `test.extend` to create reusable test setup without duplicating code:
154
+
155
+ ```typescript
156
+ // fixtures/index.ts
157
+ import { test as base, Page } from '@playwright/test';
158
+ import { LoginPage } from '../pages/LoginPage';
159
+
160
+ export const test = base.extend<{
161
+ loginPage: LoginPage;
162
+ authenticatedPage: Page;
163
+ }>({
164
+ loginPage: async ({ page }, use) => {
165
+ await use(new LoginPage(page));
166
+ },
167
+ authenticatedPage: async ({ browser }, use) => {
168
+ const context = await browser.newContext({
169
+ storageState: 'tests/.auth/user.json'
170
+ });
171
+ const page = await context.newPage();
172
+ await use(page);
173
+ await context.close();
174
+ },
175
+ });
176
+ export { expect } from '@playwright/test';
177
+ ```
178
+
179
+ Import `test` from your fixtures file, not from `@playwright/test`, in test files that need custom fixtures.
180
+
181
+ ### Mapping Tables
182
+ When converting journey specs or exploration results to code, consult the mapping tables
183
+ for standard translations of scopes, actions, assertions, and target kinds to Playwright API calls.
184
+ For low-confidence journey steps (<0.7), add extra assertions and include fallback locators as comments.
185
+
186
+ See [references/mapping-tables.md](references/mapping-tables.md) for the full tables.
187
+
188
+ ## Test Template
189
+
190
+ ```typescript
191
+ // If the project has custom fixtures (fixtures/index.ts), import from there:
192
+ // import { test, expect } from '@fixtures/index';
193
+ // Otherwise, use the default:
194
+ import { test, expect } from '@playwright/test';
195
+
196
+ test('TC-FEATURE-001: Description of test case', async ({ page }) => {
197
+ // Arrange
198
+ await page.goto('/feature-path');
199
+
200
+ // Act
201
+ await page.getByRole('button', { name: /submit/i }).click();
202
+
203
+ // Assert
204
+ await expect(page.getByText(/success/i)).toBeVisible();
205
+ });
206
+ ```
207
+
208
+ Always check for a project fixtures file before using the default import. If custom fixtures exist, you MUST import from them to get access to page objects and custom setup.
209
+
210
+ ## Anti-Patterns (Quick Reference)
211
+ 1. Raw CSS selectors — use semantic locators
212
+ 2. `waitForTimeout()` — use proper assertions/waits
213
+ 3. Fragile `.nth()` / `.first()` — scope to container
214
+ 4. Exact long text matches — use regex with key words
215
+ 5. Unscoped locators — scope to container
216
+ 6. Login via UI in every test — use storageState
217
+ 7. UI clicks for test data setup — use API
218
+ 8. No error path tests — add failure scenarios
219
+ 9. Hardcoded test data — use API setup + dynamic values
220
+ 10. Tests depending on execution order
221
+ 11. `expect(await el.isVisible()).toBe(true)` — use `await expect(el).toBeVisible()`
222
+ 12. `{ force: true }` — diagnose root cause instead
223
+ 13. `networkidle` as default wait — use specific response waits
224
+ 14. CSS utility class selectors (Tailwind/Bootstrap)
225
+ 15. Asserting exact server-computed values — use patterns or seed data
226
+
227
+ See [references/anti-patterns.md](references/anti-patterns.md) for detailed explanations and fix strategies.
@@ -0,0 +1,3 @@
1
+ frontmatter:
2
+ argument-hint: "<test description or path to test case spec file>"
3
+ user-invocable: true
@@ -0,0 +1,10 @@
1
+ interface:
2
+ display_name: "Implement Playwright Tests"
3
+ short_description: "Implement or refactor executable Playwright tests from a scenario or spec"
4
+ default_prompt: "Write or update Playwright E2E tests for this scenario or TC-ID spec."
5
+
6
+ dependencies:
7
+ tools:
8
+ - type: "mcp"
9
+ value: "agent-web-interface"
10
+ description: "Browser automation MCP used when selectors or live behavior need verification"
@@ -0,0 +1,88 @@
1
+ # Anti-Patterns: Detailed Explanations and Fix Strategies
2
+
3
+ ## 1. Raw CSS selectors
4
+ Use semantic locators (`getByRole`, `getByLabel`, `getByTestId`) instead of CSS selectors. CSS selectors are brittle and break when markup changes.
5
+
6
+ **Why:** A class rename, component refactor, or CSS-in-JS migration breaks every CSS-based selector overnight. Semantic locators survive these changes because they target accessible roles and labels, not implementation details.
7
+
8
+ **Fix:** Replace `page.locator('.submit-btn')` with `page.getByRole('button', { name: /submit/i })`. Follow the locator strategy hierarchy in the main skill.
9
+
10
+ ## 2. `waitForTimeout()`
11
+ Use proper assertions and event-driven waits. `waitForTimeout()` adds arbitrary delays that slow tests and mask timing issues.
12
+
13
+ **Why:** A 2-second sleep that works locally may be too short in CI (slower machines) or too long everywhere (wasting time). It also hides the real question: "what am I actually waiting for?"
14
+
15
+ **Fix:** Replace with `waitForResponse` for API-dependent UI, `expect(el).toBeVisible()` for element appearance, or `expect(spinner).toBeHidden()` for loading states.
16
+
17
+ ## 3. Fragile `.nth()` / `.first()`
18
+ Scope locators to a container instead of relying on position. If unavoidable, add a comment explaining why.
19
+
20
+ **Why:** Element order can change when the page adds a banner, reorders a list, or renders asynchronously. `.first()` silently picks the wrong element, causing false passes or mysterious failures.
21
+
22
+ **Fix:** Use `.filter({ hasText: 'Specific Item' })` or scope to a container: `page.locator('[data-testid="cart"]').getByRole('button')`.
23
+
24
+ ## 4. Exact long text matches
25
+ Use regex with key words instead of matching entire strings. Marketing copy and UI text change frequently.
26
+
27
+ **Why:** A copywriter changes "Sign up for free today!" to "Create your free account" and every test matching the full string breaks, even though the feature works fine.
28
+
29
+ **Fix:** Use `page.getByText(/sign up/i)` or `page.getByRole('button', { name: /free/i })` — match the stable semantic keywords.
30
+
31
+ ## 5. Unscoped locators
32
+ Scope locators to `main`, `nav`, `dialog`, or other containers when possible. Global locators match unintended elements.
33
+
34
+ **Why:** A page-wide `getByRole('button', { name: /submit/i })` may match a submit button in the header, footer, or a hidden modal — not just the one in your form. This causes the wrong click or ambiguous locator errors.
35
+
36
+ **Fix:** Scope first: `page.locator('main').getByRole('button', { name: /submit/i })` or `page.locator('[role="dialog"]').getByRole('button')`.
37
+
38
+ ## 6. Login via UI in every test
39
+ Use `storageState` or API-based auth setup. UI login in every test wastes time and creates coupling to the login flow.
40
+
41
+ **Why:** If every test clicks through the login form, a single login page change breaks the entire suite. It also adds 3-10 seconds per test — multiplied across hundreds of tests, this becomes significant CI time.
42
+
43
+ **Fix:** Log in once in `globalSetup`, save `storageState` to a JSON file, and reuse it. See `references/auth-patterns.md` for the four auth strategies.
44
+
45
+ ## 7. UI clicks to set up test data
46
+ Use API requests for data seeding. UI setup is 10-50x slower and more fragile than API calls.
47
+
48
+ **Why:** Creating a product via the admin UI takes 15+ seconds and 10+ actions. An API call takes 200ms and one line. UI setup also couples your test to two features instead of one — if the admin form breaks, your unrelated cart test fails too.
49
+
50
+ **Fix:** Use the `request` fixture: `await request.post('/api/products', { data: { ... } })`. See `references/api-setup-teardown.md`.
51
+
52
+ ## 8. No error path tests
53
+ Every feature needs at least one failure scenario test. Cover server errors (500), network timeouts, and empty states.
54
+
55
+ **Why:** Happy-path-only suites give false confidence. The app may crash on a 500, show a blank screen on empty data, or hang on a timeout — none of which are caught without explicit error path tests.
56
+
57
+ **Fix:** Use `page.route()` to mock failures. At minimum: one 500 response, one timeout (`route.abort('timedout')`), one empty state (`route.fulfill({ json: { items: [] } })`). See `references/network-interception.md`.
58
+
59
+ ## 9. Hardcoded test data
60
+ NEVER embed real entity IDs (`'ACC-SUB-2026-00025'`), real user names (`'Anas Client 73'`), real monetary amounts, or environment-specific strings in test code. Instead:
61
+ - Create data via API in `beforeEach` and capture the returned ID
62
+ - Use `Date.now()` or `crypto.randomUUID()` suffixes for uniqueness
63
+ - Read values from `process.env` or a test data module
64
+ - For read-only assertions on existing data, use pattern matchers (`expect(text).toMatch(/ACC-SUB-\d{4}-\d{5}/)`) instead of exact values
65
+
66
+ If you find yourself typing a specific ID or name into test code, STOP — that is a hardcoded value.
67
+
68
+ ## 10. Tests depending on execution order
69
+ Each test must be independently runnable. Never rely on state left by a previous test.
70
+
71
+ ## 11. `expect(await el.isVisible()).toBe(true)`
72
+ Use `await expect(el).toBeVisible()` instead. The Playwright assertion auto-retries, while the manual pattern checks once and fails on timing.
73
+
74
+ ## 12. `{ force: true }` on clicks/checks
75
+ Hides real interaction problems (overlapping elements, not scrolled into view, disabled state). Diagnose the root cause instead: use `scrollIntoViewIfNeeded()`, wait for overlay to disappear, or wait for element to be enabled. Only acceptable when interacting with a custom widget that Playwright cannot natively trigger (document why in a comment).
76
+
77
+ ## 13. `waitForLoadState('networkidle')` as default strategy
78
+ `networkidle` waits for 500ms of no network activity, which breaks on long-polling, WebSockets, analytics beacons, or chat widgets. Use it ONLY for initial full-page loads where no streaming/polling exists. For post-action waits, use `waitForResponse` targeting the specific API call, or assert directly on the resulting UI state (Playwright auto-retries).
79
+
80
+ ## 14. CSS utility class selectors (Tailwind, Bootstrap, etc.)
81
+ `button.rounded-l-lg`, `.flex.items-center`, `.bg-primary` are styling concerns that change during refactors. Treat ALL utility framework classes as volatile — never use them as selectors. If no semantic locator works, request a `data-testid` from the dev team.
82
+
83
+ ## 15. Asserting exact server-computed values
84
+ `expect(revenue).toHaveText('12450')` will break when data changes. For dashboard counters, totals, and aggregates:
85
+ - Assert the element exists and contains a number (`toMatch(/\$[\d,]+/)`)
86
+ - Assert non-zero or within a range
87
+ - Assert format correctness (`/^\d{1,3}(,\d{3})*$/`)
88
+ - If exact value matters, seed the data via API first so you control the expected value
@@ -0,0 +1,83 @@
1
+ # API-Driven Test Setup and Teardown
2
+
3
+ ## API-Driven Test Setup
4
+
5
+ Use API calls to set up test data instead of clicking through UI. This is 10-50x faster and more reliable.
6
+
7
+ **When to use API setup:** Creating test users, products, orders, seed data. Setting feature flags. Resetting state between tests.
8
+
9
+ **When to use UI setup:** Only when the creation flow IS the test being verified.
10
+
11
+ ```typescript
12
+ test('TC-CART-001: User sees items in cart', async ({ page, request }) => {
13
+ // Arrange: seed data via API (fast, deterministic)
14
+ await request.post('/api/cart/items', {
15
+ data: { productId: 'SKU-123', quantity: 2 }
16
+ });
17
+
18
+ // Act: navigate to verify UI
19
+ await page.goto('/cart');
20
+
21
+ // Assert
22
+ await expect(page.getByRole('listitem')).toHaveCount(2);
23
+ });
24
+ ```
25
+
26
+ **Reusable API fixture pattern:**
27
+ ```typescript
28
+ export const test = base.extend<{ apiClient: APIRequestContext }>({
29
+ apiClient: async ({ playwright }, use) => {
30
+ const ctx = await playwright.request.newContext({
31
+ baseURL: process.env.API_BASE_URL,
32
+ extraHTTPHeaders: { Authorization: `Bearer ${process.env.API_TOKEN}` },
33
+ });
34
+ await use(ctx);
35
+ await ctx.dispose();
36
+ },
37
+ });
38
+ ```
39
+
40
+ ## Test Data Teardown
41
+
42
+ Tests that create persistent data (database records, uploaded files, user accounts) MUST clean up after themselves. Leaked test data accumulates across runs and causes false positives/negatives in other tests (pagination counts drift, filter results change, list assertions break).
43
+
44
+ ### Strategy 1: API teardown in afterEach (Recommended)
45
+
46
+ ```typescript
47
+ let createdTicketId: string;
48
+
49
+ test.beforeEach(async ({ request }) => {
50
+ const resp = await request.post('/api/tickets', {
51
+ data: { title: `Test ${Date.now()}` }
52
+ });
53
+ createdTicketId = (await resp.json()).id;
54
+ });
55
+
56
+ test.afterEach(async ({ request }) => {
57
+ if (createdTicketId) {
58
+ await request.delete(`/api/tickets/${createdTicketId}`);
59
+ }
60
+ });
61
+ ```
62
+
63
+ ### Strategy 2: Fixture with automatic cleanup
64
+
65
+ ```typescript
66
+ export const test = base.extend<{ testTicket: { id: string; title: string } }>({
67
+ testTicket: async ({ request }, use) => {
68
+ const resp = await request.post('/api/tickets', {
69
+ data: { title: `Test ${Date.now()}` }
70
+ });
71
+ const ticket = await resp.json();
72
+ await use(ticket);
73
+ // cleanup runs automatically when test finishes
74
+ await request.delete(`/api/tickets/${ticket.id}`);
75
+ },
76
+ });
77
+ ```
78
+
79
+ ### Strategy 3: Bulk cleanup in globalTeardown
80
+
81
+ For environments where individual deletion is impractical, tag test data (e.g., `title LIKE 'Test %'`) and delete in batch during `globalTeardown.ts`.
82
+
83
+ If the cleanup API endpoint is unknown, do not invent one. Leave a clear `TODO` with the missing endpoint details, document the cleanup gap in the test file or tracker, and prefer fixture-scoped or environment reset strategies that you can verify. If cleanup is genuinely impossible (no API, no database access), document this as a known limitation in the test file header AND add an `afterEach` that logs a warning.
@@ -0,0 +1,63 @@
1
+ # Authentication Setup Patterns
2
+
3
+ Choose the right auth strategy based on the project's needs.
4
+
5
+ ## Strategy 1: storageState (Recommended for most projects)
6
+
7
+ Log in once in global setup, save cookies/localStorage to a JSON file, and reuse across all tests:
8
+
9
+ ```typescript
10
+ // global-setup.ts
11
+ import { chromium, FullConfig } from '@playwright/test';
12
+
13
+ async function globalSetup(config: FullConfig) {
14
+ const browser = await chromium.launch();
15
+ const page = await browser.newPage();
16
+ await page.goto('/login');
17
+ await page.getByLabel(/email/i).fill(process.env.TEST_USER_EMAIL!);
18
+ await page.getByLabel(/password/i).fill(process.env.TEST_USER_PASSWORD!);
19
+ await page.getByRole('button', { name: /sign in/i }).click();
20
+ await page.waitForURL('/dashboard');
21
+ await page.context().storageState({ path: 'tests/.auth/user.json' });
22
+ await browser.close();
23
+ }
24
+ export default globalSetup;
25
+ ```
26
+
27
+ Reference in config: `use: { storageState: 'tests/.auth/user.json' }`
28
+
29
+ ## Strategy 2: Worker-scoped fixture (for parallel workers needing separate accounts)
30
+
31
+ ```typescript
32
+ export const test = base.extend<{}, { workerStorageState: string }>({
33
+ storageState: ({ workerStorageState }, use) => use(workerStorageState),
34
+ workerStorageState: [async ({ browser }, use, testInfo) => {
35
+ const page = await browser.newPage({ storageState: undefined });
36
+ // Login with worker-specific account...
37
+ const path = `tests/.auth/worker-${testInfo.parallelIndex}.json`;
38
+ await page.context().storageState({ path });
39
+ await use(path);
40
+ await page.close();
41
+ }, { scope: 'worker' }],
42
+ });
43
+ ```
44
+
45
+ ## Strategy 3: Multi-role testing (admin + user in same test)
46
+
47
+ ```typescript
48
+ test('TC-ADMIN-001: Admin sees user profile', async ({ browser }) => {
49
+ const adminContext = await browser.newContext({ storageState: 'tests/.auth/admin.json' });
50
+ const userContext = await browser.newContext({ storageState: 'tests/.auth/user.json' });
51
+ const adminPage = await adminContext.newPage();
52
+ const userPage = await userContext.newPage();
53
+ // Interact with both pages...
54
+ await adminContext.close();
55
+ await userContext.close();
56
+ });
57
+ ```
58
+
59
+ ## Strategy 4: Per-test login
60
+
61
+ Only when testing login itself or permission-specific scenarios.
62
+
63
+ Never hardcode tokens. Use environment variables or `.env.test`.
@@ -0,0 +1,56 @@
1
+ # Mapping Tables
2
+
3
+ Standard translations for converting journey specs and exploration results to Playwright API calls.
4
+
5
+ ## Scope-to-Locator
6
+
7
+ | Journey Scope | Playwright Scoping |
8
+ |---------------|-------------------|
9
+ | `page` | No scoping needed |
10
+ | `header` | `page.locator('header')` |
11
+ | `main` | `page.locator('main')` |
12
+ | `nav` | `page.locator('nav')` |
13
+ | `dialog` | `page.locator('[role="dialog"]')` |
14
+
15
+ ## Action-to-Playwright
16
+
17
+ | Journey Action | Playwright Code |
18
+ |----------------|-----------------|
19
+ | `goto` | `await page.goto(url)` |
20
+ | `click` | `await locator.click()` |
21
+ | `fill` | `await locator.fill(value)` |
22
+ | `select` | `await locator.selectOption(value)` |
23
+ | `assert` | `await expect(locator).toBeVisible()` |
24
+
25
+ ## Assertion Mapping
26
+
27
+ | Observed Effect | Playwright Assertion |
28
+ |----------------|---------------------|
29
+ | `url changed to /cart` | `await expect(page).toHaveURL(/cart/)` |
30
+ | `text 'Added' visible` | `await expect(page.getByText(/added/i)).toBeVisible()` |
31
+ | `radio 256GB checked` | `await expect(locator).toBeChecked()` |
32
+ | `button now enabled` | `await expect(locator).toBeEnabled()` |
33
+
34
+ ## Target Kind to Locator
35
+
36
+ | Target Kind | Value Pattern | Playwright Locator |
37
+ |-------------|--------------|-------------------|
38
+ | `role` | `button name~Add to Bag` | `getByRole('button', { name: /add to bag/i })` |
39
+ | `role` | `radio name~256GB` | `getByRole('radio', { name: /256gb/i })` |
40
+ | `label` | `Email address` | `getByLabel(/email address/i)` |
41
+ | `testid` | `checkout-button` | `getByTestId('checkout-button')` |
42
+
43
+ ## Low Confidence Handling (<0.7)
44
+
45
+ When journey step confidence is low:
46
+ 1. Add extra assertions to verify state
47
+ 2. Include fallback locators as comments
48
+ 3. Consider retry logic for flaky interactions
49
+
50
+ ```typescript
51
+ // Primary locator
52
+ const storageRadio = page.getByRole('radio', { name: /256gb/i });
53
+ // Fallback: page.getByLabel(/256gb/i)
54
+ await storageRadio.click();
55
+ await expect(storageRadio).toBeChecked({ timeout: 5000 });
56
+ ```
@@ -0,0 +1,56 @@
1
+ # Network Interception and Error Path Testing
2
+
3
+ ## Network Interception
4
+
5
+ Use `page.route()` to intercept and mock network requests for deterministic error testing.
6
+
7
+ **Mock server errors:**
8
+ ```typescript
9
+ await page.route('**/api/checkout', route =>
10
+ route.fulfill({ status: 500, body: JSON.stringify({ error: 'Payment declined' }) })
11
+ );
12
+ ```
13
+
14
+ **Patch real responses (modify, don't replace):**
15
+ ```typescript
16
+ await page.route('**/api/products', async route => {
17
+ const response = await route.fetch();
18
+ const json = await response.json();
19
+ json.results = json.results.slice(0, 1); // reduce to 1 item
20
+ await route.fulfill({ response, json });
21
+ });
22
+ ```
23
+
24
+ **Assert backend was called:**
25
+ ```typescript
26
+ const [response] = await Promise.all([
27
+ page.waitForResponse(resp =>
28
+ resp.url().includes('/api/order') && resp.status() === 201
29
+ ),
30
+ page.getByRole('button', { name: /place order/i }).click(),
31
+ ]);
32
+ expect(response.status()).toBe(201);
33
+ ```
34
+
35
+ **Block heavy resources to speed up tests:**
36
+ ```typescript
37
+ await page.route('**/*.{png,jpg,jpeg,gif,svg}', route => route.abort());
38
+ ```
39
+
40
+ ## Error Path Testing
41
+
42
+ Every feature needs error path tests. Use network interception (see above) to simulate failures. At minimum, every feature test suite should cover:
43
+
44
+ - **Server error** — `route.fulfill({ status: 500, ... })` — verify error UI appears
45
+ - **Network timeout** — `route.abort('timedout')` — verify retry option or error message
46
+ - **Empty state** — `route.fulfill({ status: 200, json: { items: [] } })` — verify empty state UI
47
+
48
+ ```typescript
49
+ test('TC-DASHBOARD-005: Shows empty state when no data', async ({ page }) => {
50
+ await page.route('**/api/items', route =>
51
+ route.fulfill({ status: 200, json: { items: [] } })
52
+ );
53
+ await page.goto('/dashboard');
54
+ await expect(page.getByText(/no items/i)).toBeVisible();
55
+ });
56
+ ```
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "e2e-test-builder",
3
+ "version": "2.0.9",
4
+ "description": "Full-pipeline Playwright E2E test generation \u2014 explores your live site via browser, detects existing test conventions, plans coverage gaps, produces reviewed test specs, writes production-grade test code with quality gates, and stabilizes flaky tests",
5
+ "author": {
6
+ "name": "Athenaflow"
7
+ },
8
+ "skills": "./skills/",
9
+ "interface": {
10
+ "displayName": "E2E Test Builder",
11
+ "shortDescription": "Full-pipeline Playwright E2E test generation with browser exploration and quality gates",
12
+ "developerName": "Athenaflow",
13
+ "category": "Testing"
14
+ }
15
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "@athenaflow/plugin-e2e-test-builder",
3
+ "version": "2.0.9",
4
+ "description": "Full-pipeline Playwright E2E test generation — explores your live site via browser, detects existing test conventions, plans coverage gaps, produces reviewed test specs, writes production-grade test code with quality gates, and stabilizes flaky tests",
5
+ "license": "MIT",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ }
9
+ }