@vizzly-testing/cli 0.29.6 → 0.31.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/README.md +34 -6
- package/dist/api/client.js +6 -3
- package/dist/api/endpoints.js +59 -0
- package/dist/api/index.js +1 -1
- package/dist/auth/core.js +1 -1
- package/dist/auth/index.js +2 -1
- package/dist/cli.js +206 -51
- package/dist/client/index.js +21 -29
- package/dist/commands/api.js +145 -90
- package/dist/commands/baselines.js +78 -47
- package/dist/commands/builds.js +9 -8
- package/dist/commands/comparisons.js +7 -8
- package/dist/commands/config-cmd.js +15 -7
- package/dist/commands/context.js +870 -0
- package/dist/commands/doctor.js +116 -81
- package/dist/commands/init.js +202 -201
- package/dist/commands/login.js +134 -65
- package/dist/commands/logout.js +18 -7
- package/dist/commands/preview.js +29 -57
- package/dist/commands/project.js +120 -0
- package/dist/commands/projects.js +9 -2
- package/dist/commands/review.js +236 -202
- package/dist/commands/run.js +75 -72
- package/dist/commands/status.js +228 -150
- package/dist/commands/tdd-daemon-process.js +98 -0
- package/dist/commands/tdd-daemon.js +318 -212
- package/dist/commands/tdd.js +23 -8
- package/dist/commands/upload.js +10 -9
- package/dist/commands/whoami.js +64 -26
- package/dist/config/core.js +37 -36
- package/dist/context/local-workspace-provider.js +532 -0
- package/dist/context/provider-resolver.js +36 -0
- package/dist/index.js +5 -4
- package/dist/plugin-loader.js +55 -49
- package/dist/project/core.js +2 -2
- package/dist/project/operations.js +6 -3
- package/dist/reporter/reporter-bundle.css +2 -1
- package/dist/reporter/reporter-bundle.iife.js +119 -119
- package/dist/reporter-ssr/ssr-entry.js +605 -509
- package/dist/sdk/index.js +162 -107
- package/dist/server/handlers/tdd-handler.js +30 -54
- package/dist/server/routers/assets.js +4 -0
- package/dist/server/routers/baseline.js +195 -178
- package/dist/server/routers/events.js +226 -148
- package/dist/server/routers/projects.js +14 -5
- package/dist/server/routers/screenshot.js +1 -31
- package/dist/services/build-manager.js +19 -97
- package/dist/services/config-service.js +26 -34
- package/dist/services/index.js +2 -4
- package/dist/services/static-report-generator.js +11 -12
- package/dist/services/test-runner.js +21 -27
- package/dist/tdd/core/hotspot-coverage.js +1 -1
- package/dist/tdd/index.js +1 -1
- package/dist/tdd/metadata/region-metadata.js +0 -37
- package/dist/tdd/runtime-context.js +78 -0
- package/dist/tdd/server-registry.js +38 -17
- package/dist/tdd/services/baseline-manager.js +23 -0
- package/dist/tdd/services/hotspot-service.js +1 -14
- package/dist/tdd/tdd-service.js +82 -113
- package/dist/types/client.d.ts +36 -1
- package/dist/types/index.d.ts +114 -22
- package/dist/types/sdk.d.ts +47 -7
- package/dist/uploader/core.js +5 -4
- package/dist/uploader/index.js +79 -2
- package/dist/uploader/operations.js +40 -5
- package/dist/utils/api-url.js +14 -0
- package/dist/utils/async-utils.js +26 -0
- package/dist/utils/ci-env.js +19 -12
- package/dist/utils/colors.js +46 -44
- package/dist/utils/config-loader.js +39 -65
- package/dist/utils/config-schema.js +19 -55
- package/dist/utils/fetch-utils.js +12 -5
- package/dist/utils/git.js +35 -72
- package/dist/utils/global-config.js +22 -3
- package/dist/utils/output.js +19 -7
- package/dist/utils/patterns.js +14 -0
- package/dist/utils/project-link-store.js +105 -0
- package/dist/utils/report-data.js +31 -0
- package/dist/utils/screenshot-options.js +28 -0
- package/dist/utils/secret-store.js +65 -0
- package/dist/utils/security.js +3 -2
- package/package.json +14 -11
- package/dist/services/screenshot-server.js +0 -65
- package/dist/services/server-manager.js +0 -81
- package/dist/services/uploader.js +0 -100
- package/dist/tdd/services/region-service.js +0 -75
- package/dist/utils/build-history.js +0 -103
package/dist/tdd/tdd-service.js
CHANGED
|
@@ -22,7 +22,8 @@ import { generateBaselineFilename as defaultGenerateBaselineFilename, generateCo
|
|
|
22
22
|
import { createEmptyBaselineMetadata as defaultCreateEmptyBaselineMetadata, loadBaselineMetadata as defaultLoadBaselineMetadata, saveBaselineMetadata as defaultSaveBaselineMetadata, upsertScreenshotInMetadata as defaultUpsertScreenshotInMetadata } from './metadata/baseline-metadata.js';
|
|
23
23
|
import { loadHotspotMetadata as defaultLoadHotspotMetadata, saveHotspotMetadata as defaultSaveHotspotMetadata } from './metadata/hotspot-metadata.js';
|
|
24
24
|
import { loadRegionMetadata as defaultLoadRegionMetadata, saveRegionMetadata as defaultSaveRegionMetadata } from './metadata/region-metadata.js';
|
|
25
|
-
import {
|
|
25
|
+
import { buildTddDependencyOps, resolveTddPaths, resolveTddWorkingDirectory } from './runtime-context.js';
|
|
26
|
+
import { baselineExists as defaultBaselineExists, clearBaselineData as defaultClearBaselineData, clearRunData as defaultClearRunData, getBaselinePath as defaultGetBaselinePath, getCurrentPath as defaultGetCurrentPath, getDiffPath as defaultGetDiffPath, initializeDirectories as defaultInitializeDirectories, saveBaseline as defaultSaveBaseline, saveCurrent as defaultSaveCurrent } from './services/baseline-manager.js';
|
|
26
27
|
import { buildErrorComparison as defaultBuildErrorComparison, buildFailedComparison as defaultBuildFailedComparison, buildNewComparison as defaultBuildNewComparison, buildPassedComparison as defaultBuildPassedComparison, compareImages as defaultCompareImages, isDimensionMismatchError as defaultIsDimensionMismatchError } from './services/comparison-service.js';
|
|
27
28
|
import { buildResults as defaultBuildResults, getFailedComparisons as defaultGetFailedComparisons, getNewComparisons as defaultGetNewComparisons } from './services/result-service.js';
|
|
28
29
|
|
|
@@ -40,110 +41,79 @@ export function createTDDService(config, options = {}, deps = {}) {
|
|
|
40
41
|
}
|
|
41
42
|
export class TddService {
|
|
42
43
|
constructor(config, workingDir = process.cwd(), setBaseline = false, authService = null, deps = {}) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
...baseline
|
|
106
|
-
};
|
|
107
|
-
let comparisonOps = {
|
|
108
|
-
compareImages: defaultCompareImages,
|
|
109
|
-
buildPassedComparison: defaultBuildPassedComparison,
|
|
110
|
-
buildNewComparison: defaultBuildNewComparison,
|
|
111
|
-
buildFailedComparison: defaultBuildFailedComparison,
|
|
112
|
-
buildErrorComparison: defaultBuildErrorComparison,
|
|
113
|
-
isDimensionMismatchError: defaultIsDimensionMismatchError,
|
|
114
|
-
...comparison
|
|
115
|
-
};
|
|
116
|
-
let signatureOps = {
|
|
117
|
-
generateScreenshotSignature: defaultGenerateScreenshotSignature,
|
|
118
|
-
generateBaselineFilename: defaultGenerateBaselineFilename,
|
|
119
|
-
generateComparisonId: defaultGenerateComparisonId,
|
|
120
|
-
sanitizeScreenshotName: defaultSanitizeScreenshotName,
|
|
121
|
-
validateScreenshotProperties: defaultValidateScreenshotProperties,
|
|
122
|
-
safePath: defaultSafePath,
|
|
123
|
-
...signature
|
|
124
|
-
};
|
|
125
|
-
let resultsOps = {
|
|
126
|
-
buildResults: defaultBuildResults,
|
|
127
|
-
getFailedComparisons: defaultGetFailedComparisons,
|
|
128
|
-
getNewComparisons: defaultGetNewComparisons,
|
|
129
|
-
...results
|
|
44
|
+
let defaults = {
|
|
45
|
+
output: defaultOutput,
|
|
46
|
+
colors: defaultColors,
|
|
47
|
+
validatePathSecurity: defaultValidatePathSecurity,
|
|
48
|
+
initializeDirectories: defaultInitializeDirectories,
|
|
49
|
+
calculateHotspotCoverage: defaultCalculateHotspotCoverage,
|
|
50
|
+
fs: {
|
|
51
|
+
existsSync: defaultExistsSync,
|
|
52
|
+
mkdirSync: defaultMkdirSync,
|
|
53
|
+
readFileSync: defaultReadFileSync,
|
|
54
|
+
writeFileSync: defaultWriteFileSync
|
|
55
|
+
},
|
|
56
|
+
api: {
|
|
57
|
+
createApiClient: defaultCreateApiClient,
|
|
58
|
+
getTddBaselines: defaultGetTddBaselines,
|
|
59
|
+
getBuilds: defaultGetBuilds,
|
|
60
|
+
getComparison: defaultGetComparison,
|
|
61
|
+
getBatchHotspots: defaultGetBatchHotspots,
|
|
62
|
+
fetchWithTimeout: defaultFetchWithTimeout,
|
|
63
|
+
getDefaultBranch: defaultGetDefaultBranch
|
|
64
|
+
},
|
|
65
|
+
metadata: {
|
|
66
|
+
loadBaselineMetadata: defaultLoadBaselineMetadata,
|
|
67
|
+
saveBaselineMetadata: defaultSaveBaselineMetadata,
|
|
68
|
+
createEmptyBaselineMetadata: defaultCreateEmptyBaselineMetadata,
|
|
69
|
+
upsertScreenshotInMetadata: defaultUpsertScreenshotInMetadata,
|
|
70
|
+
loadHotspotMetadata: defaultLoadHotspotMetadata,
|
|
71
|
+
saveHotspotMetadata: defaultSaveHotspotMetadata,
|
|
72
|
+
loadRegionMetadata: defaultLoadRegionMetadata,
|
|
73
|
+
saveRegionMetadata: defaultSaveRegionMetadata
|
|
74
|
+
},
|
|
75
|
+
baseline: {
|
|
76
|
+
baselineExists: defaultBaselineExists,
|
|
77
|
+
clearBaselineData: defaultClearBaselineData,
|
|
78
|
+
clearRunData: defaultClearRunData,
|
|
79
|
+
getBaselinePath: defaultGetBaselinePath,
|
|
80
|
+
getCurrentPath: defaultGetCurrentPath,
|
|
81
|
+
getDiffPath: defaultGetDiffPath,
|
|
82
|
+
saveBaseline: defaultSaveBaseline,
|
|
83
|
+
saveCurrent: defaultSaveCurrent
|
|
84
|
+
},
|
|
85
|
+
comparison: {
|
|
86
|
+
compareImages: defaultCompareImages,
|
|
87
|
+
buildPassedComparison: defaultBuildPassedComparison,
|
|
88
|
+
buildNewComparison: defaultBuildNewComparison,
|
|
89
|
+
buildFailedComparison: defaultBuildFailedComparison,
|
|
90
|
+
buildErrorComparison: defaultBuildErrorComparison,
|
|
91
|
+
isDimensionMismatchError: defaultIsDimensionMismatchError
|
|
92
|
+
},
|
|
93
|
+
signature: {
|
|
94
|
+
generateScreenshotSignature: defaultGenerateScreenshotSignature,
|
|
95
|
+
generateBaselineFilename: defaultGenerateBaselineFilename,
|
|
96
|
+
generateComparisonId: defaultGenerateComparisonId,
|
|
97
|
+
sanitizeScreenshotName: defaultSanitizeScreenshotName,
|
|
98
|
+
validateScreenshotProperties: defaultValidateScreenshotProperties,
|
|
99
|
+
safePath: defaultSafePath
|
|
100
|
+
},
|
|
101
|
+
results: {
|
|
102
|
+
buildResults: defaultBuildResults,
|
|
103
|
+
getFailedComparisons: defaultGetFailedComparisons,
|
|
104
|
+
getNewComparisons: defaultGetNewComparisons
|
|
105
|
+
}
|
|
130
106
|
};
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
107
|
+
let {
|
|
108
|
+
runtimeDeps,
|
|
109
|
+
apiOps
|
|
110
|
+
} = buildTddDependencyOps(deps, defaults);
|
|
111
|
+
let {
|
|
134
112
|
output,
|
|
135
|
-
colors,
|
|
136
113
|
validatePathSecurity,
|
|
137
|
-
initializeDirectories
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
...apiOps,
|
|
141
|
-
...metadataOps,
|
|
142
|
-
...baselineOps,
|
|
143
|
-
...comparisonOps,
|
|
144
|
-
...signatureOps,
|
|
145
|
-
...resultsOps
|
|
146
|
-
};
|
|
114
|
+
initializeDirectories
|
|
115
|
+
} = runtimeDeps;
|
|
116
|
+
this._deps = runtimeDeps;
|
|
147
117
|
this.config = config;
|
|
148
118
|
this.setBaseline = setBaseline;
|
|
149
119
|
this.authService = authService;
|
|
@@ -155,15 +125,8 @@ export class TddService {
|
|
|
155
125
|
});
|
|
156
126
|
|
|
157
127
|
// Validate and secure the working directory
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
} catch (error) {
|
|
161
|
-
output.error(`Invalid working directory: ${error.message}`);
|
|
162
|
-
throw new Error(`Working directory validation failed: ${error.message}`);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Initialize directories using extracted module
|
|
166
|
-
let paths = initializeDirectories(this.workingDir);
|
|
128
|
+
this.workingDir = resolveTddWorkingDirectory(workingDir, validatePathSecurity, output);
|
|
129
|
+
let paths = resolveTddPaths(this.workingDir, initializeDirectories);
|
|
167
130
|
this.baselinePath = paths.baselinePath;
|
|
168
131
|
this.currentPath = paths.currentPath;
|
|
169
132
|
this.diffPath = paths.diffPath;
|
|
@@ -171,7 +134,7 @@ export class TddService {
|
|
|
171
134
|
// State
|
|
172
135
|
this.baselineData = null;
|
|
173
136
|
this.comparisons = [];
|
|
174
|
-
this.threshold = config.comparison?.threshold
|
|
137
|
+
this.threshold = config.comparison?.threshold ?? 2.0;
|
|
175
138
|
this.minClusterSize = config.comparison?.minClusterSize ?? 2;
|
|
176
139
|
this.signatureProperties = config.signatureProperties ?? [];
|
|
177
140
|
|
|
@@ -187,6 +150,12 @@ export class TddService {
|
|
|
187
150
|
output.info('[vizzly] Baseline update mode - will overwrite existing baselines with new ones');
|
|
188
151
|
}
|
|
189
152
|
}
|
|
153
|
+
clearRunData() {
|
|
154
|
+
this._deps.clearRunData({
|
|
155
|
+
currentPath: this.currentPath,
|
|
156
|
+
diffPath: this.diffPath
|
|
157
|
+
});
|
|
158
|
+
}
|
|
190
159
|
|
|
191
160
|
/**
|
|
192
161
|
* Download baselines from cloud
|
|
@@ -915,7 +884,7 @@ export class TddService {
|
|
|
915
884
|
return null;
|
|
916
885
|
}
|
|
917
886
|
this.baselineData = metadata;
|
|
918
|
-
this.threshold = metadata.threshold
|
|
887
|
+
this.threshold = metadata.threshold ?? this.threshold;
|
|
919
888
|
this.signatureProperties = metadata.signatureProperties || this.signatureProperties;
|
|
920
889
|
if (this.signatureProperties.length > 0) {
|
|
921
890
|
output.debug('tdd', `loaded signature properties: ${this.signatureProperties.join(', ')}`);
|
package/dist/types/client.d.ts
CHANGED
|
@@ -4,6 +4,40 @@
|
|
|
4
4
|
* @module @vizzly-testing/cli/client
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
export type ClientLogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
8
|
+
|
|
9
|
+
export const LOG_LEVELS: Readonly<Record<ClientLogLevel, number>>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Check whether client SDK output should log at the requested level.
|
|
13
|
+
*/
|
|
14
|
+
export function shouldLogClient(
|
|
15
|
+
level: string,
|
|
16
|
+
configuredLevel?: string
|
|
17
|
+
): boolean;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Auto-discover a local TDD server by searching for `.vizzly/server.json`.
|
|
21
|
+
*/
|
|
22
|
+
export function autoDiscoverTddServer(
|
|
23
|
+
startDir?: string,
|
|
24
|
+
deps?: {
|
|
25
|
+
exists?: (path: string) => boolean;
|
|
26
|
+
readFile?: (path: string, encoding: BufferEncoding) => string | Buffer;
|
|
27
|
+
}
|
|
28
|
+
): string | null;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Result returned by a successful screenshot capture.
|
|
32
|
+
*/
|
|
33
|
+
export interface ScreenshotResult {
|
|
34
|
+
success: boolean;
|
|
35
|
+
status?: 'passed' | 'failed' | 'new';
|
|
36
|
+
name?: string;
|
|
37
|
+
diffPercentage?: number;
|
|
38
|
+
[key: string]: unknown;
|
|
39
|
+
}
|
|
40
|
+
|
|
7
41
|
/**
|
|
8
42
|
* Take a screenshot for visual regression testing
|
|
9
43
|
*
|
|
@@ -38,8 +72,9 @@ export function vizzlyScreenshot(
|
|
|
38
72
|
threshold?: number;
|
|
39
73
|
minClusterSize?: number;
|
|
40
74
|
fullPage?: boolean;
|
|
75
|
+
[key: string]: unknown;
|
|
41
76
|
}
|
|
42
|
-
): Promise<
|
|
77
|
+
): Promise<ScreenshotResult | null>;
|
|
43
78
|
|
|
44
79
|
/**
|
|
45
80
|
* Flush result summary returned by vizzlyFlush
|
package/dist/types/index.d.ts
CHANGED
|
@@ -77,6 +77,7 @@ export interface ScreenshotOptions {
|
|
|
77
77
|
minClusterSize?: number;
|
|
78
78
|
fullPage?: boolean;
|
|
79
79
|
buildId?: string;
|
|
80
|
+
[key: string]: unknown;
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
export interface ScreenshotResult {
|
|
@@ -84,6 +85,7 @@ export interface ScreenshotResult {
|
|
|
84
85
|
status?: 'passed' | 'failed' | 'new';
|
|
85
86
|
name?: string;
|
|
86
87
|
diffPercentage?: number;
|
|
88
|
+
[key: string]: unknown;
|
|
87
89
|
}
|
|
88
90
|
|
|
89
91
|
// ============================================================================
|
|
@@ -262,6 +264,12 @@ export class ValidationError extends VizzlyError {
|
|
|
262
264
|
export interface VizzlySDKInstance extends EventEmitter {
|
|
263
265
|
config: VizzlyConfig;
|
|
264
266
|
|
|
267
|
+
/** Reload file config and re-apply current in-memory overrides */
|
|
268
|
+
init(): Promise<VizzlyConfig>;
|
|
269
|
+
|
|
270
|
+
/** Merge new config values into the active SDK config */
|
|
271
|
+
updateConfig(newConfig: Partial<VizzlyConfig>): VizzlyConfig;
|
|
272
|
+
|
|
265
273
|
/** Start the Vizzly server */
|
|
266
274
|
start(): Promise<{ port: number; url: string }>;
|
|
267
275
|
|
|
@@ -286,6 +294,28 @@ export interface VizzlySDKInstance extends EventEmitter {
|
|
|
286
294
|
name: string,
|
|
287
295
|
imageBuffer: Buffer | string
|
|
288
296
|
): Promise<ComparisonResult>;
|
|
297
|
+
|
|
298
|
+
/** Create an uploader using the SDK config */
|
|
299
|
+
createUploader(options?: {
|
|
300
|
+
upload?: UploadConfig;
|
|
301
|
+
signal?: AbortSignal;
|
|
302
|
+
batchSize?: number;
|
|
303
|
+
timeout?: number;
|
|
304
|
+
}): Uploader;
|
|
305
|
+
|
|
306
|
+
/** Create a local TDD service using the SDK config */
|
|
307
|
+
createTDDService(options?: {
|
|
308
|
+
workingDir?: string;
|
|
309
|
+
setBaseline?: boolean;
|
|
310
|
+
authService?: unknown;
|
|
311
|
+
}): TddService;
|
|
312
|
+
|
|
313
|
+
/** Start a local TDD service */
|
|
314
|
+
startTDD(options?: {
|
|
315
|
+
workingDir?: string;
|
|
316
|
+
setBaseline?: boolean;
|
|
317
|
+
authService?: unknown;
|
|
318
|
+
}): Promise<unknown>;
|
|
289
319
|
}
|
|
290
320
|
|
|
291
321
|
export class VizzlySDK extends EventEmitter implements VizzlySDKInstance {
|
|
@@ -293,6 +323,8 @@ export class VizzlySDK extends EventEmitter implements VizzlySDKInstance {
|
|
|
293
323
|
|
|
294
324
|
constructor(config: VizzlyConfig, services: unknown);
|
|
295
325
|
|
|
326
|
+
init(): Promise<VizzlyConfig>;
|
|
327
|
+
updateConfig(newConfig: Partial<VizzlyConfig>): VizzlyConfig;
|
|
296
328
|
start(): Promise<{ port: number; url: string }>;
|
|
297
329
|
stop(): Promise<void>;
|
|
298
330
|
getConfig(): VizzlyConfig;
|
|
@@ -306,6 +338,22 @@ export class VizzlySDK extends EventEmitter implements VizzlySDKInstance {
|
|
|
306
338
|
name: string,
|
|
307
339
|
imageBuffer: Buffer | string
|
|
308
340
|
): Promise<ComparisonResult>;
|
|
341
|
+
createUploader(options?: {
|
|
342
|
+
upload?: UploadConfig;
|
|
343
|
+
signal?: AbortSignal;
|
|
344
|
+
batchSize?: number;
|
|
345
|
+
timeout?: number;
|
|
346
|
+
}): Uploader;
|
|
347
|
+
createTDDService(options?: {
|
|
348
|
+
workingDir?: string;
|
|
349
|
+
setBaseline?: boolean;
|
|
350
|
+
authService?: unknown;
|
|
351
|
+
}): TddService;
|
|
352
|
+
startTDD(options?: {
|
|
353
|
+
workingDir?: string;
|
|
354
|
+
setBaseline?: boolean;
|
|
355
|
+
authService?: unknown;
|
|
356
|
+
}): Promise<unknown>;
|
|
309
357
|
}
|
|
310
358
|
|
|
311
359
|
// ============================================================================
|
|
@@ -344,15 +392,8 @@ export interface TddService {
|
|
|
344
392
|
}
|
|
345
393
|
|
|
346
394
|
export interface Services {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
configService: unknown;
|
|
350
|
-
projectService: unknown;
|
|
351
|
-
uploader: Uploader;
|
|
352
|
-
buildManager: unknown;
|
|
353
|
-
serverManager: unknown;
|
|
354
|
-
tddService: TddService;
|
|
355
|
-
testRunner: unknown;
|
|
395
|
+
serverManager: ServerManager;
|
|
396
|
+
testRunner: TestRunnerService;
|
|
356
397
|
}
|
|
357
398
|
|
|
358
399
|
// ============================================================================
|
|
@@ -392,11 +433,47 @@ export interface PluginServerManager {
|
|
|
392
433
|
stop(): Promise<void>;
|
|
393
434
|
}
|
|
394
435
|
|
|
436
|
+
/**
|
|
437
|
+
* Internal server manager returned by createServices().
|
|
438
|
+
*/
|
|
439
|
+
export interface ServerManager extends PluginServerManager {
|
|
440
|
+
/** Get current TDD results from the local server handler */
|
|
441
|
+
getTddResults(): Promise<TddResults | null>;
|
|
442
|
+
/** Current HTTP server facade, if running */
|
|
443
|
+
readonly server: unknown;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Internal TestRunner returned by createServices().
|
|
448
|
+
*/
|
|
449
|
+
export interface TestRunnerService extends PluginTestRunner {
|
|
450
|
+
/** Initialize daemon mode without running tests */
|
|
451
|
+
initialize(options: Record<string, unknown>): Promise<void>;
|
|
452
|
+
/** Run tests through the configured test command */
|
|
453
|
+
run(options: Record<string, unknown>): Promise<unknown>;
|
|
454
|
+
/** Cancel the active test process and stop the server */
|
|
455
|
+
cancel(): Promise<void>;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
export interface PluginGitInfo {
|
|
459
|
+
branch: string;
|
|
460
|
+
commit: string | null;
|
|
461
|
+
message: string | null;
|
|
462
|
+
prNumber: number | null;
|
|
463
|
+
buildName: string;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
export interface PluginGit {
|
|
467
|
+
/** Detect branch, commit, commit message, PR number, and build name */
|
|
468
|
+
detect(options?: { buildPrefix?: string }): Promise<PluginGitInfo>;
|
|
469
|
+
}
|
|
470
|
+
|
|
395
471
|
/**
|
|
396
472
|
* Stable services interface for plugins.
|
|
397
473
|
* This is the public API contract - internal services are NOT exposed.
|
|
398
474
|
*/
|
|
399
475
|
export interface PluginServices {
|
|
476
|
+
git: PluginGit;
|
|
400
477
|
testRunner: PluginTestRunner;
|
|
401
478
|
serverManager: PluginServerManager;
|
|
402
479
|
}
|
|
@@ -432,8 +509,6 @@ export interface PluginContext {
|
|
|
432
509
|
services: PluginServices;
|
|
433
510
|
/** Output utilities for logging */
|
|
434
511
|
output: OutputUtils;
|
|
435
|
-
/** @deprecated Use output instead. Alias for backwards compatibility. */
|
|
436
|
-
logger: OutputUtils;
|
|
437
512
|
}
|
|
438
513
|
|
|
439
514
|
/** Create stable plugin services from internal services */
|
|
@@ -444,12 +519,31 @@ export function createPluginServices(services: Services): PluginServices;
|
|
|
444
519
|
// ============================================================================
|
|
445
520
|
|
|
446
521
|
export interface OutputUtils {
|
|
447
|
-
info(message: string): void;
|
|
448
|
-
warn(message: string): void;
|
|
449
|
-
error(
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
522
|
+
info(message: string, data?: Record<string, unknown>): void;
|
|
523
|
+
warn(message: string, data?: Record<string, unknown>): void;
|
|
524
|
+
error(
|
|
525
|
+
message: string,
|
|
526
|
+
error?: Error | null,
|
|
527
|
+
data?: Record<string, unknown>
|
|
528
|
+
): void;
|
|
529
|
+
success(message: string, data?: Record<string, unknown>): void;
|
|
530
|
+
debug(
|
|
531
|
+
component: string,
|
|
532
|
+
message: string,
|
|
533
|
+
data?: Record<string, unknown>
|
|
534
|
+
): void;
|
|
535
|
+
configure(options: OutputConfigureOptions): void;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
export interface OutputConfigureOptions {
|
|
539
|
+
json?: boolean | string;
|
|
540
|
+
jsonFields?: string[] | null;
|
|
541
|
+
logLevel?: 'debug' | 'info' | 'warn' | 'error';
|
|
542
|
+
verbose?: boolean;
|
|
543
|
+
color?: boolean;
|
|
544
|
+
silent?: boolean;
|
|
545
|
+
logFile?: string | null;
|
|
546
|
+
resetTimer?: boolean;
|
|
453
547
|
}
|
|
454
548
|
|
|
455
549
|
// ============================================================================
|
|
@@ -471,8 +565,9 @@ export function vizzlyScreenshot(
|
|
|
471
565
|
threshold?: number;
|
|
472
566
|
minClusterSize?: number;
|
|
473
567
|
fullPage?: boolean;
|
|
568
|
+
[key: string]: unknown;
|
|
474
569
|
}
|
|
475
|
-
): Promise<
|
|
570
|
+
): Promise<ScreenshotResult | null>;
|
|
476
571
|
|
|
477
572
|
/** Configure the Vizzly client */
|
|
478
573
|
export function configure(config?: {
|
|
@@ -510,10 +605,7 @@ export function createTDDService(
|
|
|
510
605
|
): TddService;
|
|
511
606
|
|
|
512
607
|
/** Create all services with dependencies */
|
|
513
|
-
export function createServices(
|
|
514
|
-
config: VizzlyConfig,
|
|
515
|
-
command?: string
|
|
516
|
-
): Services;
|
|
608
|
+
export function createServices(config: VizzlyConfig): Services;
|
|
517
609
|
|
|
518
610
|
/** Load configuration from file and environment */
|
|
519
611
|
export function loadConfig(options?: { cwd?: string }): Promise<VizzlyConfig>;
|
package/dist/types/sdk.d.ts
CHANGED
|
@@ -8,16 +8,16 @@ import { EventEmitter } from 'node:events';
|
|
|
8
8
|
|
|
9
9
|
// Re-export common types
|
|
10
10
|
export {
|
|
11
|
-
|
|
12
|
-
ScreenshotOptions,
|
|
13
|
-
UploadOptions,
|
|
14
|
-
UploadResult,
|
|
11
|
+
BaselineData,
|
|
15
12
|
ComparisonResult,
|
|
13
|
+
OutputUtils,
|
|
14
|
+
ScreenshotOptions,
|
|
16
15
|
TddResults,
|
|
17
|
-
BaselineData,
|
|
18
|
-
Uploader,
|
|
19
16
|
TddService,
|
|
20
|
-
|
|
17
|
+
Uploader,
|
|
18
|
+
UploadOptions,
|
|
19
|
+
UploadResult,
|
|
20
|
+
VizzlyConfig,
|
|
21
21
|
} from './index';
|
|
22
22
|
|
|
23
23
|
/**
|
|
@@ -41,6 +41,18 @@ export class VizzlySDK extends EventEmitter {
|
|
|
41
41
|
|
|
42
42
|
constructor(config: import('./index').VizzlyConfig, services: unknown);
|
|
43
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Reload file config and re-apply current in-memory overrides.
|
|
46
|
+
*/
|
|
47
|
+
init(): Promise<import('./index').VizzlyConfig>;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Merge new config values into the active SDK config.
|
|
51
|
+
*/
|
|
52
|
+
updateConfig(
|
|
53
|
+
newConfig: Partial<import('./index').VizzlyConfig>
|
|
54
|
+
): import('./index').VizzlyConfig;
|
|
55
|
+
|
|
44
56
|
/**
|
|
45
57
|
* Start the Vizzly server
|
|
46
58
|
* @returns Server information including port and URL
|
|
@@ -90,6 +102,34 @@ export class VizzlySDK extends EventEmitter {
|
|
|
90
102
|
name: string,
|
|
91
103
|
imageBuffer: Buffer | string
|
|
92
104
|
): Promise<import('./index').ComparisonResult>;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Create an uploader using the SDK config.
|
|
108
|
+
*/
|
|
109
|
+
createUploader(options?: {
|
|
110
|
+
upload?: import('./index').UploadConfig;
|
|
111
|
+
signal?: AbortSignal;
|
|
112
|
+
batchSize?: number;
|
|
113
|
+
timeout?: number;
|
|
114
|
+
}): import('./index').Uploader;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Create a local TDD service using the SDK config.
|
|
118
|
+
*/
|
|
119
|
+
createTDDService(options?: {
|
|
120
|
+
workingDir?: string;
|
|
121
|
+
setBaseline?: boolean;
|
|
122
|
+
authService?: unknown;
|
|
123
|
+
}): import('./index').TddService;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Start a local TDD service.
|
|
127
|
+
*/
|
|
128
|
+
startTDD(options?: {
|
|
129
|
+
workingDir?: string;
|
|
130
|
+
setBaseline?: boolean;
|
|
131
|
+
authService?: unknown;
|
|
132
|
+
}): Promise<unknown>;
|
|
93
133
|
}
|
|
94
134
|
|
|
95
135
|
/**
|
package/dist/uploader/core.js
CHANGED
|
@@ -14,6 +14,7 @@ import { basename } from 'node:path';
|
|
|
14
14
|
export const DEFAULT_BATCH_SIZE = 50;
|
|
15
15
|
export const DEFAULT_SHA_CHECK_BATCH_SIZE = 100;
|
|
16
16
|
export const DEFAULT_TIMEOUT = 30000; // 30 seconds
|
|
17
|
+
export const DEFAULT_BUILD_POLL_INTERVAL = 1000; // 1 second
|
|
17
18
|
|
|
18
19
|
// ============================================================================
|
|
19
20
|
// Validation
|
|
@@ -363,8 +364,8 @@ export function resolveTimeout(options, uploadConfig) {
|
|
|
363
364
|
* @param {number} timeout - Timeout in ms
|
|
364
365
|
* @returns {boolean} True if timed out
|
|
365
366
|
*/
|
|
366
|
-
export function isTimedOut(startTime, timeout) {
|
|
367
|
-
return
|
|
367
|
+
export function isTimedOut(startTime, timeout, now = Date.now()) {
|
|
368
|
+
return now - startTime >= timeout;
|
|
368
369
|
}
|
|
369
370
|
|
|
370
371
|
/**
|
|
@@ -372,8 +373,8 @@ export function isTimedOut(startTime, timeout) {
|
|
|
372
373
|
* @param {number} startTime - Start timestamp
|
|
373
374
|
* @returns {number} Elapsed time in ms
|
|
374
375
|
*/
|
|
375
|
-
export function getElapsedTime(startTime) {
|
|
376
|
-
return
|
|
376
|
+
export function getElapsedTime(startTime, now = Date.now()) {
|
|
377
|
+
return now - startTime;
|
|
377
378
|
}
|
|
378
379
|
|
|
379
380
|
/**
|