specweave 0.23.16 → 0.24.0

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 (227) hide show
  1. package/.claude-plugin/marketplace.json +93 -38
  2. package/CLAUDE.md +159 -11
  3. package/dist/plugins/specweave-github/lib/github-spec-content-sync.d.ts.map +1 -1
  4. package/dist/plugins/specweave-github/lib/github-spec-content-sync.js +57 -0
  5. package/dist/plugins/specweave-github/lib/github-spec-content-sync.js.map +1 -1
  6. package/dist/src/cli/commands/sync-spec-content.js +3 -0
  7. package/dist/src/cli/commands/sync-spec-content.js.map +1 -1
  8. package/dist/src/cli/helpers/ado-area-path-mapper.d.ts +89 -0
  9. package/dist/src/cli/helpers/ado-area-path-mapper.d.ts.map +1 -0
  10. package/dist/src/cli/helpers/ado-area-path-mapper.js +213 -0
  11. package/dist/src/cli/helpers/ado-area-path-mapper.js.map +1 -0
  12. package/dist/src/cli/helpers/issue-tracker/ado-auto-discover.d.ts +29 -0
  13. package/dist/src/cli/helpers/issue-tracker/ado-auto-discover.d.ts.map +1 -0
  14. package/dist/src/cli/helpers/issue-tracker/ado-auto-discover.js +109 -0
  15. package/dist/src/cli/helpers/issue-tracker/ado-auto-discover.js.map +1 -0
  16. package/dist/src/cli/helpers/issue-tracker/ado.d.ts +1 -0
  17. package/dist/src/cli/helpers/issue-tracker/ado.d.ts.map +1 -1
  18. package/dist/src/cli/helpers/issue-tracker/ado.js +2 -0
  19. package/dist/src/cli/helpers/issue-tracker/ado.js.map +1 -1
  20. package/dist/src/cli/helpers/smart-filter.d.ts +83 -0
  21. package/dist/src/cli/helpers/smart-filter.d.ts.map +1 -0
  22. package/dist/src/cli/helpers/smart-filter.js +265 -0
  23. package/dist/src/cli/helpers/smart-filter.js.map +1 -0
  24. package/dist/src/core/progress/progress-tracker.d.ts +4 -1
  25. package/dist/src/core/progress/progress-tracker.d.ts.map +1 -1
  26. package/dist/src/core/progress/progress-tracker.js +33 -4
  27. package/dist/src/core/progress/progress-tracker.js.map +1 -1
  28. package/dist/src/core/qa/quality-gate-decider.d.ts +1 -1
  29. package/dist/src/core/qa/quality-gate-decider.js +2 -2
  30. package/dist/src/core/qa/quality-gate-decider.js.map +1 -1
  31. package/dist/src/core/qa/risk-calculator.d.ts +2 -2
  32. package/dist/src/core/qa/risk-calculator.js +2 -2
  33. package/dist/src/core/spec-content-sync.d.ts +1 -1
  34. package/dist/src/core/spec-content-sync.d.ts.map +1 -1
  35. package/dist/src/core/validators/ac-presence-validator.d.ts +56 -0
  36. package/dist/src/core/validators/ac-presence-validator.d.ts.map +1 -0
  37. package/dist/src/core/validators/ac-presence-validator.js +149 -0
  38. package/dist/src/core/validators/ac-presence-validator.js.map +1 -0
  39. package/dist/src/integrations/ado/ado-dependency-loader.d.ts +1 -1
  40. package/dist/src/integrations/ado/ado-dependency-loader.d.ts.map +1 -1
  41. package/dist/src/integrations/ado/ado-dependency-loader.js +39 -7
  42. package/dist/src/integrations/ado/ado-dependency-loader.js.map +1 -1
  43. package/dist/src/integrations/ado/area-path-mapper.d.ts +137 -0
  44. package/dist/src/integrations/ado/area-path-mapper.d.ts.map +1 -0
  45. package/dist/src/integrations/ado/area-path-mapper.js +267 -0
  46. package/dist/src/integrations/ado/area-path-mapper.js.map +1 -0
  47. package/dist/src/integrations/jira/filter-processor.d.ts +126 -0
  48. package/dist/src/integrations/jira/filter-processor.d.ts.map +1 -0
  49. package/dist/src/integrations/jira/filter-processor.js +207 -0
  50. package/dist/src/integrations/jira/filter-processor.js.map +1 -0
  51. package/dist/src/integrations/jira/jira-client.d.ts +13 -0
  52. package/dist/src/integrations/jira/jira-client.d.ts.map +1 -1
  53. package/dist/src/integrations/jira/jira-client.js +33 -0
  54. package/dist/src/integrations/jira/jira-client.js.map +1 -1
  55. package/dist/src/utils/ac-embedder.d.ts +63 -0
  56. package/dist/src/utils/ac-embedder.d.ts.map +1 -0
  57. package/dist/src/utils/ac-embedder.js +217 -0
  58. package/dist/src/utils/ac-embedder.js.map +1 -0
  59. package/dist/src/utils/env-manager.d.ts +86 -0
  60. package/dist/src/utils/env-manager.d.ts.map +1 -0
  61. package/dist/src/utils/env-manager.js +188 -0
  62. package/dist/src/utils/env-manager.js.map +1 -0
  63. package/package.json +1 -1
  64. package/plugins/specweave/.claude-plugin/plugin.json +1 -1
  65. package/plugins/specweave/agents/AGENTS-INDEX.md +1 -1
  66. package/plugins/specweave/agents/increment-quality-judge-v2/AGENT.md +9 -9
  67. package/plugins/specweave/commands/specweave-do.md +37 -0
  68. package/plugins/specweave/commands/specweave-done.md +159 -0
  69. package/plugins/specweave/commands/specweave-embed-acs.md +446 -0
  70. package/plugins/specweave/commands/specweave-next.md +148 -3
  71. package/plugins/specweave/commands/specweave-qa.md +2 -2
  72. package/plugins/specweave/hooks/lib/migrate-increment-work.sh +1 -1
  73. package/plugins/specweave/hooks/lib/migrate-increment-work.sh.bak +245 -0
  74. package/plugins/specweave/hooks/lib/sync-spec-content.sh +2 -2
  75. package/plugins/specweave/hooks/lib/sync-spec-content.sh.bak +149 -0
  76. package/plugins/specweave/hooks/lib/update-status-line.sh +34 -4
  77. package/plugins/specweave/hooks/lib/validate-spec-status.sh +1 -1
  78. package/plugins/specweave/hooks/lib/validate-spec-status.sh.bak +163 -0
  79. package/plugins/specweave/hooks/post-first-increment.sh +1 -1
  80. package/plugins/specweave/hooks/post-first-increment.sh.bak +61 -0
  81. package/plugins/specweave/hooks/post-spec-update.sh +1 -1
  82. package/plugins/specweave/hooks/post-spec-update.sh.bak +158 -0
  83. package/plugins/specweave/hooks/post-user-story-complete.sh +1 -1
  84. package/plugins/specweave/hooks/post-user-story-complete.sh.bak +179 -0
  85. package/plugins/specweave/hooks/pre-command-deduplication.sh +1 -1
  86. package/plugins/specweave/hooks/pre-command-deduplication.sh.bak +83 -0
  87. package/plugins/specweave/hooks/pre-increment-start.sh +168 -0
  88. package/plugins/specweave/hooks/user-prompt-submit.sh +1 -1
  89. package/plugins/specweave/hooks/user-prompt-submit.sh.bak +386 -0
  90. package/plugins/specweave/skills/SKILLS-INDEX.md +1 -1
  91. package/plugins/specweave/skills/specweave-framework/SKILL.md +1 -1
  92. package/plugins/specweave-ado/.claude-plugin/plugin.json +1 -1
  93. package/plugins/specweave-ado/agents/ado-manager/AGENT.md +23 -0
  94. package/plugins/specweave-ado/agents/ado-multi-project-mapper/AGENT.md +23 -0
  95. package/plugins/specweave-ado/agents/ado-sync-judge/AGENT.md +23 -0
  96. package/plugins/specweave-ado/commands/specweave-ado-import-projects.md +331 -0
  97. package/plugins/specweave-alternatives/.claude-plugin/plugin.json +10 -0
  98. package/plugins/specweave-alternatives/commands/alternatives-analyze.md +336 -0
  99. package/plugins/specweave-alternatives/skills/architecture-alternatives/SKILL.md +651 -0
  100. package/plugins/specweave-alternatives/skills/bmad-method/SKILL.md +420 -0
  101. package/plugins/specweave-alternatives/skills/spec-kit-expert/SKILL.md +487 -0
  102. package/plugins/specweave-backend/agents/database-optimizer/AGENT.md +23 -0
  103. package/plugins/specweave-backend/commands/api-scaffold.md +80 -0
  104. package/plugins/specweave-backend/commands/crud-generate.md +109 -0
  105. package/plugins/specweave-backend/commands/migration-generate.md +139 -0
  106. package/plugins/specweave-confluent/agents/confluent-architect/AGENT.md +23 -0
  107. package/plugins/specweave-confluent/commands/connector-deploy.md +154 -0
  108. package/plugins/specweave-confluent/commands/ksqldb-query.md +179 -0
  109. package/plugins/specweave-confluent/commands/schema-register.md +123 -0
  110. package/plugins/specweave-core/.claude-plugin/plugin.json +21 -0
  111. package/plugins/specweave-core/commands/architecture-review.md +288 -0
  112. package/plugins/specweave-core/commands/code-review.md +213 -0
  113. package/plugins/specweave-core/commands/refactor-plan.md +249 -0
  114. package/plugins/specweave-core/skills/code-quality/SKILL.md +157 -0
  115. package/plugins/specweave-core/skills/design-patterns/SKILL.md +244 -0
  116. package/plugins/specweave-core/skills/software-architecture/SKILL.md +83 -0
  117. package/plugins/specweave-cost-optimizer/.claude-plugin/plugin.json +22 -0
  118. package/plugins/specweave-cost-optimizer/commands/cost-analyze.md +360 -0
  119. package/plugins/specweave-cost-optimizer/commands/cost-optimize.md +480 -0
  120. package/plugins/specweave-cost-optimizer/skills/aws-cost-expert/SKILL.md +416 -0
  121. package/plugins/specweave-cost-optimizer/skills/cloud-pricing/SKILL.md +325 -0
  122. package/plugins/specweave-cost-optimizer/skills/cost-optimization/SKILL.md +337 -0
  123. package/plugins/specweave-diagrams/.claude-plugin/plugin.json +1 -1
  124. package/plugins/specweave-diagrams/agents/diagrams-architect/AGENT.md +23 -0
  125. package/plugins/specweave-diagrams/commands/diagrams-generate.md +168 -0
  126. package/plugins/specweave-docs/.claude-plugin/plugin.json +10 -0
  127. package/plugins/specweave-docs/commands/docs-generate.md +441 -0
  128. package/plugins/specweave-docs/commands/docs-init.md +334 -0
  129. package/plugins/specweave-docs/skills/docusaurus/SKILL.md +581 -0
  130. package/plugins/specweave-docs/skills/spec-driven-brainstorming/SKILL.md +689 -0
  131. package/plugins/specweave-docs/skills/technical-writing/SKILL.md +1039 -0
  132. package/plugins/specweave-docs-preview/.claude-plugin/plugin.json +1 -1
  133. package/plugins/specweave-figma/.claude-plugin/plugin.json +23 -0
  134. package/plugins/specweave-figma/commands/figma-import.md +690 -0
  135. package/plugins/specweave-figma/commands/figma-to-react.md +834 -0
  136. package/plugins/specweave-figma/commands/figma-tokens.md +815 -0
  137. package/plugins/specweave-frontend/.claude-plugin/plugin.json +21 -0
  138. package/plugins/specweave-frontend/agents/frontend-architect/AGENT.md +387 -0
  139. package/plugins/specweave-frontend/agents/frontend-architect/README.md +385 -0
  140. package/plugins/specweave-frontend/agents/frontend-architect/examples.md +590 -0
  141. package/plugins/specweave-frontend/agents/frontend-architect/templates/component-template.tsx +152 -0
  142. package/plugins/specweave-frontend/agents/frontend-architect/templates/hook-template.ts +311 -0
  143. package/plugins/specweave-frontend/agents/frontend-architect/templates/page-template.tsx +228 -0
  144. package/plugins/specweave-frontend/commands/component-generate.md +510 -0
  145. package/plugins/specweave-frontend/commands/design-system-init.md +494 -0
  146. package/plugins/specweave-frontend/commands/frontend-scaffold.md +207 -0
  147. package/plugins/specweave-frontend/commands/nextjs-setup.md +396 -0
  148. package/plugins/specweave-frontend/skills/design-system-architect/SKILL.md +278 -0
  149. package/plugins/specweave-frontend/skills/frontend/SKILL.md +420 -0
  150. package/plugins/specweave-frontend/skills/nextjs/SKILL.md +546 -0
  151. package/plugins/specweave-github/.claude-plugin/plugin.json +1 -1
  152. package/plugins/specweave-github/agents/github-manager/AGENT.md +23 -0
  153. package/plugins/specweave-github/agents/github-task-splitter/AGENT.md +25 -0
  154. package/plugins/specweave-github/agents/user-story-updater/AGENT.md +25 -0
  155. package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +194 -0
  156. package/plugins/specweave-github/lib/github-spec-content-sync.js +49 -0
  157. package/plugins/specweave-github/lib/github-spec-content-sync.ts +67 -0
  158. package/plugins/specweave-infrastructure/.claude-plugin/plugin.json +1 -1
  159. package/plugins/specweave-infrastructure/agents/devops/AGENT.md +26 -0
  160. package/plugins/specweave-infrastructure/agents/network-engineer/AGENT.md +26 -0
  161. package/plugins/specweave-infrastructure/agents/observability-engineer/AGENT.md +26 -0
  162. package/plugins/specweave-infrastructure/agents/performance-engineer/AGENT.md +26 -0
  163. package/plugins/specweave-infrastructure/agents/sre/AGENT.md +26 -0
  164. package/plugins/specweave-jira/.claude-plugin/plugin.json +1 -1
  165. package/plugins/specweave-jira/agents/jira-manager/AGENT.md +26 -0
  166. package/plugins/specweave-jira/commands/import-projects.js +183 -0
  167. package/plugins/specweave-jira/commands/import-projects.md +97 -0
  168. package/plugins/specweave-jira/commands/import-projects.ts +288 -0
  169. package/plugins/specweave-jira/commands/specweave-jira-import-projects.md +298 -0
  170. package/plugins/specweave-kafka/.claude-plugin/plugin.json +1 -1
  171. package/plugins/specweave-kafka/agents/kafka-architect/AGENT.md +26 -0
  172. package/plugins/specweave-kafka/agents/kafka-devops/AGENT.md +26 -0
  173. package/plugins/specweave-kafka/agents/kafka-observability/AGENT.md +26 -0
  174. package/plugins/specweave-kafka-streams/.claude-plugin/plugin.json +1 -1
  175. package/plugins/specweave-kubernetes/agents/kubernetes-architect/AGENT.md +26 -0
  176. package/plugins/specweave-kubernetes/commands/cluster-setup.md +262 -0
  177. package/plugins/specweave-kubernetes/commands/deployment-generate.md +242 -0
  178. package/plugins/specweave-kubernetes/commands/helm-scaffold.md +333 -0
  179. package/plugins/specweave-ml/.claude-plugin/plugin.json +3 -3
  180. package/plugins/specweave-ml/agents/data-scientist/AGENT.md +26 -0
  181. package/plugins/specweave-ml/agents/ml-engineer/AGENT.md +26 -0
  182. package/plugins/specweave-ml/agents/mlops-engineer/AGENT.md +26 -0
  183. package/plugins/specweave-mobile/agents/mobile-architect/AGENT.md +26 -0
  184. package/plugins/specweave-mobile/commands/app-scaffold.md +233 -0
  185. package/plugins/specweave-mobile/commands/build-config.md +256 -0
  186. package/plugins/specweave-mobile/commands/screen-generate.md +289 -0
  187. package/plugins/specweave-n8n/.claude-plugin/plugin.json +1 -1
  188. package/plugins/specweave-payments/agents/payment-integration/AGENT.md +26 -0
  189. package/plugins/specweave-plugin-dev/.claude-plugin/plugin.json +20 -0
  190. package/plugins/specweave-plugin-dev/commands/plugin-create.md +333 -0
  191. package/plugins/specweave-plugin-dev/commands/plugin-publish.md +339 -0
  192. package/plugins/specweave-plugin-dev/commands/plugin-test.md +293 -0
  193. package/plugins/specweave-plugin-dev/skills/claude-sdk/SKILL.md +162 -0
  194. package/plugins/specweave-plugin-dev/skills/marketplace-publishing/SKILL.md +263 -0
  195. package/plugins/specweave-plugin-dev/skills/plugin-development/SKILL.md +316 -0
  196. package/plugins/specweave-release/.claude-plugin/plugin.json +1 -1
  197. package/plugins/specweave-release/agents/release-manager/AGENT.md +27 -0
  198. package/plugins/specweave-release/commands/specweave-release-npm.md +110 -0
  199. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +168 -0
  200. package/plugins/specweave-testing/.claude-plugin/plugin.json +21 -0
  201. package/plugins/specweave-testing/agents/qa-engineer/AGENT.md +797 -0
  202. package/plugins/specweave-testing/agents/qa-engineer/README.md +443 -0
  203. package/plugins/specweave-testing/agents/qa-engineer/templates/playwright-e2e-test.ts +470 -0
  204. package/plugins/specweave-testing/agents/qa-engineer/templates/test-data-factory.ts +507 -0
  205. package/plugins/specweave-testing/agents/qa-engineer/templates/vitest-unit-test.ts +400 -0
  206. package/plugins/specweave-testing/agents/qa-engineer/test-strategies.md +726 -0
  207. package/plugins/specweave-testing/commands/e2e-setup.md +1081 -0
  208. package/plugins/specweave-testing/commands/test-coverage.md +979 -0
  209. package/plugins/specweave-testing/commands/test-generate.md +1156 -0
  210. package/plugins/specweave-testing/commands/test-init.md +409 -0
  211. package/plugins/specweave-testing/skills/e2e-playwright/SKILL.md +769 -0
  212. package/plugins/specweave-testing/skills/tdd-expert/SKILL.md +934 -0
  213. package/plugins/specweave-testing/skills/unit-testing-expert/SKILL.md +1011 -0
  214. package/plugins/specweave-tooling/.claude-plugin/plugin.json +22 -0
  215. package/plugins/specweave-tooling/commands/specweave-tooling-skill-create.md +691 -0
  216. package/plugins/specweave-tooling/commands/specweave-tooling-skill-package.md +751 -0
  217. package/plugins/specweave-tooling/commands/specweave-tooling-skill-validate.md +858 -0
  218. package/plugins/specweave-ui/.claude-plugin/plugin.json +10 -0
  219. package/plugins/specweave-ui/commands/ui-automate.md +199 -0
  220. package/plugins/specweave-ui/commands/ui-inspect.md +70 -0
  221. package/plugins/specweave-ui/skills/browser-automation/SKILL.md +314 -0
  222. package/plugins/specweave-ui/skills/ui-testing/SKILL.md +716 -0
  223. package/plugins/specweave-ui/skills/visual-regression/SKILL.md +728 -0
  224. package/plugins/specweave/commands/check-hooks.md +0 -257
  225. package/plugins/specweave/commands/specweave-archive-increments.md +0 -82
  226. package/plugins/specweave/skills/plugin-expert/SKILL.md +0 -340
  227. /package/plugins/specweave/{agents/code-reviewer.md → skills/code-reviewer/SKILL.md} +0 -0
