@vizzly-testing/cli 0.29.0 → 0.29.2
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/api/endpoints.js +3 -1
- package/dist/cli.js +5 -3
- package/dist/commands/builds.js +47 -4
- package/dist/commands/comparisons.js +1 -0
- package/dist/reporter/reporter-bundle.iife.js +46 -46
- package/dist/server/handlers/tdd-handler.js +81 -26
- package/dist/server/routers/dashboard.js +50 -1
- package/package.json +1 -1
package/dist/api/endpoints.js
CHANGED
|
@@ -214,7 +214,7 @@ export async function getComparison(client, comparisonId) {
|
|
|
214
214
|
* Search for comparisons by name
|
|
215
215
|
* @param {Object} client - API client
|
|
216
216
|
* @param {string} name - Screenshot name to search for
|
|
217
|
-
* @param {Object} filters - Optional filters (branch, limit, offset)
|
|
217
|
+
* @param {Object} filters - Optional filters (branch, project, organization, limit, offset)
|
|
218
218
|
* @returns {Promise<Object>} Search results with comparisons and pagination
|
|
219
219
|
*/
|
|
220
220
|
export async function searchComparisons(client, name, filters = {}) {
|
|
@@ -224,6 +224,7 @@ export async function searchComparisons(client, name, filters = {}) {
|
|
|
224
224
|
let {
|
|
225
225
|
branch,
|
|
226
226
|
project,
|
|
227
|
+
organization,
|
|
227
228
|
limit = 50,
|
|
228
229
|
offset = 0
|
|
229
230
|
} = filters;
|
|
@@ -234,6 +235,7 @@ export async function searchComparisons(client, name, filters = {}) {
|
|
|
234
235
|
};
|
|
235
236
|
if (branch) params.branch = branch;
|
|
236
237
|
if (project) params.project = project;
|
|
238
|
+
if (organization) params.organization = organization;
|
|
237
239
|
let endpoint = buildEndpointWithParams('/api/sdk/comparisons/search', params);
|
|
238
240
|
return client.request(endpoint);
|
|
239
241
|
}
|
package/dist/cli.js
CHANGED
|
@@ -432,11 +432,12 @@ program.command('status').description('Check the status of a build').argument('<
|
|
|
432
432
|
}
|
|
433
433
|
await statusCommand(buildId, options, globalOptions);
|
|
434
434
|
});
|
|
435
|
-
program.command('builds').description('List and query builds').option('-b, --build <id>', 'Get a specific build by ID').option('--branch <branch>', 'Filter by branch').option('--status <status>', 'Filter by status (created, pending, processing, completed, failed)').option('--environment <env>', 'Filter by environment').option('-p, --project <slug>', 'Filter by project slug').option('--limit <n>', 'Maximum results to return (1-250)', val => parseInt(val, 10), 20).option('--offset <n>', 'Skip first N results', val => parseInt(val, 10), 0).option('--comparisons', 'Include comparisons when fetching a specific build').addHelpText('after', `
|
|
435
|
+
program.command('builds').description('List and query builds').option('-b, --build <id>', 'Get a specific build by ID').option('--branch <branch>', 'Filter by branch').option('--status <status>', 'Filter by status (created, pending, processing, completed, failed)').option('--environment <env>', 'Filter by environment').option('-p, --project <slug>', 'Filter by project slug').option('--org <slug>', 'Filter by organization slug').option('--limit <n>', 'Maximum results to return (1-250)', val => parseInt(val, 10), 20).option('--offset <n>', 'Skip first N results', val => parseInt(val, 10), 0).option('--comparisons', 'Include comparisons when fetching a specific build').addHelpText('after', `
|
|
436
436
|
Examples:
|
|
437
437
|
$ vizzly builds # List recent builds
|
|
438
438
|
$ vizzly builds --branch main # Filter by branch
|
|
439
|
-
$ vizzly builds --project
|
|
439
|
+
$ vizzly builds --project storybook # Filter by project
|
|
440
|
+
$ vizzly builds --project storybook --org my-org # Disambiguate by org
|
|
440
441
|
$ vizzly builds --status completed # Filter by status
|
|
441
442
|
$ vizzly builds -b abc123-def456 # Get specific build by ID
|
|
442
443
|
$ vizzly builds -b abc123 --comparisons # Include comparisons
|
|
@@ -455,12 +456,13 @@ Examples:
|
|
|
455
456
|
}
|
|
456
457
|
await buildsCommand(options, globalOptions);
|
|
457
458
|
});
|
|
458
|
-
program.command('comparisons').description('Query and search comparisons').option('-b, --build <id>', 'Get comparisons for a specific build').option('--id <id>', 'Get a specific comparison by ID').option('--name <pattern>', 'Search comparisons by name (supports wildcards)').option('--status <status>', 'Filter by status (identical, new, changed)').option('--branch <branch>', 'Filter by branch (for name search)').option('--limit <n>', 'Maximum results to return (1-250)', val => parseInt(val, 10), 50).option('--offset <n>', 'Skip first N results', val => parseInt(val, 10), 0).option('-p, --project <slug>', 'Filter by project slug').addHelpText('after', `
|
|
459
|
+
program.command('comparisons').description('Query and search comparisons').option('-b, --build <id>', 'Get comparisons for a specific build').option('--id <id>', 'Get a specific comparison by ID').option('--name <pattern>', 'Search comparisons by name (supports wildcards)').option('--status <status>', 'Filter by status (identical, new, changed)').option('--branch <branch>', 'Filter by branch (for name search)').option('--limit <n>', 'Maximum results to return (1-250)', val => parseInt(val, 10), 50).option('--offset <n>', 'Skip first N results', val => parseInt(val, 10), 0).option('-p, --project <slug>', 'Filter by project slug').option('--org <slug>', 'Filter by organization slug').addHelpText('after', `
|
|
459
460
|
Examples:
|
|
460
461
|
$ vizzly comparisons -b abc123 # List comparisons for a build
|
|
461
462
|
$ vizzly comparisons --id def456 # Get specific comparison by ID
|
|
462
463
|
$ vizzly comparisons --name "Button" # Search by screenshot name
|
|
463
464
|
$ vizzly comparisons --name "Login*" # Wildcard search
|
|
465
|
+
$ vizzly comparisons --name "Button" --org my-org # Filter by org
|
|
464
466
|
$ vizzly comparisons --status changed # Only changed comparisons
|
|
465
467
|
$ vizzly comparisons --json # Output as JSON for scripting
|
|
466
468
|
`).action(async options => {
|
package/dist/commands/builds.js
CHANGED
|
@@ -73,6 +73,7 @@ export async function buildsCommand(options = {}, globalOptions = {}, deps = {})
|
|
|
73
73
|
if (options.status) filters.status = options.status;
|
|
74
74
|
if (options.environment) filters.environment = options.environment;
|
|
75
75
|
if (options.project) filters.project = options.project;
|
|
76
|
+
if (options.org) filters.organization = options.org;
|
|
76
77
|
let response = await getBuilds(client, filters);
|
|
77
78
|
output.stopSpinner();
|
|
78
79
|
let builds = response.builds || [];
|
|
@@ -110,11 +111,27 @@ export async function buildsCommand(options = {}, globalOptions = {}, deps = {})
|
|
|
110
111
|
for (let build of builds) {
|
|
111
112
|
let statusColor = getStatusColor(colors, build.status);
|
|
112
113
|
let statusBadge = statusColor(build.status.toUpperCase());
|
|
113
|
-
|
|
114
|
+
|
|
115
|
+
// Approval badge
|
|
116
|
+
let approvalBadge = '';
|
|
117
|
+
if (build.approval_status && build.status === 'completed') {
|
|
118
|
+
approvalBadge = ` ${getApprovalBadge(colors, build.approval_status)}`;
|
|
119
|
+
}
|
|
120
|
+
output.print(` ${colors.bold(build.name || build.id)} ${statusBadge}${approvalBadge}`);
|
|
114
121
|
let details = [];
|
|
115
122
|
if (build.branch) details.push(build.branch);
|
|
116
123
|
if (build.commit_sha) details.push(build.commit_sha.substring(0, 7));
|
|
117
124
|
if (build.screenshot_count) details.push(`${build.screenshot_count} screenshots`);
|
|
125
|
+
|
|
126
|
+
// Comparison counts summary
|
|
127
|
+
let compParts = [];
|
|
128
|
+
let changed = build.changed_comparisons || 0;
|
|
129
|
+
let identical = build.identical_comparisons || 0;
|
|
130
|
+
let newCount = build.new_comparisons || 0;
|
|
131
|
+
if (changed > 0) compParts.push(`${changed} changed`);
|
|
132
|
+
if (newCount > 0) compParts.push(`${newCount} new`);
|
|
133
|
+
if (identical > 0) compParts.push(`${identical} identical`);
|
|
134
|
+
if (compParts.length > 0) details.push(compParts.join(' · '));
|
|
118
135
|
if (details.length > 0) {
|
|
119
136
|
output.print(` ${colors.dim(details.join(' · '))}`);
|
|
120
137
|
}
|
|
@@ -171,7 +188,7 @@ function formatBuildForJson(build, includeComparisons = false) {
|
|
|
171
188
|
let hasHoneydiff = clusterMetadata || ssimScore != null || gmsdScore != null || fingerprintHash;
|
|
172
189
|
return {
|
|
173
190
|
id: c.id,
|
|
174
|
-
name: c.name,
|
|
191
|
+
name: c.name || c.current_name,
|
|
175
192
|
status: c.status,
|
|
176
193
|
diffPercentage: c.diff_percentage,
|
|
177
194
|
approvalStatus: c.approval_status,
|
|
@@ -236,8 +253,17 @@ function displayBuild(output, build, verbose) {
|
|
|
236
253
|
output.blank();
|
|
237
254
|
output.labelValue('Comparisons', '');
|
|
238
255
|
for (let comp of build.comparisons.slice(0, verbose ? 50 : 10)) {
|
|
239
|
-
let
|
|
240
|
-
|
|
256
|
+
let resultIcon = getComparisonStatusIcon(colors, comp.result || comp.status);
|
|
257
|
+
let compName = comp.name || comp.current_name || comp.id;
|
|
258
|
+
let diffInfo = '';
|
|
259
|
+
if (comp.diff_percentage > 0) {
|
|
260
|
+
diffInfo = colors.dim(` (${comp.diff_percentage.toFixed(2)}%)`);
|
|
261
|
+
}
|
|
262
|
+
let classification = '';
|
|
263
|
+
if (verbose && comp.cluster_metadata?.classification) {
|
|
264
|
+
classification = colors.dim(` [${comp.cluster_metadata.classification}]`);
|
|
265
|
+
}
|
|
266
|
+
output.print(` ${resultIcon} ${compName}${diffInfo}${classification}`);
|
|
241
267
|
}
|
|
242
268
|
if (build.comparisons.length > (verbose ? 50 : 10)) {
|
|
243
269
|
output.hint(` ... and ${build.comparisons.length - (verbose ? 50 : 10)} more`);
|
|
@@ -262,6 +288,23 @@ function getStatusColor(colors, status) {
|
|
|
262
288
|
}
|
|
263
289
|
}
|
|
264
290
|
|
|
291
|
+
/**
|
|
292
|
+
* Get colored approval badge
|
|
293
|
+
*/
|
|
294
|
+
function getApprovalBadge(colors, approvalStatus) {
|
|
295
|
+
switch (approvalStatus) {
|
|
296
|
+
case 'approved':
|
|
297
|
+
case 'auto_approved':
|
|
298
|
+
return colors.brand.success('APPROVED');
|
|
299
|
+
case 'rejected':
|
|
300
|
+
return colors.brand.error('REJECTED');
|
|
301
|
+
case 'pending':
|
|
302
|
+
return colors.brand.warning('PENDING');
|
|
303
|
+
default:
|
|
304
|
+
return colors.dim(approvalStatus?.toUpperCase() || '');
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
265
308
|
/**
|
|
266
309
|
* Get icon for comparison status
|
|
267
310
|
*/
|
|
@@ -107,6 +107,7 @@ export async function comparisonsCommand(options = {}, globalOptions = {}, deps
|
|
|
107
107
|
let filters = {
|
|
108
108
|
branch: options.branch,
|
|
109
109
|
project: options.project,
|
|
110
|
+
organization: options.org,
|
|
110
111
|
limit: options.limit || 50,
|
|
111
112
|
offset: options.offset || 0
|
|
112
113
|
};
|