@percy/sdk-utils 1.31.15-alpha.0 → 1.31.15-beta.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/dist/bundle.js CHANGED
@@ -327,11 +327,21 @@
327
327
  }
328
328
 
329
329
  // Returns the readiness config for a snapshot.
330
- // Priority: per-snapshot options > global percy.config > empty object (triggers balanced default).
330
+ // Shallow-merge of global .percy.yml config with per-snapshot overrides:
331
+ // per-snapshot keys win, unspecified keys are inherited from the global config.
331
332
  // SDKs obtain percy.config via the healthcheck endpoint in isPercyEnabled().
333
+ //
334
+ // Why shallow-merge instead of `||`:
335
+ // - `options.readiness = {}` would otherwise wipe the global config entirely.
336
+ // - A partial per-snapshot override like `{ stabilityWindowMs: 500 }` would
337
+ // drop a global `preset: disabled` kill switch — silently re-enabling the
338
+ // gate for a snapshot the user thought was opted out.
332
339
  function getReadinessConfig(snapshotOptions = {}) {
333
340
  var _percy$config;
334
- return (snapshotOptions === null || snapshotOptions === void 0 ? void 0 : snapshotOptions.readiness) || ((_percy$config = info.config) === null || _percy$config === void 0 || (_percy$config = _percy$config.snapshot) === null || _percy$config === void 0 ? void 0 : _percy$config.readiness) || {};
341
+ return {
342
+ ...(((_percy$config = info.config) === null || _percy$config === void 0 || (_percy$config = _percy$config.snapshot) === null || _percy$config === void 0 ? void 0 : _percy$config.readiness) || {}),
343
+ ...((snapshotOptions === null || snapshotOptions === void 0 ? void 0 : snapshotOptions.readiness) || {})
344
+ };
335
345
  }
336
346
 
337
347
  // Returns true if readiness should be skipped for this snapshot.
@@ -390,6 +400,54 @@
390
400
  `;
391
401
  }
392
402
 
403
+ // Runs the readiness gate end-to-end so every JS SDK collapses to a single
404
+ // call. The SDK's only responsibility is to provide an `evalScript` callback
405
+ // that ships the script string to the browser via its driver's evaluator
406
+ // (page.evaluate, driver.executeAsyncScript, b.executeAsync, etc.).
407
+ //
408
+ // Centralised here:
409
+ // - isReadinessDisabled kill-switch check
410
+ // - getReadinessConfig shallow-merge of global + per-snapshot config
411
+ // - waitForReadyScript script generation (callback or promise mode)
412
+ // - try/catch with debug logging — serialize is never blocked
413
+ //
414
+ // Returns: the diagnostics object from PercyDOM.waitForReady, or null
415
+ // when readiness is disabled / unavailable / failed. The caller attaches
416
+ // the non-null result to domSnapshot.readiness_diagnostics.
417
+ //
418
+ // Usage:
419
+ // // Puppeteer/Playwright (promise-mode):
420
+ // const diag = await utils.runReadinessGate(
421
+ // (script) => page.evaluate(script),
422
+ // options,
423
+ // { log }
424
+ // );
425
+ //
426
+ // // Selenium-js / WebdriverIO / Nightwatch (callback-mode):
427
+ // const diag = await utils.runReadinessGate(
428
+ // (script) => driver.executeAsyncScript(script),
429
+ // options,
430
+ // { callback: true, log }
431
+ // );
432
+ async function runReadinessGate(evalScript, snapshotOptions = {}, {
433
+ callback = false,
434
+ log
435
+ } = {}) {
436
+ if (isReadinessDisabled(snapshotOptions)) return null;
437
+ const config = getReadinessConfig(snapshotOptions);
438
+ const script = waitForReadyScript(config, {
439
+ callback
440
+ });
441
+ try {
442
+ return await evalScript(script);
443
+ } catch (err) {
444
+ if (log && typeof log.debug === 'function') {
445
+ log.debug(`waitForReady failed, proceeding to serialize: ${(err === null || err === void 0 ? void 0 : err.message) || err}`);
446
+ }
447
+ return null;
448
+ }
449
+ }
450
+
393
451
  // Iframe depth constants shared with @percy/dom's serialize-frames. Kept
394
452
  // here so external Percy SDKs (Capybara, Cypress, Playwright, etc.) can
395
453
  // clamp their own pre-CLI configuration to the same bounds the CLI enforces.
@@ -426,6 +484,7 @@
426
484
  waitForReadyScript: waitForReadyScript,
427
485
  getReadinessConfig: getReadinessConfig,
428
486
  isReadinessDisabled: isReadinessDisabled,
487
+ runReadinessGate: runReadinessGate,
429
488
  'default': index
430
489
  });
431
490
 
@@ -446,6 +505,7 @@
446
505
  exports.postComparison = postComparison;
447
506
  exports.postSnapshot = postSnapshot;
448
507
  exports.request = request;
508
+ exports.runReadinessGate = runReadinessGate;
449
509
  exports.waitForPercyIdle = waitForPercyIdle;
450
510
  exports.waitForReadyScript = waitForReadyScript;
451
511
 
package/dist/index.js CHANGED
@@ -84,6 +84,12 @@ Object.defineProperty(exports, "request", {
84
84
  return _request.default;
85
85
  }
86
86
  });
87
+ Object.defineProperty(exports, "runReadinessGate", {
88
+ enumerable: true,
89
+ get: function () {
90
+ return _serializeDom.runReadinessGate;
91
+ }
92
+ });
87
93
  Object.defineProperty(exports, "waitForPercyIdle", {
88
94
  enumerable: true,
89
95
  get: function () {
@@ -6,15 +6,26 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  exports.getReadinessConfig = getReadinessConfig;
8
8
  exports.isReadinessDisabled = isReadinessDisabled;
9
+ exports.runReadinessGate = runReadinessGate;
9
10
  exports.waitForReadyScript = waitForReadyScript;
10
11
  var _percyInfo = _interopRequireDefault(require("./percy-info.js"));
11
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
13
  // Returns the readiness config for a snapshot.
13
- // Priority: per-snapshot options > global percy.config > empty object (triggers balanced default).
14
+ // Shallow-merge of global .percy.yml config with per-snapshot overrides:
15
+ // per-snapshot keys win, unspecified keys are inherited from the global config.
14
16
  // SDKs obtain percy.config via the healthcheck endpoint in isPercyEnabled().
17
+ //
18
+ // Why shallow-merge instead of `||`:
19
+ // - `options.readiness = {}` would otherwise wipe the global config entirely.
20
+ // - A partial per-snapshot override like `{ stabilityWindowMs: 500 }` would
21
+ // drop a global `preset: disabled` kill switch — silently re-enabling the
22
+ // gate for a snapshot the user thought was opted out.
15
23
  function getReadinessConfig(snapshotOptions = {}) {
16
24
  var _percy$config;
17
- return (snapshotOptions === null || snapshotOptions === void 0 ? void 0 : snapshotOptions.readiness) || ((_percy$config = _percyInfo.default.config) === null || _percy$config === void 0 || (_percy$config = _percy$config.snapshot) === null || _percy$config === void 0 ? void 0 : _percy$config.readiness) || {};
25
+ return {
26
+ ...(((_percy$config = _percyInfo.default.config) === null || _percy$config === void 0 || (_percy$config = _percy$config.snapshot) === null || _percy$config === void 0 ? void 0 : _percy$config.readiness) || {}),
27
+ ...((snapshotOptions === null || snapshotOptions === void 0 ? void 0 : snapshotOptions.readiness) || {})
28
+ };
18
29
  }
19
30
 
20
31
  // Returns true if readiness should be skipped for this snapshot.
@@ -72,4 +83,52 @@ function waitForReadyScript(readinessConfig = {}, {
72
83
  }
73
84
  `;
