Skip to content

Commit 0167fb3

Browse files
authored
merge: test: Implement Visual Regression Testing for SVG Generators (#8115)
## Description Fixes #7794 ### Summary This PR implements visual regression testing for the project's SVG generators using **Vitest**, **@resvg/resvg-js**, and **pixelmatch**. ### Changes * Added a visual regression test suite covering all primary SVG generators. * Added baseline PNG snapshots for visual comparison. * Added `test:visual` and `test:visual:update` scripts. * Added `pixelmatch`, `pngjs`, and related development dependencies. * Configured CI to upload visual regression diff artifacts when tests fail. * Ignored generated visual diff outputs via `.gitignore`. * Fixed `font-family` quoting in the Versus SVG generators to ensure valid SVG rendering during visual regression testing. ## Pillar * [ ] 🎨 Pillar 1 — New Theme Design * [ ] 📐 Pillar 2 — Geometric SVG Improvement * [ ] 🕐 Pillar 3 — Timezone Logic Optimization * [x] 🛠️ Other (Bug fix, refactoring, docs) ## Visual Preview N/A (Tooling / Testing change) ## Checklist before requesting a review: * [x] I have read the `CONTRIBUTING.md` file. * [x] I have tested these changes locally (`localhost:3000/api/streak?user=YOUR_USERNAME`). * [x] I have run `npm run format` and `npm run lint` locally and resolved all errors (CI will fail otherwise). * [x] My commits follow the Conventional Commits format (e.g., `feat(themes): ...`, `fix(calculate): ...`). * [ ] I have updated `README.md` if I added a new theme or URL parameter. *(Not applicable)* * [x] I have starred the repo. * [x] I have made sure that I have only one commit to merge in this PR. * [x] The SVG output matches the CommitPulse "premium quality" aesthetic standard. * [x] (Recommended) I joined the CommitPulse Discord community for contributor discussions, mentorship, and faster PR support. ### Local Verification * ✅ `npm run test:visual` * Test Files: **1 passed (1)** * Tests: **20 passed (20)** * ✅ `npm test` * Test Files: **1333 passed | 2 skipped** * Tests: **9283 passed | 1 expected fail | 14 skipped**
2 parents f5de6fc + 7b61821 commit 0167fb3

26 files changed

Lines changed: 403 additions & 2 deletions

.github/workflows/ci.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ jobs:
4747
- name: Run Unit Tests (Vitest)
4848
run: npm run test:coverage
4949

50+
- name: Upload Visual Regression Diffs
51+
if: failure()
52+
uses: actions/upload-artifact@v4
53+
with:
54+
name: visual-test-diffs
55+
path: tests/visual/diffs/
56+
if-no-files-found: ignore
57+
5058
build:
5159
name: Production Build
5260
runs-on: ubuntu-latest

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
# testing
1414
/coverage
15+
/tests/visual/diffs/
1516

1617
# next.js
1718
/.next/

lib/svg/generator.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2488,7 +2488,7 @@ export function generateVersusSVG(
24882488
24892489
<g transform="translate(${singleW}, ${H / 2})">
24902490
<circle cx="0" cy="0" r="${s(24)}" fill="${bg}" stroke="${accent}" stroke-width="2" />
2491-
<text x="0" y="${s(6)}" text-anchor="middle" font-family="${statsFont}" fill="${accent}" font-size="${s(16)}" font-weight="bold">VS</text>
2491+
<text x="0" y="${s(6)}" text-anchor="middle" font-family="${statsFont.replace(/"/g, "'")}" fill="${accent}" font-size="${s(16)}" font-weight="bold">VS</text>
24922492
</g>
24932493
</svg>`;
24942494
}
@@ -2595,7 +2595,7 @@ function generateAutoThemeVersusSVG(
25952595
25962596
<g transform="translate(${singleW}, ${H / 2})">
25972597
<circle cx="0" cy="0" r="${s(24)}" class="cp-bg-fill" stroke="var(--cp-accent)" stroke-width="2" />
2598-
<text x="0" y="${s(6)}" text-anchor="middle" font-family="${statsFont}" class="cp-accent-fill" font-size="${s(16)}" font-weight="bold">VS</text>
2598+
<text x="0" y="${s(6)}" text-anchor="middle" font-family="${statsFont.replace(/"/g, "'")}" class="cp-accent-fill" font-size="${s(16)}" font-weight="bold">VS</text>
25992599
</g>
26002600
</svg>`;
26012601
}

package-lock.json

Lines changed: 73 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
"test": "vitest run",
1515
"test:ui": "vitest --ui",
1616
"test:coverage": "vitest --coverage",
17+
"test:visual": "vitest run tests/visual",
18+
"test:visual:update": "cross-env UPDATE_VISUAL_BASELINES=true vitest run tests/visual",
1719
"bench:svg": "tsx scripts/benchmark-svg.ts",
1820
"check:api-breaking": "tsx scripts/detect-breaking-api-changes.ts",
1921
"prepare": "husky"
@@ -74,19 +76,24 @@
7476
"@types/jspdf": "^1.3.3",
7577
"@types/node": "^20",
7678
"@types/pdf-parse": "^1.1.5",
79+
"@types/pixelmatch": "^5.2.6",
80+
"@types/pngjs": "^6.0.5",
7781
"@types/react": "^19",
7882
"@types/react-dom": "^19",
7983
"@vitejs/plugin-react": "^6.0.2",
8084
"@vitest/coverage-v8": "^4.1.4",
8185
"@vitest/ui": "^4.1.4",
8286
"autoprefixer": "^10.5.0",
87+
"cross-env": "^10.1.0",
8388
"eslint": "^9",
8489
"eslint-config-next": "16.2.3",
8590
"eslint-config-prettier": "^10.1.8",
8691
"husky": "^9.1.7",
8792
"jsdom": "^29.1.1",
8893
"lint-staged": "^15.2.11",
8994
"node-mocks-http": "^1.17.2",
95+
"pixelmatch": "^7.2.0",
96+
"pngjs": "^7.0.0",
9097
"postcss": "^8.5.10",
9198
"prettier": "^3.8.3",
9299
"react-is": "^19.2.6",
50.4 KB
Loading
1.57 KB
Loading
18.9 KB
Loading
41 KB
Loading
4.58 KB
Loading

0 commit comments

Comments
 (0)