specweave 0.23.18 → 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 (167) hide show
  1. package/.claude-plugin/marketplace.json +93 -49
  2. package/CLAUDE.md +137 -4
  3. package/dist/src/cli/helpers/ado-area-path-mapper.d.ts +89 -0
  4. package/dist/src/cli/helpers/ado-area-path-mapper.d.ts.map +1 -0
  5. package/dist/src/cli/helpers/ado-area-path-mapper.js +213 -0
  6. package/dist/src/cli/helpers/ado-area-path-mapper.js.map +1 -0
  7. package/dist/src/cli/helpers/issue-tracker/ado-auto-discover.d.ts +29 -0
  8. package/dist/src/cli/helpers/issue-tracker/ado-auto-discover.d.ts.map +1 -0
  9. package/dist/src/cli/helpers/issue-tracker/ado-auto-discover.js +109 -0
  10. package/dist/src/cli/helpers/issue-tracker/ado-auto-discover.js.map +1 -0
  11. package/dist/src/cli/helpers/issue-tracker/ado.d.ts +1 -0
  12. package/dist/src/cli/helpers/issue-tracker/ado.d.ts.map +1 -1
  13. package/dist/src/cli/helpers/issue-tracker/ado.js +2 -0
  14. package/dist/src/cli/helpers/issue-tracker/ado.js.map +1 -1
  15. package/dist/src/cli/helpers/smart-filter.d.ts +83 -0
  16. package/dist/src/cli/helpers/smart-filter.d.ts.map +1 -0
  17. package/dist/src/cli/helpers/smart-filter.js +265 -0
  18. package/dist/src/cli/helpers/smart-filter.js.map +1 -0
  19. package/dist/src/core/qa/quality-gate-decider.d.ts +1 -1
  20. package/dist/src/core/qa/quality-gate-decider.js +2 -2
  21. package/dist/src/core/qa/quality-gate-decider.js.map +1 -1
  22. package/dist/src/core/qa/risk-calculator.d.ts +2 -2
  23. package/dist/src/core/qa/risk-calculator.js +2 -2
  24. package/dist/src/core/validators/ac-presence-validator.d.ts +56 -0
  25. package/dist/src/core/validators/ac-presence-validator.d.ts.map +1 -0
  26. package/dist/src/core/validators/ac-presence-validator.js +149 -0
  27. package/dist/src/core/validators/ac-presence-validator.js.map +1 -0
  28. package/dist/src/integrations/ado/area-path-mapper.d.ts +137 -0
  29. package/dist/src/integrations/ado/area-path-mapper.d.ts.map +1 -0
  30. package/dist/src/integrations/ado/area-path-mapper.js +267 -0
  31. package/dist/src/integrations/ado/area-path-mapper.js.map +1 -0
  32. package/dist/src/integrations/jira/filter-processor.d.ts +126 -0
  33. package/dist/src/integrations/jira/filter-processor.d.ts.map +1 -0
  34. package/dist/src/integrations/jira/filter-processor.js +207 -0
  35. package/dist/src/integrations/jira/filter-processor.js.map +1 -0
  36. package/dist/src/integrations/jira/jira-client.d.ts +13 -0
  37. package/dist/src/integrations/jira/jira-client.d.ts.map +1 -1
  38. package/dist/src/integrations/jira/jira-client.js +33 -0
  39. package/dist/src/integrations/jira/jira-client.js.map +1 -1
  40. package/dist/src/utils/ac-embedder.d.ts +63 -0
  41. package/dist/src/utils/ac-embedder.d.ts.map +1 -0
  42. package/dist/src/utils/ac-embedder.js +217 -0
  43. package/dist/src/utils/ac-embedder.js.map +1 -0
  44. package/dist/src/utils/env-manager.d.ts +86 -0
  45. package/dist/src/utils/env-manager.d.ts.map +1 -0
  46. package/dist/src/utils/env-manager.js +188 -0
  47. package/dist/src/utils/env-manager.js.map +1 -0
  48. package/package.json +1 -1
  49. package/plugins/specweave/.claude-plugin/plugin.json +1 -1
  50. package/plugins/specweave/agents/AGENTS-INDEX.md +1 -1
  51. package/plugins/specweave/agents/increment-quality-judge-v2/AGENT.md +9 -9
  52. package/plugins/specweave/commands/specweave-do.md +37 -0
  53. package/plugins/specweave/commands/specweave-done.md +159 -0
  54. package/plugins/specweave/commands/specweave-embed-acs.md +446 -0
  55. package/plugins/specweave/commands/specweave-next.md +148 -3
  56. package/plugins/specweave/commands/specweave-qa.md +2 -2
  57. package/plugins/specweave/hooks/pre-increment-start.sh +168 -0
  58. package/plugins/specweave/skills/SKILLS-INDEX.md +1 -1
  59. package/plugins/specweave-ado/.claude-plugin/plugin.json +1 -1
  60. package/plugins/specweave-ado/commands/specweave-ado-import-projects.md +331 -0
  61. package/plugins/specweave-alternatives/.claude-plugin/plugin.json +10 -0
  62. package/plugins/specweave-alternatives/commands/alternatives-analyze.md +336 -0
  63. package/plugins/specweave-alternatives/skills/architecture-alternatives/SKILL.md +651 -0
  64. package/plugins/specweave-alternatives/skills/bmad-method/SKILL.md +420 -0
  65. package/plugins/specweave-alternatives/skills/spec-kit-expert/SKILL.md +487 -0
  66. package/plugins/specweave-backend/commands/api-scaffold.md +80 -0
  67. package/plugins/specweave-backend/commands/crud-generate.md +109 -0
  68. package/plugins/specweave-backend/commands/migration-generate.md +139 -0
  69. package/plugins/specweave-confluent/commands/connector-deploy.md +154 -0
  70. package/plugins/specweave-confluent/commands/ksqldb-query.md +179 -0
  71. package/plugins/specweave-confluent/commands/schema-register.md +123 -0
  72. package/plugins/specweave-core/.claude-plugin/plugin.json +21 -0
  73. package/plugins/specweave-core/commands/architecture-review.md +288 -0
  74. package/plugins/specweave-core/commands/code-review.md +213 -0
  75. package/plugins/specweave-core/commands/refactor-plan.md +249 -0
  76. package/plugins/specweave-core/skills/code-quality/SKILL.md +157 -0
  77. package/plugins/specweave-core/skills/design-patterns/SKILL.md +244 -0
  78. package/plugins/specweave-core/skills/software-architecture/SKILL.md +83 -0
  79. package/plugins/specweave-cost-optimizer/.claude-plugin/plugin.json +22 -0
  80. package/plugins/specweave-cost-optimizer/commands/cost-analyze.md +360 -0
  81. package/plugins/specweave-cost-optimizer/commands/cost-optimize.md +480 -0
  82. package/plugins/specweave-cost-optimizer/skills/aws-cost-expert/SKILL.md +416 -0
  83. package/plugins/specweave-cost-optimizer/skills/cloud-pricing/SKILL.md +325 -0
  84. package/plugins/specweave-cost-optimizer/skills/cost-optimization/SKILL.md +337 -0
  85. package/plugins/specweave-diagrams/.claude-plugin/plugin.json +1 -1
  86. package/plugins/specweave-diagrams/commands/diagrams-generate.md +168 -0
  87. package/plugins/specweave-docs/.claude-plugin/plugin.json +10 -0
  88. package/plugins/specweave-docs/commands/docs-generate.md +441 -0
  89. package/plugins/specweave-docs/commands/docs-init.md +334 -0
  90. package/plugins/specweave-docs/skills/docusaurus/SKILL.md +581 -0
  91. package/plugins/specweave-docs/skills/spec-driven-brainstorming/SKILL.md +689 -0
  92. package/plugins/specweave-docs/skills/technical-writing/SKILL.md +1039 -0
  93. package/plugins/specweave-docs-preview/.claude-plugin/plugin.json +1 -1
  94. package/plugins/specweave-figma/.claude-plugin/plugin.json +23 -0
  95. package/plugins/specweave-figma/commands/figma-import.md +690 -0
  96. package/plugins/specweave-figma/commands/figma-to-react.md +834 -0
  97. package/plugins/specweave-figma/commands/figma-tokens.md +815 -0
  98. package/plugins/specweave-frontend/.claude-plugin/plugin.json +21 -0
  99. package/plugins/specweave-frontend/agents/frontend-architect/AGENT.md +387 -0
  100. package/plugins/specweave-frontend/agents/frontend-architect/README.md +385 -0
  101. package/plugins/specweave-frontend/agents/frontend-architect/examples.md +590 -0
  102. package/plugins/specweave-frontend/agents/frontend-architect/templates/component-template.tsx +152 -0
  103. package/plugins/specweave-frontend/agents/frontend-architect/templates/hook-template.ts +311 -0
  104. package/plugins/specweave-frontend/agents/frontend-architect/templates/page-template.tsx +228 -0
  105. package/plugins/specweave-frontend/commands/component-generate.md +510 -0
  106. package/plugins/specweave-frontend/commands/design-system-init.md +494 -0
  107. package/plugins/specweave-frontend/commands/frontend-scaffold.md +207 -0
  108. package/plugins/specweave-frontend/commands/nextjs-setup.md +396 -0
  109. package/plugins/specweave-frontend/skills/design-system-architect/SKILL.md +278 -0
  110. package/plugins/specweave-frontend/skills/frontend/SKILL.md +420 -0
  111. package/plugins/specweave-frontend/skills/nextjs/SKILL.md +546 -0
  112. package/plugins/specweave-github/.claude-plugin/plugin.json +1 -1
  113. package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +194 -0
  114. package/plugins/specweave-infrastructure/.claude-plugin/plugin.json +1 -1
  115. package/plugins/specweave-jira/.claude-plugin/plugin.json +1 -1
  116. package/plugins/specweave-jira/commands/import-projects.js +183 -0
  117. package/plugins/specweave-jira/commands/import-projects.md +97 -0
  118. package/plugins/specweave-jira/commands/import-projects.ts +288 -0
  119. package/plugins/specweave-jira/commands/specweave-jira-import-projects.md +298 -0
  120. package/plugins/specweave-kafka/.claude-plugin/plugin.json +1 -1
  121. package/plugins/specweave-kafka-streams/.claude-plugin/plugin.json +1 -1
  122. package/plugins/specweave-kubernetes/commands/cluster-setup.md +262 -0
  123. package/plugins/specweave-kubernetes/commands/deployment-generate.md +242 -0
  124. package/plugins/specweave-kubernetes/commands/helm-scaffold.md +333 -0
  125. package/plugins/specweave-ml/.claude-plugin/plugin.json +1 -1
  126. package/plugins/specweave-mobile/commands/app-scaffold.md +233 -0
  127. package/plugins/specweave-mobile/commands/build-config.md +256 -0
  128. package/plugins/specweave-mobile/commands/screen-generate.md +289 -0
  129. package/plugins/specweave-n8n/.claude-plugin/plugin.json +1 -1
  130. package/plugins/specweave-plugin-dev/.claude-plugin/plugin.json +13 -12
  131. package/plugins/specweave-plugin-dev/commands/plugin-create.md +333 -0
  132. package/plugins/specweave-plugin-dev/commands/plugin-publish.md +339 -0
  133. package/plugins/specweave-plugin-dev/commands/plugin-test.md +293 -0
  134. package/plugins/specweave-plugin-dev/skills/claude-sdk/SKILL.md +162 -0
  135. package/plugins/specweave-plugin-dev/skills/marketplace-publishing/SKILL.md +263 -0
  136. package/plugins/specweave-plugin-dev/skills/plugin-development/SKILL.md +316 -0
  137. package/plugins/specweave-release/.claude-plugin/plugin.json +1 -1
  138. package/plugins/specweave-release/commands/specweave-release-npm.md +110 -0
  139. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +168 -0
  140. package/plugins/specweave-testing/.claude-plugin/plugin.json +21 -0
  141. package/plugins/specweave-testing/agents/qa-engineer/AGENT.md +797 -0
  142. package/plugins/specweave-testing/agents/qa-engineer/README.md +443 -0
  143. package/plugins/specweave-testing/agents/qa-engineer/templates/playwright-e2e-test.ts +470 -0
  144. package/plugins/specweave-testing/agents/qa-engineer/templates/test-data-factory.ts +507 -0
  145. package/plugins/specweave-testing/agents/qa-engineer/templates/vitest-unit-test.ts +400 -0
  146. package/plugins/specweave-testing/agents/qa-engineer/test-strategies.md +726 -0
  147. package/plugins/specweave-testing/commands/e2e-setup.md +1081 -0
  148. package/plugins/specweave-testing/commands/test-coverage.md +979 -0
  149. package/plugins/specweave-testing/commands/test-generate.md +1156 -0
  150. package/plugins/specweave-testing/commands/test-init.md +409 -0
  151. package/plugins/specweave-testing/skills/e2e-playwright/SKILL.md +769 -0
  152. package/plugins/specweave-testing/skills/tdd-expert/SKILL.md +934 -0
  153. package/plugins/specweave-testing/skills/unit-testing-expert/SKILL.md +1011 -0
  154. package/plugins/specweave-tooling/.claude-plugin/plugin.json +22 -0
  155. package/plugins/specweave-tooling/commands/specweave-tooling-skill-create.md +691 -0
  156. package/plugins/specweave-tooling/commands/specweave-tooling-skill-package.md +751 -0
  157. package/plugins/specweave-tooling/commands/specweave-tooling-skill-validate.md +858 -0
  158. package/plugins/specweave-ui/.claude-plugin/plugin.json +10 -0
  159. package/plugins/specweave-ui/commands/ui-automate.md +199 -0
  160. package/plugins/specweave-ui/commands/ui-inspect.md +70 -0
  161. package/plugins/specweave-ui/skills/browser-automation/SKILL.md +314 -0
  162. package/plugins/specweave-ui/skills/ui-testing/SKILL.md +716 -0
  163. package/plugins/specweave-ui/skills/visual-regression/SKILL.md +728 -0
  164. package/plugins/specweave/commands/check-hooks.md +0 -257
  165. package/plugins/specweave/commands/specweave-archive-increments.md +0 -82
  166. package/plugins/specweave-plugin-dev/skills/plugin-expert/SKILL.md +0 -1231
  167. /package/plugins/specweave/{agents/code-reviewer.md → skills/code-reviewer/SKILL.md} +0 -0
