@juxtapose/core 0.2.0 → 0.4.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/dist/analysis/affected.d.ts +21 -0
- package/dist/analysis/affected.js +37 -0
- package/dist/analysis/affected.js.map +1 -1
- package/dist/capture/capture.js +8 -1
- package/dist/capture/capture.js.map +1 -1
- package/dist/capture/env.d.ts +8 -0
- package/dist/capture/env.js +38 -0
- package/dist/capture/env.js.map +1 -0
- package/dist/index.d.ts +11 -11
- package/dist/index.js +28 -11
- package/dist/index.js.map +1 -1
- package/dist/report/comment.d.ts +2 -1
- package/dist/report/comment.js +299 -57
- package/dist/report/comment.js.map +1 -1
- package/dist/report/format.d.ts +2 -0
- package/dist/report/format.js +12 -0
- package/dist/report/format.js.map +1 -0
- package/dist/report/github.d.ts +12 -0
- package/dist/report/github.js +21 -0
- package/dist/report/github.js.map +1 -1
- package/dist/report/html.d.ts +12 -0
- package/dist/report/html.js +202 -0
- package/dist/report/html.js.map +1 -0
- package/dist/run/phases.d.ts +19 -0
- package/dist/run/phases.js +50 -0
- package/dist/run/phases.js.map +1 -0
- package/dist/run/run.d.ts +4 -0
- package/dist/run/run.js +25 -5
- package/dist/run/run.js.map +1 -1
- package/dist/types.d.ts +35 -2
- package/package.json +11 -2
package/dist/report/comment.js
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
// A pure function, separate from posting it, so the formatting can be tested
|
|
4
4
|
// without a network or a token — and so `jux run --json` consumers can render
|
|
5
5
|
// the same summary elsewhere.
|
|
6
|
+
//
|
|
7
|
+
// The comment is a triage surface, not a report. Two constraints shape it:
|
|
8
|
+
//
|
|
9
|
+
// 1. The `###` heading is the only part that renders in the PR timeline
|
|
10
|
+
// collapse and in GitHub notification emails — tables do not. For a large
|
|
11
|
+
// share of readers the heading IS the comment, so the decisive number
|
|
12
|
+
// (largest mismatch) goes there rather than in row one of a table.
|
|
13
|
+
// 2. Images are impossible. GitHub's sanitizer strips `src` from both
|
|
14
|
+
// `<img src="data:...">` and ``; only https:// survives, via
|
|
15
|
+
// camo. So the text has to carry everything and link out for pixels.
|
|
16
|
+
import { formatPercent } from './format.js';
|
|
6
17
|
/**
|
|
7
18
|
* Invisible marker identifying our own comment.
|
|
8
19
|
*
|
|
@@ -11,89 +22,320 @@
|
|
|
11
22
|
* A PR with ten pushes ends up with one comment, not ten.
|
|
12
23
|
*/
|
|
13
24
|
export const COMMENT_MARKER = '<!-- juxtapose-bot -->';
|
|
25
|
+
/** GitHub comments have a size limit, but attention is the binding constraint
|
|
26
|
+
* long before bytes are: nobody triages row 34 in a PR comment. */
|
|
27
|
+
const MAX_ROWS = 30;
|
|
14
28
|
/** Stories that block a merge — anything a human or agent must judge. */
|
|
15
29
|
function blocking(report) {
|
|
16
30
|
return report.results.filter((r) => r.status === 'fail' || r.status === 'new' || r.status === 'stale');
|
|
17
31
|
}
|
|
32
|
+
/** A story whose pixels differ. An errored capture is marked 'fail' too, but it
|
|
33
|
+
* is not a visual decision — nothing about it can be reviewed or approved. */
|
|
34
|
+
const changed = (r) => r.status === 'fail' && !r.error;
|
|
18
35
|
export function buildComment({ report, artifactUrl }) {
|
|
19
|
-
const s = report.summary;
|
|
20
36
|
const needsReview = blocking(report);
|
|
21
37
|
const lines = [COMMENT_MARKER, ''];
|
|
22
|
-
// Lead with the verdict. Someone scanning a PR should not have to parse a
|
|
23
|
-
// table to learn whether they need to do anything.
|
|
24
38
|
if (needsReview.length === 0) {
|
|
25
|
-
lines.push(`### Visual tests passed`, '');
|
|
26
|
-
lines.push(`${s.pass} ${s.pass === 1 ? 'story' : 'stories'} match their baselines.`);
|
|
27
|
-
if (s.skip > 0)
|
|
28
|
-
lines.push(`${s.skip} skipped.`);
|
|
39
|
+
lines.push(`### Visual tests passed`, '', passingBody(report));
|
|
29
40
|
lines.push('', footer(report, artifactUrl));
|
|
30
41
|
return lines.join('\n');
|
|
31
42
|
}
|
|
32
|
-
|
|
33
|
-
lines.push(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (
|
|
37
|
-
lines.push(
|
|
38
|
-
|
|
39
|
-
lines.push(`| **new** | **${s.new}** |`);
|
|
40
|
-
if (s.stale > 0)
|
|
41
|
-
lines.push(`| **stale** | **${s.stale}** |`);
|
|
42
|
-
if (s.skip > 0)
|
|
43
|
-
lines.push(`| skipped | ${s.skip} |`);
|
|
44
|
-
lines.push('');
|
|
45
|
-
// Open by default: the whole point is that a reviewer sees what changed
|
|
46
|
-
// without clicking. Collapsed only when the list is long enough to bury the
|
|
47
|
-
// rest of the PR conversation.
|
|
48
|
-
const open = needsReview.length <= 10 ? ' open' : '';
|
|
49
|
-
lines.push(`<details${open}>`, `<summary>${needsReview.length} ${needsReview.length === 1 ? 'story' : 'stories'}</summary>`, '');
|
|
50
|
-
lines.push('| story | status | changed |', '| --- | --- | --- |');
|
|
51
|
-
for (const r of needsReview.slice(0, MAX_ROWS)) {
|
|
52
|
-
lines.push(`| \`${r.storyId}\` | ${label(r.status)} | ${detail(r)} |`);
|
|
43
|
+
const rows = triageOrder(needsReview);
|
|
44
|
+
lines.push(`### ${heading(rows)}`, '');
|
|
45
|
+
// A first run has nothing to compare against, and the table alone does not
|
|
46
|
+
// say so — every other shape is self-explanatory from the heading.
|
|
47
|
+
if (rows.every((r) => r.status === 'new')) {
|
|
48
|
+
lines.push('Nothing to compare against: these stories have never been approved. ' +
|
|
49
|
+
'Check the captures look right, then approve to establish them as baselines.', '');
|
|
53
50
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
lines.push(...table(rows));
|
|
52
|
+
lines.push('');
|
|
53
|
+
// Uncollapsed, and one fence. The comment is edited in place, so GitHub does
|
|
54
|
+
// not re-notify on a push — the repeat reader only sees this when they come
|
|
55
|
+
// back to act on it. The first-time reader is the one who would otherwise pay
|
|
56
|
+
// a click to discover the tool even has a CTA.
|
|
57
|
+
lines.push('```bash', ...commands(rows), '```', '');
|
|
58
|
+
lines.push(...guidance(rows));
|
|
59
59
|
lines.push(footer(report, artifactUrl));
|
|
60
60
|
return lines.join('\n');
|
|
61
61
|
}
|
|
62
|
-
/**
|
|
63
|
-
*
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
62
|
+
/**
|
|
63
|
+
* Order by triage cost, not by magnitude alone.
|
|
64
|
+
*
|
|
65
|
+
* Errors lead: a capture that crashed is not a visual decision, and it cannot
|
|
66
|
+
* be ranked by percentage anyway — a crash records 0% (run.ts) while a
|
|
67
|
+
* dimension mismatch records 100% (diff.ts), so sorting on the number would
|
|
68
|
+
* scatter the two error kinds to opposite ends. `error != null` is the only
|
|
69
|
+
* reliable marker.
|
|
70
|
+
*
|
|
71
|
+
* Then fail by magnitude descending, then new, then stale — stale last because
|
|
72
|
+
* its pixels are byte-identical and it is the cheapest thing on the list to
|
|
73
|
+
* clear. Ties break on storyId so the body is stable across re-runs; an
|
|
74
|
+
* unstable order would show up as a phantom edit on every push.
|
|
75
|
+
*/
|
|
76
|
+
function triageOrder(results) {
|
|
77
|
+
const rank = (r) => {
|
|
78
|
+
if (r.error)
|
|
79
|
+
return 0;
|
|
80
|
+
if (r.status === 'fail')
|
|
81
|
+
return 1;
|
|
82
|
+
if (r.status === 'new')
|
|
83
|
+
return 2;
|
|
84
|
+
return 3;
|
|
85
|
+
};
|
|
86
|
+
return [...results].sort((a, b) => {
|
|
87
|
+
const byRank = rank(a) - rank(b);
|
|
88
|
+
if (byRank !== 0)
|
|
89
|
+
return byRank;
|
|
90
|
+
if (rank(a) === 1) {
|
|
91
|
+
const byPct = b.mismatchPercent - a.mismatchPercent;
|
|
92
|
+
if (byPct !== 0)
|
|
93
|
+
return byPct;
|
|
94
|
+
}
|
|
95
|
+
return a.storyId.localeCompare(b.storyId);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The heading carries the verdict AND its magnitude.
|
|
100
|
+
*
|
|
101
|
+
* Under a byte-exact hash, "3 changed" is produced equally by three
|
|
102
|
+
* antialiasing hairs and three collapsed layouts. The count alone cannot be
|
|
103
|
+
* acted on; the largest mismatch can.
|
|
104
|
+
*/
|
|
105
|
+
function heading(rows) {
|
|
106
|
+
const errors = rows.filter((r) => r.error).length;
|
|
107
|
+
const fails = rows.filter(changed);
|
|
108
|
+
if (errors > 0) {
|
|
109
|
+
const rest = rows.length - errors;
|
|
110
|
+
const tail = rest > 0 ? ` — ${rest} more ${rest === 1 ? 'needs' : 'need'} review` : '';
|
|
111
|
+
return `${count(errors, 'story', 'stories')} failed to capture${tail}`;
|
|
75
112
|
}
|
|
113
|
+
// Derived from `rows`, not `report.summary`: summary.fail counts errored
|
|
114
|
+
// stories too (run.ts marks them 'fail'), so a summary-based check here would
|
|
115
|
+
// silently depend on the errors branch above catching them first.
|
|
116
|
+
//
|
|
117
|
+
// A first run is 100% new by construction. Calling that a failure teaches
|
|
118
|
+
// people the tool cries wolf on day one.
|
|
119
|
+
if (rows.every((r) => r.status === 'new')) {
|
|
120
|
+
return `${count(rows.length, 'new story', 'new stories')} — no baselines yet`;
|
|
121
|
+
}
|
|
122
|
+
if (rows.every((r) => r.status === 'stale')) {
|
|
123
|
+
return `${count(rows.length, 'stale baseline', 'stale baselines')} — pixels identical, re-approve to re-anchor`;
|
|
124
|
+
}
|
|
125
|
+
if (fails.length === 0) {
|
|
126
|
+
return `${count(rows.length, 'story', 'stories')} need review`;
|
|
127
|
+
}
|
|
128
|
+
const largest = Math.max(...fails.map((r) => r.mismatchPercent));
|
|
129
|
+
// Below 0.1% the individual numbers are noise and a wall of them reads as
|
|
130
|
+
// alarming; saying so once is more useful than quoting the largest hair.
|
|
131
|
+
// `formatPercent` never renders "0.00%", which would read as a tool bug.
|
|
132
|
+
const magnitude = largest < 0.1 ? 'all under 0.1%' : `largest ${formatPercent(largest)}`;
|
|
133
|
+
// Mixed: name the shape, since "5 changes" would overstate what changed.
|
|
134
|
+
if (rows.length > fails.length) {
|
|
135
|
+
return `${count(rows.length, 'story', 'stories')} need review — ${fails.length} changed, ${magnitude}`;
|
|
136
|
+
}
|
|
137
|
+
const noun = count(fails.length, 'visual change', 'visual changes');
|
|
138
|
+
const verb = fails.length === 1 ? 'needs' : 'need';
|
|
139
|
+
const detail = fails.length === 1 && largest >= 0.1 ? formatPercent(largest) : magnitude;
|
|
140
|
+
return `${noun} ${verb} review — ${detail}`;
|
|
76
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Drop columns that carry no information.
|
|
144
|
+
*
|
|
145
|
+
* When every row shares a status the column is a stack of identical strings,
|
|
146
|
+
* and when nothing was compared there is no mismatch to show. Both are the
|
|
147
|
+
* common case: a fail-only run and a first run.
|
|
148
|
+
*/
|
|
149
|
+
function table(rows) {
|
|
150
|
+
const statuses = new Set(rows.map((r) => r.status));
|
|
151
|
+
const showStatus = statuses.size > 1;
|
|
152
|
+
// Nothing to say about magnitude when nothing was compared — an all-new run
|
|
153
|
+
// would otherwise carry a column reading "first capture" on every row.
|
|
154
|
+
const showDetail = rows.some((r) => r.error || r.status === 'fail' || r.status === 'stale');
|
|
155
|
+
const head = [
|
|
156
|
+
'story',
|
|
157
|
+
showStatus ? 'status' : null,
|
|
158
|
+
showDetail ? 'changed' : null,
|
|
159
|
+
].filter((c) => c !== null);
|
|
160
|
+
const out = [`| ${head.join(' | ')} |`, `| ${head.map(() => '---').join(' | ')} |`];
|
|
161
|
+
for (const r of rows.slice(0, MAX_ROWS)) {
|
|
162
|
+
const cells = [
|
|
163
|
+
`\`${cell(r.storyId)}\``,
|
|
164
|
+
showStatus ? (r.status === 'fail' ? 'changed' : r.status) : null,
|
|
165
|
+
showDetail ? detail(r) : null,
|
|
166
|
+
].filter((c) => c !== null);
|
|
167
|
+
out.push(`| ${cells.join(' | ')} |`);
|
|
168
|
+
}
|
|
169
|
+
if (rows.length > MAX_ROWS) {
|
|
170
|
+
const omitted = rows.slice(MAX_ROWS);
|
|
171
|
+
// "smallest changes" is only true when the tail is all fails — they sort by
|
|
172
|
+
// magnitude. `new` and `stale` sort after them by storyId, so a mixed tail
|
|
173
|
+
// is cut alphabetically and has no magnitude to be smallest of.
|
|
174
|
+
const why = omitted.every(changed) ? ', smallest changes omitted' : '';
|
|
175
|
+
// A plain line, not a table row: a row would need its cell count to track
|
|
176
|
+
// the columns above, and renders as trailing empty cells.
|
|
177
|
+
out.push('', `_…and ${omitted.length} more${why}._`);
|
|
178
|
+
}
|
|
179
|
+
return out;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* One copyable sequence.
|
|
183
|
+
*
|
|
184
|
+
* `jux run` leads because approval reads the LAST LOCAL RUN — the run being
|
|
185
|
+
* reported here happened on a CI runner, so `jux approve` alone either fails
|
|
186
|
+
* with "no run found" or silently approves a stale local run. Keeping it in the
|
|
187
|
+
* same fence is deliberate: a reader who copies a later block must not end up
|
|
188
|
+
* with approve-without-run.
|
|
189
|
+
*/
|
|
190
|
+
function commands(rows) {
|
|
191
|
+
const out = [annotate('jux run', 'approval reads a local run, so capture first')];
|
|
192
|
+
// Only worth investigating a change big enough to be something. Below 0.1%
|
|
193
|
+
// is antialiasing territory (see magnitudeHint in agent/handoff.ts), and
|
|
194
|
+
// pointing the "investigate this" tool at noise wastes the reader's time.
|
|
195
|
+
const worthInvestigating = rows.find((r) => changed(r) && r.mismatchPercent >= 0.1);
|
|
196
|
+
if (worthInvestigating) {
|
|
197
|
+
out.push(annotate(`jux handoff ${worthInvestigating.storyId}`, 'unsure? agent-ready prompt: what moved, where'));
|
|
198
|
+
}
|
|
199
|
+
// Never name an errored story here: approving a crashed capture bakes a
|
|
200
|
+
// broken baseline into the manifest, which is the one outcome worse than a
|
|
201
|
+
// red build.
|
|
202
|
+
const approvable = rows.find((r) => !r.error);
|
|
203
|
+
out.push(approvable
|
|
204
|
+
? annotate('jux approve --all', `or --story ${approvable.storyId}`)
|
|
205
|
+
: 'jux approve --all');
|
|
206
|
+
return out;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Align a trailing `#` comment, or drop it.
|
|
210
|
+
*
|
|
211
|
+
* Story ids are long — the examples already hit 31 characters and a real design
|
|
212
|
+
* system goes well past that. Padding past the column produces a line that
|
|
213
|
+
* wraps inside GitHub's fixed-width code block, which is worse than having no
|
|
214
|
+
* annotation at all.
|
|
215
|
+
*/
|
|
216
|
+
function annotate(command, note) {
|
|
217
|
+
return command.length > COMMENT_COLUMN
|
|
218
|
+
? command
|
|
219
|
+
: `${command.padEnd(COMMENT_COLUMN)} # ${note}`;
|
|
220
|
+
}
|
|
221
|
+
const COMMENT_COLUMN = 32;
|
|
222
|
+
/**
|
|
223
|
+
* Reference material, collapsed.
|
|
224
|
+
*
|
|
225
|
+
* A first-timer reads this once; a repeat reader has internalized it. Only the
|
|
226
|
+
* statuses actually present get a paragraph — a fail-only run should not
|
|
227
|
+
* explain what "stale" means.
|
|
228
|
+
*/
|
|
229
|
+
function guidance(rows) {
|
|
230
|
+
const has = (s) => rows.some((r) => r.status === s && !r.error);
|
|
231
|
+
const paras = [];
|
|
232
|
+
if (rows.some((r) => r.error)) {
|
|
233
|
+
paras.push('Some stories failed to capture. That is not a visual decision — approving ' +
|
|
234
|
+
'one would bake a broken baseline into the manifest. Fix the capture first.');
|
|
235
|
+
}
|
|
236
|
+
if (has('fail')) {
|
|
237
|
+
paras.push('Pixels differ from the approved baseline. Decide intentional vs regression ' +
|
|
238
|
+
'before approving.');
|
|
239
|
+
}
|
|
240
|
+
if (has('new')) {
|
|
241
|
+
paras.push('New stories have no baseline, so nothing was compared. Confirm the render is ' +
|
|
242
|
+
'correct, then approve to establish it.');
|
|
243
|
+
}
|
|
244
|
+
if (has('stale')) {
|
|
245
|
+
paras.push('Stale baselines render **byte-identical** pixels — there is nothing to look at. ' +
|
|
246
|
+
'The baseline was approved on a commit that is not in this history, usually a ' +
|
|
247
|
+
'branch that never merged. Re-approving re-anchors it.');
|
|
248
|
+
}
|
|
249
|
+
paras.push('Then commit `juxtapose.manifest.json` and `.juxtapose/baselines/` — that is what ' +
|
|
250
|
+
'makes approval a reviewable diff.');
|
|
251
|
+
paras.push('Prefer a UI? Start the run from the **Juxtapose** panel in Storybook to approve, ' +
|
|
252
|
+
'diff, and copy agent prompts without leaving the browser.');
|
|
253
|
+
return [
|
|
254
|
+
'<details><summary>What these mean, and what to commit</summary>',
|
|
255
|
+
'',
|
|
256
|
+
...paras.flatMap((p) => [p, '']),
|
|
257
|
+
'</details>',
|
|
258
|
+
'',
|
|
259
|
+
];
|
|
260
|
+
}
|
|
261
|
+
function passingBody(report) {
|
|
262
|
+
const s = report.summary;
|
|
263
|
+
// `pass` counts CAPTURED passes, so "42 stories match" is a lie on a narrowed
|
|
264
|
+
// run where only six were captured.
|
|
265
|
+
const narrowed = report.capturedCount < report.totalCount;
|
|
266
|
+
const head = narrowed
|
|
267
|
+
? `${count(s.pass, 'captured story matches', 'captured stories match')} their baselines.`
|
|
268
|
+
: `${count(s.pass, 'story matches', 'stories match')} their baselines.`;
|
|
269
|
+
return s.skip > 0 ? `${head} ${s.skip} skipped.` : head;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Say something true for every status — an em-dash column is dead weight, and
|
|
273
|
+
* on a first run it is dead weight on every single row.
|
|
274
|
+
*/
|
|
77
275
|
function detail(r) {
|
|
78
276
|
if (r.error)
|
|
79
|
-
return r.error;
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
277
|
+
return cell(r.error);
|
|
278
|
+
// Blank only when the whole table is new stories and the column is dropped
|
|
279
|
+
// entirely; alongside other statuses it needs to say why it is not a number.
|
|
280
|
+
if (r.status === 'new')
|
|
281
|
+
return 'first capture';
|
|
282
|
+
// Reachable only after a byte-exact hash match (baseline/status.ts), so this
|
|
283
|
+
// is a guarantee rather than a guess.
|
|
284
|
+
if (r.status === 'stale')
|
|
285
|
+
return 'pixels identical';
|
|
286
|
+
const parts = [`**${formatPercent(r.mismatchPercent)}**`];
|
|
287
|
+
const where = regionHint(r);
|
|
288
|
+
if (where)
|
|
289
|
+
parts.push(where);
|
|
290
|
+
return parts.join(' · ');
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* How localized the change is — percentage alone cannot tell a text tweak from
|
|
294
|
+
* a token that moved everything. One region at top-left is a button; six
|
|
295
|
+
* scattered regions is a font or a design token.
|
|
296
|
+
*
|
|
297
|
+
* `computeChangedRegions` returns row-scan discovery order, NOT size order, so
|
|
298
|
+
* the largest has to be picked explicitly.
|
|
299
|
+
*/
|
|
300
|
+
function regionHint(r) {
|
|
301
|
+
if (!r.viewport || r.changedRegions.length === 0)
|
|
302
|
+
return null;
|
|
303
|
+
const n = r.changedRegions.length;
|
|
304
|
+
const largest = r.changedRegions.reduce((a, b) => b.width * b.height > a.width * a.height ? b : a);
|
|
305
|
+
const v = r.viewport;
|
|
306
|
+
const cx = largest.x + largest.width / 2;
|
|
307
|
+
const cy = largest.y + largest.height / 2;
|
|
308
|
+
const vertical = cy < v.height / 3 ? 'top' : cy > (v.height * 2) / 3 ? 'bottom' : 'middle';
|
|
309
|
+
const horizontal = cx < v.width / 3 ? 'left' : cx > (v.width * 2) / 3 ? 'right' : 'center';
|
|
310
|
+
return `${n} ${n === 1 ? 'region' : 'regions'}, ${vertical}-${horizontal}`;
|
|
83
311
|
}
|
|
84
312
|
function footer(report, artifactUrl) {
|
|
313
|
+
// A narrowed capture count reads as alarming without a reason; naming the
|
|
314
|
+
// mechanism rules out "the tool gave up and skipped things".
|
|
315
|
+
const captured = report.capturedCount < report.totalCount
|
|
316
|
+
? `${report.capturedCount} of ${report.totalCount} captured (change analysis)`
|
|
317
|
+
: `${report.capturedCount}/${report.totalCount} captured`;
|
|
85
318
|
const parts = [
|
|
86
319
|
`\`${report.commitSha.slice(0, 7)}\``,
|
|
87
|
-
|
|
320
|
+
captured,
|
|
88
321
|
`${(report.durationMs / 1000).toFixed(1)}s`,
|
|
89
322
|
];
|
|
90
323
|
const meta = `<sub>juxtapose · ${parts.join(' · ')}</sub>`;
|
|
91
|
-
|
|
324
|
+
// Describes the destination, not the content: it resolves to a run page with
|
|
325
|
+
// a zip, which is a true statement even if the upload step was skipped.
|
|
326
|
+
return artifactUrl
|
|
327
|
+
? `${meta}\n\n<sub>[CI run — report.html is in the artifacts](${artifactUrl})</sub>`
|
|
328
|
+
: meta;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* A pipe in a cell silently corrupts the table into gibberish. Story ids come
|
|
332
|
+
* from the platform and error strings come from thrown exceptions — neither is
|
|
333
|
+
* ours to trust.
|
|
334
|
+
*/
|
|
335
|
+
function cell(value) {
|
|
336
|
+
return value.replace(/\|/g, '\\|');
|
|
92
337
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (pct >= 0.01)
|
|
96
|
-
return `${pct.toFixed(2)}%`;
|
|
97
|
-
return pct > 0 ? '<0.01%' : '0%';
|
|
338
|
+
function count(n, one, many) {
|
|
339
|
+
return `${n} ${n === 1 ? one : many}`;
|
|
98
340
|
}
|
|
99
341
|
//# sourceMappingURL=comment.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comment.js","sourceRoot":"","sources":["../../src/report/comment.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"comment.js","sourceRoot":"","sources":["../../src/report/comment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// How the mismatch number is written, everywhere it is written.
|
|
2
|
+
//
|
|
3
|
+
// Shared rather than copied because it is a product rule, not a formatter: a
|
|
4
|
+
// real change displaying as "0.00%" reads as a tool bug, so anything below the
|
|
5
|
+
// rounding floor says "<0.01%" instead. Five call sites had their own copy.
|
|
6
|
+
/** Never show "0.00%" next to the word "changed" — it reads as a tool bug. */
|
|
7
|
+
export function formatPercent(pct) {
|
|
8
|
+
if (pct >= 0.01)
|
|
9
|
+
return `${pct.toFixed(2)}%`;
|
|
10
|
+
return pct > 0 ? '<0.01%' : '0%';
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/report/format.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,EAAE;AACF,6EAA6E;AAC7E,+EAA+E;AAC/E,4EAA4E;AAE5E,8EAA8E;AAC9E,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IAC7C,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AACnC,CAAC"}
|
package/dist/report/github.d.ts
CHANGED
|
@@ -18,6 +18,18 @@ export interface GitHubContext {
|
|
|
18
18
|
* build that otherwise passed.
|
|
19
19
|
*/
|
|
20
20
|
export declare function resolveGitHubContext(env?: NodeJS.ProcessEnv): Promise<GitHubContext | null>;
|
|
21
|
+
/**
|
|
22
|
+
* The Actions run page, where uploaded artifacts are listed.
|
|
23
|
+
*
|
|
24
|
+
* Deliberately not derived from env vars alone. `GITHUB_RUN_ID` is set on every
|
|
25
|
+
* Actions run including ones that upload nothing, so keying off it would
|
|
26
|
+
* produce a link to an empty artifacts list — a promise to a dead end, which
|
|
27
|
+
* costs the reader a click and some trust. The caller passes `hasArtifact` only
|
|
28
|
+
* when it actually wrote a report, so no report means no link.
|
|
29
|
+
*
|
|
30
|
+
* We cannot link the artifact file itself: that URL is auth-gated and expires.
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveArtifactUrl(hasArtifact: boolean, env?: NodeJS.ProcessEnv): string | undefined;
|
|
21
33
|
/**
|
|
22
34
|
* Create or update the juxtapose comment.
|
|
23
35
|
*
|
package/dist/report/github.js
CHANGED
|
@@ -28,6 +28,27 @@ export async function resolveGitHubContext(env = process.env) {
|
|
|
28
28
|
apiUrl: env.GITHUB_API_URL ?? 'https://api.github.com',
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* The Actions run page, where uploaded artifacts are listed.
|
|
33
|
+
*
|
|
34
|
+
* Deliberately not derived from env vars alone. `GITHUB_RUN_ID` is set on every
|
|
35
|
+
* Actions run including ones that upload nothing, so keying off it would
|
|
36
|
+
* produce a link to an empty artifacts list — a promise to a dead end, which
|
|
37
|
+
* costs the reader a click and some trust. The caller passes `hasArtifact` only
|
|
38
|
+
* when it actually wrote a report, so no report means no link.
|
|
39
|
+
*
|
|
40
|
+
* We cannot link the artifact file itself: that URL is auth-gated and expires.
|
|
41
|
+
*/
|
|
42
|
+
export function resolveArtifactUrl(hasArtifact, env = process.env) {
|
|
43
|
+
if (!hasArtifact)
|
|
44
|
+
return undefined;
|
|
45
|
+
const server = env.GITHUB_SERVER_URL;
|
|
46
|
+
const repository = env.GITHUB_REPOSITORY;
|
|
47
|
+
const runId = env.GITHUB_RUN_ID;
|
|
48
|
+
if (!server || !repository || !runId)
|
|
49
|
+
return undefined;
|
|
50
|
+
return `${server}/${repository}/actions/runs/${runId}`;
|
|
51
|
+
}
|
|
31
52
|
/**
|
|
32
53
|
* Find the PR number.
|
|
33
54
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/report/github.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/report/github.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,EAAE;AACF,6EAA6E;AAC7E,+EAA+E;AAC/E,wBAAwB;AAExB,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAc9C;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,IAAI,GAAG,CAAC,QAAQ,CAAC;IAC/C,MAAM,UAAU,GAAG,GAAG,CAAC,iBAAiB,CAAC;IACzC,IAAI,CAAC,KAAK,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAEvC,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEnC,OAAO;QACL,KAAK;QACL,UAAU;QACV,QAAQ;QACR,MAAM,EAAE,GAAG,CAAC,cAAc,IAAI,wBAAwB;KACvD,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAChC,WAAoB,EACpB,MAAyB,OAAO,CAAC,GAAG;IAEpC,IAAI,CAAC,WAAW;QAAE,OAAO,SAAS,CAAC;IACnC,MAAM,MAAM,GAAG,GAAG,CAAC,iBAAiB,CAAC;IACrC,MAAM,UAAU,GAAG,GAAG,CAAC,iBAAiB,CAAC;IACzC,MAAM,KAAK,GAAG,GAAG,CAAC,aAAa,CAAC;IAChC,IAAI,CAAC,MAAM,IAAI,CAAC,UAAU,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IACvD,OAAO,GAAG,MAAM,IAAI,UAAU,iBAAiB,KAAK,EAAE,CAAC;AACzD,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,YAAY,CAAC,GAAsB;IAChD,MAAM,SAAS,GAAG,GAAG,CAAC,iBAAiB,CAAC;IACxC,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAGzD,CAAC;YACF,MAAM,CAAC,GAAG,KAAK,CAAC,YAAY,EAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC;YACrD,IAAI,OAAO,CAAC,KAAK,QAAQ;gBAAE,OAAO,CAAC,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,4DAA4D;QAC9D,CAAC;IACH,CAAC;IAED,sBAAsB;IACtB,MAAM,KAAK,GAAG,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;IAChE,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACzC,CAAC;AAOD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,GAAkB,EAClB,IAAY;IAEZ,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;QAE3C,MAAM,GAAG,GAAG,QAAQ;YAClB,CAAC,CAAC,MAAM,GAAG,CAAC,GAAG,EAAE,UAAU,GAAG,CAAC,UAAU,oBAAoB,QAAQ,CAAC,EAAE,EAAE,EAAE;gBACxE,MAAM,EAAE,OAAO;gBACf,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC;aAC/B,CAAC;YACJ,CAAC,CAAC,MAAM,GAAG,CAAC,GAAG,EAAE,UAAU,GAAG,CAAC,UAAU,WAAW,GAAG,CAAC,QAAQ,WAAW,EAAE;gBACzE,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC;aAC/B,CAAC,CAAC;QAEP,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QACzB,MAAM,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA0B,CAAC;QAC5D,OAAO,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,cAAc,CAAC,GAAkB;IAC9C,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,IAAI,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC;QAC7C,MAAM,GAAG,GAAG,MAAM,GAAG,CACnB,GAAG,EACH,UAAU,GAAG,CAAC,UAAU,WAAW,GAAG,CAAC,QAAQ,+BAA+B,IAAI,EAAE,CACrF,CAAC;QACF,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAEzB,MAAM,QAAQ,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAc,CAAC;QACjD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC;QACrE,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QACxB,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG;YAAE,OAAO,IAAI,CAAC;IACzC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,SAAS,GAAG,EAAE,CAAC;AAErB,SAAS,GAAG,CACV,GAAkB,EAClB,IAAY,EACZ,OAAoB,EAAE;IAEtB,OAAO,KAAK,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,IAAI,EAAE,EAAE;QACnC,GAAG,IAAI;QACP,OAAO,EAAE;YACP,MAAM,EAAE,6BAA6B;YACrC,aAAa,EAAE,UAAU,GAAG,CAAC,KAAK,EAAE;YACpC,sBAAsB,EAAE,YAAY;YACpC,cAAc,EAAE,kBAAkB;YAClC,GAAG,IAAI,CAAC,OAAO;SAChB;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RunReport } from '../types.js';
|
|
2
|
+
export interface HtmlReportOptions {
|
|
3
|
+
report: RunReport;
|
|
4
|
+
/** storyId -> image bytes. Missing entries are expected: a new story has no
|
|
5
|
+
* baseline, a passing one needs no diff. */
|
|
6
|
+
images: Map<string, {
|
|
7
|
+
baseline?: Buffer;
|
|
8
|
+
current?: Buffer;
|
|
9
|
+
diff?: Buffer;
|
|
10
|
+
}>;
|
|
11
|
+
}
|
|
12
|
+
export declare function buildHtmlReport({ report, images }: HtmlReportOptions): string;
|