@@ -13,16 +13,17 @@ import {
1313 isTddMode ,
1414 setVizzlyEnabled ,
1515} from '../utils/environment-config.js' ;
16+ import { createScreenshotProperties } from '../utils/screenshot-options.js' ;
1617
1718// Internal client state
1819let currentClient = null ;
1920let isDisabled = false ;
2021
2122// Default timeout for screenshot requests (30 seconds)
22- const DEFAULT_TIMEOUT_MS = 30000 ;
23+ let DEFAULT_TIMEOUT_MS = 30000 ;
2324
2425// Log levels for client SDK output control
25- export const LOG_LEVELS = { debug : 0 , info : 1 , warn : 2 , error : 3 } ;
26+ export let LOG_LEVELS = { debug : 0 , info : 1 , warn : 2 , error : 3 } ;
2627
2728/**
2829 * Check if client should log at the given level
@@ -71,16 +72,16 @@ export function autoDiscoverTddServer(startDir, deps = {}) {
7172 try {
7273 // Look for .vizzly/server.json in current directory and parent directories
7374 let currentDir = startDir || process . cwd ( ) ;
74- const root = parse ( currentDir ) . root ;
75+ let root = parse ( currentDir ) . root ;
7576
7677 while ( currentDir !== root ) {
77- const serverJsonPath = join ( currentDir , '.vizzly' , 'server.json' ) ;
78+ let serverJsonPath = join ( currentDir , '.vizzly' , 'server.json' ) ;
7879
7980 if ( exists ( serverJsonPath ) ) {
8081 try {
81- const serverInfo = JSON . parse ( readFile ( serverJsonPath , 'utf8' ) ) ;
82+ let serverInfo = JSON . parse ( readFile ( serverJsonPath , 'utf8' ) ) ;
8283 if ( serverInfo . port ) {
83- const url = `http://localhost:${ serverInfo . port } ` ;
84+ let url = `http://localhost:${ serverInfo . port } ` ;
8485 return url ;
8586 }
8687 } catch {
@@ -199,23 +200,17 @@ function createSimpleClient(serverUrl) {
199200 let image = isFilePath ? imageBuffer : imageBuffer . toString ( 'base64' ) ;
200201 let type = isFilePath ? 'file-path' : 'base64' ;
201202
202- let {
203- fullPage,
204- threshold,
205- properties : userProperties ,
206- ...rest
207- } = options ;
203+ let properties = createScreenshotProperties ( options ) ;
208204
209205 let httpStart = Date . now ( ) ;
210- const { status, json } = await httpPost (
206+ let { status, json } = await httpPost (
211207 `${ serverUrl } /screenshot` ,
212208 {
213209 buildId : getBuildId ( ) ,
214210 name,
215211 image,
216212 type,
217- properties : { ...rest , ...userProperties } ,
218- fullPage : fullPage || false ,
213+ properties,
219214 } ,
220215 DEFAULT_TIMEOUT_MS
221216 ) ;
@@ -321,10 +316,11 @@ function createSimpleClient(serverUrl) {
321316 * @param {Buffer|string } imageBuffer - PNG image data as a Buffer, or a file path to an image
322317 * @param {Object } [options] - Optional configuration
323318 * @param {Record<string, any> } [options.properties] - Additional properties to attach to the screenshot
324- * @param {number } [options.threshold=0] - Pixel difference threshold (0-100)
325- * @param {boolean } [options.fullPage=false] - Whether this is a full page screenshot
319+ * @param {number } [options.threshold] - CIEDE2000 Delta E threshold for this screenshot
320+ * @param {number } [options.minClusterSize] - Minimum changed cluster size for this screenshot
321+ * @param {boolean } [options.fullPage] - Whether this is a full page screenshot
326322 *
327- * @returns {Promise<void> }
323+ * @returns {Promise<Object|null> } Screenshot result from the server, or null when capture is skipped
328324 *
329325 * @example
330326 * // Basic usage with Buffer
@@ -347,20 +343,18 @@ function createSimpleClient(serverUrl) {
347343 * threshold: 5
348344 * });
349345 *
350- * @throws {VizzlyError } When screenshot capture fails or client is not initialized
351- * @throws {VizzlyError } When file path is provided but file doesn't exist
352- * @throws {VizzlyError } When file cannot be read due to permissions or I/O errors
346+ * Capture failures are logged and return null so test suites can continue.
353347 */
354348export async function vizzlyScreenshot ( name , imageBuffer , options = { } ) {
355349 if ( isVizzlyDisabled ( ) ) {
356- return ; // Silently skip when disabled
350+ return null ; // Silently skip when disabled
357351 }
358352
359353 let client = getClient ( ) ;
360354 if ( ! client ) {
361355 // Silently disable - no server running, nothing to do
362356 disableVizzly ( ) ;
363- return ;
357+ return null ;
364358 }
365359
366360 // Pass through the original value (Buffer or file path)
@@ -371,18 +365,19 @@ export async function vizzlyScreenshot(name, imageBuffer, options = {}) {
371365/**
372366 * Wait for all queued screenshots to be processed
373367 *
374- * @returns {Promise<void> }
368+ * @returns {Promise<Object|null> } Flush summary, or null if no server is connected
375369 *
376370 * @example
377371 * afterAll(async () => {
378372 * await vizzlyFlush();
379373 * });
380374 */
381375export async function vizzlyFlush ( ) {
382- const client = getClient ( ) ;
376+ let client = getClient ( ) ;
383377 if ( client ) {
384378 return client . flush ( ) ;
385379 }
380+ return null ;
386381}
387382
388383/**
@@ -431,7 +426,7 @@ export function setEnabled(enabled) {
431426 * @returns {Object } Client information
432427 */
433428export function getVizzlyInfo ( ) {
434- const client = getClient ( ) ;
429+ let client = getClient ( ) ;
435430 return {
436431 enabled : ! isVizzlyDisabled ( ) ,
437432 serverUrl : getServerUrl ( ) ,
0 commit comments