@fusion.dev/helix-cli 0.205.2 → 0.206.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fusion.dev/helix-cli",
3
3
  "description": "The Helix command line, for a workspace that reaches it through npm, and the visual tests it runs.",
4
- "version": "0.205.2",
4
+ "version": "0.206.0",
5
5
  "license": "MIT",
6
6
  "author": "Ross Sheppard <ross.sheppard@fusion.dev>",
7
7
  "repository": {
@@ -41,11 +41,11 @@
41
41
  "visual-regression"
42
42
  ],
43
43
  "optionalDependencies": {
44
- "@fusion.dev/helix-cli-darwin-arm64": "0.205.2",
45
- "@fusion.dev/helix-cli-darwin-x64": "0.205.2",
46
- "@fusion.dev/helix-cli-linux-arm64": "0.205.2",
47
- "@fusion.dev/helix-cli-linux-x64": "0.205.2",
48
- "@fusion.dev/helix-cli-win32-x64": "0.205.2"
44
+ "@fusion.dev/helix-cli-darwin-arm64": "0.206.0",
45
+ "@fusion.dev/helix-cli-darwin-x64": "0.206.0",
46
+ "@fusion.dev/helix-cli-linux-arm64": "0.206.0",
47
+ "@fusion.dev/helix-cli-linux-x64": "0.206.0",
48
+ "@fusion.dev/helix-cli-win32-x64": "0.206.0"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "@anthropic-ai/sdk": ">=0.132",
package/visual/README.md CHANGED
@@ -159,7 +159,9 @@ export default defineConfig({
159
159
  ground it is painted on, in each color scheme the shots picture. The ground
160
160
  is composited through every translucent layer, and a ground that is a
161
161
  picture or a video is not judged. Text hidden from the accessibility tree is
162
- a glyph for the eye, and answers to the 3:1 of a graphic. `rules` names the colors of lines that
162
+ a glyph for the eye, and answers to the 3:1 of a graphic. The run record
163
+ lists every ink and ground pair it measured, passing or not, under
164
+ `painted`, so a project can say which of its colors its pages put together. `rules` names the colors of lines that
163
165
  separate, which answer to no target.
164
166
  - Each check takes `ignore`, selectors it leaves alone with everything inside
165
167
  them, and an exception's `checks` excuses one entry from the checks it names.
package/visual/checks.mjs CHANGED
@@ -12,11 +12,15 @@
12
12
 
13
13
  /**
14
14
  * Reads the page for the checks `options` turns on: `clipped`, `overlap` and
15
- * `contrast`, each with its own settings, or absent.
15
+ * `contrast`, each with its own settings, or absent. Returns the findings,
16
+ * and every ink and ground pair contrast measured, passing or not, as
17
+ * `<scheme> <ink> on <ground>` in hex, so a run can say which pairs its pages
18
+ * paint.
16
19
  */
17
20
  export const readPage = (page, options) =>
18
21
  page.evaluate((options) => {
19
22
  const findings = []
23
+ const pairs = new Set()
20
24
 
21
25
  /* **Every element, shadow roots included**, because the boxes a component
22
26
  lays out for itself are inside one, and the light tree alone holds only
@@ -696,6 +700,7 @@ export const readPage = (page, options) =>
696
700
  const wanted =
697
701
  !text || drawn || size >= large || (bold && size >= largeBold) ? component : target
698
702
  const flat = ink.a === 1 ? ink : over(ink, ground.color)
703
+ pairs.add(`${scheme} ${hex(flat)} on ${hex(ground.color)}`)
699
704
  const measured = ratio(flat, ground.color)
700
705
  if (measured < wanted) {
701
706
  const line = `${describe(painter)} is ${hex(flat)} on ${hex(ground.color)} in ${scheme}, ${measured.toFixed(2)}:1 against ${wanted}:1: "${sample(element.textContent ?? '')}"`
@@ -712,7 +717,7 @@ export const readPage = (page, options) =>
712
717
  window.scrollTo(pageAt[0], pageAt[1])
713
718
  }
714
719
 
715
- return findings
720
+ return { findings, pairs: [...pairs] }
716
721
  }, options)
717
722
 
718
723
  /**
package/visual/driver.mjs CHANGED
@@ -397,6 +397,8 @@ const take = async (lane, item, { elements, readyProperty }, progress) => {
397
397
  let error = null
398
398
  let problems = []
399
399
  let findings = []
400
+ /* Every ink and ground pair contrast measured on the page. */
401
+ let painted = []
400
402
  let aria = null
401
403
  /* The color schemes contrast has been read in. */
402
404
  const read = new Set()
@@ -488,13 +490,13 @@ const take = async (lane, item, { elements, readyProperty }, progress) => {
488
490
  if ((index === 0 && (item.checks?.clipped || item.checks?.overlap)) || contrast) {
489
491
  progress.stage = 'reading the page'
490
492
  read.add(shot.scheme)
491
- findings = findings.concat(
492
- await readPage(page, {
493
- clipped: index === 0 ? (item.checks.clipped ?? null) : null,
494
- contrast: contrast ? { ...item.checks.contrast, scheme: shot.scheme } : null,
495
- overlap: index === 0 ? (item.checks.overlap ?? null) : null,
496
- }),
497
- )
493
+ const reading = await readPage(page, {
494
+ clipped: index === 0 ? (item.checks.clipped ?? null) : null,
495
+ contrast: contrast ? { ...item.checks.contrast, scheme: shot.scheme } : null,
496
+ overlap: index === 0 ? (item.checks.overlap ?? null) : null,
497
+ })
498
+ findings = findings.concat(reading.findings)
499
+ painted = painted.concat(reading.pairs)
498
500
  }
499
501
  if (index === 0 && item.aria) {
500
502
  progress.stage = 'taking its accessibility snapshot'
@@ -526,6 +528,7 @@ const take = async (lane, item, { elements, readyProperty }, progress) => {
526
528
  findings,
527
529
  key: item.key,
528
530
  op: 'item',
531
+ painted,
529
532
  problems,
530
533
  seconds,
531
534
  })