Skip to content

Commit f6267b6

Browse files
committed
up
1 parent 305ed5b commit f6267b6

2 files changed

Lines changed: 234 additions & 0 deletions

File tree

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
name: Percy Visual Regression Tests
2+
3+
# Purpose: Capture and compare visual snapshots of critical UI components
4+
# Constitution requirement: Percy integration with 0.1% difference threshold
5+
# Runs on: Every PR to detect visual regressions, every push to main to update baseline
6+
#
7+
# Workflow:
8+
# 1. PR opened/updated → Capture snapshots → Compare against main baseline
9+
# 2. Differences > 0.1% → Flag for manual review in Percy dashboard
10+
# 3. Developer reviews and approves/rejects visual changes
11+
# 4. Once approved → Status check passes → PR can merge
12+
# 5. PR merged to main → Snapshots become new baseline for future comparisons
13+
14+
on:
15+
pull_request:
16+
# Run on PRs to compare against baseline
17+
branches:
18+
- main
19+
- develop
20+
- 'feature/**'
21+
paths:
22+
# Only run when UI code changes
23+
- 'src/app/**'
24+
- 'src/components/**'
25+
- 'src/styles/**'
26+
- 'public/**'
27+
- 'tailwind.config.ts'
28+
- 'tests/visual/**'
29+
- '.percy.yml'
30+
push:
31+
# Run on main to update baseline snapshots
32+
branches:
33+
- main
34+
workflow_dispatch:
35+
# Allow manual trigger for baseline updates
36+
37+
# Environment variables for Percy
38+
env:
39+
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
40+
PERCY_BRANCH: ${{ github.head_ref || github.ref_name }}
41+
PERCY_COMMIT: ${{ github.sha }}
42+
PERCY_PULL_REQUEST: ${{ github.event.pull_request.number }}
43+
NODE_ENV: test
44+
DATABASE_URL: file:./prisma/test.db
45+
NEXTAUTH_SECRET: test-secret-for-ci
46+
NEXTAUTH_URL: http://localhost:3000
47+
48+
jobs:
49+
percy-visual-tests:
50+
name: Percy Visual Regression
51+
runs-on: ubuntu-latest
52+
timeout-minutes: 30
53+
54+
strategy:
55+
fail-fast: false
56+
matrix:
57+
# Run tests in parallel for faster execution
58+
shard: [1, 2]
59+
60+
steps:
61+
- name: Checkout code
62+
uses: actions/checkout@v4
63+
with:
64+
fetch-depth: 0 # Fetch full history for Percy baseline comparison
65+
66+
- name: Setup Node.js
67+
uses: actions/setup-node@v4
68+
with:
69+
node-version: '20.x'
70+
cache: 'npm'
71+
72+
- name: Install dependencies
73+
run: npm ci
74+
75+
- name: Install Playwright browsers
76+
run: npx playwright install --with-deps chromium
77+
78+
- name: Setup test database
79+
run: |
80+
npx prisma generate
81+
npx prisma db push --skip-generate
82+
npx prisma db seed
83+
84+
- name: Build Next.js application
85+
run: npm run build
86+
87+
- name: Start Next.js server
88+
run: |
89+
npm run start &
90+
npx wait-on http://localhost:3000 --timeout 60000
91+
env:
92+
PORT: 3000
93+
94+
- name: Run Percy visual tests
95+
run: |
96+
npx percy exec -- npx playwright test tests/visual/percy.spec.ts \
97+
--shard=${{ matrix.shard }}/2 \
98+
--reporter=list
99+
env:
100+
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
101+
PERCY_PARALLEL_NONCE: ${{ github.run_id }}-${{ github.run_attempt }}
102+
PERCY_PARALLEL_TOTAL: 2
103+
104+
- name: Upload Playwright test results
105+
if: failure()
106+
uses: actions/upload-artifact@v4
107+
with:
108+
name: percy-test-results-${{ matrix.shard }}
109+
path: |
110+
test-results/
111+
playwright-report/
112+
retention-days: 7
113+
114+
percy-finalize:
115+
name: Finalize Percy Build
116+
runs-on: ubuntu-latest
117+
needs: percy-visual-tests
118+
if: always()
119+
timeout-minutes: 5
120+
121+
steps:
122+
- name: Checkout code
123+
uses: actions/checkout@v4
124+
125+
- name: Setup Node.js
126+
uses: actions/setup-node@v4
127+
with:
128+
node-version: '20.x'
129+
130+
- name: Install Percy CLI
131+
run: npm install -g @percy/cli
132+
133+
- name: Finalize Percy build
134+
run: npx percy build:finalize
135+
env:
136+
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
137+
PERCY_PARALLEL_NONCE: ${{ github.run_id }}-${{ github.run_attempt }}
138+
139+
percy-status-check:
140+
name: Percy Status Check
141+
runs-on: ubuntu-latest
142+
needs: percy-finalize
143+
if: github.event_name == 'pull_request'
144+
timeout-minutes: 10
145+
146+
steps:
147+
- name: Wait for Percy to finish processing
148+
run: sleep 30
149+
150+
- name: Check Percy build status
151+
run: |
152+
echo "Percy build complete. Review visual changes at:"
153+
echo "https://percy.io/${{ github.repository_owner }}/stormcom/builds"
154+
echo ""
155+
echo "If visual differences > 0.1% threshold detected:"
156+
echo "1. Review snapshots in Percy dashboard"
157+
echo "2. Approve or reject visual changes"
158+
echo "3. Once approved, status check will pass"
159+
160+
- name: Comment Percy results on PR
161+
if: github.event_name == 'pull_request'
162+
uses: actions/github-script@v7
163+
with:
164+
script: |
165+
const percyUrl = `https://percy.io/${{ github.repository_owner }}/stormcom/builds`;
166+
const comment = `## Percy Visual Regression Results
167+
168+
Visual regression tests have completed for this PR.
169+
170+
📸 **Review snapshots**: [Percy Dashboard](${percyUrl})
171+
172+
**Next steps:**
173+
1. Review visual changes in Percy dashboard
174+
2. Approve or reject snapshots
175+
3. Once approved, this status check will pass
176+
177+
**Threshold**: Differences > 0.1% require manual approval
178+
**Critical pages tested**: Dashboard, Checkout, Product List, Admin Settings
179+
**Viewports**: Mobile (375px), Tablet (768px), Desktop (1280px)
180+
`;
181+
182+
github.rest.issues.createComment({
183+
issue_number: context.issue.number,
184+
owner: context.repo.owner,
185+
repo: context.repo.repo,
186+
body: comment
187+
});
188+
189+
# Percy baseline management:
190+
#
191+
# Creating initial baseline:
192+
# 1. Merge first PR with visual tests to main
193+
# 2. Percy captures snapshots from main branch
194+
# 3. These become the baseline for future comparisons
195+
#
196+
# Updating baseline (intentional visual changes):
197+
# 1. Make UI changes in feature branch
198+
# 2. Open PR → Percy compares against baseline
199+
# 3. Review visual differences in Percy dashboard
200+
# 4. Approve snapshots in Percy UI
201+
# 5. Merge PR → New snapshots become baseline
202+
#
203+
# Reverting to previous baseline:
204+
# 1. Find previous build in Percy dashboard
205+
# 2. Set as baseline manually
206+
# 3. Or revert code changes and merge
207+
#
208+
# Percy dashboard: https://percy.io/[org]/stormcom
209+
# Percy docs: https://docs.percy.io/
210+
211+
# Troubleshooting:
212+
#
213+
# Percy token not found:
214+
# - Add PERCY_TOKEN to GitHub repository secrets
215+
# - Get token from: https://percy.io/settings
216+
#
217+
# Snapshots are inconsistent:
218+
# - Check for dynamic timestamps (add to percyCSS hide list)
219+
# - Verify animations are disabled (see percy.spec.ts)
220+
# - Ensure test data is seeded consistently
221+
# - Wait for networkidle before capturing snapshots
222+
#
223+
# Status check not updating:
224+
# - Check Percy dashboard for build status
225+
# - Verify webhook configuration in Percy settings
226+
# - Ensure PERCY_TOKEN has correct permissions
227+
#
228+
# Parallel builds failing:
229+
# - Increase PERCY_PARALLEL_TOTAL if needed
230+
# - Check for shard configuration issues
231+
# - Review Percy CLI logs for errors

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
"test:coverage": "node --max-old-space-size=4096 ./node_modules/vitest/vitest.mjs run --coverage",
2121
"test:e2e": "playwright test",
2222
"test:e2e:ui": "playwright test --ui",
23+
"test:percy": "percy exec -- playwright test tests/visual/percy.spec.ts",
24+
"test:percy:local": "percy exec --verbose -- playwright test tests/visual/percy.spec.ts",
25+
"percy:baseline": "percy exec -- playwright test tests/visual/percy.spec.ts --update-snapshots",
2326
"lighthouse": "lhci autorun --config=lighthouserc.js",
2427
"lighthouse:mobile": "lhci autorun --config=lighthouserc.mobile.js",
2528
"k6:checkout": "k6 run tests/performance/checkout-load-test.js",

0 commit comments

Comments
 (0)