@vizzly-testing/cli 0.28.1 → 0.29.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/builds.js +29 -7
- package/dist/commands/comparisons.js +68 -15
- package/package.json +1 -1
package/dist/commands/builds.js
CHANGED
|
@@ -161,13 +161,35 @@ function formatBuildForJson(build, includeComparisons = false) {
|
|
|
161
161
|
completedAt: build.completed_at
|
|
162
162
|
};
|
|
163
163
|
if (includeComparisons && build.comparisons) {
|
|
164
|
-
result.comparisonDetails = build.comparisons.map(c =>
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
164
|
+
result.comparisonDetails = build.comparisons.map(c => {
|
|
165
|
+
let diffUrl = c.diff_image?.url || c.diff_image_url || c.diff_url || null;
|
|
166
|
+
let diffImage = c.diff_image || {};
|
|
167
|
+
let clusterMetadata = c.cluster_metadata || diffImage.cluster_metadata || null;
|
|
168
|
+
let ssimScore = c.ssim_score ?? diffImage.ssim_score ?? null;
|
|
169
|
+
let gmsdScore = c.gmsd_score ?? diffImage.gmsd_score ?? null;
|
|
170
|
+
let fingerprintHash = c.fingerprint_hash || diffImage.fingerprint_hash || null;
|
|
171
|
+
let hasHoneydiff = clusterMetadata || ssimScore != null || gmsdScore != null || fingerprintHash;
|
|
172
|
+
return {
|
|
173
|
+
id: c.id,
|
|
174
|
+
name: c.name,
|
|
175
|
+
status: c.status,
|
|
176
|
+
diffPercentage: c.diff_percentage,
|
|
177
|
+
approvalStatus: c.approval_status,
|
|
178
|
+
urls: {
|
|
179
|
+
baseline: c.baseline_screenshot?.original_url || c.baseline_original_url || c.baseline_screenshot_url || null,
|
|
180
|
+
current: c.current_screenshot?.original_url || c.current_original_url || c.current_screenshot_url || null,
|
|
181
|
+
diff: diffUrl
|
|
182
|
+
},
|
|
183
|
+
honeydiff: hasHoneydiff ? {
|
|
184
|
+
ssimScore,
|
|
185
|
+
gmsdScore,
|
|
186
|
+
clusterClassification: clusterMetadata?.classification || null,
|
|
187
|
+
clusterMetadata,
|
|
188
|
+
fingerprintHash,
|
|
189
|
+
diffRegions: c.diff_regions ?? diffImage.diff_regions ?? null
|
|
190
|
+
} : null
|
|
191
|
+
};
|
|
192
|
+
});
|
|
171
193
|
}
|
|
172
194
|
return result;
|
|
173
195
|
}
|
|
@@ -154,6 +154,16 @@ export async function comparisonsCommand(options = {}, globalOptions = {}, deps
|
|
|
154
154
|
* Format a comparison for JSON output
|
|
155
155
|
*/
|
|
156
156
|
function formatComparisonForJson(comparison) {
|
|
157
|
+
// API endpoints return different shapes:
|
|
158
|
+
// - Single comparison: nested baseline_screenshot/current_screenshot + flat diff_url, honeydiff at top level
|
|
159
|
+
// - Build comparisons: flat diff_url/diff_image_url, no storage URLs, limited honeydiff
|
|
160
|
+
// - Search: nested diff_image with honeydiff, no current/baseline URLs
|
|
161
|
+
let diffImage = comparison.diff_image || {};
|
|
162
|
+
let clusterMetadata = comparison.cluster_metadata || diffImage.cluster_metadata || null;
|
|
163
|
+
let ssimScore = comparison.ssim_score ?? diffImage.ssim_score ?? null;
|
|
164
|
+
let gmsdScore = comparison.gmsd_score ?? diffImage.gmsd_score ?? null;
|
|
165
|
+
let fingerprintHash = comparison.fingerprint_hash || diffImage.fingerprint_hash || null;
|
|
166
|
+
let hasHoneydiff = clusterMetadata || ssimScore != null || gmsdScore != null || fingerprintHash;
|
|
157
167
|
return {
|
|
158
168
|
id: comparison.id,
|
|
159
169
|
name: comparison.name,
|
|
@@ -166,10 +176,20 @@ function formatComparisonForJson(comparison) {
|
|
|
166
176
|
} : null,
|
|
167
177
|
browser: comparison.browser || null,
|
|
168
178
|
urls: {
|
|
169
|
-
baseline: comparison.baseline_screenshot?.original_url || null,
|
|
170
|
-
current: comparison.current_screenshot?.original_url || null,
|
|
171
|
-
diff: comparison.diff_image?.url || null
|
|
179
|
+
baseline: comparison.baseline_screenshot?.original_url || comparison.baseline_original_url || comparison.baseline_screenshot_url || null,
|
|
180
|
+
current: comparison.current_screenshot?.original_url || comparison.current_original_url || comparison.current_screenshot_url || null,
|
|
181
|
+
diff: comparison.diff_image?.url || comparison.diff_image_url || comparison.diff_url || null
|
|
172
182
|
},
|
|
183
|
+
honeydiff: hasHoneydiff ? {
|
|
184
|
+
ssimScore,
|
|
185
|
+
gmsdScore,
|
|
186
|
+
clusterClassification: clusterMetadata?.classification || null,
|
|
187
|
+
clusterMetadata,
|
|
188
|
+
fingerprintHash,
|
|
189
|
+
diffRegions: comparison.diff_regions ?? diffImage.diff_regions ?? null,
|
|
190
|
+
diffLines: comparison.diff_lines ?? diffImage.diff_lines ?? null,
|
|
191
|
+
fingerprintData: comparison.fingerprint_data ?? diffImage.fingerprint_data ?? null
|
|
192
|
+
} : null,
|
|
173
193
|
buildId: comparison.build_id,
|
|
174
194
|
buildName: comparison.build_name,
|
|
175
195
|
buildBranch: comparison.build_branch,
|
|
@@ -209,18 +229,40 @@ function displayComparison(output, comparison, verbose) {
|
|
|
209
229
|
output.labelValue('Commit', comparison.build_commit_sha.substring(0, 8));
|
|
210
230
|
}
|
|
211
231
|
|
|
212
|
-
//
|
|
232
|
+
// Honeydiff analysis in verbose mode
|
|
213
233
|
if (verbose) {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
234
|
+
let clusterMetadata = comparison.cluster_metadata || comparison.diff_image?.cluster_metadata;
|
|
235
|
+
let ssim = comparison.ssim_score ?? comparison.diff_image?.ssim_score;
|
|
236
|
+
let gmsd = comparison.gmsd_score ?? comparison.diff_image?.gmsd_score;
|
|
237
|
+
let fingerprint = comparison.fingerprint_hash || comparison.diff_image?.fingerprint_hash;
|
|
238
|
+
if (clusterMetadata || ssim != null || gmsd != null || fingerprint) {
|
|
239
|
+
output.blank();
|
|
240
|
+
if (clusterMetadata?.classification) {
|
|
241
|
+
output.labelValue('Classification', clusterMetadata.classification);
|
|
242
|
+
}
|
|
243
|
+
if (ssim != null) {
|
|
244
|
+
output.labelValue('SSIM', ssim.toFixed(4));
|
|
245
|
+
}
|
|
246
|
+
if (gmsd != null) {
|
|
247
|
+
output.labelValue('GMSD', gmsd.toFixed(4));
|
|
248
|
+
}
|
|
249
|
+
if (fingerprint) {
|
|
250
|
+
output.labelValue('Fingerprint', fingerprint);
|
|
251
|
+
}
|
|
221
252
|
}
|
|
222
|
-
|
|
223
|
-
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// URLs in verbose mode
|
|
256
|
+
if (verbose) {
|
|
257
|
+
let baselineUrl = comparison.baseline_screenshot?.original_url || comparison.baseline_original_url || comparison.baseline_screenshot_url;
|
|
258
|
+
let currentUrl = comparison.current_screenshot?.original_url || comparison.current_original_url || comparison.current_screenshot_url;
|
|
259
|
+
let diffUrl = comparison.diff_image?.url || comparison.diff_image_url || comparison.diff_url;
|
|
260
|
+
if (baselineUrl || currentUrl || diffUrl) {
|
|
261
|
+
output.blank();
|
|
262
|
+
output.labelValue('URLs', '');
|
|
263
|
+
if (baselineUrl) output.print(` Baseline: ${baselineUrl}`);
|
|
264
|
+
if (currentUrl) output.print(` Current: ${currentUrl}`);
|
|
265
|
+
if (diffUrl) output.print(` Diff: ${diffUrl}`);
|
|
224
266
|
}
|
|
225
267
|
}
|
|
226
268
|
if (comparison.created_at) {
|
|
@@ -258,7 +300,8 @@ function displayBuildComparisons(output, build, comparisons, verbose) {
|
|
|
258
300
|
for (let comp of comparisons.slice(0, verbose ? 100 : 20)) {
|
|
259
301
|
let icon = getStatusIcon(colors, comp.status);
|
|
260
302
|
let diffInfo = comp.diff_percentage != null ? colors.dim(` (${(comp.diff_percentage * 100).toFixed(1)}%)`) : '';
|
|
261
|
-
|
|
303
|
+
let classification = verbose ? getClassificationLabel(colors, comp.cluster_metadata) : '';
|
|
304
|
+
output.print(` ${icon} ${comp.name}${diffInfo}${classification}`);
|
|
262
305
|
}
|
|
263
306
|
if (comparisons.length > (verbose ? 100 : 20)) {
|
|
264
307
|
output.blank();
|
|
@@ -299,7 +342,8 @@ function displaySearchResults(output, comparisons, searchPattern, pagination, ve
|
|
|
299
342
|
}
|
|
300
343
|
for (let comp of group.comparisons.slice(0, verbose ? 10 : 3)) {
|
|
301
344
|
let icon = getStatusIcon(colors, comp.status);
|
|
302
|
-
|
|
345
|
+
let classification = verbose ? getClassificationLabel(colors, comp.cluster_metadata || comp.diff_image?.cluster_metadata) : '';
|
|
346
|
+
output.print(` ${icon} ${comp.name}${classification}`);
|
|
303
347
|
}
|
|
304
348
|
if (group.comparisons.length > (verbose ? 10 : 3)) {
|
|
305
349
|
output.print(` ${colors.dim(`... and ${group.comparisons.length - (verbose ? 10 : 3)} more`)}`);
|
|
@@ -311,6 +355,15 @@ function displaySearchResults(output, comparisons, searchPattern, pagination, ve
|
|
|
311
355
|
}
|
|
312
356
|
}
|
|
313
357
|
|
|
358
|
+
/**
|
|
359
|
+
* Get a classification label for verbose display
|
|
360
|
+
*/
|
|
361
|
+
function getClassificationLabel(colors, clusterMetadata) {
|
|
362
|
+
let classification = clusterMetadata?.classification;
|
|
363
|
+
if (!classification) return '';
|
|
364
|
+
return colors.dim(` [${classification}]`);
|
|
365
|
+
}
|
|
366
|
+
|
|
314
367
|
/**
|
|
315
368
|
* Get icon for comparison status
|
|
316
369
|
*/
|