@vizzly-testing/cli 0.15.1 → 0.16.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/dist/client/index.js +21 -4
- package/dist/reporter/reporter-bundle.css +1 -1
- package/dist/reporter/reporter-bundle.iife.js +11 -11
- package/dist/sdk/index.js +6 -6
- package/dist/services/api-service.js +42 -0
- package/dist/services/tdd-service.js +189 -6
- package/dist/services/test-runner.js +0 -8
- package/dist/services/uploader.js +1 -1
- package/dist/types/client.d.ts +88 -0
- package/dist/types/config.d.ts +29 -0
- package/dist/types/index.d.ts +426 -9
- package/dist/types/sdk.d.ts +146 -0
- package/dist/utils/config-helpers.js +2 -2
- package/docs/tdd-mode.md +34 -0
- package/package.json +21 -4
- package/dist/types/cli.d.ts +0 -2
- package/dist/types/client/index.d.ts +0 -80
- package/dist/types/commands/doctor.d.ts +0 -11
- package/dist/types/commands/finalize.d.ts +0 -13
- package/dist/types/commands/init.d.ts +0 -32
- package/dist/types/commands/login.d.ts +0 -11
- package/dist/types/commands/logout.d.ts +0 -11
- package/dist/types/commands/project.d.ts +0 -28
- package/dist/types/commands/run.d.ts +0 -16
- package/dist/types/commands/status.d.ts +0 -13
- package/dist/types/commands/tdd-daemon.d.ts +0 -24
- package/dist/types/commands/tdd.d.ts +0 -17
- package/dist/types/commands/upload.d.ts +0 -13
- package/dist/types/commands/whoami.d.ts +0 -11
- package/dist/types/errors/vizzly-error.d.ts +0 -75
- package/dist/types/plugin-loader.d.ts +0 -7
- package/dist/types/reporter/src/api/client.d.ts +0 -178
- package/dist/types/reporter/src/components/app-router.d.ts +0 -1
- package/dist/types/reporter/src/components/code-block.d.ts +0 -4
- package/dist/types/reporter/src/components/comparison/comparison-actions.d.ts +0 -5
- package/dist/types/reporter/src/components/comparison/comparison-card.d.ts +0 -7
- package/dist/types/reporter/src/components/comparison/comparison-group.d.ts +0 -10
- package/dist/types/reporter/src/components/comparison/comparison-list.d.ts +0 -6
- package/dist/types/reporter/src/components/comparison/comparison-modes/onion-skin-mode.d.ts +0 -10
- package/dist/types/reporter/src/components/comparison/comparison-modes/overlay-mode.d.ts +0 -11
- package/dist/types/reporter/src/components/comparison/comparison-modes/shared/base-comparison-mode.d.ts +0 -14
- package/dist/types/reporter/src/components/comparison/comparison-modes/shared/image-renderer.d.ts +0 -30
- package/dist/types/reporter/src/components/comparison/comparison-modes/toggle-view.d.ts +0 -8
- package/dist/types/reporter/src/components/comparison/comparison-viewer.d.ts +0 -8
- package/dist/types/reporter/src/components/comparison/fullscreen-viewer.d.ts +0 -13
- package/dist/types/reporter/src/components/comparison/screenshot-display.d.ts +0 -16
- package/dist/types/reporter/src/components/comparison/screenshot-list.d.ts +0 -9
- package/dist/types/reporter/src/components/comparison/variant-selector.d.ts +0 -9
- package/dist/types/reporter/src/components/comparison/view-mode-selector.d.ts +0 -4
- package/dist/types/reporter/src/components/dashboard/dashboard-filters.d.ts +0 -16
- package/dist/types/reporter/src/components/design-system/alert.d.ts +0 -9
- package/dist/types/reporter/src/components/design-system/badge.d.ts +0 -17
- package/dist/types/reporter/src/components/design-system/button.d.ts +0 -19
- package/dist/types/reporter/src/components/design-system/card.d.ts +0 -31
- package/dist/types/reporter/src/components/design-system/empty-state.d.ts +0 -13
- package/dist/types/reporter/src/components/design-system/form-controls.d.ts +0 -44
- package/dist/types/reporter/src/components/design-system/health-ring.d.ts +0 -7
- package/dist/types/reporter/src/components/design-system/index.d.ts +0 -11
- package/dist/types/reporter/src/components/design-system/modal.d.ts +0 -10
- package/dist/types/reporter/src/components/design-system/skeleton.d.ts +0 -19
- package/dist/types/reporter/src/components/design-system/spinner.d.ts +0 -10
- package/dist/types/reporter/src/components/design-system/tabs.d.ts +0 -13
- package/dist/types/reporter/src/components/layout/header.d.ts +0 -5
- package/dist/types/reporter/src/components/layout/index.d.ts +0 -2
- package/dist/types/reporter/src/components/layout/layout.d.ts +0 -6
- package/dist/types/reporter/src/components/ui/smart-image.d.ts +0 -7
- package/dist/types/reporter/src/components/ui/toast.d.ts +0 -4
- package/dist/types/reporter/src/components/views/builds-view.d.ts +0 -1
- package/dist/types/reporter/src/components/views/comparison-detail-view.d.ts +0 -5
- package/dist/types/reporter/src/components/views/comparisons-view.d.ts +0 -5
- package/dist/types/reporter/src/components/views/projects-view.d.ts +0 -1
- package/dist/types/reporter/src/components/views/settings-view.d.ts +0 -1
- package/dist/types/reporter/src/components/views/stats-view.d.ts +0 -1
- package/dist/types/reporter/src/components/waiting-for-screenshots.d.ts +0 -1
- package/dist/types/reporter/src/hooks/queries/use-auth-queries.d.ts +0 -15
- package/dist/types/reporter/src/hooks/queries/use-cloud-queries.d.ts +0 -6
- package/dist/types/reporter/src/hooks/queries/use-config-queries.d.ts +0 -6
- package/dist/types/reporter/src/hooks/queries/use-tdd-queries.d.ts +0 -9
- package/dist/types/reporter/src/hooks/use-comparison-filters.d.ts +0 -20
- package/dist/types/reporter/src/hooks/use-image-loader.d.ts +0 -1
- package/dist/types/reporter/src/lib/query-client.d.ts +0 -2
- package/dist/types/reporter/src/lib/query-keys.d.ts +0 -13
- package/dist/types/reporter/src/main.d.ts +0 -1
- package/dist/types/reporter/src/services/api-client.d.ts +0 -11
- package/dist/types/reporter/src/utils/comparison-helpers.d.ts +0 -16
- package/dist/types/reporter/src/utils/constants.d.ts +0 -37
- package/dist/types/reporter/vite.config.d.ts +0 -2
- package/dist/types/reporter/vite.dev.config.d.ts +0 -2
- package/dist/types/sdk/index.d.ts +0 -110
- package/dist/types/server/handlers/api-handler.d.ts +0 -88
- package/dist/types/server/handlers/tdd-handler.d.ts +0 -162
- package/dist/types/server/http-server.d.ts +0 -6
- package/dist/types/server/middleware/cors.d.ts +0 -11
- package/dist/types/server/middleware/json-parser.d.ts +0 -10
- package/dist/types/server/middleware/response.d.ts +0 -50
- package/dist/types/server/routers/assets.d.ts +0 -6
- package/dist/types/server/routers/auth.d.ts +0 -9
- package/dist/types/server/routers/baseline.d.ts +0 -13
- package/dist/types/server/routers/cloud-proxy.d.ts +0 -11
- package/dist/types/server/routers/config.d.ts +0 -9
- package/dist/types/server/routers/dashboard.d.ts +0 -6
- package/dist/types/server/routers/health.d.ts +0 -11
- package/dist/types/server/routers/projects.d.ts +0 -9
- package/dist/types/server/routers/screenshot.d.ts +0 -11
- package/dist/types/services/api-service.d.ts +0 -100
- package/dist/types/services/auth-service.d.ts +0 -59
- package/dist/types/services/build-manager.d.ts +0 -69
- package/dist/types/services/config-service.d.ts +0 -97
- package/dist/types/services/html-report-generator.d.ts +0 -52
- package/dist/types/services/index.d.ts +0 -7
- package/dist/types/services/project-service.d.ts +0 -105
- package/dist/types/services/report-generator/viewer.d.ts +0 -0
- package/dist/types/services/screenshot-server.d.ts +0 -10
- package/dist/types/services/server-manager.d.ts +0 -269
- package/dist/types/services/static-report-generator.d.ts +0 -25
- package/dist/types/services/tdd-service.d.ts +0 -95
- package/dist/types/services/test-runner.d.ts +0 -31
- package/dist/types/services/uploader.d.ts +0 -36
- package/dist/types/utils/browser.d.ts +0 -6
- package/dist/types/utils/build-history.d.ts +0 -16
- package/dist/types/utils/ci-env.d.ts +0 -55
- package/dist/types/utils/colors.d.ts +0 -12
- package/dist/types/utils/config-helpers.d.ts +0 -6
- package/dist/types/utils/config-loader.d.ts +0 -25
- package/dist/types/utils/config-schema.d.ts +0 -51
- package/dist/types/utils/environment-config.d.ts +0 -59
- package/dist/types/utils/environment.d.ts +0 -36
- package/dist/types/utils/fetch-utils.d.ts +0 -1
- package/dist/types/utils/file-helpers.d.ts +0 -18
- package/dist/types/utils/git.d.ts +0 -56
- package/dist/types/utils/global-config.d.ts +0 -84
- package/dist/types/utils/image-input-detector.d.ts +0 -71
- package/dist/types/utils/output.d.ts +0 -84
- package/dist/types/utils/package-info.d.ts +0 -15
- package/dist/types/utils/security.d.ts +0 -30
package/dist/types/index.d.ts
CHANGED
|
@@ -1,9 +1,426 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Vizzly CLI Type Definitions
|
|
3
|
+
* @module @vizzly-testing/cli
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { EventEmitter } from 'events';
|
|
7
|
+
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Configuration Types
|
|
10
|
+
// ============================================================================
|
|
11
|
+
|
|
12
|
+
export interface ServerConfig {
|
|
13
|
+
port?: number;
|
|
14
|
+
timeout?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface BuildConfig {
|
|
18
|
+
name?: string;
|
|
19
|
+
environment?: string;
|
|
20
|
+
branch?: string;
|
|
21
|
+
commit?: string;
|
|
22
|
+
message?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface UploadConfig {
|
|
26
|
+
screenshotsDir?: string | string[];
|
|
27
|
+
batchSize?: number;
|
|
28
|
+
timeout?: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface ComparisonConfig {
|
|
32
|
+
threshold?: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface TddConfig {
|
|
36
|
+
openReport?: boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface VizzlyConfig {
|
|
40
|
+
apiKey?: string;
|
|
41
|
+
apiUrl?: string;
|
|
42
|
+
server?: ServerConfig;
|
|
43
|
+
build?: BuildConfig;
|
|
44
|
+
upload?: UploadConfig;
|
|
45
|
+
comparison?: ComparisonConfig;
|
|
46
|
+
tdd?: TddConfig;
|
|
47
|
+
plugins?: string[];
|
|
48
|
+
parallelId?: string;
|
|
49
|
+
baselineBuildId?: string;
|
|
50
|
+
baselineComparisonId?: string;
|
|
51
|
+
eager?: boolean;
|
|
52
|
+
wait?: boolean;
|
|
53
|
+
allowNoToken?: boolean;
|
|
54
|
+
/** Allow additional plugin-specific configuration */
|
|
55
|
+
[key: string]: unknown;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ============================================================================
|
|
59
|
+
// Screenshot Types
|
|
60
|
+
// ============================================================================
|
|
61
|
+
|
|
62
|
+
export interface ScreenshotOptions {
|
|
63
|
+
properties?: Record<string, unknown>;
|
|
64
|
+
threshold?: number;
|
|
65
|
+
fullPage?: boolean;
|
|
66
|
+
buildId?: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface ScreenshotResult {
|
|
70
|
+
success: boolean;
|
|
71
|
+
status?: 'passed' | 'failed' | 'new';
|
|
72
|
+
name?: string;
|
|
73
|
+
diffPercentage?: number;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ============================================================================
|
|
77
|
+
// Comparison Types
|
|
78
|
+
// ============================================================================
|
|
79
|
+
|
|
80
|
+
export interface ComparisonResult {
|
|
81
|
+
id: string;
|
|
82
|
+
name: string;
|
|
83
|
+
status: 'passed' | 'failed' | 'new' | 'error' | 'baseline-updated';
|
|
84
|
+
baseline: string;
|
|
85
|
+
current: string;
|
|
86
|
+
diff: string | null;
|
|
87
|
+
properties: Record<string, unknown>;
|
|
88
|
+
signature: string;
|
|
89
|
+
threshold?: number;
|
|
90
|
+
diffPercentage?: number;
|
|
91
|
+
diffCount?: number;
|
|
92
|
+
error?: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface TddResults {
|
|
96
|
+
total: number;
|
|
97
|
+
passed: number;
|
|
98
|
+
failed: number;
|
|
99
|
+
new: number;
|
|
100
|
+
errors: number;
|
|
101
|
+
comparisons: ComparisonResult[];
|
|
102
|
+
baseline: BaselineData | null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface BaselineData {
|
|
106
|
+
buildId: string;
|
|
107
|
+
buildName: string;
|
|
108
|
+
environment?: string;
|
|
109
|
+
branch?: string;
|
|
110
|
+
threshold: number;
|
|
111
|
+
createdAt?: string;
|
|
112
|
+
screenshots: BaselineScreenshot[];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface BaselineScreenshot {
|
|
116
|
+
name: string;
|
|
117
|
+
originalName?: string;
|
|
118
|
+
sha256?: string;
|
|
119
|
+
id?: string;
|
|
120
|
+
properties: Record<string, unknown>;
|
|
121
|
+
path: string;
|
|
122
|
+
signature: string;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// ============================================================================
|
|
126
|
+
// Upload Types
|
|
127
|
+
// ============================================================================
|
|
128
|
+
|
|
129
|
+
export interface UploadOptions {
|
|
130
|
+
screenshotsDir?: string;
|
|
131
|
+
buildName?: string;
|
|
132
|
+
branch?: string;
|
|
133
|
+
commit?: string;
|
|
134
|
+
message?: string;
|
|
135
|
+
environment?: string;
|
|
136
|
+
threshold?: number;
|
|
137
|
+
pullRequestNumber?: string;
|
|
138
|
+
parallelId?: string;
|
|
139
|
+
onProgress?: (progress: UploadProgress) => void;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface UploadProgress {
|
|
143
|
+
phase:
|
|
144
|
+
| 'scanning'
|
|
145
|
+
| 'processing'
|
|
146
|
+
| 'deduplication'
|
|
147
|
+
| 'uploading'
|
|
148
|
+
| 'completed';
|
|
149
|
+
message: string;
|
|
150
|
+
total?: number;
|
|
151
|
+
current?: number;
|
|
152
|
+
toUpload?: number;
|
|
153
|
+
existing?: number;
|
|
154
|
+
buildId?: string;
|
|
155
|
+
url?: string;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export interface UploadResult {
|
|
159
|
+
success: boolean;
|
|
160
|
+
buildId: string;
|
|
161
|
+
url: string | null;
|
|
162
|
+
stats: {
|
|
163
|
+
total: number;
|
|
164
|
+
uploaded: number;
|
|
165
|
+
skipped: number;
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export interface BuildResult {
|
|
170
|
+
status: 'completed' | 'failed' | 'pending';
|
|
171
|
+
build: unknown;
|
|
172
|
+
comparisons?: number;
|
|
173
|
+
passedComparisons?: number;
|
|
174
|
+
failedComparisons?: number;
|
|
175
|
+
url?: string;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// ============================================================================
|
|
179
|
+
// Error Types
|
|
180
|
+
// ============================================================================
|
|
181
|
+
|
|
182
|
+
export class VizzlyError extends Error {
|
|
183
|
+
code: string;
|
|
184
|
+
context: Record<string, unknown>;
|
|
185
|
+
timestamp: string;
|
|
186
|
+
constructor(
|
|
187
|
+
message: string,
|
|
188
|
+
code?: string,
|
|
189
|
+
context?: Record<string, unknown>
|
|
190
|
+
);
|
|
191
|
+
getUserMessage(): string;
|
|
192
|
+
toJSON(): {
|
|
193
|
+
name: string;
|
|
194
|
+
code: string;
|
|
195
|
+
message: string;
|
|
196
|
+
context: Record<string, unknown>;
|
|
197
|
+
timestamp: string;
|
|
198
|
+
stack?: string;
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export class ConfigError extends VizzlyError {
|
|
203
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export class AuthError extends VizzlyError {
|
|
207
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export class NetworkError extends VizzlyError {
|
|
211
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export class UploadError extends VizzlyError {
|
|
215
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export class ScreenshotError extends VizzlyError {
|
|
219
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export class BuildError extends VizzlyError {
|
|
223
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export class TimeoutError extends VizzlyError {
|
|
227
|
+
duration: number;
|
|
228
|
+
constructor(
|
|
229
|
+
message: string,
|
|
230
|
+
duration?: number,
|
|
231
|
+
context?: Record<string, unknown>
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export class ValidationError extends VizzlyError {
|
|
236
|
+
errors: string[];
|
|
237
|
+
constructor(
|
|
238
|
+
message: string,
|
|
239
|
+
errors?: string[],
|
|
240
|
+
context?: Record<string, unknown>
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// ============================================================================
|
|
245
|
+
// SDK Types
|
|
246
|
+
// ============================================================================
|
|
247
|
+
|
|
248
|
+
export interface VizzlySDKInstance extends EventEmitter {
|
|
249
|
+
config: VizzlyConfig;
|
|
250
|
+
|
|
251
|
+
/** Start the Vizzly server */
|
|
252
|
+
start(): Promise<{ port: number; url: string }>;
|
|
253
|
+
|
|
254
|
+
/** Stop the Vizzly server */
|
|
255
|
+
stop(): Promise<void>;
|
|
256
|
+
|
|
257
|
+
/** Get current configuration */
|
|
258
|
+
getConfig(): VizzlyConfig;
|
|
259
|
+
|
|
260
|
+
/** Capture a screenshot */
|
|
261
|
+
screenshot(
|
|
262
|
+
name: string,
|
|
263
|
+
imageBuffer: Buffer | string,
|
|
264
|
+
options?: ScreenshotOptions
|
|
265
|
+
): Promise<void>;
|
|
266
|
+
|
|
267
|
+
/** Upload all captured screenshots */
|
|
268
|
+
upload(options?: UploadOptions): Promise<UploadResult>;
|
|
269
|
+
|
|
270
|
+
/** Run local comparison in TDD mode */
|
|
271
|
+
compare(
|
|
272
|
+
name: string,
|
|
273
|
+
imageBuffer: Buffer | string
|
|
274
|
+
): Promise<ComparisonResult>;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export class VizzlySDK extends EventEmitter implements VizzlySDKInstance {
|
|
278
|
+
config: VizzlyConfig;
|
|
279
|
+
|
|
280
|
+
constructor(config: VizzlyConfig, services: unknown);
|
|
281
|
+
|
|
282
|
+
start(): Promise<{ port: number; url: string }>;
|
|
283
|
+
stop(): Promise<void>;
|
|
284
|
+
getConfig(): VizzlyConfig;
|
|
285
|
+
screenshot(
|
|
286
|
+
name: string,
|
|
287
|
+
imageBuffer: Buffer | string,
|
|
288
|
+
options?: ScreenshotOptions
|
|
289
|
+
): Promise<void>;
|
|
290
|
+
upload(options?: UploadOptions): Promise<UploadResult>;
|
|
291
|
+
compare(
|
|
292
|
+
name: string,
|
|
293
|
+
imageBuffer: Buffer | string
|
|
294
|
+
): Promise<ComparisonResult>;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// ============================================================================
|
|
298
|
+
// Service Types
|
|
299
|
+
// ============================================================================
|
|
300
|
+
|
|
301
|
+
export interface Uploader {
|
|
302
|
+
upload(options: UploadOptions): Promise<UploadResult>;
|
|
303
|
+
waitForBuild(buildId: string, timeout?: number): Promise<BuildResult>;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
export interface TddService {
|
|
307
|
+
downloadBaselines(
|
|
308
|
+
environment?: string,
|
|
309
|
+
branch?: string,
|
|
310
|
+
buildId?: string,
|
|
311
|
+
comparisonId?: string
|
|
312
|
+
): Promise<BaselineData | null>;
|
|
313
|
+
|
|
314
|
+
loadBaseline(): Promise<BaselineData | null>;
|
|
315
|
+
|
|
316
|
+
compareScreenshot(
|
|
317
|
+
name: string,
|
|
318
|
+
imageBuffer: Buffer,
|
|
319
|
+
properties?: Record<string, unknown>
|
|
320
|
+
): Promise<ComparisonResult>;
|
|
321
|
+
|
|
322
|
+
getResults(): TddResults;
|
|
323
|
+
printResults(): Promise<TddResults>;
|
|
324
|
+
updateBaselines(): number;
|
|
325
|
+
acceptBaseline(idOrComparison: string | ComparisonResult): Promise<{
|
|
326
|
+
name: string;
|
|
327
|
+
status: string;
|
|
328
|
+
message: string;
|
|
329
|
+
}>;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export interface Services {
|
|
333
|
+
apiService: unknown;
|
|
334
|
+
authService: unknown;
|
|
335
|
+
configService: unknown;
|
|
336
|
+
projectService: unknown;
|
|
337
|
+
uploader: Uploader;
|
|
338
|
+
buildManager: unknown;
|
|
339
|
+
serverManager: unknown;
|
|
340
|
+
tddService: TddService;
|
|
341
|
+
testRunner: unknown;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// ============================================================================
|
|
345
|
+
// Output Utilities
|
|
346
|
+
// ============================================================================
|
|
347
|
+
|
|
348
|
+
export interface OutputUtils {
|
|
349
|
+
info(message: string): void;
|
|
350
|
+
warn(message: string): void;
|
|
351
|
+
error(message: string): void;
|
|
352
|
+
success(message: string): void;
|
|
353
|
+
debug(category: string, ...args: unknown[]): void;
|
|
354
|
+
configure(options: { verbose?: boolean }): void;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// ============================================================================
|
|
358
|
+
// Main Exports
|
|
359
|
+
// ============================================================================
|
|
360
|
+
|
|
361
|
+
/** Create a new Vizzly SDK instance */
|
|
362
|
+
export function createVizzly(
|
|
363
|
+
config?: VizzlyConfig,
|
|
364
|
+
options?: { verbose?: boolean }
|
|
365
|
+
): Promise<VizzlySDKInstance>;
|
|
366
|
+
|
|
367
|
+
/** Take a screenshot for visual regression testing */
|
|
368
|
+
export function vizzlyScreenshot(
|
|
369
|
+
name: string,
|
|
370
|
+
imageBuffer: Buffer | string,
|
|
371
|
+
options?: {
|
|
372
|
+
properties?: Record<string, unknown>;
|
|
373
|
+
threshold?: number;
|
|
374
|
+
fullPage?: boolean;
|
|
375
|
+
}
|
|
376
|
+
): Promise<void>;
|
|
377
|
+
|
|
378
|
+
/** Configure the Vizzly client */
|
|
379
|
+
export function configure(config?: {
|
|
380
|
+
serverUrl?: string;
|
|
381
|
+
enabled?: boolean;
|
|
382
|
+
}): void;
|
|
383
|
+
|
|
384
|
+
/** Enable or disable screenshot capture */
|
|
385
|
+
export function setEnabled(enabled: boolean): void;
|
|
386
|
+
|
|
387
|
+
/** Create an uploader instance */
|
|
388
|
+
export function createUploader(
|
|
389
|
+
config?: {
|
|
390
|
+
apiKey?: string;
|
|
391
|
+
apiUrl?: string;
|
|
392
|
+
userAgent?: string;
|
|
393
|
+
command?: string;
|
|
394
|
+
upload?: UploadConfig;
|
|
395
|
+
},
|
|
396
|
+
options?: {
|
|
397
|
+
signal?: AbortSignal;
|
|
398
|
+
batchSize?: number;
|
|
399
|
+
timeout?: number;
|
|
400
|
+
}
|
|
401
|
+
): Uploader;
|
|
402
|
+
|
|
403
|
+
/** Create a TDD service instance */
|
|
404
|
+
export function createTDDService(
|
|
405
|
+
config: VizzlyConfig,
|
|
406
|
+
options?: {
|
|
407
|
+
workingDir?: string;
|
|
408
|
+
setBaseline?: boolean;
|
|
409
|
+
authService?: unknown;
|
|
410
|
+
}
|
|
411
|
+
): TddService;
|
|
412
|
+
|
|
413
|
+
/** Create all services with dependencies */
|
|
414
|
+
export function createServices(
|
|
415
|
+
config: VizzlyConfig,
|
|
416
|
+
command?: string
|
|
417
|
+
): Services;
|
|
418
|
+
|
|
419
|
+
/** Load configuration from file and environment */
|
|
420
|
+
export function loadConfig(options?: { cwd?: string }): Promise<VizzlyConfig>;
|
|
421
|
+
|
|
422
|
+
/** Define Vizzly configuration with type hints */
|
|
423
|
+
export function defineConfig(config: VizzlyConfig): VizzlyConfig;
|
|
424
|
+
|
|
425
|
+
/** Output utilities namespace */
|
|
426
|
+
export const output: OutputUtils;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vizzly SDK Type Definitions
|
|
3
|
+
* Full SDK for custom integrations
|
|
4
|
+
* @module @vizzly-testing/cli/sdk
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { EventEmitter } from 'events';
|
|
8
|
+
|
|
9
|
+
// Re-export common types
|
|
10
|
+
export {
|
|
11
|
+
VizzlyConfig,
|
|
12
|
+
ScreenshotOptions,
|
|
13
|
+
UploadOptions,
|
|
14
|
+
UploadResult,
|
|
15
|
+
ComparisonResult,
|
|
16
|
+
TddResults,
|
|
17
|
+
BaselineData,
|
|
18
|
+
Uploader,
|
|
19
|
+
TddService,
|
|
20
|
+
OutputUtils,
|
|
21
|
+
} from './index';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* VizzlySDK class - Full SDK for custom integrations
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* import { createVizzly } from '@vizzly-testing/cli/sdk';
|
|
28
|
+
*
|
|
29
|
+
* const vizzly = await createVizzly({
|
|
30
|
+
* apiKey: process.env.VIZZLY_TOKEN,
|
|
31
|
+
* server: { port: 3003 }
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* await vizzly.start();
|
|
35
|
+
* await vizzly.screenshot('test', buffer);
|
|
36
|
+
* await vizzly.upload();
|
|
37
|
+
* await vizzly.stop();
|
|
38
|
+
*/
|
|
39
|
+
export class VizzlySDK extends EventEmitter {
|
|
40
|
+
config: import('./index').VizzlyConfig;
|
|
41
|
+
|
|
42
|
+
constructor(config: import('./index').VizzlyConfig, services: unknown);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Start the Vizzly server
|
|
46
|
+
* @returns Server information including port and URL
|
|
47
|
+
*/
|
|
48
|
+
start(): Promise<{ port: number; url: string }>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Stop the Vizzly server
|
|
52
|
+
*/
|
|
53
|
+
stop(): Promise<void>;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get current configuration
|
|
57
|
+
*/
|
|
58
|
+
getConfig(): import('./index').VizzlyConfig;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Capture a screenshot
|
|
62
|
+
* @param name - Screenshot name
|
|
63
|
+
* @param imageBuffer - Image data as a Buffer, or a file path to an image
|
|
64
|
+
* @param options - Screenshot options
|
|
65
|
+
* @throws VizzlyError when server is not running
|
|
66
|
+
* @throws VizzlyError when file path is provided but file doesn't exist
|
|
67
|
+
*/
|
|
68
|
+
screenshot(
|
|
69
|
+
name: string,
|
|
70
|
+
imageBuffer: Buffer | string,
|
|
71
|
+
options?: import('./index').ScreenshotOptions
|
|
72
|
+
): Promise<void>;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Upload all captured screenshots
|
|
76
|
+
* @param options - Upload options
|
|
77
|
+
* @returns Upload result with build URL and stats
|
|
78
|
+
*/
|
|
79
|
+
upload(
|
|
80
|
+
options?: import('./index').UploadOptions
|
|
81
|
+
): Promise<import('./index').UploadResult>;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Run local comparison in TDD mode
|
|
85
|
+
* @param name - Screenshot name
|
|
86
|
+
* @param imageBuffer - Current image as a Buffer, or a file path to an image
|
|
87
|
+
* @returns Comparison result
|
|
88
|
+
*/
|
|
89
|
+
compare(
|
|
90
|
+
name: string,
|
|
91
|
+
imageBuffer: Buffer | string
|
|
92
|
+
): Promise<import('./index').ComparisonResult>;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Create a new Vizzly SDK instance
|
|
97
|
+
*
|
|
98
|
+
* @param config - Configuration options
|
|
99
|
+
* @param options - Additional options
|
|
100
|
+
* @returns Configured Vizzly SDK instance
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* const vizzly = await createVizzly({
|
|
104
|
+
* apiKey: process.env.VIZZLY_TOKEN,
|
|
105
|
+
* apiUrl: 'https://app.vizzly.dev',
|
|
106
|
+
* server: { port: 3003 }
|
|
107
|
+
* });
|
|
108
|
+
*/
|
|
109
|
+
export function createVizzly(
|
|
110
|
+
config?: import('./index').VizzlyConfig,
|
|
111
|
+
options?: { verbose?: boolean }
|
|
112
|
+
): Promise<VizzlySDK>;
|
|
113
|
+
|
|
114
|
+
/** Load configuration from file and environment */
|
|
115
|
+
export function loadConfig(options?: {
|
|
116
|
+
cwd?: string;
|
|
117
|
+
}): Promise<import('./index').VizzlyConfig>;
|
|
118
|
+
|
|
119
|
+
/** Output utilities */
|
|
120
|
+
export const output: import('./index').OutputUtils;
|
|
121
|
+
|
|
122
|
+
/** Create an uploader instance */
|
|
123
|
+
export function createUploader(
|
|
124
|
+
config?: {
|
|
125
|
+
apiKey?: string;
|
|
126
|
+
apiUrl?: string;
|
|
127
|
+
userAgent?: string;
|
|
128
|
+
command?: string;
|
|
129
|
+
upload?: import('./index').UploadConfig;
|
|
130
|
+
},
|
|
131
|
+
options?: {
|
|
132
|
+
signal?: AbortSignal;
|
|
133
|
+
batchSize?: number;
|
|
134
|
+
timeout?: number;
|
|
135
|
+
}
|
|
136
|
+
): import('./index').Uploader;
|
|
137
|
+
|
|
138
|
+
/** Create a TDD service instance */
|
|
139
|
+
export function createTDDService(
|
|
140
|
+
config: import('./index').VizzlyConfig,
|
|
141
|
+
options?: {
|
|
142
|
+
workingDir?: string;
|
|
143
|
+
setBaseline?: boolean;
|
|
144
|
+
authService?: unknown;
|
|
145
|
+
}
|
|
146
|
+
): import('./index').TddService;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Define Vizzly configuration with type hints
|
|
3
|
-
* @param {
|
|
4
|
-
* @returns {
|
|
3
|
+
* @param {Object} config - Vizzly configuration object
|
|
4
|
+
* @returns {Object} The same configuration object (passthrough for type hints)
|
|
5
5
|
*/
|
|
6
6
|
export function defineConfig(config) {
|
|
7
7
|
return config;
|
package/docs/tdd-mode.md
CHANGED
|
@@ -311,6 +311,40 @@ npx vizzly tdd run "npm test"
|
|
|
311
311
|
npx vizzly run "npm test" --build-name "Fix: Header alignment issue"
|
|
312
312
|
```
|
|
313
313
|
|
|
314
|
+
## Hotspot Filtering
|
|
315
|
+
|
|
316
|
+
When connected to Vizzly cloud, TDD mode automatically filters out "noise" from known hotspot areas - regions that frequently change across builds (like timestamps, animations, or dynamic content).
|
|
317
|
+
|
|
318
|
+
### How It Works
|
|
319
|
+
|
|
320
|
+
1. **Download baselines** - Use the TDD dashboard's Builds page to download baselines from the cloud (hotspot data is included automatically)
|
|
321
|
+
2. **Automatic filtering** - During comparisons, if a diff falls within a known hotspot region, it's automatically marked as passed
|
|
322
|
+
3. **Visual feedback** - You'll see output like:
|
|
323
|
+
```
|
|
324
|
+
✅ PASSED Dashboard - differences in known hotspots (0.15% different, 42 pixels, 1 region, 95% in hotspots)
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Requirements
|
|
328
|
+
|
|
329
|
+
Hotspot filtering activates automatically when:
|
|
330
|
+
- You have an API token configured (`vizzly login` or `VIZZLY_TOKEN`)
|
|
331
|
+
- You've downloaded baselines from the cloud (via the TDD dashboard's Builds page)
|
|
332
|
+
- The cloud has enough historical build data to calculate hotspot regions
|
|
333
|
+
|
|
334
|
+
### Filtering Criteria
|
|
335
|
+
|
|
336
|
+
A diff is filtered (auto-passed) when:
|
|
337
|
+
- **80%+ of the diff** falls within known hotspot regions
|
|
338
|
+
- **High confidence** hotspot data (confidence score ≥ 70)
|
|
339
|
+
|
|
340
|
+
If the diff falls outside hotspots or confidence is low, the comparison fails normally so you can review it.
|
|
341
|
+
|
|
342
|
+
### Benefits
|
|
343
|
+
|
|
344
|
+
- **Reduced noise** - Stop seeing the same timestamp/animation diffs over and over
|
|
345
|
+
- **Faster reviews** - Focus on real visual changes, not known dynamic areas
|
|
346
|
+
- **Smart detection** - Hotspots are calculated from your actual build history, not manual configuration
|
|
347
|
+
|
|
314
348
|
## Comparison Settings
|
|
315
349
|
|
|
316
350
|
TDD Mode uses the same comparison settings as production:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vizzly-testing/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.1",
|
|
4
4
|
"description": "Visual review platform for UI developers and designers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"visual-testing",
|
|
@@ -23,18 +23,22 @@
|
|
|
23
23
|
"type": "module",
|
|
24
24
|
"exports": {
|
|
25
25
|
".": {
|
|
26
|
+
"types": "./dist/types/index.d.ts",
|
|
26
27
|
"import": "./dist/index.js",
|
|
27
28
|
"require": "./dist/index.js"
|
|
28
29
|
},
|
|
29
30
|
"./client": {
|
|
31
|
+
"types": "./dist/types/client.d.ts",
|
|
30
32
|
"import": "./dist/client/index.js",
|
|
31
33
|
"require": "./dist/client/index.js"
|
|
32
34
|
},
|
|
33
35
|
"./sdk": {
|
|
36
|
+
"types": "./dist/types/sdk.d.ts",
|
|
34
37
|
"import": "./dist/sdk/index.js",
|
|
35
38
|
"require": "./dist/sdk/index.js"
|
|
36
39
|
},
|
|
37
40
|
"./config": {
|
|
41
|
+
"types": "./dist/types/config.d.ts",
|
|
38
42
|
"import": "./dist/utils/config-helpers.js",
|
|
39
43
|
"require": "./dist/utils/config-helpers.js"
|
|
40
44
|
}
|
|
@@ -54,14 +58,15 @@
|
|
|
54
58
|
],
|
|
55
59
|
"scripts": {
|
|
56
60
|
"start": "node src/index.js",
|
|
57
|
-
"build": "npm run clean && npm run compile && npm run copy-assets && npm run build:reporter && npm run types",
|
|
61
|
+
"build": "npm run clean && npm run compile && npm run copy-assets && npm run build:reporter && npm run copy-types",
|
|
58
62
|
"clean": "rimraf dist",
|
|
59
63
|
"compile": "babel src --out-dir dist --ignore '**/*.test.js'",
|
|
60
64
|
"copy-assets": "cp src/services/report-generator/report.css dist/services/report-generator/",
|
|
65
|
+
"copy-types": "mkdir -p dist/types && cp src/types/*.d.ts dist/types/",
|
|
61
66
|
"build:reporter": "cd src/reporter && vite build",
|
|
62
67
|
"dev:reporter": "cd src/reporter && vite --config vite.dev.config.js",
|
|
63
|
-
"types": "
|
|
64
|
-
"prepublishOnly": "npm
|
|
68
|
+
"test:types": "tsd",
|
|
69
|
+
"prepublishOnly": "npm run build",
|
|
65
70
|
"test": "vitest run",
|
|
66
71
|
"test:watch": "vitest",
|
|
67
72
|
"test:reporter": "playwright test --config=tests/reporter/playwright.config.js",
|
|
@@ -87,6 +92,16 @@
|
|
|
87
92
|
"glob": "^13.0.0",
|
|
88
93
|
"zod": "^4.1.12"
|
|
89
94
|
},
|
|
95
|
+
"tsd": {
|
|
96
|
+
"directory": "test-d",
|
|
97
|
+
"typingsFile": "src/types/index.d.ts",
|
|
98
|
+
"compilerOptions": {
|
|
99
|
+
"esModuleInterop": true,
|
|
100
|
+
"module": "ESNext",
|
|
101
|
+
"moduleResolution": "node",
|
|
102
|
+
"strict": true
|
|
103
|
+
}
|
|
104
|
+
},
|
|
90
105
|
"devDependencies": {
|
|
91
106
|
"@babel/cli": "^7.28.0",
|
|
92
107
|
"@babel/core": "^7.23.6",
|
|
@@ -99,6 +114,7 @@
|
|
|
99
114
|
"@playwright/test": "^1.55.1",
|
|
100
115
|
"@tailwindcss/postcss": "^4.1.13",
|
|
101
116
|
"@tanstack/react-query": "^5.90.11",
|
|
117
|
+
"@types/node": "^24.10.1",
|
|
102
118
|
"@vitejs/plugin-react": "^5.0.3",
|
|
103
119
|
"@vitest/coverage-v8": "^4.0.3",
|
|
104
120
|
"autoprefixer": "^10.4.21",
|
|
@@ -114,6 +130,7 @@
|
|
|
114
130
|
"react-dom": "^19.1.1",
|
|
115
131
|
"rimraf": "^6.0.1",
|
|
116
132
|
"tailwindcss": "^4.1.13",
|
|
133
|
+
"tsd": "^0.33.0",
|
|
117
134
|
"typescript": "^5.0.4",
|
|
118
135
|
"vite": "^7.1.7",
|
|
119
136
|
"vitest": "^4.0.3",
|