@@ -0,0 +1,728 @@
1
+ ---
2
+ name: visual-regression
3
+ description: Visual regression testing expert using Playwright snapshots, Percy, Chromatic, BackstopJS, and pixel-diff analysis. Covers baseline management, responsive testing, cross-browser visual testing, component visual testing, and CI integration. Activates for visual regression, screenshot testing, visual diff, Percy, Chromatic, BackstopJS, pixel comparison, snapshot testing, visual testing, CSS regression.
4
+ ---
5
+
6
+ # Visual Regression Testing Skill
7
+
8
+ Expert in visual regression testing - automated detection of unintended visual changes in web applications using screenshot comparison, pixel diffing, and visual testing frameworks.
9
+
10
+ ## Why Visual Regression Testing?
11
+
12
+ **Problems It Solves**:
13
+ - CSS changes breaking layout unexpectedly
14
+ - Responsive design regressions (mobile/tablet/desktop)
15
+ - Cross-browser rendering differences
16
+ - Component library changes affecting consumers
17
+ - UI regressions that functional tests miss
18
+
19
+ **Example Scenario**:
20
+ ```
21
+ Developer changes global CSS: `.container { padding: 10px }`
22
+
23
+ Accidentally breaks checkout page layout
24
+
25
+ Functional E2E tests pass (buttons still clickable)
26
+
27
+ Visual regression test catches layout shift
28
+ ```
29
+
30
+ ## Core Tools
31
+
32
+ ### 1. Playwright Visual Snapshots (Built-in)
33
+
34
+ **Why Playwright?**
35
+ - No third-party service required (free)
36
+ - Fast (parallel execution)
37
+ - Built-in automatic masking (hide dynamic content)
38
+ - Cross-browser support (Chromium, Firefox, WebKit)
39
+
40
+ #### Basic Snapshot Test
41
+
42
+ ```typescript
43
+ import { test, expect } from '@playwright/test';
44
+
45
+ test('homepage should match visual baseline', async ({ page }) => {
46
+ await page.goto('https://example.com');
47
+
48
+ // Take full-page screenshot and compare to baseline
49
+ await expect(page).toHaveScreenshot('homepage.png');
50
+ });
51
+ ```
52
+
53
+ **First Run** (create baseline):
54
+ ```bash
55
+ npx playwright test --update-snapshots
56
+ # Creates: tests/__screenshots__/homepage.spec.ts/homepage-chromium-darwin.png
57
+ ```
58
+
59
+ **Subsequent Runs** (compare to baseline):
60
+ ```bash
61
+ npx playwright test
62
+ # Compares current screenshot to baseline
63
+ # Fails if difference exceeds threshold
64
+ ```
65
+
66
+ #### Element-Level Snapshots
67
+
68
+ ```typescript
69
+ test('button should match visual baseline', async ({ page }) => {
70
+ await page.goto('/buttons');
71
+
72
+ const submitButton = page.locator('[data-testid="submit-button"]');
73
+ await expect(submitButton).toHaveScreenshot('submit-button.png');
74
+ });
75
+ ```
76
+
77
+ #### Configurable Thresholds
78
+
79
+ ```typescript
80
+ // playwright.config.ts
81
+ export default defineConfig({
82
+ expect: {
83
+ toHaveScreenshot: {
84
+ maxDiffPixels: 100, // Allow max 100 pixels to differ
85
+ // OR
86
+ maxDiffPixelRatio: 0.01, // Allow 1% of pixels to differ
87
+ },
88
+ },
89
+ });
90
+ ```
91
+
92
+ #### Masking Dynamic Content
93
+
94
+ ```typescript
95
+ test('dashboard with dynamic data', async ({ page }) => {
96
+ await page.goto('/dashboard');
97
+
98
+ // Mask elements that change frequently (timestamps, user IDs)
99
+ await expect(page).toHaveScreenshot({
100
+ mask: [
101
+ page.locator('.timestamp'),
102
+ page.locator('.user-avatar'),
103
+ page.locator('[data-testid="ad-banner"]'),
104
+ ],
105
+ });
106
+ });
107
+ ```
108
+
109
+ #### Responsive Testing (Multiple Viewports)
110
+
111
+ ```typescript
112
+ const viewports = [
113
+ { name: 'mobile', width: 375, height: 667 },
114
+ { name: 'tablet', width: 768, height: 1024 },
115
+ { name: 'desktop', width: 1920, height: 1080 },
116
+ ];
117
+
118
+ for (const viewport of viewports) {
119
+ test(`homepage on ${viewport.name}`, async ({ page }) => {
120
+ await page.setViewportSize({ width: viewport.width, height: viewport.height });
121
+ await page.goto('https://example.com');
122
+
123
+ await expect(page).toHaveScreenshot(`homepage-${viewport.name}.png`);
124
+ });
125
+ }
126
+ ```
127
+
128
+ ### 2. Percy (Cloud-Based Visual Testing)
129
+
130
+ **Why Percy?**
131
+ - Smart diffing (ignores anti-aliasing differences)
132
+ - Review UI (approve/reject changes)
133
+ - Integrates with GitHub PRs
134
+ - Parallel testing across browsers
135
+ - Automatic baseline management
136
+
137
+ #### Setup
138
+
139
+ ```bash
140
+ npm install --save-dev @percy/playwright
141
+ ```
142
+
143
+ ```typescript
144
+ // tests/visual.spec.ts
145
+ import { test } from '@playwright/test';
146
+ import percySnapshot from '@percy/playwright';
147
+
148
+ test('homepage visual test', async ({ page }) => {
149
+ await page.goto('https://example.com');
150
+
151
+ // Percy captures screenshot and compares to baseline
152
+ await percySnapshot(page, 'Homepage');
153
+ });
154
+ ```
155
+
156
+ ```bash
157
+ # Run tests with Percy
158
+ PERCY_TOKEN=your_token npx percy exec -- npx playwright test
159
+ ```
160
+
161
+ #### Percy Configuration
162
+
163
+ ```yaml
164
+ # .percy.yml
165
+ version: 2
166
+ snapshot:
167
+ widths:
168
+ - 375 # Mobile
169
+ - 768 # Tablet
170
+ - 1280 # Desktop
171
+ min-height: 1024
172
+ percy-css: |
173
+ /* Hide dynamic elements */
174
+ .timestamp { visibility: hidden; }
175
+ .ad-banner { display: none; }
176
+ ```
177
+
178
+ #### Percy in CI (GitHub Actions)
179
+
180
+ ```yaml
181
+ name: Visual Tests
182
+
183
+ on: [pull_request]
184
+
185
+ jobs:
186
+ percy:
187
+ runs-on: ubuntu-latest
188
+ steps:
189
+ - uses: actions/checkout@v3
190
+ - uses: actions/setup-node@v3
191
+ - run: npm ci
192
+ - run: npx playwright install --with-deps
193
+
194
+ - name: Run Percy tests
195
+ run: npx percy exec -- npx playwright test
196
+ env:
197
+ PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
198
+ ```
199
+
200
+ ### 3. Chromatic (Storybook Visual Testing)
201
+
202
+ **Why Chromatic?**
203
+ - Designed for component libraries (Storybook integration)
204
+ - Captures all component states automatically
205
+ - UI review workflow (approve/reject)
206
+ - Detects accessibility issues
207
+ - Version control for design system
208
+
209
+ #### Setup (Storybook + Chromatic)
210
+
211
+ ```bash
212
+ npm install --save-dev chromatic
213
+ npx chromatic --project-token=your_token
214
+ ```
215
+
216
+ ```javascript
217
+ // .storybook/main.js
218
+ module.exports = {
219
+ stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)'],
220
+ addons: ['@storybook/addon-essentials'],
221
+ };
222
+ ```
223
+
224
+ ```typescript
225
+ // Button.stories.tsx
226
+ import { Button } from './Button';
227
+
228
+ export default {
229
+ title: 'Components/Button',
230
+ component: Button,
231
+ };
232
+
233
+ export const Primary = () => <Button variant="primary">Click me</Button>;
234
+ export const Disabled = () => <Button disabled>Disabled</Button>;
235
+ export const Loading = () => <Button loading>Loading...</Button>;
236
+ ```
237
+
238
+ ```bash
239
+ # Chromatic captures all stories automatically
240
+ npx chromatic --project-token=your_token
241
+ ```
242
+
243
+ #### Chromatic in CI
244
+
245
+ ```yaml
246
+ name: Chromatic
247
+
248
+ on: push
249
+
250
+ jobs:
251
+ chromatic:
252
+ runs-on: ubuntu-latest
253
+ steps:
254
+ - uses: actions/checkout@v3
255
+ with:
256
+ fetch-depth: 0 # Required for Chromatic
257
+ - uses: actions/setup-node@v3
258
+ - run: npm ci
259
+ - run: npx chromatic --project-token=${{ secrets.CHROMATIC_TOKEN }}
260
+ ```
261
+
262
+ ### 4. BackstopJS (Configuration-Based)
263
+
264
+ **Why BackstopJS?**
265
+ - No code required (JSON configuration)
266
+ - Local execution (no cloud service)
267
+ - Interactive reports
268
+ - CSS selector-based scenarios
269
+
270
+ #### Configuration
271
+
272
+ ```json
273
+ {
274
+ "id": "myapp_visual_tests",
275
+ "viewports": [
276
+ { "label": "phone", "width": 375, "height": 667 },
277
+ { "label": "tablet", "width": 768, "height": 1024 },
278
+ { "label": "desktop", "width": 1920, "height": 1080 }
279
+ ],
280
+ "scenarios": [
281
+ {
282
+ "label": "Homepage",
283
+ "url": "https://example.com",
284
+ "selectors": ["document"],
285
+ "delay": 500
286
+ },
287
+ {
288
+ "label": "Login Form",
289
+ "url": "https://example.com/login",
290
+ "selectors": [".login-form"],
291
+ "hideSelectors": [".banner-ad"],
292
+ "delay": 1000
293
+ }
294
+ ],
295
+ "paths": {
296
+ "bitmaps_reference": "backstop_data/bitmaps_reference",
297
+ "bitmaps_test": "backstop_data/bitmaps_test",
298
+ "html_report": "backstop_data/html_report"
299
+ }
300
+ }
301
+ ```
302
+
303
+ ```bash
304
+ # Create baseline
305
+ backstop reference
306
+
307
+ # Run test (compare to baseline)
308
+ backstop test
309
+
310
+ # Update baseline (approve changes)
311
+ backstop approve
312
+ ```
313
+
314
+ ## Testing Strategies
315
+
316
+ ### 1. Component-Level Visual Testing
317
+
318
+ **Use Case**: Design system components (buttons, inputs, modals)
319
+
320
+ ```typescript
321
+ // Component snapshots
322
+ test.describe('Button component', () => {
323
+ test('primary variant', async ({ page }) => {
324
+ await page.goto('/storybook?path=/story/button--primary');
325
+ await expect(page.locator('.button')).toHaveScreenshot('button-primary.png');
326
+ });
327
+
328
+ test('disabled state', async ({ page }) => {
329
+ await page.goto('/storybook?path=/story/button--disabled');
330
+ await expect(page.locator('.button')).toHaveScreenshot('button-disabled.png');
331
+ });
332
+
333
+ test('hover state', async ({ page }) => {
334
+ await page.goto('/storybook?path=/story/button--primary');
335
+ const button = page.locator('.button');
336
+ await button.hover();
337
+ await expect(button).toHaveScreenshot('button-hover.png');
338
+ });
339
+ });
340
+ ```
341
+
342
+ ### 2. Page-Level Visual Testing
343
+
344
+ **Use Case**: Full pages (homepage, checkout, profile)
345
+
346
+ ```typescript
347
+ test('checkout page visual baseline', async ({ page }) => {
348
+ await page.goto('/checkout');
349
+
350
+ // Wait for page to fully load
351
+ await page.waitForLoadState('networkidle');
352
+
353
+ // Mask dynamic content
354
+ await expect(page).toHaveScreenshot('checkout.png', {
355
+ mask: [page.locator('.cart-timestamp'), page.locator('.promo-banner')],
356
+ fullPage: true, // Capture entire page (scrolling)
357
+ });
358
+ });
359
+ ```
360
+
361
+ ### 3. Interaction-Based Visual Testing
362
+
363
+ **Use Case**: Modals, dropdowns, tooltips (require interaction)
364
+
365
+ ```typescript
366
+ test('modal visual test', async ({ page }) => {
367
+ await page.goto('/');
368
+
369
+ // Open modal
370
+ await page.click('[data-testid="open-modal"]');
371
+ await page.waitForSelector('.modal');
372
+
373
+ // Capture modal screenshot
374
+ await expect(page.locator('.modal')).toHaveScreenshot('modal-open.png');
375
+
376
+ // Test error state
377
+ await page.fill('input[name="email"]', 'invalid');
378
+ await page.click('button[type="submit"]');
379
+ await expect(page.locator('.modal')).toHaveScreenshot('modal-error.png');
380
+ });
381
+ ```
382
+
383
+ ### 4. Cross-Browser Visual Testing
384
+
385
+ ```typescript
386
+ // playwright.config.ts
387
+ export default defineConfig({
388
+ projects: [
389
+ { name: 'chromium', use: { ...devices['Desktop Chrome'] } },
390
+ { name: 'firefox', use: { ...devices['Desktop Firefox'] } },
391
+ { name: 'webkit', use: { ...devices['Desktop Safari'] } },
392
+ ],
393
+ });
394
+ ```
395
+
396
+ ```bash
397
+ # Run tests across all browsers
398
+ npx playwright test
399
+
400
+ # Generates separate baselines per browser:
401
+ # - homepage-chromium-darwin.png
402
+ # - homepage-firefox-darwin.png
403
+ # - homepage-webkit-darwin.png
404
+ ```
405
+
406
+ ## Best Practices
407
+
408
+ ### 1. Stabilize Before Capturing
409
+
410
+ **Problem**: Animations, lazy loading, fonts cause flaky tests.
411
+
412
+ ```typescript
413
+ // ❌ BAD: Capture immediately
414
+ await page.goto('/');
415
+ await expect(page).toHaveScreenshot();
416
+
417
+ // ✅ GOOD: Wait for stability
418
+ await page.goto('/');
419
+ await page.waitForLoadState('networkidle'); // Wait for network idle
420
+ await page.waitForSelector('.main-content'); // Wait for key element
421
+ await page.evaluate(() => document.fonts.ready); // Wait for fonts
422
+
423
+ // Disable animations for consistent screenshots
424
+ await page.addStyleTag({
425
+ content: `
426
+ *, *::before, *::after {
427
+ animation-duration: 0s !important;
428
+ transition-duration: 0s !important;
429
+ }
430
+ `,
431
+ });
432
+
433
+ await expect(page).toHaveScreenshot();
434
+ ```
435
+
436
+ ### 2. Mask Dynamic Content
437
+
438
+ ```typescript
439
+ await expect(page).toHaveScreenshot({
440
+ mask: [
441
+ page.locator('.timestamp'), // Changes every second
442
+ page.locator('.user-id'), // Different per user
443
+ page.locator('[data-dynamic="true"]'), // Marked as dynamic
444
+ page.locator('video'), // Video frames vary
445
+ ],
446
+ });
447
+ ```
448
+
449
+ ### 3. Use Meaningful Names
450
+
451
+ ```typescript
452
+ // ❌ BAD: Generic names
453
+ await expect(page).toHaveScreenshot('test1.png');
454
+
455
+ // ✅ GOOD: Descriptive names
456
+ await expect(page).toHaveScreenshot('homepage-logged-in-user.png');
457
+ await expect(page).toHaveScreenshot('checkout-empty-cart-error.png');
458
+ ```
459
+
460
+ ### 4. Test Critical Paths Only
461
+
462
+ **Visual regression tests are expensive (slow, storage)**. Prioritize:
463
+
464
+ ```typescript
465
+ // ✅ High Priority (critical user flows)
466
+ - Homepage (first impression)
467
+ - Checkout flow (revenue-critical)
468
+ - Login/signup (user acquisition)
469
+ - Product details (conversion)
470
+
471
+ // ⚠️ Medium Priority (important but not critical)
472
+ - Profile settings
473
+ - Search results
474
+ - Category pages
475
+
476
+ // ❌ Low Priority (skip or sample)
477
+ - Admin dashboards (internal users)
478
+ - Footer (rarely changes)
479
+ - Legal pages
480
+ ```
481
+
482
+ ### 5. Baseline Management Strategy
483
+
484
+ **When to Update Baselines**:
485
+ - ✅ Intentional design changes (approved by design team)
486
+ - ✅ Component library upgrades (reviewed)
487
+ - ✅ Browser updates (expected differences)
488
+ - ❌ Unintentional changes (investigate first!)
489
+
490
+ ```bash
491
+ # Review diff report BEFORE approving
492
+ npx playwright test --update-snapshots # Use carefully!
493
+
494
+ # Better: Update selectively
495
+ npx playwright test homepage.spec.ts --update-snapshots
496
+ ```
497
+
498
+ ## Debugging Visual Diffs
499
+
500
+ ### 1. Review Diff Report
501
+
502
+ Playwright generates HTML report with side-by-side comparison:
503
+
504
+ ```bash
505
+ npx playwright test
506
+ # On failure, opens: playwright-report/index.html
507
+ # Shows: Expected | Actual | Diff (highlighted pixels)
508
+ ```
509
+
510
+ ### 2. Adjust Thresholds
511
+
512
+ ```typescript
513
+ // Tolerate minor differences (anti-aliasing, font rendering)
514
+ await expect(page).toHaveScreenshot({
515
+ maxDiffPixelRatio: 0.02, // 2% tolerance
516
+ });
517
+ ```
518
+
519
+ ### 3. Ignore Specific Regions
520
+
521
+ ```typescript
522
+ // Ignore regions that legitimately differ
523
+ await expect(page).toHaveScreenshot({
524
+ mask: [page.locator('.animated-banner')],
525
+ clip: { x: 0, y: 0, width: 800, height: 600 }, // Capture specific area
526
+ });
527
+ ```
528
+
529
+ ## CI/CD Integration
530
+
531
+ ### 1. GitHub Actions (Playwright Snapshots)
532
+
533
+ ```yaml
534
+ name: Visual Regression Tests
535
+
536
+ on:
537
+ pull_request:
538
+ branches: [main]
539
+
540
+ jobs:
541
+ visual:
542
+ runs-on: ubuntu-latest
543
+ steps:
544
+ - uses: actions/checkout@v3
545
+ - uses: actions/setup-node@v3
546
+ - run: npm ci
547
+ - run: npx playwright install --with-deps
548
+
549
+ - name: Run visual tests
550
+ run: npx playwright test
551
+
552
+ - name: Upload diff report
553
+ if: failure()
554
+ uses: actions/upload-artifact@v3
555
+ with:
556
+ name: visual-diff-report
557
+ path: playwright-report/
558
+ ```
559
+
560
+ ### 2. Baseline Storage Strategies
561
+
562
+ **Option 1: Git LFS (Large File Storage)**
563
+ - Store baselines in Git (versioned with code)
564
+ - Use Git LFS to avoid bloating repository
565
+ - Automatic sync across developers
566
+
567
+ ```bash
568
+ # .gitattributes
569
+ *.png filter=lfs diff=lfs merge=lfs -text
570
+
571
+ git lfs install
572
+ git add tests/__screenshots__/*.png
573
+ git commit -m "Add visual baselines"
574
+ ```
575
+
576
+ **Option 2: Cloud Storage (S3, GCS)**
577
+ - Store baselines in cloud bucket
578
+ - Download in CI before test
579
+ - Faster CI (no Git LFS checkout)
580
+
581
+ ```yaml
582
+ - name: Download baselines
583
+ run: aws s3 sync s3://my-bucket/baselines tests/__screenshots__/
584
+ ```
585
+
586
+ **Option 3: Percy/Chromatic (Managed)**
587
+ - Baselines stored in service (no Git needed)
588
+ - Automatic baseline management
589
+ - UI for reviewing changes
590
+
591
+ ### 3. Handling Baseline Drift
592
+
593
+ **Problem**: Developer A updates baselines, Developer B's tests fail.
594
+
595
+ **Solution 1: Require baseline review**
596
+ ```yaml
597
+ # PR merge rules
598
+ - Require approval for changes in tests/__screenshots__/
599
+ ```
600
+
601
+ **Solution 2: Auto-update in CI**
602
+ ```yaml
603
+ - name: Update baselines if approved
604
+ if: contains(github.event.pull_request.labels.*.name, 'update-baselines')
605
+ run: |
606
+ npx playwright test --update-snapshots
607
+ git config user.name "GitHub Actions"
608
+ git add tests/__screenshots__/
609
+ git commit -m "Update visual baselines"
610
+ git push
611
+ ```
612
+
613
+ ## Common Pitfalls
614
+
615
+ ### 1. Flaky Tests Due to Animations
616
+
617
+ ❌ **Bad**:
618
+ ```typescript
619
+ await page.goto('/'); // Page has CSS animations
620
+ await expect(page).toHaveScreenshot(); // Fails randomly (mid-animation)
621
+ ```
622
+
623
+ ✅ **Good**:
624
+ ```typescript
625
+ await page.goto('/');
626
+ await page.addStyleTag({ content: '* { animation: none !important; }' });
627
+ await expect(page).toHaveScreenshot();
628
+ ```
629
+
630
+ ### 2. Font Loading Issues
631
+
632
+ ❌ **Bad**:
633
+ ```typescript
634
+ await page.goto('/'); // Fonts loading async
635
+ await expect(page).toHaveScreenshot(); // Sometimes uses fallback font
636
+ ```
637
+
638
+ ✅ **Good**:
639
+ ```typescript
640
+ await page.goto('/');
641
+ await page.evaluate(() => document.fonts.ready); // Wait for fonts
642
+ await expect(page).toHaveScreenshot();
643
+ ```
644
+
645
+ ### 3. Testing Everything (Slow CI)
646
+
647
+ ❌ **Bad**: 500 visual tests (30 min CI time)
648
+ ✅ **Good**: 50 critical visual tests (5 min CI time)
649
+
650
+ **Optimize**:
651
+ ```typescript
652
+ // Run visual tests only on visual changes
653
+ if (changedFiles.some(file => file.endsWith('.css'))) {
654
+ runVisualTests();
655
+ }
656
+ ```
657
+
658
+ ### 4. Platform Differences (macOS vs Linux)
659
+
660
+ **Problem**: Screenshots differ between macOS (local) and Linux (CI).
661
+
662
+ **Solution**: Use Docker for local development
663
+ ```bash
664
+ # Local development with Docker
665
+ docker run -it --rm -v $(pwd):/work -w /work mcr.microsoft.com/playwright:v1.40.0-focal npx playwright test
666
+ ```
667
+
668
+ ## Advanced Techniques
669
+
670
+ ### 1. Visual Regression for Emails
671
+
672
+ ```typescript
673
+ test('email template visual test', async ({ page }) => {
674
+ const emailHtml = await generateEmailTemplate({ userName: 'John', orderTotal: '$99.99' });
675
+
676
+ await page.setContent(emailHtml);
677
+ await expect(page).toHaveScreenshot('order-confirmation-email.png');
678
+ });
679
+ ```
680
+
681
+ ### 2. PDF Visual Testing
682
+
683
+ ```typescript
684
+ test('invoice PDF visual test', async ({ page }) => {
685
+ await page.goto('/invoice/123');
686
+ const pdfBuffer = await page.pdf({ format: 'A4' });
687
+
688
+ // Convert PDF to image and compare
689
+ const pdfImage = await pdfToImage(pdfBuffer);
690
+ expect(pdfImage).toMatchSnapshot('invoice.png');
691
+ });
692
+ ```
693
+
694
+ ### 3. A/B Test Visual Variants
695
+
696
+ ```typescript
697
+ test('A/B test variant visual comparison', async ({ page }) => {
698
+ // Test control variant
699
+ await page.goto('/?variant=control');
700
+ await expect(page).toHaveScreenshot('homepage-control.png');
701
+
702
+ // Test experiment variant
703
+ await page.goto('/?variant=experiment');
704
+ await expect(page).toHaveScreenshot('homepage-experiment.png');
705
+
706
+ // Manual review to ensure both look good
707
+ });
708
+ ```
709
+
710
+ ## Resources
711
+
712
+ - [Playwright Visual Comparisons](https://playwright.dev/docs/test-snapshots)
713
+ - [Percy Documentation](https://docs.percy.io/)
714
+ - [Chromatic Documentation](https://www.chromatic.com/docs/)
715
+ - [BackstopJS](https://github.com/garris/BackstopJS)
716
+
717
+ ## Activation Keywords
718
+
719
+ Ask me about:
720
+ - "How to set up visual regression testing"
721
+ - "Playwright screenshot testing"
722
+ - "Percy vs Chromatic comparison"
723
+ - "Visual testing for components"
724
+ - "How to fix flaky visual tests"
725
+ - "Managing visual baselines in CI"
726
+ - "Cross-browser visual testing"
727
+ - "Screenshot comparison best practices"
728
+ - "Visual regression CI integration"