Skip to content

Commit 16a0bb5

Browse files
committed
✨ split SDK helper contracts
Carve the SDK, client, and low-level helper contract changes into their own reviewable slice.
1 parent d093578 commit 16a0bb5

21 files changed

Lines changed: 1124 additions & 197 deletions

src/client/index.js

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -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
1819
let currentClient = null;
1920
let 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
*/
354348
export 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
*/
381375
export 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
*/
433428
export function getVizzlyInfo() {
434-
const client = getClient();
429+
let client = getClient();
435430
return {
436431
enabled: !isVizzlyDisabled(),
437432
serverUrl: getServerUrl(),

0 commit comments

Comments
 (0)