74
85
  }
86
+
87
+ // Runs the readiness gate end-to-end so every JS SDK collapses to a single
88
+ // call. The SDK's only responsibility is to provide an `evalScript` callback
89
+ // that ships the script string to the browser via its driver's evaluator
90
+ // (page.evaluate, driver.executeAsyncScript, b.executeAsync, etc.).
91
+ //
92
+ // Centralised here:
93
+ // - isReadinessDisabled kill-switch check
94
+ // - getReadinessConfig shallow-merge of global + per-snapshot config
95
+ // - waitForReadyScript script generation (callback or promise mode)
96
+ // - try/catch with debug logging — serialize is never blocked
97
+ //
98
+ // Returns: the diagnostics object from PercyDOM.waitForReady, or null
99
+ // when readiness is disabled / unavailable / failed. The caller attaches
100
+ // the non-null result to domSnapshot.readiness_diagnostics.
101
+ //
102
+ // Usage:
103
+ // // Puppeteer/Playwright (promise-mode):
104
+ // const diag = await utils.runReadinessGate(
105
+ // (script) => page.evaluate(script),
106
+ // options,
107
+ // { log }
108
+ // );
109
+ //
110
+ // // Selenium-js / WebdriverIO / Nightwatch (callback-mode):
111
+ // const diag = await utils.runReadinessGate(
112
+ // (script) => driver.executeAsyncScript(script),
113
+ // options,
114
+ // { callback: true, log }
115
+ // );
116
+ async function runReadinessGate(evalScript, snapshotOptions = {}, {
117
+ callback = false,
118
+ log
119
+ } = {}) {
120
+ if (isReadinessDisabled(snapshotOptions)) return null;
121
+ const config = getReadinessConfig(snapshotOptions);
122
+ const script = waitForReadyScript(config, {
123
+ callback
124
+ });
125
+ try {
126
+ return await evalScript(script);
127
+ } catch (err) {
128
+ if (log && typeof log.debug === 'function') {
129
+ log.debug(`waitForReady failed, proceeding to serialize: ${(err === null || err === void 0 ? void 0 : err.message) || err}`);
130
+ }
131
+ return null;
132
+ }
133
+ }
75
134
  var _default = exports.default = waitForReadyScript;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@percy/sdk-utils",
3
- "version": "1.31.15-alpha.0",
3
+ "version": "1.31.15-beta.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -9,7 +9,7 @@
9
9
  },
10
10
  "publishConfig": {
11
11
  "access": "public",
12
- "tag": "alpha"
12
+ "tag": "beta"
13
13
  },
14
14
  "engines": {
15
15
  "node": ">=14"
@@ -54,5 +54,5 @@
54
54
  "dependencies": {
55
55
  "pac-proxy-agent": "^7.0.2"
56
56
  },
57
- "gitHead": "726ab78fcd37479a0904996a88400a0b6626daac"
57
+ "gitHead": "b2012ce5dae37e5009dd3f4190454bb9d9d118e3"
58
58
  }