Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions docs/output.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,25 @@ DOM and iframes aren't searched.
## Computed styles (`--computed`)

With `--computed`, after the shot renderdiff reads the computed style of every rendered
element on both sides: the properties `dom` compares, plus `outline`,
`text-decoration-line` and `content`, and `::before` and
`::after` wherever they generate content. Masked subtrees and `script`/`style`-like tags
element on both sides, and of `::before` and `::after` wherever they generate content.
Masked subtrees and `script`/`style`-like tags
are skipped; a `display: none` element is read, its subtree isn't. Script-driven
animations are finished first. The summary gets one block, after the rows:
animations are finished first.

It reads a fixed list of properties, not every one, so `0 findings` means none of these
changed:

- Layout: `display`, `position`, `float`, `flex-direction`, `flex-wrap`,
`justify-content`, `align-items`, `gap`, `grid-template-columns`, `z-index`.
- Box: `margin-*`, `padding-*`, `border-*-width`, `border-top-color`,
`border-top-left-radius`, `outline`, `width`, `height`.
- Text: `font-family`, `font-size`, `font-weight`, `line-height`, `letter-spacing`,
`text-align`, `text-transform`, `text-decoration-line`, `white-space`, `word-break`,
`overflow-wrap`, `hyphens`, `text-wrap-style`, `color`.
- Paint: `background-color`, `background-image`, `box-shadow`, `opacity`, `transform`,
`visibility`, `clip`, `clip-path`, `mask`, `content`.

The summary gets one block, after the rows:

```
computed: 2 findings; dom identical on 2 of 3 route(s), differs /pricing (1), so findings there are hints
Expand All @@ -197,7 +211,8 @@ computed: 2 findings; dom identical on 2 of 3 route(s), differs /pricing (1), so
style change under it then shows only as `dom differs` and `unmatched`, not as a
finding.
- One change high in the tree is one finding. An inherited property (`font-*`,
`line-height`, `letter-spacing`, `text-*`, `white-space`, `color`, `visibility`) is
`line-height`, `letter-spacing`, `text-*`, `white-space`, `word-break`, `overflow-wrap`,
`hyphens`, `color`, `visibility`) is
dropped where the parent has the same change, so a `body` font change is one line, not
one per element. A `width` is dropped inside a parent whose width changed, and a
`height` around a child whose height changed, so the box that caused it is what's left.
Expand Down
9 changes: 6 additions & 3 deletions skills/renderdiff/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,8 @@ not a route error: the pixel result stands.

## `--computed`

After each shot, reads the computed style (the `dom` properties plus `content`) of every
rendered element and its `::before`/`::after`, on both sides, and compares the markup. One
block after the rows:
After each shot, reads the computed style of every rendered element and its
`::before`/`::after`, on both sides, and compares the markup. One block after the rows:

```
computed: 2 findings; dom identical on 2 of 3 route(s), differs /pricing (1), so findings there are hints
Expand All @@ -149,6 +148,10 @@ computed: 2 findings; dom identical on 2 of 3 route(s), differs /pricing (1), so
unmatched /pricing@1440 -body > main > section.plans:nth-of-type(3)
```

- The properties are a fixed list, not every one: the `dom` ones plus `outline`,
`text-decoration-line`, `word-break`, `overflow-wrap`, `hyphens`, `text-wrap-style`,
`clip`, `clip-path`, `mask` and `content` (full list: docs/output.md in the renderdiff
repo). `0 findings` means none of those changed, not that no style did.
- A finding is `key prop left→right`, then up to three `route@widths` (`+N routes`). One per
distinct change across the run, most widespread first, accepted shots included; 20 shown.
`--progress` rows say `computed dom identical, N change(s)` or `dom differs (N)`.
Expand Down
4 changes: 4 additions & 0 deletions src/computed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ const INHERITED = new Set([
"text-align",
"text-transform",
"white-space",
"word-break",
"overflow-wrap",
"hyphens",
"text-wrap-style",
"color",
"visibility",
]);
Expand Down
14 changes: 13 additions & 1 deletion src/locate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,19 @@ export const PROPS = [
];

/** `--computed` reads these too; pixel mode's `changed`, and so accepted fingerprints, don't. */
export const SNAP_PROPS = [...PROPS, "outline", "text-decoration-line", "content"];
export const SNAP_PROPS = [
...PROPS,
"outline",
"text-decoration-line",
"word-break",
"overflow-wrap",
"hyphens",
"text-wrap-style",
"clip",
"clip-path",
"mask",
"content",
];

/** Links and controls forced into each state, per page per side. */
export const MAX_STATES = 500;
Expand Down
18 changes: 18 additions & 0 deletions tests/visual/computed.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,21 @@ test("past 500 links the rest are counted, and the page is left resting", async
assert.deepEqual(await snapshot(p, [], BUDGET, null), before);
await p.close();
});

test("a lint autofix swapping wrapping or clipping keywords is a finding, not inherited down", async () => {
const body =
`<div style="width:120px"><code>averyveryverylongidentifierwithoutbreaks<b>x</b></code></div>` +
`<span class="h">hidden</span><p>Some text.</p>`;
const h = ".h { position: absolute; width: 1px; height: 1px; overflow: hidden }";
const { d } = await diff(body, body, [
`${h} code { overflow-wrap: anywhere } .h { clip-path: inset(50%) }`,
`${h} code { word-break: break-word } .h { clip: rect(0 0 0 0) }`,
]);
assert.equal(d.dom, 0);
assert.deepEqual(changed(d), [
["body > div > code", "word-break"],
["body > div > code", "overflow-wrap"],
["body > span.h", "clip"],
["body > span.h", "clip-path"],
]);
});
Loading