@@ -0,0 +1,470 @@
1
+ /**
2
+ * Playwright E2E Test Template
3
+ *
4
+ * This template demonstrates best practices for writing end-to-end tests
5
+ * with Playwright for web applications.
6
+ *
7
+ * Features:
8
+ * - Page Object Model (POM)
9
+ * - Test fixtures
10
+ * - Cross-browser testing
11
+ * - Mobile emulation
12
+ * - API mocking
13
+ * - Visual regression
14
+ * - Accessibility testing
15
+ */
16
+
17
+ import { test, expect, Page } from '@playwright/test';
18
+ import AxeBuilder from '@axe-core/playwright';
19
+
20
+ // ============================================================================
21
+ // PAGE OBJECTS
22
+ // ============================================================================
23
+
24
+ /**
25
+ * Login Page Object
26
+ *
27
+ * Encapsulates all interactions with the login page
28
+ */
29
+ class LoginPage {
30
+ constructor(private page: Page) {}
31
+
32
+ // Locators
33
+ get emailInput() {
34
+ return this.page.getByLabel('Email');
35
+ }
36
+
37
+ get passwordInput() {
38
+ return this.page.getByLabel('Password');
39
+ }
40
+
41
+ get loginButton() {
42
+ return this.page.getByRole('button', { name: 'Login' });
43
+ }
44
+
45
+ get errorMessage() {
46
+ return this.page.getByRole('alert');
47
+ }
48
+
49
+ // Actions
50
+ async goto() {
51
+ await this.page.goto('/login');
52
+ }
53
+
54
+ async login(email: string, password: string) {
55
+ await this.emailInput.fill(email);
56
+ await this.passwordInput.fill(password);
57
+ await this.loginButton.click();
58
+ }
59
+
60
+ async expectError(message: string) {
61
+ await expect(this.errorMessage).toContainText(message);
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Dashboard Page Object
67
+ */
68
+ class DashboardPage {
69
+ constructor(private page: Page) {}
70
+
71
+ get welcomeMessage() {
72
+ return this.page.getByText(/Welcome,/);
73
+ }
74
+
75
+ get logoutButton() {
76
+ return this.page.getByRole('button', { name: 'Logout' });
77
+ }
78
+
79
+ async expectLoggedIn(username: string) {
80
+ await expect(this.welcomeMessage).toContainText(username);
81
+ }
82
+
83
+ async logout() {
84
+ await this.logoutButton.click();
85
+ }
86
+ }
87
+
88
+ // ============================================================================
89
+ // TEST FIXTURES
90
+ // ============================================================================
91
+
92
+ /**
93
+ * Custom fixture that provides authenticated page
94
+ */
95
+ const test = base.extend<{ authenticatedPage: Page }>({
96
+ authenticatedPage: async ({ page }, use) => {
97
+ // Setup: Login before test
98
+ const loginPage = new LoginPage(page);
99
+ await loginPage.goto();
100
+ await loginPage.login('user@example.com', 'password123');
101
+
102
+ // Wait for navigation to dashboard
103
+ await page.waitForURL('/dashboard');
104
+
105
+ // Provide authenticated page to test
106
+ await use(page);
107
+
108
+ // Teardown: Logout after test
109
+ const dashboardPage = new DashboardPage(page);
110
+ await dashboardPage.logout();
111
+ },
112
+ });
113
+
114
+ // ============================================================================
115
+ // BASIC E2E TESTS
116
+ // ============================================================================
117
+
118
+ test.describe('Authentication Flow', () => {
119
+ test('should login successfully with valid credentials', async ({ page }) => {
120
+ // ARRANGE
121
+ const loginPage = new LoginPage(page);
122
+ await loginPage.goto();
123
+
124
+ // ACT
125
+ await loginPage.login('user@example.com', 'password123');
126
+
127
+ // ASSERT
128
+ await expect(page).toHaveURL('/dashboard');
129
+ const dashboardPage = new DashboardPage(page);
130
+ await dashboardPage.expectLoggedIn('User');
131
+ });
132
+
133
+ test('should show error for invalid credentials', async ({ page }) => {
134
+ // ARRANGE
135
+ const loginPage = new LoginPage(page);
136
+ await loginPage.goto();
137
+
138
+ // ACT
139
+ await loginPage.login('invalid@example.com', 'wrongpassword');
140
+
141
+ // ASSERT
142
+ await loginPage.expectError('Invalid email or password');
143
+ await expect(page).toHaveURL('/login'); // Still on login page
144
+ });
145
+
146
+ test('should show validation errors for empty fields', async ({ page }) => {
147
+ // ARRANGE
148
+ const loginPage = new LoginPage(page);
149
+ await loginPage.goto();
150
+
151
+ // ACT
152
+ await loginPage.loginButton.click();
153
+
154
+ // ASSERT
155
+ await expect(page.getByText('Email is required')).toBeVisible();
156
+ await expect(page.getByText('Password is required')).toBeVisible();
157
+ });
158
+ });
159
+
160
+ // ============================================================================
161
+ // AUTHENTICATED TESTS (Using Fixture)
162
+ // ============================================================================
163
+
164
+ test.describe('Dashboard Features', () => {
165
+ test('should display user profile', async ({ authenticatedPage }) => {
166
+ // Navigate to profile
167
+ await authenticatedPage.goto('/profile');
168
+
169
+ // Verify profile data
170
+ await expect(
171
+ authenticatedPage.getByText('user@example.com')
172
+ ).toBeVisible();
173
+ await expect(authenticatedPage.getByText('Member since')).toBeVisible();
174
+ });
175
+
176
+ test('should allow editing profile', async ({ authenticatedPage }) => {
177
+ // Navigate to profile
178
+ await authenticatedPage.goto('/profile');
179
+
180
+ // Edit name
181
+ const nameInput = authenticatedPage.getByLabel('Name');
182
+ await nameInput.clear();
183
+ await nameInput.fill('New Name');
184
+
185
+ // Save changes
186
+ await authenticatedPage
187
+ .getByRole('button', { name: 'Save Changes' })
188
+ .click();
189
+
190
+ // Verify success
191
+ await expect(
192
+ authenticatedPage.getByText('Profile updated successfully')
193
+ ).toBeVisible();
194
+ });
195
+ });
196
+
197
+ // ============================================================================
198
+ // API MOCKING
199
+ // ============================================================================
200
+
201
+ test.describe('API Mocking', () => {
202
+ test('should handle API errors gracefully', async ({ page }) => {
203
+ // Mock API to return error
204
+ await page.route('**/api/users', (route) => {
205
+ route.fulfill({
206
+ status: 500,
207
+ body: JSON.stringify({ error: 'Internal Server Error' }),
208
+ });
209
+ });
210
+
211
+ // Navigate to users page
212
+ await page.goto('/users');
213
+
214
+ // Verify error message
215
+ await expect(
216
+ page.getByText('Failed to load users. Please try again.')
217
+ ).toBeVisible();
218
+ });
219
+
220
+ test('should display mocked user data', async ({ page }) => {
221
+ // Mock API to return test data
222
+ await page.route('**/api/users', (route) => {
223
+ route.fulfill({
224
+ status: 200,
225
+ body: JSON.stringify([
226
+ { id: 1, name: 'John Doe', email: 'john@example.com' },
227
+ { id: 2, name: 'Jane Smith', email: 'jane@example.com' },
228
+ ]),
229
+ });
230
+ });
231
+
232
+ // Navigate to users page
233
+ await page.goto('/users');
234
+
235
+ // Verify mocked data is displayed
236
+ await expect(page.getByText('John Doe')).toBeVisible();
237
+ await expect(page.getByText('Jane Smith')).toBeVisible();
238
+ });
239
+ });
240
+
241
+ // ============================================================================
242
+ // VISUAL REGRESSION TESTING
243
+ // ============================================================================
244
+
245
+ test.describe('Visual Regression', () => {
246
+ test('homepage matches baseline', async ({ page }) => {
247
+ await page.goto('/');
248
+
249
+ // Capture screenshot and compare to baseline
250
+ await expect(page).toHaveScreenshot('homepage.png', {
251
+ fullPage: true,
252
+ animations: 'disabled',
253
+ });
254
+ });
255
+
256
+ test('button states match baseline', async ({ page }) => {
257
+ await page.goto('/components');
258
+
259
+ const button = page.getByRole('button', { name: 'Submit' });
260
+
261
+ // Default state
262
+ await expect(button).toHaveScreenshot('button-default.png');
263
+
264
+ // Hover state
265
+ await button.hover();
266
+ await expect(button).toHaveScreenshot('button-hover.png');
267
+
268
+ // Focus state
269
+ await button.focus();
270
+ await expect(button).toHaveScreenshot('button-focus.png');
271
+ });
272
+ });
273
+
274
+ // ============================================================================
275
+ // ACCESSIBILITY TESTING
276
+ // ============================================================================
277
+
278
+ test.describe('Accessibility', () => {
279
+ test('should not have accessibility violations', async ({ page }) => {
280
+ await page.goto('/');
281
+
282
+ // Run axe accessibility scan
283
+ const accessibilityScanResults = await new AxeBuilder({ page })
284
+ .withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'])
285
+ .analyze();
286
+
287
+ // Assert no violations
288
+ expect(accessibilityScanResults.violations).toEqual([]);
289
+ });
290
+
291
+ test('should support keyboard navigation', async ({ page }) => {
292
+ await page.goto('/form');
293
+
294
+ // Tab through form fields
295
+ await page.keyboard.press('Tab');
296
+ await expect(page.getByLabel('Email')).toBeFocused();
297
+
298
+ await page.keyboard.press('Tab');
299
+ await expect(page.getByLabel('Password')).toBeFocused();
300
+
301
+ await page.keyboard.press('Tab');
302
+ await expect(
303
+ page.getByRole('button', { name: 'Submit' })
304
+ ).toBeFocused();
305
+
306
+ // Submit with Enter
307
+ await page.keyboard.press('Enter');
308
+ });
309
+
310
+ test('should have proper ARIA labels', async ({ page }) => {
311
+ await page.goto('/');
312
+
313
+ // Check navigation has aria-label
314
+ await expect(
315
+ page.getByRole('navigation', { name: 'Main navigation' })
316
+ ).toBeVisible();
317
+
318
+ // Check main content has aria-label
319
+ await expect(page.getByRole('main')).toHaveAttribute(
320
+ 'aria-label',
321
+ 'Main content'
322
+ );
323
+
324
+ // Check all images have alt text
325
+ const images = await page.getByRole('img').all();
326
+ for (const img of images) {
327
+ await expect(img).toHaveAttribute('alt');
328
+ }
329
+ });
330
+ });
331
+
332
+ // ============================================================================
333
+ // MOBILE TESTING
334
+ // ============================================================================
335
+
336
+ test.describe('Mobile Experience', () => {
337
+ test.use({ viewport: { width: 375, height: 667 } }); // iPhone SE
338
+
339
+ test('should render mobile navigation', async ({ page }) => {
340
+ await page.goto('/');
341
+
342
+ // Mobile menu button should be visible
343
+ await expect(
344
+ page.getByRole('button', { name: 'Menu' })
345
+ ).toBeVisible();
346
+
347
+ // Desktop navigation should be hidden
348
+ const desktopNav = page.getByRole('navigation').first();
349
+ await expect(desktopNav).toBeHidden();
350
+ });
351
+
352
+ test('should handle touch gestures', async ({ page }) => {
353
+ await page.goto('/gallery');
354
+
355
+ // Get image element
356
+ const image = page.getByRole('img').first();
357
+
358
+ // Swipe left
359
+ await image.dispatchEvent('touchstart', {
360
+ touches: [{ clientX: 300, clientY: 200 }],
361
+ });
362
+ await image.dispatchEvent('touchmove', {
363
+ touches: [{ clientX: 100, clientY: 200 }],
364
+ });
365
+ await image.dispatchEvent('touchend');
366
+
367
+ // Verify navigation to next image
368
+ await expect(page.getByText('Image 2 of 10')).toBeVisible();
369
+ });
370
+ });
371
+
372
+ // ============================================================================
373
+ // PERFORMANCE TESTING
374
+ // ============================================================================
375
+
376
+ test.describe('Performance', () => {
377
+ test('page load performance', async ({ page }) => {
378
+ await page.goto('/');
379
+
380
+ // Get performance metrics
381
+ const performanceMetrics = await page.evaluate(() => {
382
+ const perfData = window.performance.timing;
383
+ return {
384
+ loadTime: perfData.loadEventEnd - perfData.navigationStart,
385
+ domContentLoaded:
386
+ perfData.domContentLoadedEventEnd - perfData.navigationStart,
387
+ };
388
+ });
389
+
390
+ // Assert performance targets
391
+ expect(performanceMetrics.loadTime).toBeLessThan(3000); // 3s max
392
+ expect(performanceMetrics.domContentLoaded).toBeLessThan(2000); // 2s max
393
+ });
394
+ });
395
+
396
+ // ============================================================================
397
+ // FILE UPLOAD/DOWNLOAD
398
+ // ============================================================================
399
+
400
+ test.describe('File Operations', () => {
401
+ test('should upload file', async ({ page }) => {
402
+ await page.goto('/upload');
403
+
404
+ // Set up file chooser
405
+ const fileChooserPromise = page.waitForEvent('filechooser');
406
+ await page.getByRole('button', { name: 'Upload File' }).click();
407
+ const fileChooser = await fileChooserPromise;
408
+
409
+ // Upload file
410
+ await fileChooser.setFiles('tests/fixtures/test-file.pdf');
411
+
412
+ // Verify upload success
413
+ await expect(page.getByText('File uploaded successfully')).toBeVisible();
414
+ });
415
+
416
+ test('should download file', async ({ page }) => {
417
+ await page.goto('/downloads');
418
+
419
+ // Set up download
420
+ const downloadPromise = page.waitForEvent('download');
421
+ await page.getByRole('link', { name: 'Download Report' }).click();
422
+ const download = await downloadPromise;
423
+
424
+ // Verify download
425
+ expect(download.suggestedFilename()).toBe('report.pdf');
426
+ await download.saveAs(`/tmp/${download.suggestedFilename()}`);
427
+ });
428
+ });
429
+
430
+ // ============================================================================
431
+ // MULTI-TAB/WINDOW TESTING
432
+ // ============================================================================
433
+
434
+ test.describe('Multi-Window', () => {
435
+ test('should handle popup windows', async ({ context, page }) => {
436
+ await page.goto('/');
437
+
438
+ // Wait for popup
439
+ const [popup] = await Promise.all([
440
+ context.waitForEvent('page'),
441
+ page.getByRole('button', { name: 'Open Help' }).click(),
442
+ ]);
443
+
444
+ // Interact with popup
445
+ await expect(popup.getByText('Help Center')).toBeVisible();
446
+ await popup.close();
447
+ });
448
+ });
449
+
450
+ // ============================================================================
451
+ // BEST PRACTICES CHECKLIST
452
+ // ============================================================================
453
+
454
+ /*
455
+ ✅ Page Object Model (POM)
456
+ ✅ Test Fixtures for Setup/Teardown
457
+ ✅ Descriptive Test Names
458
+ ✅ Auto-Waiting (Playwright built-in)
459
+ ✅ User-Centric Selectors (getByRole, getByLabel)
460
+ ✅ API Mocking for Reliability
461
+ ✅ Visual Regression Testing
462
+ ✅ Accessibility Testing (axe-core)
463
+ ✅ Mobile/Responsive Testing
464
+ ✅ Performance Assertions
465
+ ✅ File Upload/Download
466
+ ✅ Multi-Tab/Window Handling
467
+ ✅ Screenshot/Video on Failure (configured in playwright.config.ts)
468
+ ✅ Parallel Execution (configured in playwright.config.ts)
469
+ ✅ Cross-Browser Testing (configured in playwright.config.ts)
470
+ */