@variance-authority/storybook-collector 0.14.0 → 0.19.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 +516 -0
- package/README.md +103 -37
- package/dist/contract.d.ts +44 -9
- package/dist/contract.js.map +1 -1
- package/dist/execution.d.ts +16 -60
- package/dist/execution.js +37 -110
- package/dist/execution.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +70 -8
- package/dist/index.js.map +1 -1
- package/dist/options.d.ts +25 -3
- package/dist/options.js.map +1 -1
- package/dist/page-agent-entry.js +6 -0
- package/dist/page-agent-entry.js.map +1 -1
- package/dist/page-agent.bundle.js +3333 -2327
- package/dist/page-agent.d.ts +11 -2
- package/dist/page-agent.js +7 -3
- package/dist/page-agent.js.map +1 -1
- package/dist/parameters.d.ts +24 -8
- package/dist/parameters.js +49 -35
- package/dist/parameters.js.map +1 -1
- package/dist/preset.d.ts +62 -0
- package/dist/preset.js +331 -0
- package/dist/preset.js.map +1 -0
- package/dist/read.d.ts +2 -1
- package/dist/read.js +28 -10
- package/dist/read.js.map +1 -1
- package/dist/serve.js +9 -0
- package/dist/serve.js.map +1 -1
- package/dist/source.d.ts +17 -6
- package/dist/source.js +15 -10
- package/dist/source.js.map +1 -1
- package/dist/world.d.ts +23 -9
- package/dist/world.js +20 -20
- package/dist/world.js.map +1 -1
- package/package.json +17 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,521 @@
|
|
|
1
1
|
# @variance-authority/storybook-collector
|
|
2
2
|
|
|
3
|
+
## 0.19.0
|
|
4
|
+
|
|
5
|
+
Lockstep release — nothing in this package changed. Every `@variance-authority/*` package shares one version.
|
|
6
|
+
|
|
7
|
+
## 0.18.0
|
|
8
|
+
|
|
9
|
+
Lockstep release — nothing in this package changed. Every `@variance-authority/*` package shares one version.
|
|
10
|
+
|
|
11
|
+
## 0.17.1
|
|
12
|
+
|
|
13
|
+
Lockstep release — nothing in this package changed. Every `@variance-authority/*` package shares one version.
|
|
14
|
+
|
|
15
|
+
## 0.17.0
|
|
16
|
+
|
|
17
|
+
Lockstep release — nothing in this package changed. Every `@variance-authority/*` package shares one version.
|
|
18
|
+
|
|
19
|
+
## 0.16.0
|
|
20
|
+
|
|
21
|
+
### Minor Changes
|
|
22
|
+
|
|
23
|
+
- 402ce9f: A story's parameters are read when the story is reached, so no story file is imported before its story comes up
|
|
24
|
+
|
|
25
|
+
Your Storybook run used to read every story's `parameters.variance` before the
|
|
26
|
+
first story, through the preview's `extract()`. That imported every story file
|
|
27
|
+
up front: on a large Storybook you paid for the whole build before seeing one
|
|
28
|
+
story, and each file's first story then timed its import as 0 in `collect`.
|
|
29
|
+
|
|
30
|
+
The run now plans from `index.json` alone. When it reaches a story, it asks the
|
|
31
|
+
preview for that story's merged parameters, which imports only that story's
|
|
32
|
+
file, the import showing the story would have made anyway. That import is
|
|
33
|
+
charged to the story's `collect`, so the first story of each file carries what
|
|
34
|
+
its file costs. A story that excludes itself is still skipped and listed in the
|
|
35
|
+
report with its reason, and a story whose parameters cannot be read is read at
|
|
36
|
+
your run's `viewport` with a warning naming it. A preview too old to read one
|
|
37
|
+
story's parameters says so once per run, not once per story.
|
|
38
|
+
|
|
39
|
+
A story that declares `widths` is still read as `<story id>@<width>` at each
|
|
40
|
+
width, with its own baseline, and all its widths are read on the same page in
|
|
41
|
+
one visit: nothing is opened, booted or loaded again for a second width. A
|
|
42
|
+
run that does not read such a story, because `--subjects`, `--since` or a shard
|
|
43
|
+
left it out, because its visit failed, or because its parameters could not be read, still counts its width baselines as
|
|
44
|
+
planned rather than naming them as baselines your plan no longer holds. A
|
|
45
|
+
story that excludes itself when it is reached holds no subject of the run, so
|
|
46
|
+
every baseline it left, under its own id and at each width, is named. A
|
|
47
|
+
shard prices the story at the sum of the widths its last visit read.
|
|
48
|
+
|
|
49
|
+
If you write a collector, `collect` may now return a `Visit` instead of a
|
|
50
|
+
`Collected`: every subject the visit to the planned one produced, each with its own
|
|
51
|
+
result, each id the planned id or the planned id at a width (`<id>@<width>`),
|
|
52
|
+
and any warnings the visit raised. A visit that could not learn every subject
|
|
53
|
+
it realizes, such as a story read without its parameters, says `incomplete: true`.
|
|
54
|
+
A visit that produced no subject is
|
|
55
|
+
reported as a failed one, and so is a visit that produced any other id. The run and `variance collect` report each subject
|
|
56
|
+
at the position the plan gave the planned subject, and evidence parts record
|
|
57
|
+
the planned id as `of`; a merge refuses a part whose subject is neither. A
|
|
58
|
+
`--subjects` glob that names one width, such as `*@375`, now reaches the story
|
|
59
|
+
it comes from, and only a width suffix extends a story id: `button--primary`
|
|
60
|
+
no longer reaches `button--primary-large`.
|
|
61
|
+
|
|
62
|
+
`@variance-authority/core/format` exports `atWidth`, which writes a subject's
|
|
63
|
+
id and name at a width, and `widenedFrom`, which reads the planned id back
|
|
64
|
+
from a width id, and `realizes`, which says whether a visit to one id may
|
|
65
|
+
produce another.
|
|
66
|
+
|
|
67
|
+
`readParameters(page)` is now `readParameters(page, storyId)` and returns one
|
|
68
|
+
story's parameters; the up-front read of every story is gone.
|
|
69
|
+
- d7f8b72: A story's execution record now says where the browser spent it, timed by the page: `prepare` for the preview's load, paid by the first story read on a document and 0 for every later one; `collect` for importing the story's file and unmounting the story before it; `cases` for the render through `afterEach`. `collectStory` returns them as `timing`, and `watchStoryTiming` starts the page's watch; the collector's page agent runs it.
|
|
70
|
+
- bd4243a: An image, font or media request still unanswered when the network wait runs
|
|
71
|
+
out refuses the subject, naming the URL. The subject used to be read without
|
|
72
|
+
it, with a `network-not-quiet` warning. `NetworkObservation.settle()` now
|
|
73
|
+
resolves that refusal, or `undefined` once nothing is in flight; a caller that
|
|
74
|
+
ignores it reads a subject whose bytes nobody hashed.
|
|
75
|
+
Only the requests a subject started count against it: one still open from an
|
|
76
|
+
earlier subject on the same page was named in that subject's refusal.
|
|
77
|
+
One the read itself asks for and never gets makes `acquireFromAgent` throw
|
|
78
|
+
`UnansweredAssets`, which both collectors turn into that subject's refusal.
|
|
79
|
+
- 8b189b9: Place the probes ahead of your transforms with `placement: 'before-transforms'`
|
|
80
|
+
|
|
81
|
+
The probes go in after your transforms by default, so a compiler that reads
|
|
82
|
+
syntax never reads one. That costs a second parse and the map back to each
|
|
83
|
+
file. A unit-test run whose transforms only strip types or JSX can skip both:
|
|
84
|
+
`placement: 'before-transforms'` places the probes in the file as read, with
|
|
85
|
+
one parse and no map. It means the same on the Vitest, Jest and Rstest
|
|
86
|
+
`withTestSelection`, on `testSelectionProbes` and `testSelectionRule`, and as an
|
|
87
|
+
option of the Storybook addon. With Compiled, React Compiler or another compiler
|
|
88
|
+
that reads syntax in the run, keep the default: nothing detects them for you.
|
|
89
|
+
- 7ff6d4b: Record what each story executed under Rspack and Webpack too
|
|
90
|
+
|
|
91
|
+
Add `@variance-authority/storybook-collector` to your Storybook's `addons`, and
|
|
92
|
+
the preview build carries the probes `tests` reads, whichever builder runs it:
|
|
93
|
+
`testSelectionProbes()` under Vite, the `testSelectionRule()` loader under
|
|
94
|
+
Rspack and Webpack 5. The probes go in after every compiler the build runs, so a
|
|
95
|
+
Storybook built by Rspack with `@compiled/react` records its stories. The
|
|
96
|
+
addon's options are the probes' own: `root`, `mode`, `include` and `placement`.
|
|
97
|
+
|
|
98
|
+
The addon probes only the builds the collector records: `storybook build
|
|
99
|
+
--test` and a dev server. Any other `storybook build`, the one a team
|
|
100
|
+
publishes, gets nothing from it, so build the recorded Storybook with `--test`.
|
|
101
|
+
The collector's `tests` is read in a later process, after the build, so the
|
|
102
|
+
build cannot ask it; Storybook's own `--test` is how a build says it is for
|
|
103
|
+
testing.
|
|
104
|
+
|
|
105
|
+
Under Rspack and Webpack, where the build writes no source map the loaders can
|
|
106
|
+
read, as `storybook build --test` does, the addon hands the loaders their maps
|
|
107
|
+
and the build still writes no `.map` file. `devtool` stays as you set it.
|
|
108
|
+
|
|
109
|
+
Storybook runs an addon's builder hooks before the ones in your `main.js`, so
|
|
110
|
+
the addon places the rule from a plugin, once the config is final: a post
|
|
111
|
+
loader your own `webpackFinal` or `rsbuildFinal` adds still runs ahead of the
|
|
112
|
+
probes. If you added `testSelectionProbes()` or `testSelectionRule()` to the
|
|
113
|
+
Storybook's builder config yourself, remove it and add the addon instead: a
|
|
114
|
+
second one stops the build with "remove your testSelectionRule(); the addon
|
|
115
|
+
places it", or the same of `testSelectionProbes()`, wherever the rule sits,
|
|
116
|
+
in `oneOf` or nested `rules` too, and whether it names the loader by its path
|
|
117
|
+
or as `@variance-authority/sense/probes-loader`. One your `vite.config` lists is
|
|
118
|
+
kept, and the addon adds no second one; if the addon was also given a `mode`,
|
|
119
|
+
`include` or `placement` that differs from it, the build stops and names the
|
|
120
|
+
option. The Vite config `@storybook/addon-vitest` loads your presets for,
|
|
121
|
+
inside Vitest, gets nothing from the addon. Under Rsbuild, an `rsbuildFinal` of
|
|
122
|
+
yours that assigns `tools.rspack` outright, rather than adding to it, drops the
|
|
123
|
+
addon's plugin, and the build runs unprobed.
|
|
124
|
+
|
|
125
|
+
When `tests` is on and the preview has no probes, the run's stderr now says to
|
|
126
|
+
add the addon and build with `storybook build --test`, where it named
|
|
127
|
+
`testSelectionProbes()`. The `tests` option's documentation says the same.
|
|
128
|
+
|
|
129
|
+
### Patch Changes
|
|
130
|
+
|
|
131
|
+
- 8d1bcc1: A link in a doc comment opens from `node_modules`
|
|
132
|
+
|
|
133
|
+
Doc comments linked to documentation by repository paths such as
|
|
134
|
+
`../../../../docs/flakiness.md`, which resolve to nothing in an installed
|
|
135
|
+
package. They now link to the page on variance-authority.dev, or to the file on
|
|
136
|
+
GitHub when the site does not publish it, so the link works on hover in your
|
|
137
|
+
editor and in what `variance ask symbol` prints.
|
|
138
|
+
|
|
139
|
+
The MCP server's instructions and its observability answer linked to
|
|
140
|
+
`/start-cli` and `/presentation`, which the site does not serve. They now link
|
|
141
|
+
to `/start/cli` and `/docs/presentation`, and the `@variance-authority/cli`,
|
|
142
|
+
`@variance-authority/help`, `@variance-authority/mcp` and
|
|
143
|
+
`@variance-authority/vitest-browser` READMEs link to the guides where the site
|
|
144
|
+
publishes them.
|
|
145
|
+
|
|
146
|
+
`variancePrecondition`, `wiringOf`, `tapCommits` and `provenanceOf` carry an
|
|
147
|
+
`@see` link to the section of the guide that documents them.
|
|
148
|
+
- 0e77166: A Vite Storybook with a `.storybook/preview` file builds with the addon
|
|
149
|
+
|
|
150
|
+
From Storybook 9.1 on, Storybook rewrites each `sb.mock(import('../lib/api'))`
|
|
151
|
+
in the preview file to `sb.mock('../lib/api')` by printing the whole file
|
|
152
|
+
again, with no map back to your lines, so `storybook build --test` stopped at
|
|
153
|
+
the probes on any preview, whether it mocked a module or not. The addon now has
|
|
154
|
+
that rewrite edit the file in place: `import(` and its closing parenthesis
|
|
155
|
+
become spaces, every other character keeps its line and column, and the
|
|
156
|
+
preview's decorators are recorded where you wrote them. Storybook 10 builds the
|
|
157
|
+
same way. A Storybook that rewrites more calls than the edit in place makes
|
|
158
|
+
stops the build with an error that names `storybook:mock-loader-preview` and
|
|
159
|
+
the preview, rather than shipping a mock that no longer mocks.
|
|
160
|
+
- c3c8e61: An absolute `source.dirs` entry is walked
|
|
161
|
+
|
|
162
|
+
Both collectors joined every `source.dirs` entry onto the working directory, so
|
|
163
|
+
an absolute path such as `/repo/packages/ui/src` was looked for under that
|
|
164
|
+
directory, matched nothing, and the run was refused for having no source files.
|
|
165
|
+
An absolute entry is now walked as written, and a relative one is still resolved
|
|
166
|
+
against the working directory. File names in the index stay relative to that
|
|
167
|
+
directory either way. When no entry matches any file, the refusal lists each
|
|
168
|
+
directory by the absolute path it walked, in place of the entries as spelled
|
|
169
|
+
followed by `(from <root>)`.
|
|
170
|
+
- 52d87e4: A run starts one Chromium. Harnesses and the renderer lease one browser per launch recipe and the last to close it closes it, so a Storybook or route run with four workers launches one browser instead of five. A Storybook run's workers also share one browser context, and with it the HTTP cache: a worker's preview boots from what the first page fetched instead of downloading the bundle again (at four workers on the storybook case, 75 fetches and 29 MB became 17 fetches and 6 MB).
|
|
171
|
+
|
|
172
|
+
New options: `createHarness({ warm })` opens the page in a context shared with other warm harnesses, `createHarness({ isolated })` launches a browser of the harness's own, and `observeNetwork(page, { cache })` watches the wire through the DevTools protocol with the HTTP cache left on (Chromium only). The `alone` reading in both collectors stays in a browser of its own.
|
|
173
|
+
- e6afc58: One recorder for every visual subject
|
|
174
|
+
|
|
175
|
+
`@variance-authority/sense/journal` exports `createSubjectRecorder`, which keeps
|
|
176
|
+
one row per subject of a visual run with the page and every head joined, and
|
|
177
|
+
`driveJourneys`, the driver's listener, cookies and settling wait. The
|
|
178
|
+
Storybook collector records through the first, the Playwright fixture through
|
|
179
|
+
the second, so a story, a page and a test file record their journeys the same
|
|
180
|
+
way.
|
|
181
|
+
|
|
182
|
+
## 0.15.0
|
|
183
|
+
|
|
184
|
+
### Minor Changes
|
|
185
|
+
|
|
186
|
+
- 1a0b845: A subject is read with nothing hovered, nothing focused, motion reduced and `Date` fixed
|
|
187
|
+
|
|
188
|
+
Every layout and raster baseline made before this release is compared under a
|
|
189
|
+
moved recipe once; a semantic baseline, read in jsdom, does not move. The
|
|
190
|
+
default recipes gained tricks, so the stabilization digest every reading records
|
|
191
|
+
has changed, and each subject names that recipe as the cause of whatever it
|
|
192
|
+
reports. Review the changes and adopt them with `variance accept --all`, as for
|
|
193
|
+
any recipe change.
|
|
194
|
+
|
|
195
|
+
The standard collection recipe now also holds:
|
|
196
|
+
|
|
197
|
+
- `no-hover`: the pointer is moved to `(-1, -1)`, off the page, once per page
|
|
198
|
+
before it loads. On the `variance` fixture's page it is moved again before
|
|
199
|
+
every observation, a frame each, and not put back: a menu a script opened on
|
|
200
|
+
hover is closed for your test's next step.
|
|
201
|
+
- `no-focus`: whatever holds focus is blurred before the subject is read,
|
|
202
|
+
including an element inside a shadow root. On a page your test or agent goes
|
|
203
|
+
on using, focus goes back to that element once the reading and any screenshot
|
|
204
|
+
of it are taken, so a test types where it left off. The blur still ran the
|
|
205
|
+
page's blur handlers, and what they did, such as a validate-on-blur error,
|
|
206
|
+
stays.
|
|
207
|
+
- `reduced-motion`: the browser reports `prefers-reduced-motion: reduce`, which
|
|
208
|
+
stops the script animations of a page that honours it, and the reading
|
|
209
|
+
declares the same preference among the conditions its `@media` rules are
|
|
210
|
+
resolved against. A `prefers-reduced-motion` condition you declare through
|
|
211
|
+
`createHarness`'s `features` wins, and the browser is asked for that value;
|
|
212
|
+
a declared `no-preference` is not recorded as `reduced-motion`. Rules under
|
|
213
|
+
`@media (prefers-reduced-motion: no-preference)` are not read by default;
|
|
214
|
+
leave `reduced-motion` out to read them.
|
|
215
|
+
- `freeze-clock`: `Date` reads one instant. A script added before the page's
|
|
216
|
+
own replaces `new Date()`, `Date()` and `Date.now()`, and gives the same
|
|
217
|
+
instant to `Intl.DateTimeFormat`'s `format()` and `formatToParts()` called
|
|
218
|
+
without a date. Timers, animation frames and `performance.now()` are the
|
|
219
|
+
browser's own, so a page that settles on a timer still settles. No Playwright
|
|
220
|
+
clock is installed, so `page.clock` stays yours, and a clock your test
|
|
221
|
+
installs replaces the fixed `Date`; the reading still records `freeze-clock`,
|
|
222
|
+
so leave it out of the list when your test owns the clock. `Temporal.Now` and
|
|
223
|
+
`Date` inside a worker are not fixed. The default instant is in the past, and
|
|
224
|
+
the browser's cookie store keeps real time: a cookie your page's script sets
|
|
225
|
+
with an expiry counted from `Date.now()` is already expired and is not
|
|
226
|
+
stored, so a dismissed consent banner can come back after the next
|
|
227
|
+
navigation. Set `varianceNow` or `now` near today, or leave `freeze-clock`
|
|
228
|
+
out.
|
|
229
|
+
|
|
230
|
+
The render and layout recipes gain `no-focus` alone, because a painted document
|
|
231
|
+
still honours a collected `autofocus`. The other three have nothing to act on
|
|
232
|
+
there: the date the page printed is already text in the document, and its
|
|
233
|
+
`@media` rules were resolved when it was read. A `<script>` inside a subject
|
|
234
|
+
root is carried into the render document and runs there under the real clock.
|
|
235
|
+
Every document is painted under the render recipe, so a reading taken without
|
|
236
|
+
`no-focus` is still painted blurred.
|
|
237
|
+
|
|
238
|
+
The instant defaults to `DEFAULT_NOW`, `2024-06-15T12:00:00.000Z`, exported
|
|
239
|
+
from `@variance-authority/core/format`. `routeCollector` and
|
|
240
|
+
`storybookCollector` take a `now` option to choose another. It must be an ISO
|
|
241
|
+
8601 instant with its zone; anything else is refused before a browser opens.
|
|
242
|
+
An instant other than the default is spelled in the clock's id,
|
|
243
|
+
`freeze-clock@<instant>`, so it is part of the environment key, and a baseline taken at one instant is compared
|
|
244
|
+
with a run at another with the moved instant named as the cause.
|
|
245
|
+
|
|
246
|
+
To read a subject hovered, focused, animated or at the real time, pass your own
|
|
247
|
+
`stabilize` list without that trick: `DEFAULT_STABILIZE`, the ids of the
|
|
248
|
+
default recipe, filtered, as in
|
|
249
|
+
`DEFAULT_STABILIZE.filter((id) => id !== 'freeze-clock')`. It is exported from
|
|
250
|
+
`@variance-authority/core/format`, `@variance-authority/route-collector`,
|
|
251
|
+
`@variance-authority/storybook-collector` and
|
|
252
|
+
`@variance-authority/playwright-test`. `storybookCollector` and `observe` in
|
|
253
|
+
`@variance-authority/playwright-test` now take `stabilize`, as `routeCollector`
|
|
254
|
+
already did.
|
|
255
|
+
|
|
256
|
+
A trick needs a browser driver to apply it, and is recorded only where one did.
|
|
257
|
+
The collectors apply all four. So does the `variance` fixture in
|
|
258
|
+
`@variance-authority/playwright-test`: it sets `reduced-motion` and
|
|
259
|
+
`freeze-clock` on the `page` it hands your test, before the test body runs, and
|
|
260
|
+
takes the pointer off the page and releases focus before every observation,
|
|
261
|
+
giving focus back after it. Two new fixture options, `varianceStabilize` and
|
|
262
|
+
`varianceNow`, choose what it sets and the instant, and are set with
|
|
263
|
+
`test.use`; `varianceDriven` holds the ids it set. A fixed `Date` stops code
|
|
264
|
+
that times itself with `Date.now()`: a debounce or a throttle, such as lodash's
|
|
265
|
+
`debounce`, sees no time pass and never fires, so a test that types into a
|
|
266
|
+
debounced search box can stop getting results after this upgrade. A loop that
|
|
267
|
+
waits for `Date.now()` to pass a mark hangs the page, an animation timed by
|
|
268
|
+
`Date`, such as jQuery's `animate`, never calls its `complete`, and a client
|
|
269
|
+
that checks a token's `nbf` or `iat` against `Date.now()` can refuse a token
|
|
270
|
+
issued today. None of these failures names the clock. Leave
|
|
271
|
+
`freeze-clock` out for such a test, and for one that sets `page.clock` itself:
|
|
272
|
+
|
|
273
|
+
```ts
|
|
274
|
+
import { DEFAULT_STABILIZE } from '@variance-authority/playwright-test';
|
|
275
|
+
|
|
276
|
+
test.use({ varianceStabilize: DEFAULT_STABILIZE.filter((id) => id !== 'freeze-clock') });
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
On a page the fixture never handed your test,
|
|
280
|
+
such as one opened from your own browser context, call the new
|
|
281
|
+
`driveBeforeTest(page)` before `page.goto()` to set the same two; `observe` and
|
|
282
|
+
`createVariance` there apply `no-hover` and `no-focus`.
|
|
283
|
+
`@variance-authority/vitest-browser` reads from inside your page and has no
|
|
284
|
+
driver; `@variance-authority/presentation` reads through the Playwright `Page`
|
|
285
|
+
you hand it, a test's or an agent's live browser, and does not drive it. Both
|
|
286
|
+
apply `no-focus` only, giving focus back once the reading is taken. A trick left out is absent from the
|
|
287
|
+
reading's ids and digest, as a trick a tier cannot reach already is.
|
|
288
|
+
`stabilizeForObservation` in `@variance-authority/dom` takes `driven`, the ids
|
|
289
|
+
your driver applied, and returns `refocus()`, which gives focus back to the
|
|
290
|
+
element the reading released. `stabilizeAsRequested` takes the recipe by id, as
|
|
291
|
+
a page agent receives it. `createHarness` in `@variance-authority/playwright`
|
|
292
|
+
takes a `stabilize` recipe to drive its page before the first navigation, and
|
|
293
|
+
reports the ids it applied as `driven`. `createObservedHarness` opens one with
|
|
294
|
+
`observeNetwork` started before its first navigation, as both collectors do.
|
|
295
|
+
|
|
296
|
+
`createPlaywrightRenderer` no longer couples `no-focus` to `waitForFonts`:
|
|
297
|
+
`waitForFonts: false` turns off the waits alone.
|
|
298
|
+
|
|
299
|
+
`@variance-authority/core/format` exports `DEFAULT_STABILIZE`, `DEFAULT_NOW`,
|
|
300
|
+
`driveBeforeLoad` and `driveBeforeRead`, which apply the driver tricks to a
|
|
301
|
+
Playwright `Page`, `forDriver`, which drops the ones a host did not apply,
|
|
302
|
+
`featuresOf`, which declares the motion preference a recipe drove, and
|
|
303
|
+
`recipeToDrive`, which resolves a `stabilize` list and checks `now` before a
|
|
304
|
+
browser opens.
|
|
305
|
+
- d432339: A page reads its clock in UTC and formats for en-US, not for the host
|
|
306
|
+
|
|
307
|
+
The harness the route and Storybook collectors open, and the pages the renderer
|
|
308
|
+
paints, took their timezone and locale from the machine. A date the page
|
|
309
|
+
formatted read one way on a laptop in Sydney and another on a runner in
|
|
310
|
+
Virginia, from one build, and the two compared against one baseline as
|
|
311
|
+
`changed`.
|
|
312
|
+
|
|
313
|
+
Both are pinned: `timezoneId` to `UTC` and `locale` to `en-US`. Declare either
|
|
314
|
+
in `variance.config.json` (`"timezoneId": "Europe/Berlin"`, `"locale":
|
|
315
|
+
"de-DE"`) and the collectors and the renderer pin that instead; an unknown
|
|
316
|
+
timezone or a malformed language tag is refused by its field.
|
|
317
|
+
`createHarness` and `createPlaywrightRenderer` take the same two options.
|
|
318
|
+
`@variance-authority/core/format` exports their type, `PageRegion`, and
|
|
319
|
+
`@variance-authority/playwright` exports `pinnedRegion`, which fills in `UTC`
|
|
320
|
+
and `en-US` for a field left out.
|
|
321
|
+
|
|
322
|
+
Both are part of the environment key, and the renderer's pair is part of
|
|
323
|
+
`RenderIdentity.rasterization`. A capture read in another timezone or language
|
|
324
|
+
is another environment, and an image painted in one is compared with a
|
|
325
|
+
baseline painted in another, with `rasterization` named as the cause of
|
|
326
|
+
whatever moved.
|
|
327
|
+
|
|
328
|
+
`@variance-authority/playwright-test` paints each test in the timezone and
|
|
329
|
+
locale its page runs in: whatever the Playwright project or `test.use` sets.
|
|
330
|
+
When neither sets a `timezoneId`, `varianceFixtures` opens the page in `UTC`
|
|
331
|
+
rather than the host's, so a laptop and a runner in UTC read it under one key;
|
|
332
|
+
Playwright Test already opens it in `en-US` when nothing sets a `locale`. That
|
|
333
|
+
reaches every test of a suite extended with `varianceFixtures`, including tests
|
|
334
|
+
that never call `variance`, so a test that asserts a date formatted in your
|
|
335
|
+
machine's timezone reads it in `UTC` after this upgrade; set `timezoneId` in
|
|
336
|
+
`use` to keep your own. A page
|
|
337
|
+
you hand to `createVariance` is read and painted in whatever its own context
|
|
338
|
+
opened it in, which is the host's timezone when that context set none: open the
|
|
339
|
+
context with `timezoneId: 'UTC'` to match. `varianceRenderer` is now a test fixture, chosen
|
|
340
|
+
by the page, and `varianceRenderers` is the worker's set of renderers, one per
|
|
341
|
+
timezone and locale; a project that overrode `varianceRenderer` at worker scope
|
|
342
|
+
overrides it at test scope instead.
|
|
343
|
+
|
|
344
|
+
**Every image painted by the Playwright renderer is compared under a moved
|
|
345
|
+
recipe once after this upgrade**, because its recipe now carries the timezone
|
|
346
|
+
and locale. Each subject names `rasterization` as the cause of what it reports,
|
|
347
|
+
and one whose pixels moved is `changed`:
|
|
348
|
+
|
|
349
|
+
- With `variance run`: the run exits `1` for each `changed` subject. Review
|
|
350
|
+
them in `variance report --format html` and adopt them with
|
|
351
|
+
`variance accept --all`. A rerun reports `unchanged`.
|
|
352
|
+
- With `@variance-authority/playwright-test`: the suite fails each `changed`
|
|
353
|
+
test, and `--update-snapshots=changed` adopts them.
|
|
354
|
+
- With `@variance-authority/vitest-browser`: `vitest --update` adopts them, as
|
|
355
|
+
`variance accept --all` does.
|
|
356
|
+
|
|
357
|
+
`@variance-authority/vitest-browser` reads no `variance.config.json` and takes no
|
|
358
|
+
timezone or locale, so it paints in `UTC` and `en-US` whatever its tab ran in,
|
|
359
|
+
and neither it nor `@variance-authority/unit-test` writes a timezone or locale
|
|
360
|
+
to the environment key.
|
|
361
|
+
- 3e6a370: A run's cases travel in its record
|
|
362
|
+
|
|
363
|
+
The case index, the cases a run replaced and the run that replaced them are
|
|
364
|
+
sections of `coverage.bin`, no longer a `coverage.bin.cases.bin` beside it. The
|
|
365
|
+
one file is landed, layered, seeded, repinned, sharded and shared by the same
|
|
366
|
+
rules and under the same lock as the coverage it was recorded with, so the two
|
|
367
|
+
always answer for the same runs. A share, a seed or a fetch carries the index
|
|
368
|
+
and drops the replaced cases and the run that names them, which belong to the
|
|
369
|
+
machine that ran.
|
|
370
|
+
|
|
371
|
+
A record that carries cases is format 10, and a reader that knows only coverage
|
|
372
|
+
refuses it rather than misreading it. A record without cases keeps format 9. A
|
|
373
|
+
`coverage.bin.cases.bin` left from an earlier run is not read; the next run
|
|
374
|
+
writes its cases into the record.
|
|
375
|
+
|
|
376
|
+
The `executionFile` option is removed from `withTestSelection`, the Jest and
|
|
377
|
+
rstest seams, `startRecording`, the Playwright reporter and the Storybook
|
|
378
|
+
collector, along with the JSON it could write. `decodeExecutionIndex`,
|
|
379
|
+
`readExecutionIndex`, `variance covering --against`, `variance review` and
|
|
380
|
+
`distill --execution` read the index out of a record; JSON stays readable as
|
|
381
|
+
the spelling a foreign tool supplies. `landCaseIndexes` is replaced by
|
|
382
|
+
`landCases`, which returns the sections for the record you write, and
|
|
383
|
+
`lastCaseRunOf` reads the run they name. `caseLayerFiles` and
|
|
384
|
+
`executionIndexBytes`, which named and read the file beside the record, are
|
|
385
|
+
removed. `CaseSections`, `caseSectionsAt`, `caseSectionsOf`, `caseIndexOf`,
|
|
386
|
+
`recordedCases`, `withCaseSections`, `keepsCases` and `sharedRecord` read and
|
|
387
|
+
write the sections.
|
|
388
|
+
- 754d04c: The port a build is served on is no part of a render
|
|
389
|
+
|
|
390
|
+
The route and Storybook collectors serve a build on a free port, and that port
|
|
391
|
+
reached three identities. An asset the page loaded was keyed by its absolute
|
|
392
|
+
URL, a `url()` in a computed style was the absolute URL the engine resolved,
|
|
393
|
+
and the document digest read both. One build served twice therefore read as two
|
|
394
|
+
environment keys and two documents: each run missed the render cache, painted
|
|
395
|
+
again, and read its document as changed against its own baseline.
|
|
396
|
+
|
|
397
|
+
An asset the page's own origin serves is keyed by its path, and the page's
|
|
398
|
+
origin is dropped from a `url()` before it is hashed. An asset another origin
|
|
399
|
+
serves keeps its absolute URL. A capture carries the page's `baseUrl` so core
|
|
400
|
+
knows which origin is the page's, and the renderer resolves a path-keyed asset
|
|
401
|
+
against the document's `baseUrl`. `documentDigest` reads the page's own base
|
|
402
|
+
and resources as paths, so one build served on two ports addresses one render
|
|
403
|
+
and the render cache hits; the document keeps them absolute for the renderer,
|
|
404
|
+
and a resource another origin serves stays absolute in the digest too.
|
|
405
|
+
|
|
406
|
+
A `@variance-authority/unit-test` capture keys its assets the same way, so a
|
|
407
|
+
`@variance-authority/vitest-browser` observation, which captures through it on
|
|
408
|
+
the port the runner had free, keeps the port out of its environment key.
|
|
409
|
+
`readCapture` reads back a capture whose asset is keyed by path, resolving the
|
|
410
|
+
key against the document's `baseUrl` as the renderer does; `assetUrl` in
|
|
411
|
+
`@variance-authority/core/format` is that one resolution.
|
|
412
|
+
|
|
413
|
+
**The document of every page served over `http` moves once after this
|
|
414
|
+
upgrade.** `documentDigest` now reads a document's base and resources without
|
|
415
|
+
the page's origin, so the digest of every document served over `http` or
|
|
416
|
+
`https` changes: every route, every story, every Vitest browser page, and every
|
|
417
|
+
Playwright page opened by URL. A moved document misses the render cache once,
|
|
418
|
+
and its image is still compared with the baseline: a page whose pixels did not
|
|
419
|
+
move reads `unchanged`, and one whose pixels did reads `changed`, which
|
|
420
|
+
`variance accept --all` and Playwright's `--update-snapshots=changed` adopt.
|
|
421
|
+
`RULESET_VERSION` moves from `r1` to `r2`. The ruleset is part of a snapshot's
|
|
422
|
+
environment key, not of the render recipe, so no image names it as a moved
|
|
423
|
+
identity; a snapshot diffed against one recorded under `r1` names the ruleset as its
|
|
424
|
+
environment root.
|
|
425
|
+
|
|
426
|
+
### Patch Changes
|
|
427
|
+
|
|
428
|
+
- 8dbc834: The components a module declares are read from its code. A declaration written
|
|
429
|
+
in a block comment, a JSDoc example or a template literal no longer names a
|
|
430
|
+
component, so a commented-out `function Retired()` no longer makes its file
|
|
431
|
+
the one that declares `Retired`. A name is declared by a statement of the
|
|
432
|
+
module itself: a function, class or binding inside a function body belongs to
|
|
433
|
+
that function and no longer counts. An `export async function Page()`, an
|
|
434
|
+
abstract class, a generator, a second name in `const A = 1, B = 2`, and a name
|
|
435
|
+
that starts with a non-ASCII capital or carries a `$` are now declared too.
|
|
436
|
+
|
|
437
|
+
`variance run`, `variance collect`, the Storybook collector and the route
|
|
438
|
+
collector resolve a component to its `file:line` from the same reading, through
|
|
439
|
+
`indexDeclarations`, which `sense` now exports. What that changes in the index
|
|
440
|
+
they build from `source.dirs`:
|
|
441
|
+
|
|
442
|
+
- The line is the first line of the declaring statement. A decorated class
|
|
443
|
+
sits at its first decorator, or at its `export` when the decorator is written
|
|
444
|
+
above the `export`, and a second name in a multi-line `const` at the line of
|
|
445
|
+
the `const`.
|
|
446
|
+
- `.d.ts` files, and test, spec and story files your own `exclude` lets
|
|
447
|
+
through, declare nothing.
|
|
448
|
+
- A file the parser cannot read declares nothing, where the text scan found
|
|
449
|
+
the components in it. That covers a Flow-annotated `.js` file, and a `.vue`,
|
|
450
|
+
`.svelte` or `.mdx` file you add to a collector's `extensions`, which is
|
|
451
|
+
parsed as TSX and fails. The index built from `source.dirs` or a collector's
|
|
452
|
+
`source` does not say so: the file's components are missing, and nothing
|
|
453
|
+
names the file. Only `sense`'s source index, for a file it records, names the
|
|
454
|
+
parse error in that file's record.
|
|
455
|
+
- Building the index needs `sense`'s native addon, which ships for macOS on
|
|
456
|
+
arm64, Linux on x64 and arm64 with glibc, and Windows on x64. On any other
|
|
457
|
+
machine, including an Intel Mac, an Alpine image and Windows on arm64, a
|
|
458
|
+
configured `source.dirs` fails at its first file and names why the addon did
|
|
459
|
+
not load, where the text scan ran anywhere. The route collector depends on
|
|
460
|
+
`sense` for it.
|
|
461
|
+
|
|
462
|
+
`indexSource` is removed from `@variance-authority/core/attribute`. Build a
|
|
463
|
+
`SourceIndex` with `indexDeclarations` from `@variance-authority/sense`, or
|
|
464
|
+
write one as plain data: a map from component name to `{ file, line, via }`.
|
|
465
|
+
`SourceRef['via']` loses `'declared'`, which nothing produced, and
|
|
466
|
+
`readCapture` in `@variance-authority/unit-test` refuses a capture whose source
|
|
467
|
+
index carries it.
|
|
468
|
+
|
|
469
|
+
The source index format moves to version 18, so an index written before this
|
|
470
|
+
release is rebuilt once instead of keeping the names it read from comments.
|
|
471
|
+
- 1eed290: A form filled in after mount is painted and compared filled in
|
|
472
|
+
|
|
473
|
+
Text a play function or a test typed into an `<input>` or `<textarea>`, the
|
|
474
|
+
option it chose in a `<select>` and the box it ticked now reach the render
|
|
475
|
+
document and the snapshot. Before, the document painted the form as the server
|
|
476
|
+
sent it and the snapshot did not move for typed text or a chosen option. A
|
|
477
|
+
password field's value is carried as one `•` per character, and a file input's
|
|
478
|
+
value is not carried. A form nobody filled in reads exactly as before.
|
|
479
|
+
|
|
480
|
+
This is part of `RULESET_VERSION` `r2`. A subject whose form was filled in
|
|
481
|
+
after the server sent it has a new render document, so after this upgrade its
|
|
482
|
+
image shows the form filled in and reads `changed` against a baseline painted
|
|
483
|
+
empty; `variance accept --all` adopts it. A Playwright test painted its form
|
|
484
|
+
filled in before this change, so it does not move there.
|
|
485
|
+
- ef496ad: READMEs name what the program does
|
|
486
|
+
|
|
487
|
+
The package READMEs, and the `@variance-authority/vantage` and
|
|
488
|
+
`@variance-authority/playwright-test` descriptions, no longer write a test, a
|
|
489
|
+
record or a run as something that says, asks or knows. Each sentence names what
|
|
490
|
+
the program does: a command prints, a record holds a field, a test runs or
|
|
491
|
+
covers. Where a value is filled in from configuration or a default rather than
|
|
492
|
+
recorded, the README says so. Four renamed headings change their anchors:
|
|
493
|
+
`help`'s "Where the declaration is undocumented", `playwright`'s "Where a
|
|
494
|
+
component is declared, read from the engine", `storybook`'s "What a pass sends
|
|
495
|
+
the preview" and `sense`'s "Correct what a file's text declares it imports".
|
|
496
|
+
- 4799688: The checkout says what the probes meant: no build writes module records
|
|
497
|
+
|
|
498
|
+
A probe names the file it was placed on and the digest of that text,
|
|
499
|
+
`path@digest`. When a run is folded, each module the journals name is cut again
|
|
500
|
+
from the file in the checkout. A file whose text still matches is read on its
|
|
501
|
+
own regions; a file that has moved on since the build reads as one whose reach
|
|
502
|
+
is not known, which selects every test that entered it; a file that is gone
|
|
503
|
+
counts the same way. Nothing is written beside the build, and nothing under the
|
|
504
|
+
cache's `test-selection/<key>/<label>/` is read.
|
|
505
|
+
|
|
506
|
+
Breaking:
|
|
507
|
+
|
|
508
|
+
- `testSelectionProbes()` takes no `cacheRoot`. Its `label` names the journey
|
|
509
|
+
head and nothing else.
|
|
510
|
+
- `recordExecution()` takes no `label` and no `heads`.
|
|
511
|
+
- The Jest journeys options (`withJourneyCoverage`) take no `heads`.
|
|
512
|
+
- `jestStore` is removed from `@variance-authority/sense/jest`.
|
|
513
|
+
- `instrumentModule(code, file)` takes no options: call it first, on the file as
|
|
514
|
+
it is on disk.
|
|
515
|
+
- A journal names a module by `path@digest`. A driver that writes its own
|
|
516
|
+
journal builds the id with `moduleId(path, code)` from
|
|
517
|
+
`@variance-authority/sense/journal`.
|
|
518
|
+
|
|
3
519
|
## 0.14.0
|
|
4
520
|
|
|
5
521
|
Lockstep release — nothing in this package changed. Every `@variance-authority/*` package shares one version.
|