@vizzly-testing/cli 0.35.0 → 0.35.1
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/README.md +31 -7
- package/dist/api/core.js +16 -3
- package/dist/api/endpoints.js +38 -15
- package/dist/api/index.js +1 -1
- package/dist/cli.js +252 -189
- package/dist/commands/preview.js +19 -17
- package/dist/commands/run.js +7 -4
- package/dist/commands/status.js +14 -1
- package/dist/commands/tdd-daemon-process.js +5 -1
- package/dist/commands/tdd-daemon.js +217 -144
- package/dist/commands/tdd.js +2 -1
- package/dist/reporter/reporter-bundle.iife.js +5 -5
- package/dist/tdd/tdd-service.js +6 -2
- package/dist/test-runner/core.js +4 -2
- package/dist/test-runner/operations.js +17 -2
- package/dist/utils/config-loader.js +1 -0
- package/dist/utils/output.js +3 -0
- package/package.json +1 -1
- package/skills/vizzly/SKILL.md +12 -4
- package/skills/vizzly/references/cli-context.md +8 -2
- package/skills/vizzly/references/setup-ci.md +3 -1
package/dist/commands/preview.js
CHANGED
|
@@ -269,25 +269,10 @@ export async function previewCommand(path, options = {}, globalOptions = {}, dep
|
|
|
269
269
|
color: !globalOptions.noColor
|
|
270
270
|
});
|
|
271
271
|
try {
|
|
272
|
-
// Load configuration
|
|
273
|
-
let allOptions = {
|
|
274
|
-
...globalOptions,
|
|
275
|
-
...options
|
|
276
|
-
};
|
|
277
|
-
let config = await loadConfig(globalOptions.config, allOptions);
|
|
278
|
-
|
|
279
|
-
// Validate API token (skip for dry-run)
|
|
280
|
-
if (!options.dryRun && !config.apiKey) {
|
|
281
|
-
output.error('API token required. Use --token or set VIZZLY_TOKEN environment variable');
|
|
282
|
-
exit(1);
|
|
283
|
-
return {
|
|
284
|
-
success: false,
|
|
285
|
-
reason: 'no-api-key'
|
|
286
|
-
};
|
|
287
|
-
}
|
|
288
272
|
let uploadPath = options.base ? resolve(path, options.base) : path;
|
|
289
273
|
|
|
290
|
-
// Validate path exists and is a directory
|
|
274
|
+
// Validate path exists and is a directory before auth so local input
|
|
275
|
+
// mistakes are visible without requiring credentials.
|
|
291
276
|
if (!existsSync(uploadPath)) {
|
|
292
277
|
output.error(`Path does not exist: ${uploadPath}`);
|
|
293
278
|
exit(1);
|
|
@@ -306,6 +291,23 @@ export async function previewCommand(path, options = {}, globalOptions = {}, dep
|
|
|
306
291
|
};
|
|
307
292
|
}
|
|
308
293
|
|
|
294
|
+
// Load configuration
|
|
295
|
+
let allOptions = {
|
|
296
|
+
...globalOptions,
|
|
297
|
+
...options
|
|
298
|
+
};
|
|
299
|
+
let config = await loadConfig(globalOptions.config, allOptions);
|
|
300
|
+
|
|
301
|
+
// Validate API token (skip for dry-run)
|
|
302
|
+
if (!options.dryRun && !config.apiKey) {
|
|
303
|
+
output.error('API token required. Use --token or set VIZZLY_TOKEN environment variable');
|
|
304
|
+
exit(1);
|
|
305
|
+
return {
|
|
306
|
+
success: false,
|
|
307
|
+
reason: 'no-api-key'
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
|
|
309
311
|
// Resolve build ID
|
|
310
312
|
let buildId = options.build;
|
|
311
313
|
let buildSource = 'flag';
|
package/dist/commands/run.js
CHANGED
|
@@ -246,7 +246,8 @@ export async function runCommand(testCommand, options = {}, globalOptions = {},
|
|
|
246
246
|
wait: config.wait || options.wait || false,
|
|
247
247
|
uploadAll: options.uploadAll || false,
|
|
248
248
|
pullRequestNumber,
|
|
249
|
-
parallelId: config.parallelId
|
|
249
|
+
parallelId: config.parallelId,
|
|
250
|
+
json: globalOptions.json
|
|
250
251
|
};
|
|
251
252
|
|
|
252
253
|
// Start test run
|
|
@@ -336,10 +337,12 @@ export async function runCommand(testCommand, options = {}, globalOptions = {},
|
|
|
336
337
|
result
|
|
337
338
|
};
|
|
338
339
|
}
|
|
339
|
-
|
|
340
|
+
if (!globalOptions.json) {
|
|
341
|
+
output.complete('Test run completed');
|
|
342
|
+
}
|
|
340
343
|
|
|
341
344
|
// Show Vizzly summary with link to results
|
|
342
|
-
if (result.buildId) {
|
|
345
|
+
if (result.buildId && !globalOptions.json) {
|
|
343
346
|
output.blank();
|
|
344
347
|
let colors = output.getColors();
|
|
345
348
|
output.print(` ${colors.brand.textTertiary('Screenshots')} ${colors.white(result.screenshotsCaptured)}`);
|
|
@@ -386,7 +389,7 @@ export async function runCommand(testCommand, options = {}, globalOptions = {},
|
|
|
386
389
|
});
|
|
387
390
|
output.cleanup();
|
|
388
391
|
} else {
|
|
389
|
-
output.error('Test run failed');
|
|
392
|
+
output.error('Test run failed', error);
|
|
390
393
|
}
|
|
391
394
|
return {
|
|
392
395
|
success: false,
|
package/dist/commands/status.js
CHANGED
|
@@ -36,6 +36,19 @@ function createStatusClient({
|
|
|
36
36
|
command: 'status'
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
|
+
function isMissingPreviewError(error) {
|
|
40
|
+
return error.context?.status === 404;
|
|
41
|
+
}
|
|
42
|
+
async function fetchOptionalPreviewInfo(getPreviewInfo, client, buildId) {
|
|
43
|
+
try {
|
|
44
|
+
return await getPreviewInfo(client, buildId);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
if (isMissingPreviewError(error)) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
39
52
|
export function normalizeBuildStatus(buildStatus) {
|
|
40
53
|
return buildStatus.build || buildStatus;
|
|
41
54
|
}
|
|
@@ -251,7 +264,7 @@ export async function statusCommand(buildId, options = {}, globalOptions = {}, d
|
|
|
251
264
|
let buildStatus = await getBuild(client, buildId);
|
|
252
265
|
|
|
253
266
|
// Also fetch preview info (if exists)
|
|
254
|
-
let previewInfo = await getPreviewInfo
|
|
267
|
+
let previewInfo = await fetchOptionalPreviewInfo(getPreviewInfo, client, buildId);
|
|
255
268
|
output.stopSpinner();
|
|
256
269
|
|
|
257
270
|
// Extract build data from API response
|
|
@@ -18,7 +18,7 @@ function isProcessRunning(pid) {
|
|
|
18
18
|
return false;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
function parsePositiveInteger(value) {
|
|
21
|
+
export function parsePositiveInteger(value) {
|
|
22
22
|
let text = String(value).trim();
|
|
23
23
|
if (!/^\d+$/.test(text)) {
|
|
24
24
|
return null;
|
|
@@ -71,12 +71,16 @@ export async function resolveDaemonPid({
|
|
|
71
71
|
pidFile = join(process.cwd(), '.vizzly', 'server.pid'),
|
|
72
72
|
readPid = readDaemonPidFile,
|
|
73
73
|
findByPort = findDaemonPidByPort,
|
|
74
|
+
allowPortFallback = false,
|
|
74
75
|
fileDeps = {}
|
|
75
76
|
} = {}) {
|
|
76
77
|
let pid = readPid(pidFile, fileDeps);
|
|
77
78
|
if (pid) {
|
|
78
79
|
return pid;
|
|
79
80
|
}
|
|
81
|
+
if (!allowPortFallback) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
80
84
|
return await findByPort(port);
|
|
81
85
|
}
|
|
82
86
|
export async function waitForProcessExit(pid, {
|