@testivai/witness 1.3.0 → 1.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/commands/report.d.ts.map +1 -1
- package/dist/commands/report.js +3 -1
- package/dist/commands/report.js.map +1 -1
- package/dist/config/local-config.d.ts +17 -0
- package/dist/config/local-config.d.ts.map +1 -1
- package/dist/config/local-config.js +8 -0
- package/dist/config/local-config.js.map +1 -1
- package/dist/diff/diff.d.ts.map +1 -1
- package/dist/diff/diff.js +13 -2
- package/dist/diff/diff.js.map +1 -1
- package/dist/diff/mask.d.ts +98 -0
- package/dist/diff/mask.d.ts.map +1 -0
- package/dist/diff/mask.js +209 -0
- package/dist/diff/mask.js.map +1 -0
- package/dist/diff/regions.d.ts +17 -4
- package/dist/diff/regions.d.ts.map +1 -1
- package/dist/diff/regions.js +70 -5
- package/dist/diff/regions.js.map +1 -1
- package/dist/diff/types.d.ts +13 -0
- package/dist/diff/types.d.ts.map +1 -1
- package/dist/report/compare.d.ts +9 -0
- package/dist/report/compare.d.ts.map +1 -1
- package/dist/report/compare.js +72 -12
- package/dist/report/compare.js.map +1 -1
- package/dist/report/generator.d.ts +12 -1
- package/dist/report/generator.d.ts.map +1 -1
- package/dist/report/generator.js +36 -15
- package/dist/report/generator.js.map +1 -1
- package/dist/report/results.d.ts +12 -0
- package/dist/report/results.d.ts.map +1 -1
- package/dist/report/template.d.ts.map +1 -1
- package/dist/report/template.js +74 -0
- package/dist/report/template.js.map +1 -1
- package/package.json +1 -1
package/dist/report/template.js
CHANGED
|
@@ -97,6 +97,19 @@ function renderHtml(data) {
|
|
|
97
97
|
.approve-cmd button:hover { background: #30363d; }
|
|
98
98
|
.approve-cmd button.copied { background: #3fb950; color: #0d1117; }
|
|
99
99
|
|
|
100
|
+
/* Regions */
|
|
101
|
+
.regions { margin-top: 8px; padding: 10px 12px; background: #0d1117; border: 1px solid #21262d; border-radius: 8px; font-size: 12px; }
|
|
102
|
+
.regions .regions-title { color: #8b949e; font-weight: 600; margin-bottom: 6px; }
|
|
103
|
+
.regions ul { list-style: none; display: flex; flex-wrap: wrap; gap: 6px; }
|
|
104
|
+
.regions li a { display: inline-block; padding: 3px 10px; border-radius: 10px; background: #f8514922; color: #f85149; text-decoration: none; font-family: 'SF Mono', 'Fira Code', monospace; font-size: 11px; }
|
|
105
|
+
.regions li a:hover { background: #f8514944; }
|
|
106
|
+
|
|
107
|
+
/* Masks (audit trail) */
|
|
108
|
+
.masks { margin-top: 8px; padding: 10px 12px; background: repeating-linear-gradient(45deg, #161b22, #161b22 6px, #1c2129 6px, #1c2129 8px); border: 1px solid #30363d; border-radius: 8px; font-size: 12px; color: #8b949e; }
|
|
109
|
+
.masks .label { font-weight: 600; color: #c9d1d9; }
|
|
110
|
+
.masks code { color: #79c0ff; font-size: 11px; }
|
|
111
|
+
.mask-warning { margin-top: 8px; padding: 10px 12px; background: #f0883e1a; border: 1px solid #f0883e44; border-radius: 8px; font-size: 12px; color: #f0883e; }
|
|
112
|
+
|
|
100
113
|
/* Zoom overlay */
|
|
101
114
|
.zoom-overlay { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.9); z-index: 100; justify-content: center; align-items: center; cursor: zoom-out; }
|
|
102
115
|
.zoom-overlay.active { display: flex; }
|
|
@@ -192,6 +205,17 @@ function renderHtml(data) {
|
|
|
192
205
|
document.getElementById('zoomOverlay').classList.remove('active');
|
|
193
206
|
});
|
|
194
207
|
|
|
208
|
+
// Region chips zoom the diff image for inspection
|
|
209
|
+
document.querySelectorAll('.region-chip').forEach(chip => {
|
|
210
|
+
chip.addEventListener('click', (e) => {
|
|
211
|
+
e.preventDefault();
|
|
212
|
+
const diff = chip.dataset.diff;
|
|
213
|
+
if (!diff) return;
|
|
214
|
+
document.getElementById('zoomImage').src = diff;
|
|
215
|
+
document.getElementById('zoomOverlay').classList.add('active');
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
|
|
195
219
|
// Copy approve command
|
|
196
220
|
document.querySelectorAll('.copy-btn').forEach(btn => {
|
|
197
221
|
btn.addEventListener('click', () => {
|
|
@@ -230,6 +254,8 @@ function renderSnapshot(snapshot) {
|
|
|
230
254
|
</div>
|
|
231
255
|
${snapshot.status === 'changed' || snapshot.autoPassed ? `<div class="snapshot-stats">Diff: ${snapshot.diffPercent.toFixed(2)}% (${snapshot.diffCount} pixels)${snapshot.autoPassed ? ` — auto-passed: ${snapshot.autoPassed === 'noise' ? 'DOM unchanged, within noise tolerance' : 'within configured diff tolerance'}` : ''}</div>` : ''}
|
|
232
256
|
${renderDomHint(snapshot)}
|
|
257
|
+
${renderRegions(snapshot)}
|
|
258
|
+
${renderMasks(snapshot)}
|
|
233
259
|
<div class="${gridClass}">
|
|
234
260
|
${hasBaseline ? `<div class="diff-col"><label>Baseline</label><img src="${snapshot.baselinePath}" alt="Baseline"></div>` : ''}
|
|
235
261
|
${hasDiff ? `<div class="diff-col"><label>Diff</label><img src="${snapshot.diffPath}" alt="Diff"></div>` : ''}
|
|
@@ -282,6 +308,54 @@ function renderDomHint(snapshot) {
|
|
|
282
308
|
<span class="summary">— ${escapeHtml(parts.join(', ') || 'structural difference')}.</span>
|
|
283
309
|
</div>`;
|
|
284
310
|
}
|
|
311
|
+
/**
|
|
312
|
+
* Region chip list: "N changed regions" with coordinates. Clicking a chip
|
|
313
|
+
* zooms the diff image so the reviewer can inspect that area.
|
|
314
|
+
*/
|
|
315
|
+
function renderRegions(snapshot) {
|
|
316
|
+
const regions = snapshot.regions ?? [];
|
|
317
|
+
if (regions.length === 0 || snapshot.status === 'new')
|
|
318
|
+
return '';
|
|
319
|
+
const chips = regions
|
|
320
|
+
.map((r, i) => `<li><a href="#" class="region-chip" data-diff="${snapshot.diffPath ?? ''}" title="${r.diffPixels} changed pixels">#${i + 1} · ${r.width}×${r.height} @ (${r.x}, ${r.y})</a></li>`)
|
|
321
|
+
.join('');
|
|
322
|
+
return `
|
|
323
|
+
<div class="regions">
|
|
324
|
+
<div class="regions-title">${regions.length} changed region${regions.length === 1 ? '' : 's'}</div>
|
|
325
|
+
<ul>${chips}</ul>
|
|
326
|
+
</div>`;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Mask audit trail: every mask applied to this comparison is listed with
|
|
330
|
+
* its source — masking is visible in review, never silent. Warnings cover
|
|
331
|
+
* masks that could not be applied (e.g. selector without captured rects).
|
|
332
|
+
*/
|
|
333
|
+
function renderMasks(snapshot) {
|
|
334
|
+
const masks = snapshot.masks ?? [];
|
|
335
|
+
const warnings = snapshot.maskWarnings ?? [];
|
|
336
|
+
if (masks.length === 0 && warnings.length === 0)
|
|
337
|
+
return '';
|
|
338
|
+
const describe = (m) => {
|
|
339
|
+
const src = m.source.type === 'selector'
|
|
340
|
+
? `selector <code>${escapeHtml(String(m.source.spec))}</code>`
|
|
341
|
+
: m.source.type === 'edge'
|
|
342
|
+
? `edge <code>${escapeHtml(JSON.stringify(m.source.spec))}</code>`
|
|
343
|
+
: `region <code>${escapeHtml(JSON.stringify(m.source.spec))}</code>`;
|
|
344
|
+
return `${src} → ${m.width}×${m.height} @ (${m.x}, ${m.y}) <em>(${m.source.origin})</em>`;
|
|
345
|
+
};
|
|
346
|
+
const maskBlock = masks.length > 0
|
|
347
|
+
? `
|
|
348
|
+
<div class="masks" title="Masked areas are excluded from the pixel diff and hatched in the diff image.">
|
|
349
|
+
<span class="label">🙈 ${masks.length} mask${masks.length === 1 ? '' : 's'} applied</span>
|
|
350
|
+
— ${masks.map(describe).join('; ')}
|
|
351
|
+
</div>`
|
|
352
|
+
: '';
|
|
353
|
+
const warningBlock = warnings.length > 0
|
|
354
|
+
? `
|
|
355
|
+
<div class="mask-warning">⚠️ ${warnings.map((w) => escapeHtml(w)).join('<br>')}</div>`
|
|
356
|
+
: '';
|
|
357
|
+
return maskBlock + warningBlock;
|
|
358
|
+
}
|
|
285
359
|
function escapeHtml(str) {
|
|
286
360
|
return str
|
|
287
361
|
.replace(/&/g, '&')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/report/template.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAOH,
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/report/template.ts"],"names":[],"mappings":"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"}
|