reflection-check 0.0.3 → 0.0.5
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/dist/cli.js +1 -1
- package/dist/commands/doctor.js +24 -3
- package/dist/commands/doctor.js.map +1 -1
- package/dist/contracts/component/component-visual-contract.d.ts +15 -2
- package/dist/contracts/component/component-visual-contract.js +224 -52
- package/dist/contracts/component/component-visual-contract.js.map +1 -1
- package/dist/contracts/component/portal-entry.d.ts +17 -0
- package/dist/contracts/component/portal-entry.js +2 -0
- package/dist/contracts/component/portal-entry.js.map +1 -0
- package/dist/core/config.d.ts +24 -3
- package/dist/core/config.js +100 -6
- package/dist/core/config.js.map +1 -1
- package/dist/core/target-ir.d.ts +10 -3
- package/dist/core/target-ir.js +11 -3
- package/dist/core/target-ir.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/integrations/playwright/context-factory.d.ts +3 -2
- package/dist/integrations/playwright/context-factory.js +6 -3
- package/dist/integrations/playwright/context-factory.js.map +1 -1
- package/dist/integrations/portal/server.d.ts +25 -0
- package/dist/integrations/portal/server.js +186 -0
- package/dist/integrations/portal/server.js.map +1 -0
- package/docs/artifacts-and-gc.md +4 -1
- package/docs/configuration.md +82 -1
- package/docs/target-ir-and-adapters.md +4 -4
- package/docs/visual-contract.md +47 -2
- package/package.json +3 -2
|
@@ -30,7 +30,7 @@ The IR currently supports four families:
|
|
|
30
30
|
| --- | --- | --- | --- |
|
|
31
31
|
| `browser-route` | browser routes | `smoke`, `full` | Render a route and evaluate DOM/layout/console expectations. |
|
|
32
32
|
| `route-visual` | browser visual smoke cases | `smoke`, `full` | Compare route screenshots against read-only baselines. |
|
|
33
|
-
| `component-visual` | Storybook component cases | `visual`, `full` | Compare component
|
|
33
|
+
| `component-visual` | Storybook or portal component cases | `visual`, `full` | Compare component screenshots against read-only baselines. |
|
|
34
34
|
| `design-command` | design command checks | `design`, `full` | Run project-owned design contract commands. |
|
|
35
35
|
|
|
36
36
|
All targets include:
|
|
@@ -59,20 +59,20 @@ console.log(ir.targets.map((target) => `${target.family}:${target.id}`));
|
|
|
59
59
|
// ]
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
The compiler preserves visual metadata that matters to later review, including zero-valued thresholds
|
|
62
|
+
The compiler preserves visual metadata that matters to later review, including component source (`storybook` or `portal`), portal paths, story ids, zero-valued thresholds, explicit component `viewportSize` values, and component `framing`. Do not use truthiness checks when copying optional numeric metadata; use explicit `!== undefined` checks so values like `0` survive.
|
|
63
63
|
|
|
64
64
|
## Adapter contract
|
|
65
65
|
|
|
66
66
|
Adapters should compile their input into the same target shape and mark targets with `source: 'adapter'`.
|
|
67
67
|
|
|
68
|
-
Adapters must not make core runners aware of the source format. The runner should receive normalized route/
|
|
68
|
+
Adapters must not make core runners aware of the source format. The runner should receive normalized route/component/visual/command information and should not branch on adapter names.
|
|
69
69
|
|
|
70
70
|
A good adapter is:
|
|
71
71
|
|
|
72
72
|
- **optional** — normal Reflection config works without it;
|
|
73
73
|
- **validated** — malformed adapter input fails before runner execution;
|
|
74
74
|
- **neutral** — no external product names leak into core commands or reports unless the user explicitly names their own target ids;
|
|
75
|
-
- **lossless enough for review** — route paths, viewports, expectations, baselines, thresholds, and blocking semantics are preserved in IR.
|
|
75
|
+
- **lossless enough for review** — route paths, component portal paths or Storybook ids, viewports, component viewport sizes, component framing, expectations, baselines, thresholds, and blocking semantics are preserved in IR.
|
|
76
76
|
|
|
77
77
|
## Route manifest adapter proof
|
|
78
78
|
|
package/docs/visual-contract.md
CHANGED
|
@@ -82,7 +82,7 @@ If the matching browser route result is missing, the visual check becomes a revi
|
|
|
82
82
|
|
|
83
83
|
## Component visual baselines
|
|
84
84
|
|
|
85
|
-
Component visual cases use Storybook
|
|
85
|
+
Component visual cases can use Storybook or a Reflection-generated portal. Storybook cases resolve `storyId` through Storybook `/index.json`; portal cases open a configured `path` in a generated Vite runtime.
|
|
86
86
|
|
|
87
87
|
```ts
|
|
88
88
|
component: {
|
|
@@ -96,7 +96,13 @@ component: {
|
|
|
96
96
|
{
|
|
97
97
|
id: 'button-primary',
|
|
98
98
|
storyId: 'atoms-button--primary',
|
|
99
|
-
viewport: '
|
|
99
|
+
viewport: 'button-default',
|
|
100
|
+
viewportSize: { width: 390, height: 220 },
|
|
101
|
+
framing: {
|
|
102
|
+
background: '#ffffff',
|
|
103
|
+
align: 'center',
|
|
104
|
+
padding: 0
|
|
105
|
+
},
|
|
100
106
|
baselineRoot: 'tests/fixtures/baselines',
|
|
101
107
|
baseline: 'components/button/primary.chromium-linux.light.png',
|
|
102
108
|
threshold: { maxDiffPixelRatio: 0.005 }
|
|
@@ -105,6 +111,44 @@ component: {
|
|
|
105
111
|
}
|
|
106
112
|
```
|
|
107
113
|
|
|
114
|
+
Portal cases use the same case fields, but replace `storyId` with `path` and configure `component.portal`:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
component: {
|
|
118
|
+
portal: {
|
|
119
|
+
entry: './tests/reflection/react-portal.tsx',
|
|
120
|
+
readyUrl: 'http://127.0.0.1:6106'
|
|
121
|
+
},
|
|
122
|
+
cases: [
|
|
123
|
+
{
|
|
124
|
+
id: 'button-primary',
|
|
125
|
+
path: '/reflection/button/primary/light',
|
|
126
|
+
viewport: 'button-default',
|
|
127
|
+
viewportSize: { width: 390, height: 220 },
|
|
128
|
+
framing: {
|
|
129
|
+
rootSelector: '#reflection-root',
|
|
130
|
+
background: '#ffffff',
|
|
131
|
+
align: 'center',
|
|
132
|
+
padding: 0
|
|
133
|
+
},
|
|
134
|
+
baselineRoot: 'tests/fixtures/baselines',
|
|
135
|
+
baseline: 'components/button/primary.chromium-linux.light.png',
|
|
136
|
+
threshold: { maxDiffPixels: 0, maxDiffPixelRatio: 0 },
|
|
137
|
+
strict: true
|
|
138
|
+
}
|
|
139
|
+
]
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
For component baselines exported from a design tool, treat `viewportSize` and `framing` as part of the visual contract. The exported PNG width/height and the runtime screenshot width/height must be identical. `viewport` may be a built-in preset such as `component` or a semantic custom label such as `button-default`; when `viewportSize` is present, the explicit dimensions win. Portal cases require `viewportSize`, and the generated frame uses those dimensions directly.
|
|
144
|
+
|
|
145
|
+
`framing` is optional and only affects the screenshot when configured. It applies fixed canvas styles before capture so the runtime component can match a Figma frame:
|
|
146
|
+
|
|
147
|
+
- `rootSelector`: root to frame; defaults to `#storybook-root` for Storybook and `#reflection-root` for portal cases.
|
|
148
|
+
- `background`: CSS background matching the Figma frame fill.
|
|
149
|
+
- `align`: `center` or `start`; `center` places the component in the middle of the frame.
|
|
150
|
+
- `padding`: integer pixel padding inside the frame.
|
|
151
|
+
|
|
108
152
|
### Pseudo states
|
|
109
153
|
|
|
110
154
|
Prefer story-controlled states. A story named `Button/Hover` or `Button/Focused` is usually more deterministic than moving the mouse in the browser.
|
|
@@ -130,6 +174,7 @@ When the browser must force a state, Reflection requires effective animation sta
|
|
|
130
174
|
Reports include `statePolicy` metadata:
|
|
131
175
|
|
|
132
176
|
- `story-controlled` when no `browserState` is configured;
|
|
177
|
+
- `portal-controlled` when the generated portal renders the state;
|
|
133
178
|
- `browser-forced-with-stabilization` when Reflection applies hover/focus in the browser.
|
|
134
179
|
|
|
135
180
|
## Thresholds
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reflection-check",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "CLI for evidence-backed rendered UI validation.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -45,8 +45,9 @@
|
|
|
45
45
|
"commander": "^14.0.3",
|
|
46
46
|
"jiti": "^2.7.0",
|
|
47
47
|
"pixelmatch": "^7.2.0",
|
|
48
|
-
"pngjs": "^7.0.0",
|
|
49
48
|
"playwright": "^1.60.0",
|
|
49
|
+
"pngjs": "^7.0.0",
|
|
50
|
+
"vite": "^8.0.16",
|
|
50
51
|
"zod": "^4.4.3"
|
|
51
52
|
},
|
|
52
53
|
"devDependencies": {
|