cornhsu-parity 0.14.0 → 1.1.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.
- package/README.md +20 -5
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
## GitHub Action
|
|
12
12
|
|
|
13
13
|
```yaml
|
|
14
|
-
- uses: HSU-YU-MING/cornhsu-parity@
|
|
14
|
+
- uses: HSU-YU-MING/cornhsu-parity@v1 # @v1 tracks the latest 1.x (interfaces frozen since 1.0)
|
|
15
15
|
with:
|
|
16
16
|
config: parity.config.json # optional, defaults to parity.config.json
|
|
17
17
|
target: /pricing # optional, check only this route (omit for all)
|
|
@@ -63,11 +63,11 @@ PR comment, updating the same comment rather than adding new ones.
|
|
|
63
63
|
|
|
64
64
|
| | |
|
|
65
65
|
|---|---|
|
|
66
|
-
| Releases |
|
|
66
|
+
| Releases | 27 on NuGet (v0.1.0 → v1.1.0). Pushing a tag publishes via OIDC Trusted Publishing — zero long-lived keys in the repo |
|
|
67
67
|
| Compared properties | Size, padding, spacing, typography, color (CIEDE2000 ΔE), relative position — **absolute coordinates are deliberately excluded** (they are guaranteed false positives in a flexible layout) |
|
|
68
68
|
| Design sources | 4: the Figma API, a rendering snapshot, an image + annotations (pixel sampling — any tool that exports a PNG works), or JSON |
|
|
69
69
|
| Implementation sources | The web (including **shadow DOM, same-origin iframes, and multiple responsive breakpoints**) plus **Electron** (attached to the live window over CDP) |
|
|
70
|
-
| Tests | **
|
|
70
|
+
| Tests | **208**, covering the CIEDE2000 reference data set (Sharma), match disambiguation, position false-positive guards, image sampling, and real-browser capture regressions |
|
|
71
71
|
| Proven in CI | The GitHub Action is validated by **real PRs in an external repo**: blocking the PR, commenting automatically (updating in place), and baseline regression gating |
|
|
72
72
|
| Proven in production | **All 21 pages of cornhsu.com are gated by Parity itself** — dogfooding has already found and fixed three flaky root causes (most recently a scroll-triggered entrance animation; see 0.11.1) |
|
|
73
73
|
|
|
@@ -173,7 +173,7 @@ electron . --remote-debugging-port=9222 # your app, with this one extra fla
|
|
|
173
173
|
| Design source | config | Who it is for |
|
|
174
174
|
|---|---|---|
|
|
175
175
|
| **Figma** (primary) | `figmaFileKey` + `FIGMA_TOKEN` | The normal workflow, when you have a Figma file |
|
|
176
|
-
| **Snapshot** (`parity snapshot`) | `designFile` pointing at the generated snapshot JSON | **Refactor/redesign guard**: today's rendering is correct, so freeze it as the baseline and later checks prove nothing drifted (the numeric version of visual regression). Matching goes through selector identity, so it is 100% deterministic — randomized ids (React `useId`, CSS-in-JS) are detected at capture time and replaced with structural paths, so they survive regeneration. Baselines taken by older versions may list such nodes as unmatched (reason `randomized-id`); re-run `parity snapshot` once to migrate |
|
|
176
|
+
| **Snapshot** (`parity snapshot`) | `designFile` pointing at the generated snapshot JSON | **Refactor/redesign guard**: today's rendering is correct, so freeze it as the baseline and later checks prove nothing drifted (the numeric version of visual regression). Matching goes through selector identity, so it is 100% deterministic — randomized ids (React `useId`, CSS-in-JS) are detected at capture time and replaced with structural paths, so they survive regeneration; purely alphabetic random ids (the kind character heuristics cannot see) are caught **empirically**: snapshot loads the page twice, ids that differ between loads are never used as anchors, and the measured stable-id allowlist is stored in the snapshot for `check` to anchor the same way. Baselines taken by older versions may list such nodes as unmatched (reason `randomized-id`); re-run `parity snapshot` once to migrate |
|
|
177
177
|
| **An image + annotations** | `designImage` (PNG/JPG) + `designFile` (annotations) | When all you have is a picture: an outsourced PNG, or a legacy project down to screenshots. **This is also the path for XD / Sketch / Photoshop and anything else that can export an image** — a universal adapter. The annotations are DesignNode JSON, and `fill` may be omitted: the engine samples the color from the corresponding region of the image. (Text color is deliberately not sampled — anti-aliasing blends it and the reading is unreliable — but you can fill it in by hand.) |
|
|
178
178
|
| Hand-written JSON | `designFile` | Offline demos and tests |
|
|
179
179
|
|
|
@@ -184,6 +184,14 @@ parity snapshot # 1. Freeze the current rendering (writes parity.snap
|
|
|
184
184
|
parity check # 2. Refactor fearlessly; 3. check proves it still matches the snapshot
|
|
185
185
|
```
|
|
186
186
|
|
|
187
|
+
## Picking a Figma frame: three lessons from wild testing
|
|
188
|
+
|
|
189
|
+
Everything below was measured on public design-system files (IBM Carbon, Ant Design, Wikimedia Codex — method and full findings in `docs/野生實查-2026-08-11-路線B-figma方言.md`):
|
|
190
|
+
|
|
191
|
+
1. **Pick a frame that draws *one screen*, not the component master sheet.** Design-system kits lay every variant out on a single sheet; that sheet shares no structure with any real page, so the match rate will hug the floor (measured: 0.2% on Carbon's Button sheet, 5.8% on Codex's) — that is the matcher being honest, not broken. To check a single component, pair a **single variant node** against a single Storybook story or one component on a demo page.
|
|
192
|
+
2. **If the kit's text is placeholder text, go straight to the map file.** Auto-matching leans on text anchoring (same text on both sides), but library components often say "Button text" — which no real page ever does. Skip auto-matching and write `parity.map.json` directly (measured on Codex: all 129 Button variants use placeholder text; one map line completed the pairing).
|
|
193
|
+
3. **Free-plan API quota is measured in *days* — spend it on new frames only.** Figma's free-plan quota is plan-level: one or two queries against a large file can drain it, and `Retry-After` comes back counted in days (hit twice during testing: 4.3 and 3.7 days). Frames you have fetched live on in `.parity/cache`, so reruns and offline compares cost nothing — the quota only goes to frames you have never fetched.
|
|
194
|
+
|
|
187
195
|
## What gets compared, and what does not
|
|
188
196
|
|
|
189
197
|
Only the things that should hold no matter how the layout flows:
|
|
@@ -318,7 +326,7 @@ jobs:
|
|
|
318
326
|
- run: |
|
|
319
327
|
npm ci && npm run build
|
|
320
328
|
npm run preview & # e.g. serving on localhost:8080
|
|
321
|
-
- uses: HSU-YU-MING/cornhsu-parity@
|
|
329
|
+
- uses: HSU-YU-MING/cornhsu-parity@v1 # @v1 tracks the latest 1.x
|
|
322
330
|
with:
|
|
323
331
|
config: parity.config.json
|
|
324
332
|
figma-token: ${{ secrets.FIGMA_TOKEN }} # omit when the design source is a local JSON file
|
|
@@ -393,6 +401,13 @@ file is released immediately), and the engine's `BaselineComparer` is a pure, un
|
|
|
393
401
|
|
|
394
402
|
## See also
|
|
395
403
|
|
|
404
|
+
[**設計還原度怎麼自動檢查**](https://cornhsu.com/articles/figma-design-fidelity-check)
|
|
405
|
+
(in Traditional Chinese) — background on the whole category rather than this tool: what overlays,
|
|
406
|
+
pixel regression and property-level comparison each actually answer, why colour needs CIEDE2000
|
|
407
|
+
instead of hex equality, why absolute coordinates cannot be compared at all, and where this class
|
|
408
|
+
of tool does not help (SVG paths, font rasterisation, shadows, image cropping). It names the other
|
|
409
|
+
tools in the space and says when to pick one of them over this one.
|
|
410
|
+
|
|
396
411
|
[**XamlContrast**](https://github.com/HSU-YU-MING/cornhsu-xamlcontrast) — a sibling project by the
|
|
397
412
|
same author, built on the same philosophy: numeric checks that gate CI. Parity answers "**does the
|
|
398
413
|
implementation match the design?**" (fidelity); XamlContrast answers "**can anyone actually see
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cornhsu-parity",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Property-Level Design QA that can gate your CI. Compares real numeric values from your Figma file against the rendered UI and fails the PR when the implementation drifts from the design.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"figma",
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"node": ">=18"
|
|
35
35
|
},
|
|
36
36
|
"optionalDependencies": {
|
|
37
|
-
"@cornhsu/parity-win32-x64": "
|
|
38
|
-
"@cornhsu/parity-win32-arm64": "
|
|
39
|
-
"@cornhsu/parity-linux-x64": "
|
|
40
|
-
"@cornhsu/parity-linux-arm64": "
|
|
41
|
-
"@cornhsu/parity-darwin-x64": "
|
|
42
|
-
"@cornhsu/parity-darwin-arm64": "
|
|
37
|
+
"@cornhsu/parity-win32-x64": "1.1.0",
|
|
38
|
+
"@cornhsu/parity-win32-arm64": "1.1.0",
|
|
39
|
+
"@cornhsu/parity-linux-x64": "1.1.0",
|
|
40
|
+
"@cornhsu/parity-linux-arm64": "1.1.0",
|
|
41
|
+
"@cornhsu/parity-darwin-x64": "1.1.0",
|
|
42
|
+
"@cornhsu/parity-darwin-arm64": "1.1.0"
|
|
43
43
|
}
|
|
44
44
|
}
|