@vizzly-testing/cli 0.11.2 → 0.13.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 +87 -544
- package/dist/client/index.js +7 -5
- package/dist/reporter/reporter-bundle.css +1 -1
- package/dist/reporter/reporter-bundle.iife.js +20 -13
- package/dist/server/handlers/api-handler.js +53 -1
- package/dist/server/handlers/tdd-handler.js +262 -24
- package/dist/server/http-server.js +9 -9
- package/dist/services/tdd-service.js +173 -57
- package/dist/types/reporter/src/components/comparison/comparison-card.d.ts +2 -1
- package/dist/types/reporter/src/components/comparison/comparison-group.d.ts +10 -0
- package/dist/types/reporter/src/components/comparison/variant-selector.d.ts +9 -0
- package/dist/types/reporter/src/services/api-client.d.ts +1 -1
- package/dist/types/server/handlers/api-handler.d.ts +48 -0
- package/dist/types/server/handlers/tdd-handler.d.ts +69 -12
- package/dist/types/services/server-manager.d.ts +117 -12
- package/dist/types/services/tdd-service.d.ts +4 -2
- package/dist/types/utils/image-input-detector.d.ts +71 -0
- package/dist/utils/image-input-detector.js +150 -0
- package/docs/tdd-mode.md +6 -6
- package/package.json +3 -3
|
@@ -14,6 +14,65 @@ export class ServerManager extends BaseService {
|
|
|
14
14
|
error: string;
|
|
15
15
|
details: any;
|
|
16
16
|
tddMode: boolean;
|
|
17
|
+
originalPath?: undefined;
|
|
18
|
+
filePath?: undefined;
|
|
19
|
+
receivedType?: undefined;
|
|
20
|
+
comparison?: undefined;
|
|
21
|
+
status?: undefined;
|
|
22
|
+
message?: undefined;
|
|
23
|
+
success?: undefined;
|
|
24
|
+
};
|
|
25
|
+
} | {
|
|
26
|
+
statusCode: number;
|
|
27
|
+
body: {
|
|
28
|
+
error: string;
|
|
29
|
+
originalPath: any;
|
|
30
|
+
tddMode: boolean;
|
|
31
|
+
details?: undefined;
|
|
32
|
+
filePath?: undefined;
|
|
33
|
+
receivedType?: undefined;
|
|
34
|
+
comparison?: undefined;
|
|
35
|
+
status?: undefined;
|
|
36
|
+
message?: undefined;
|
|
37
|
+
success?: undefined;
|
|
38
|
+
};
|
|
39
|
+
} | {
|
|
40
|
+
statusCode: number;
|
|
41
|
+
body: {
|
|
42
|
+
error: string;
|
|
43
|
+
filePath: any;
|
|
44
|
+
tddMode: boolean;
|
|
45
|
+
details?: undefined;
|
|
46
|
+
originalPath?: undefined;
|
|
47
|
+
receivedType?: undefined;
|
|
48
|
+
comparison?: undefined;
|
|
49
|
+
status?: undefined;
|
|
50
|
+
message?: undefined;
|
|
51
|
+
success?: undefined;
|
|
52
|
+
};
|
|
53
|
+
} | {
|
|
54
|
+
statusCode: number;
|
|
55
|
+
body: {
|
|
56
|
+
error: string;
|
|
57
|
+
tddMode: boolean;
|
|
58
|
+
details?: undefined;
|
|
59
|
+
originalPath?: undefined;
|
|
60
|
+
filePath?: undefined;
|
|
61
|
+
receivedType?: undefined;
|
|
62
|
+
comparison?: undefined;
|
|
63
|
+
status?: undefined;
|
|
64
|
+
message?: undefined;
|
|
65
|
+
success?: undefined;
|
|
66
|
+
};
|
|
67
|
+
} | {
|
|
68
|
+
statusCode: number;
|
|
69
|
+
body: {
|
|
70
|
+
error: string;
|
|
71
|
+
receivedType: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function";
|
|
72
|
+
tddMode: boolean;
|
|
73
|
+
details?: undefined;
|
|
74
|
+
originalPath?: undefined;
|
|
75
|
+
filePath?: undefined;
|
|
17
76
|
comparison?: undefined;
|
|
18
77
|
status?: undefined;
|
|
19
78
|
message?: undefined;
|
|
@@ -34,6 +93,9 @@ export class ServerManager extends BaseService {
|
|
|
34
93
|
threshold: any;
|
|
35
94
|
};
|
|
36
95
|
tddMode: boolean;
|
|
96
|
+
originalPath?: undefined;
|
|
97
|
+
filePath?: undefined;
|
|
98
|
+
receivedType?: undefined;
|
|
37
99
|
status?: undefined;
|
|
38
100
|
message?: undefined;
|
|
39
101
|
success?: undefined;
|
|
@@ -55,17 +117,9 @@ export class ServerManager extends BaseService {
|
|
|
55
117
|
tddMode: boolean;
|
|
56
118
|
error?: undefined;
|
|
57
119
|
details?: undefined;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
statusCode: number;
|
|
62
|
-
body: {
|
|
63
|
-
error: string;
|
|
64
|
-
tddMode: boolean;
|
|
65
|
-
details?: undefined;
|
|
66
|
-
comparison?: undefined;
|
|
67
|
-
status?: undefined;
|
|
68
|
-
message?: undefined;
|
|
120
|
+
originalPath?: undefined;
|
|
121
|
+
filePath?: undefined;
|
|
122
|
+
receivedType?: undefined;
|
|
69
123
|
success?: undefined;
|
|
70
124
|
};
|
|
71
125
|
} | {
|
|
@@ -84,6 +138,9 @@ export class ServerManager extends BaseService {
|
|
|
84
138
|
tddMode: boolean;
|
|
85
139
|
error?: undefined;
|
|
86
140
|
details?: undefined;
|
|
141
|
+
originalPath?: undefined;
|
|
142
|
+
filePath?: undefined;
|
|
143
|
+
receivedType?: undefined;
|
|
87
144
|
status?: undefined;
|
|
88
145
|
message?: undefined;
|
|
89
146
|
};
|
|
@@ -97,7 +154,7 @@ export class ServerManager extends BaseService {
|
|
|
97
154
|
comparisons: any[];
|
|
98
155
|
baseline: any;
|
|
99
156
|
}>;
|
|
100
|
-
acceptBaseline: (
|
|
157
|
+
acceptBaseline: (comparisonId: any) => Promise<any>;
|
|
101
158
|
acceptAllBaselines: () => Promise<{
|
|
102
159
|
count: number;
|
|
103
160
|
}>;
|
|
@@ -117,16 +174,61 @@ export class ServerManager extends BaseService {
|
|
|
117
174
|
count: number;
|
|
118
175
|
message: string;
|
|
119
176
|
error?: undefined;
|
|
177
|
+
originalPath?: undefined;
|
|
178
|
+
filePath?: undefined;
|
|
179
|
+
receivedType?: undefined;
|
|
180
|
+
name?: undefined;
|
|
181
|
+
};
|
|
182
|
+
} | {
|
|
183
|
+
statusCode: number;
|
|
184
|
+
body: {
|
|
185
|
+
error: string;
|
|
186
|
+
success?: undefined;
|
|
187
|
+
disabled?: undefined;
|
|
188
|
+
count?: undefined;
|
|
189
|
+
message?: undefined;
|
|
190
|
+
originalPath?: undefined;
|
|
191
|
+
filePath?: undefined;
|
|
192
|
+
receivedType?: undefined;
|
|
193
|
+
name?: undefined;
|
|
194
|
+
};
|
|
195
|
+
} | {
|
|
196
|
+
statusCode: number;
|
|
197
|
+
body: {
|
|
198
|
+
error: string;
|
|
199
|
+
originalPath: any;
|
|
200
|
+
success?: undefined;
|
|
201
|
+
disabled?: undefined;
|
|
202
|
+
count?: undefined;
|
|
203
|
+
message?: undefined;
|
|
204
|
+
filePath?: undefined;
|
|
205
|
+
receivedType?: undefined;
|
|
206
|
+
name?: undefined;
|
|
207
|
+
};
|
|
208
|
+
} | {
|
|
209
|
+
statusCode: number;
|
|
210
|
+
body: {
|
|
211
|
+
error: string;
|
|
212
|
+
filePath: any;
|
|
213
|
+
success?: undefined;
|
|
214
|
+
disabled?: undefined;
|
|
215
|
+
count?: undefined;
|
|
216
|
+
message?: undefined;
|
|
217
|
+
originalPath?: undefined;
|
|
218
|
+
receivedType?: undefined;
|
|
120
219
|
name?: undefined;
|
|
121
220
|
};
|
|
122
221
|
} | {
|
|
123
222
|
statusCode: number;
|
|
124
223
|
body: {
|
|
125
224
|
error: string;
|
|
225
|
+
receivedType: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function";
|
|
126
226
|
success?: undefined;
|
|
127
227
|
disabled?: undefined;
|
|
128
228
|
count?: undefined;
|
|
129
229
|
message?: undefined;
|
|
230
|
+
originalPath?: undefined;
|
|
231
|
+
filePath?: undefined;
|
|
130
232
|
name?: undefined;
|
|
131
233
|
};
|
|
132
234
|
} | {
|
|
@@ -138,6 +240,9 @@ export class ServerManager extends BaseService {
|
|
|
138
240
|
disabled?: undefined;
|
|
139
241
|
message?: undefined;
|
|
140
242
|
error?: undefined;
|
|
243
|
+
originalPath?: undefined;
|
|
244
|
+
filePath?: undefined;
|
|
245
|
+
receivedType?: undefined;
|
|
141
246
|
};
|
|
142
247
|
}>;
|
|
143
248
|
getScreenshotCount: () => number;
|
|
@@ -22,12 +22,14 @@ export class TddService {
|
|
|
22
22
|
handleLocalBaselines(): Promise<any | null>;
|
|
23
23
|
loadBaseline(): Promise<any>;
|
|
24
24
|
compareScreenshot(name: any, imageBuffer: any, properties?: {}): Promise<{
|
|
25
|
+
id: any;
|
|
25
26
|
name: any;
|
|
26
27
|
status: string;
|
|
27
28
|
baseline: any;
|
|
28
29
|
current: any;
|
|
29
30
|
diff: any;
|
|
30
31
|
properties: any;
|
|
32
|
+
signature: string;
|
|
31
33
|
}>;
|
|
32
34
|
getResults(): {
|
|
33
35
|
total: number;
|
|
@@ -74,9 +76,9 @@ export class TddService {
|
|
|
74
76
|
private updateSingleBaseline;
|
|
75
77
|
/**
|
|
76
78
|
* Accept a current screenshot as the new baseline
|
|
77
|
-
* @param {string}
|
|
79
|
+
* @param {string} id - Comparison ID to accept (generated from signature)
|
|
78
80
|
* @returns {Object} Result object
|
|
79
81
|
*/
|
|
80
|
-
acceptBaseline(
|
|
82
|
+
acceptBaseline(id: string): any;
|
|
81
83
|
}
|
|
82
84
|
import { ApiService } from '../services/api-service.js';
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module image-input-detector
|
|
3
|
+
* @description Utilities for detecting whether a string is a base64 image or a file path
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Check if a string is valid base64 encoded data
|
|
7
|
+
*
|
|
8
|
+
* Base64 strings consist only of:
|
|
9
|
+
* - A-Z, a-z, 0-9, +, /
|
|
10
|
+
* - Optional padding with = at the end
|
|
11
|
+
* - Must be in groups of 4 characters (with optional 2-3 char group at end with padding)
|
|
12
|
+
*
|
|
13
|
+
* @param {string} str - String to check
|
|
14
|
+
* @returns {boolean} True if the string appears to be valid base64
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* isBase64('ZmFrZS1wbmctZGF0YQ==') // true
|
|
18
|
+
* isBase64('./screenshot.png') // false
|
|
19
|
+
* isBase64('/absolute/path.png') // false
|
|
20
|
+
*/
|
|
21
|
+
export function isBase64(str: string): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Check if a string looks like a file path
|
|
24
|
+
*
|
|
25
|
+
* Detects common file path patterns across platforms:
|
|
26
|
+
* - Relative paths: ./file.png, ../file.png, subdirectory/file.png
|
|
27
|
+
* - Absolute Unix paths: /absolute/path/file.png
|
|
28
|
+
* - Absolute Windows paths: C:\path\file.png, C:/path/file.png
|
|
29
|
+
* - File URIs: file:///path/to/file.png
|
|
30
|
+
* - Paths with common image extensions
|
|
31
|
+
*
|
|
32
|
+
* Note: This is heuristic-based and doesn't check file existence
|
|
33
|
+
*
|
|
34
|
+
* @param {string} str - String to check
|
|
35
|
+
* @returns {boolean} True if the string looks like a file path
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* looksLikeFilePath('./screenshot.png') // true
|
|
39
|
+
* looksLikeFilePath('/abs/path/file.png') // true
|
|
40
|
+
* looksLikeFilePath('C:\\Windows\\file.png') // true
|
|
41
|
+
* looksLikeFilePath('ZmFrZS1wbmctZGF0YQ==') // false
|
|
42
|
+
*/
|
|
43
|
+
export function looksLikeFilePath(str: string): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Detect the type of image input
|
|
46
|
+
*
|
|
47
|
+
* Determines whether a string input is:
|
|
48
|
+
* - 'base64': Base64 encoded image data
|
|
49
|
+
* - 'file-path': A file path (relative or absolute)
|
|
50
|
+
* - 'unknown': Cannot determine (ambiguous or invalid)
|
|
51
|
+
*
|
|
52
|
+
* Strategy:
|
|
53
|
+
* 1. First check if it's valid base64 (can contain / which might look like paths)
|
|
54
|
+
* 2. Then check if it looks like a file path (more specific patterns)
|
|
55
|
+
* 3. Otherwise return 'unknown'
|
|
56
|
+
*
|
|
57
|
+
* This order prevents base64 strings (which can contain /) from being
|
|
58
|
+
* misidentified as file paths. Base64 validation is stricter and should
|
|
59
|
+
* be checked first.
|
|
60
|
+
*
|
|
61
|
+
* @param {string} str - String to detect
|
|
62
|
+
* @returns {'base64' | 'file-path' | 'unknown'} Detected input type
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* detectImageInputType('./screenshot.png') // 'file-path'
|
|
66
|
+
* detectImageInputType('ZmFrZS1wbmctZGF0YQ==') // 'base64'
|
|
67
|
+
* detectImageInputType('data:image/png;base64,iVBOR...') // 'base64'
|
|
68
|
+
* detectImageInputType('C:\\path\\image.png') // 'file-path'
|
|
69
|
+
* detectImageInputType('invalid!!!') // 'unknown'
|
|
70
|
+
*/
|
|
71
|
+
export function detectImageInputType(str: string): "base64" | "file-path" | "unknown";
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module image-input-detector
|
|
3
|
+
* @description Utilities for detecting whether a string is a base64 image or a file path
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Check if a string is valid base64 encoded data
|
|
8
|
+
*
|
|
9
|
+
* Base64 strings consist only of:
|
|
10
|
+
* - A-Z, a-z, 0-9, +, /
|
|
11
|
+
* - Optional padding with = at the end
|
|
12
|
+
* - Must be in groups of 4 characters (with optional 2-3 char group at end with padding)
|
|
13
|
+
*
|
|
14
|
+
* @param {string} str - String to check
|
|
15
|
+
* @returns {boolean} True if the string appears to be valid base64
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* isBase64('ZmFrZS1wbmctZGF0YQ==') // true
|
|
19
|
+
* isBase64('./screenshot.png') // false
|
|
20
|
+
* isBase64('/absolute/path.png') // false
|
|
21
|
+
*/
|
|
22
|
+
export function isBase64(str) {
|
|
23
|
+
if (typeof str !== 'string' || str.length === 0) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Strip data URI prefix if present (e.g., data:image/png;base64,...)
|
|
28
|
+
let base64Content = str;
|
|
29
|
+
if (str.startsWith('data:')) {
|
|
30
|
+
const match = str.match(/^data:[a-zA-Z0-9+/.-]+;base64,(.+)$/);
|
|
31
|
+
if (!match) {
|
|
32
|
+
return false; // Has data: prefix but invalid format
|
|
33
|
+
}
|
|
34
|
+
base64Content = match[1];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Base64 regex: groups of 4 chars [A-Za-z0-9+/], with optional padding
|
|
38
|
+
// Valid endings: no padding, or 2/3 chars + padding (= or ==)
|
|
39
|
+
const base64Pattern = /^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
|
40
|
+
return base64Pattern.test(base64Content);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Check if a string looks like a file path
|
|
45
|
+
*
|
|
46
|
+
* Detects common file path patterns across platforms:
|
|
47
|
+
* - Relative paths: ./file.png, ../file.png, subdirectory/file.png
|
|
48
|
+
* - Absolute Unix paths: /absolute/path/file.png
|
|
49
|
+
* - Absolute Windows paths: C:\path\file.png, C:/path/file.png
|
|
50
|
+
* - File URIs: file:///path/to/file.png
|
|
51
|
+
* - Paths with common image extensions
|
|
52
|
+
*
|
|
53
|
+
* Note: This is heuristic-based and doesn't check file existence
|
|
54
|
+
*
|
|
55
|
+
* @param {string} str - String to check
|
|
56
|
+
* @returns {boolean} True if the string looks like a file path
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* looksLikeFilePath('./screenshot.png') // true
|
|
60
|
+
* looksLikeFilePath('/abs/path/file.png') // true
|
|
61
|
+
* looksLikeFilePath('C:\\Windows\\file.png') // true
|
|
62
|
+
* looksLikeFilePath('ZmFrZS1wbmctZGF0YQ==') // false
|
|
63
|
+
*/
|
|
64
|
+
export function looksLikeFilePath(str) {
|
|
65
|
+
if (typeof str !== 'string' || str.length === 0) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// 0. Explicitly reject data URIs first (they contain : and / which would match path patterns)
|
|
70
|
+
if (str.startsWith('data:')) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// 1. Check for file:// URI scheme
|
|
75
|
+
if (str.startsWith('file://')) {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// 2. Check for absolute paths (Unix or Windows)
|
|
80
|
+
// Unix: starts with /
|
|
81
|
+
// Windows: starts with drive letter like C:\ or C:/
|
|
82
|
+
if (str.startsWith('/') || /^[A-Za-z]:[/\\]/.test(str)) {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// 3. Check for relative path indicators
|
|
87
|
+
// ./ or ../ or .\ or ..\
|
|
88
|
+
if (/^\.\.?[/\\]/.test(str)) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 4. Check for path separators (forward or back slash)
|
|
93
|
+
// This catches paths like: subdirectory/file.png or subdirectory\file.png
|
|
94
|
+
if (/[/\\]/.test(str)) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// 5. Check for common image file extensions
|
|
99
|
+
// This catches simple filenames like: screenshot.png
|
|
100
|
+
// Common extensions: png, jpg, jpeg, gif, webp, bmp, svg, tiff, ico
|
|
101
|
+
if (/\.(png|jpe?g|gif|webp|bmp|svg|tiff?|ico)$/i.test(str)) {
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Detect the type of image input
|
|
109
|
+
*
|
|
110
|
+
* Determines whether a string input is:
|
|
111
|
+
* - 'base64': Base64 encoded image data
|
|
112
|
+
* - 'file-path': A file path (relative or absolute)
|
|
113
|
+
* - 'unknown': Cannot determine (ambiguous or invalid)
|
|
114
|
+
*
|
|
115
|
+
* Strategy:
|
|
116
|
+
* 1. First check if it's valid base64 (can contain / which might look like paths)
|
|
117
|
+
* 2. Then check if it looks like a file path (more specific patterns)
|
|
118
|
+
* 3. Otherwise return 'unknown'
|
|
119
|
+
*
|
|
120
|
+
* This order prevents base64 strings (which can contain /) from being
|
|
121
|
+
* misidentified as file paths. Base64 validation is stricter and should
|
|
122
|
+
* be checked first.
|
|
123
|
+
*
|
|
124
|
+
* @param {string} str - String to detect
|
|
125
|
+
* @returns {'base64' | 'file-path' | 'unknown'} Detected input type
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* detectImageInputType('./screenshot.png') // 'file-path'
|
|
129
|
+
* detectImageInputType('ZmFrZS1wbmctZGF0YQ==') // 'base64'
|
|
130
|
+
* detectImageInputType('data:image/png;base64,iVBOR...') // 'base64'
|
|
131
|
+
* detectImageInputType('C:\\path\\image.png') // 'file-path'
|
|
132
|
+
* detectImageInputType('invalid!!!') // 'unknown'
|
|
133
|
+
*/
|
|
134
|
+
export function detectImageInputType(str) {
|
|
135
|
+
if (typeof str !== 'string' || str.length === 0) {
|
|
136
|
+
return 'unknown';
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Check base64 FIRST - base64 strings can contain / which looks like paths
|
|
140
|
+
// Base64 validation is stricter and more deterministic
|
|
141
|
+
if (isBase64(str)) {
|
|
142
|
+
return 'base64';
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Then check file path - catch patterns that aren't valid base64
|
|
146
|
+
if (looksLikeFilePath(str)) {
|
|
147
|
+
return 'file-path';
|
|
148
|
+
}
|
|
149
|
+
return 'unknown';
|
|
150
|
+
}
|
package/docs/tdd-mode.md
CHANGED
|
@@ -7,7 +7,7 @@ TDD (Test-Driven Development) Mode enables fast local development with an intera
|
|
|
7
7
|
TDD Mode transforms your visual testing workflow with:
|
|
8
8
|
|
|
9
9
|
- **Interactive Dashboard** - Real-time visual feedback as tests run
|
|
10
|
-
- **Local Comparison** - Compares screenshots on your machine using `
|
|
10
|
+
- **Local Comparison** - Compares screenshots on your machine using `honeydiff`
|
|
11
11
|
- **Live Updates** - See comparisons instantly in the browser
|
|
12
12
|
- **Baseline Management** - Accept/reject changes directly from the UI
|
|
13
13
|
- **Fast Feedback** - No network uploads during development
|
|
@@ -90,7 +90,7 @@ TDD Mode provides two workflows:
|
|
|
90
90
|
### Single-Shot Workflow
|
|
91
91
|
|
|
92
92
|
1. **Run tests** - `vizzly tdd run "npm test"` executes once
|
|
93
|
-
2. **Compares locally** - Uses `
|
|
93
|
+
2. **Compares locally** - Uses `honeydiff` for high-performance comparison
|
|
94
94
|
3. **Generates report** - Creates HTML report with visual comparisons
|
|
95
95
|
4. **Exit with status** - Fails if differences exceed threshold
|
|
96
96
|
|
|
@@ -452,14 +452,14 @@ rm -rf .vizzly/baselines/
|
|
|
452
452
|
npx vizzly tdd run "npm test"
|
|
453
453
|
```
|
|
454
454
|
|
|
455
|
-
###
|
|
455
|
+
### Honeydiff Not Found
|
|
456
456
|
```
|
|
457
|
-
Error:
|
|
457
|
+
Error: Cannot find module '@vizzly-testing/honeydiff'
|
|
458
458
|
```
|
|
459
459
|
|
|
460
|
-
**Solution**: The
|
|
460
|
+
**Solution**: The `@vizzly-testing/honeydiff` package should be installed automatically. Try:
|
|
461
461
|
```bash
|
|
462
|
-
npm install
|
|
462
|
+
npm install @vizzly-testing/honeydiff
|
|
463
463
|
```
|
|
464
464
|
|
|
465
465
|
## Best Practices
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vizzly-testing/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Visual review platform for UI developers and designers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"visual-testing",
|
|
@@ -72,19 +72,19 @@
|
|
|
72
72
|
"format:check": "prettier --check src tests"
|
|
73
73
|
},
|
|
74
74
|
"engines": {
|
|
75
|
-
"node": ">=
|
|
75
|
+
"node": ">=22.0.0"
|
|
76
76
|
},
|
|
77
77
|
"publishConfig": {
|
|
78
78
|
"access": "public",
|
|
79
79
|
"registry": "https://registry.npmjs.org/"
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|
|
82
|
+
"@vizzly-testing/honeydiff": "^0.1.0",
|
|
82
83
|
"commander": "^14.0.0",
|
|
83
84
|
"cosmiconfig": "^9.0.0",
|
|
84
85
|
"dotenv": "^17.2.1",
|
|
85
86
|
"form-data": "^4.0.0",
|
|
86
87
|
"glob": "^11.0.3",
|
|
87
|
-
"odiff-bin": "^3.2.1",
|
|
88
88
|
"zod": "^4.1.12"
|
|
89
89
|
},
|
|
90
90
|
"devDependencies": {
|