styleproof 1.0.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/CHANGELOG.md +204 -0
- package/LICENSE +21 -0
- package/README.md +661 -0
- package/bin/styleproof-diff.mjs +110 -0
- package/bin/styleproof-init.mjs +190 -0
- package/bin/styleproof-report.mjs +106 -0
- package/dist/capture.d.ts +79 -0
- package/dist/capture.js +323 -0
- package/dist/diff.d.ts +51 -0
- package/dist/diff.js +121 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +4 -0
- package/dist/report.d.ts +45 -0
- package/dist/report.js +463 -0
- package/dist/runner.d.ts +45 -0
- package/dist/runner.js +35 -0
- package/docs/demo-composite.png +0 -0
- package/package.json +86 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to **StyleProof** are documented here.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
|
|
6
|
+
this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [1.0.0]
|
|
11
|
+
|
|
12
|
+
First stable release and first publish to npm. The capture format, the public API
|
|
13
|
+
(`src/index.ts`), the three CLIs, and the GitHub Action are now considered stable under
|
|
14
|
+
semver. This release also lands the engine and packaging hardening below.
|
|
15
|
+
|
|
16
|
+
> **Upgrading from 0.x:** the pseudo-element pruning fix changes captured output for
|
|
17
|
+
> elements with pseudo-elements, so a baseline captured by an earlier version may show
|
|
18
|
+
> spurious diffs on first run — regenerate your committed baseline once after upgrading.
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- Published to npm as `styleproof`; install with
|
|
23
|
+
`npm i -D styleproof @playwright/test`.
|
|
24
|
+
- `styleproof-init` CLI: scaffold a starter capture spec (and `playwright.config.ts`) into
|
|
25
|
+
any project.
|
|
26
|
+
- `styleproof-report` CLI flags `--pad`, `--max-crops`, `--min-width`, `--min-height`,
|
|
27
|
+
`--include-layout-noise`; `-h`/`--help` on all three CLIs.
|
|
28
|
+
- `CaptureOptions.captureStates` (default true) and `CaptureOptions.maxInteractive`
|
|
29
|
+
(default 800) to skip or cap the expensive forced-state layer on huge pages.
|
|
30
|
+
- `summarizeProps` and `prettyLabel` are now exported for downstream report builders.
|
|
31
|
+
- A real test suite (`node:test` unit tests + a self-contained Playwright smoke), a CI
|
|
32
|
+
matrix (Node 18/20/22), and a provenance-signed release workflow.
|
|
33
|
+
- Full documentation set: complete README (API/CLI/Action reference tables, CI recipes,
|
|
34
|
+
env-parity and determinism guidance, limitations, troubleshooting, a comparison vs
|
|
35
|
+
pixel-snapshot tools), `CONTRIBUTING.md`, this `CHANGELOG.md`, plus
|
|
36
|
+
`CODE_OF_CONDUCT.md`, `SECURITY.md`, and issue/PR templates.
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
|
|
40
|
+
- **Pseudo-elements are pruned against their own UA defaults**, not the host element's
|
|
41
|
+
tag defaults — a pseudo-element's computed baseline differs from the element's, so the
|
|
42
|
+
old pruning could both drop real changes and bloat the file. (Behaviour change; see the
|
|
43
|
+
upgrade note above.)
|
|
44
|
+
- **CDP/page interactive-element count skew no longer aborts the capture.** It warns and
|
|
45
|
+
skips only the forced-state layer for that surface (base + pseudo capture still
|
|
46
|
+
succeed), and records `statesSkipped` on the map so a diff against a fully-captured side
|
|
47
|
+
flags the gap loudly instead of reading as "identical".
|
|
48
|
+
- **Shadow DOM and iframe content** are surfaced with a one-time capture warning counting
|
|
49
|
+
the shadow hosts / same-origin frames skipped, so the (still-present) non-traversal
|
|
50
|
+
limitation is loud, not silent.
|
|
51
|
+
- Both `loadStyleMap`-backed CLIs now exit `2` with a file-naming message on a
|
|
52
|
+
corrupt/truncated `.gz`, instead of a raw zlib stack trace.
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
|
|
56
|
+
- Public API and capture/serialization format frozen under semver: a change to the map
|
|
57
|
+
structure, an exported type, a CLI flag, or an Action input is now a versioned revision.
|
|
58
|
+
- The GitHub Action's report-branch push is re-derived from the current remote tip on each
|
|
59
|
+
retry (concurrency-safe on a first-run race, no `rebase` unrelated-histories trap), and
|
|
60
|
+
public-repo inline images get a `?v=<sha>` cache-bust so an overwritten crop can't serve
|
|
61
|
+
stale from the CDN.
|
|
62
|
+
|
|
63
|
+
## [0.7.0]
|
|
64
|
+
|
|
65
|
+
### Added
|
|
66
|
+
|
|
67
|
+
- **Readable property tables in the report and PR comment.** The raw diff is a wall of
|
|
68
|
+
longhands (one `border` change is 16 entries, one `color` change drags 8
|
|
69
|
+
`currentColor` echoes); the report now renders per-element tables that collapse
|
|
70
|
+
shorthand families (`border-width`/`-style`/`-color`, `border-radius`,
|
|
71
|
+
`margin`/`padding` via CSS 1–4-value notation, `gap`), drop logical-property
|
|
72
|
+
duplicates and `currentColor` echoes, fold repeated tokens (`368px ×3`) and round
|
|
73
|
+
decimals, group identical sibling elements into one `×N` block, label by the semantic
|
|
74
|
+
marker class (`div.who-grid`, `a.nav-cta`) instead of the structural path, and put
|
|
75
|
+
each colour in its own cell so GitHub renders swatches.
|
|
76
|
+
|
|
77
|
+
### Changed
|
|
78
|
+
|
|
79
|
+
- The PR-comment action embeds these text tables (so they render even on private repos)
|
|
80
|
+
instead of a raw diff dump; public repos also inline the images, private repos link
|
|
81
|
+
them.
|
|
82
|
+
- Report header counts the collapsed total, not the raw longhand count.
|
|
83
|
+
- The certification differ (`styleproof-diff`) stays raw and complete — only the report
|
|
84
|
+
collapses.
|
|
85
|
+
|
|
86
|
+
## [0.6.0]
|
|
87
|
+
|
|
88
|
+
### Changed
|
|
89
|
+
|
|
90
|
+
- **Reports crop the component, not the page.** A layout change reflows the page, so
|
|
91
|
+
`height`/`width`/`transform-origin`/`perspective-origin` and `top`/`left`/`inset`
|
|
92
|
+
shift all the way up the ancestor chain (`body`, `main`, `section`…). Those ancestors
|
|
93
|
+
were becoming the "outermost changed element", so an organism-level change cropped to
|
|
94
|
+
the entire page. The report now ignores size/position-derived longhands when choosing
|
|
95
|
+
crop anchors and in its findings.
|
|
96
|
+
|
|
97
|
+
### Added
|
|
98
|
+
|
|
99
|
+
- `includeLayoutNoise: true` (`ReportOptions`) restores those longhands in the report.
|
|
100
|
+
The certification differ keeps them unconditionally — a reflow is a change to certify.
|
|
101
|
+
|
|
102
|
+
## [0.5.0]
|
|
103
|
+
|
|
104
|
+
### Added
|
|
105
|
+
|
|
106
|
+
- **Orphan report branch with stable per-PR links.** Reports live on a `styleproof-reports`
|
|
107
|
+
orphan branch (reports only, never your code); each run overwrites `pr-<n>/`, so the
|
|
108
|
+
report URL is permanent for the PR's life and reports are never pruned.
|
|
109
|
+
- **Public/private image modes** via `inline-images: auto` — public repos embed
|
|
110
|
+
composites directly in the comment (public raw URL); private repos link the committed
|
|
111
|
+
`report.md`, whose relative images render through the viewer's authenticated session.
|
|
112
|
+
- Concurrency-safe additive pushes with a rebase-retry loop (different PRs touch
|
|
113
|
+
different folders).
|
|
114
|
+
- A squash snippet in the README to reclaim orphan-branch git history without breaking
|
|
115
|
+
current report URLs.
|
|
116
|
+
|
|
117
|
+
### Changed
|
|
118
|
+
|
|
119
|
+
- Leaner images: commit only the composite (not the separate before/after crops), and
|
|
120
|
+
write PNGs lossless-but-lean — drop alpha (crops are opaque), max deflate, adaptive
|
|
121
|
+
filtering (~15% smaller).
|
|
122
|
+
|
|
123
|
+
## [0.4.0]
|
|
124
|
+
|
|
125
|
+
### Fixed
|
|
126
|
+
|
|
127
|
+
- **Private-repo inline images.** The earlier action embedded `raw.githubusercontent`
|
|
128
|
+
image URLs in the comment body; GitHub's Camo proxy fetches those anonymously, so they
|
|
129
|
+
404 on private repos. The action now commits the report to a branch and **links** it
|
|
130
|
+
from the comment — a committed file's relative images render inline through the
|
|
131
|
+
viewer's authenticated session, like a private README's images. Fully automated,
|
|
132
|
+
token-only, no browser, no public hosting.
|
|
133
|
+
|
|
134
|
+
### Added
|
|
135
|
+
|
|
136
|
+
- `report-url` output on the action.
|
|
137
|
+
- Path-safe crop filenames (`hero@1280` → `hero-1280`) so relative links resolve in any
|
|
138
|
+
markdown host.
|
|
139
|
+
|
|
140
|
+
## [0.3.0]
|
|
141
|
+
|
|
142
|
+
### Changed
|
|
143
|
+
|
|
144
|
+
- **One composite image per change.** The report stitches each region's before/after
|
|
145
|
+
crops into a single labelled image (before-left / after-right, divider, grey→blue
|
|
146
|
+
accent bars as a font-free cue) and embeds that one image per change — one upload,
|
|
147
|
+
reads cleanly inline.
|
|
148
|
+
|
|
149
|
+
## [0.2.1]
|
|
150
|
+
|
|
151
|
+
### Added
|
|
152
|
+
|
|
153
|
+
- `Surface.height` may be a function of width (`height?: number | ((width: number) =>
|
|
154
|
+
number)`), so each viewport band can capture at its own height. Default remains 800.
|
|
155
|
+
|
|
156
|
+
## [0.2.0]
|
|
157
|
+
|
|
158
|
+
### Added
|
|
159
|
+
|
|
160
|
+
- **Visual diff reports.** `styleproof-report` (and `generateStyleMapReport`) crop the
|
|
161
|
+
before/after full-page screenshots around the outermost changed element (descendants
|
|
162
|
+
fold into ancestors, nearby regions merge, both sides framed at identical dimensions)
|
|
163
|
+
and write PR-comment-ready markdown with the exact property changes — `report.md`,
|
|
164
|
+
`report.json`, and `crops/`. Uses `pngjs` only; no native deps.
|
|
165
|
+
- Captures now record each element's document-space bounding box, and the runner saves a
|
|
166
|
+
full-page screenshot per capture (`screenshots: false` to opt out), so the committed
|
|
167
|
+
baseline carries pixels and reports never rebuild the old code.
|
|
168
|
+
- `--json <file>` on `styleproof-diff`.
|
|
169
|
+
- A composite GitHub Action: diff against the committed baseline, publish crops, upsert
|
|
170
|
+
a PR comment, flip it to ✓ when clean.
|
|
171
|
+
|
|
172
|
+
### Changed
|
|
173
|
+
|
|
174
|
+
- Diff core extracted to `src/diff.ts` with typed `Finding`s, shared by both CLIs.
|
|
175
|
+
|
|
176
|
+
## [0.1.0]
|
|
177
|
+
|
|
178
|
+
### Added
|
|
179
|
+
|
|
180
|
+
- Initial release, extracted from a production CSS-to-Tailwind migration (~680 lines
|
|
181
|
+
certified to zero diff).
|
|
182
|
+
- `captureStyleMap` records every computed longhand on every element (pruned against
|
|
183
|
+
per-tag UA defaults measured in a stylesheet-free iframe), the pseudo-elements
|
|
184
|
+
`::before`/`::after`/`::marker`/`::placeholder`, declared transition/animation
|
|
185
|
+
longhands (frozen so every other value is a settled end state), and forced
|
|
186
|
+
`:hover`/`:focus`(`-visible`)/`:active` deltas via the Chrome DevTools Protocol.
|
|
187
|
+
- Maps are keyed by DOM structure, never class names, so a migration can rewrite every
|
|
188
|
+
`class` attribute while the map stays comparable. Custom properties (`--*`) are
|
|
189
|
+
ignored — inputs, not outcomes.
|
|
190
|
+
- `defineStyleMapCapture` generates one Playwright test per surface × width, inert until
|
|
191
|
+
`STYLEMAP_DIR` is set; `saveStyleMap`/`loadStyleMap` persist `.json` or `.json.gz`.
|
|
192
|
+
- `styleproof-diff` CLI: certifies a refactor (exit 0) or names the exact element,
|
|
193
|
+
property, and state that drifted (exit 1).
|
|
194
|
+
|
|
195
|
+
[Unreleased]: https://github.com/BenSheridanEdwards/styleproof/compare/v1.0.0...HEAD
|
|
196
|
+
[1.0.0]: https://github.com/BenSheridanEdwards/styleproof/compare/v0.7.0...v1.0.0
|
|
197
|
+
[0.7.0]: https://github.com/BenSheridanEdwards/styleproof/compare/v0.6.0...v0.7.0
|
|
198
|
+
[0.6.0]: https://github.com/BenSheridanEdwards/styleproof/compare/v0.5.0...v0.6.0
|
|
199
|
+
[0.5.0]: https://github.com/BenSheridanEdwards/styleproof/compare/v0.4.0...v0.5.0
|
|
200
|
+
[0.4.0]: https://github.com/BenSheridanEdwards/styleproof/compare/v0.3.0...v0.4.0
|
|
201
|
+
[0.3.0]: https://github.com/BenSheridanEdwards/styleproof/compare/v0.2.1...v0.3.0
|
|
202
|
+
[0.2.1]: https://github.com/BenSheridanEdwards/styleproof/compare/v0.2.0...v0.2.1
|
|
203
|
+
[0.2.0]: https://github.com/BenSheridanEdwards/styleproof/compare/v0.1.0...v0.2.0
|
|
204
|
+
[0.1.0]: https://github.com/BenSheridanEdwards/styleproof/releases/tag/v0.1.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ben Sheridan-Edwards
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|