@percy/sdk-utils 1.31.14-beta.3 → 1.31.14-beta.4

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
@@ -326,6 +326,70 @@
326
326
  }
327
327
  }
328
328
 
329
+ // Returns the readiness config for a snapshot.
330
+ // Priority: per-snapshot options > global percy.config > empty object (triggers balanced default).
331
+ // SDKs obtain percy.config via the healthcheck endpoint in isPercyEnabled().
332
+ function getReadinessConfig(snapshotOptions = {}) {
333
+ 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) || {};
335
+ }
336
+
337
+ // Returns true if readiness should be skipped for this snapshot.
338
+ function isReadinessDisabled(snapshotOptions = {}) {
339
+ let config = getReadinessConfig(snapshotOptions);
340
+ return (config === null || config === void 0 ? void 0 : config.preset) === 'disabled';
341
+ }
342
+
343
+ // Returns a JavaScript code string that SDKs evaluate in the browser
344
+ // to run readiness checks BEFORE serialize.
345
+ //
346
+ // This is the READINESS-ONLY call. Serialize stays as a separate sync call.
347
+ // The two-call pattern:
348
+ // 1. await evaluate(waitForReadyScript(config)) — async, readiness
349
+ // 2. evaluate('return PercyDOM.serialize(options)') — sync, unchanged
350
+ //
351
+ // Usage:
352
+ // // Puppeteer/Playwright (page.evaluate auto-awaits):
353
+ // await page.evaluate(waitForReadyScript(config));
354
+ //
355
+ // // Selenium (executeAsyncScript with callback):
356
+ // driver.execute_async_script(waitForReadyScript(config, { callback: true }));
357
+ //
358
+ // Graceful degradation:
359
+ // - If PercyDOM.waitForReady is not available (old CLI): resolves immediately
360
+ // - If waitForReady throws: resolves immediately (catch swallows the error)
361
+ // - If readiness times out: waitForReady resolves with { timed_out: true }
362
+ //
363
+ // IMPORTANT: The output is intended for CDP / executeScript / executeAsyncScript channels.
364
+ // Do NOT inline this string into HTML — `</script>` sequences in user config would break out
365
+ // of a <script> tag. SDK authors must add HTML escaping before any HTML-inline use.
366
+ function waitForReadyScript(readinessConfig = {}, {
367
+ callback = false
368
+ } = {}) {
369
+ // U+2028 (LINE SEPARATOR) and U+2029 (PARAGRAPH SEPARATOR) are valid in JSON strings but
370
+ // were illegal in JS source string literals before ES2019. Escaping them keeps the emitted
371
+ // script source legal on older engines that may host the SDK eval.
372
+ let config = JSON.stringify(readinessConfig).replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029');
373
+ if (callback) {
374
+ // For executeAsyncScript — last argument is the callback
375
+ return `
376
+ var done = arguments[arguments.length - 1];
377
+ try {
378
+ if (typeof PercyDOM !== 'undefined' && typeof PercyDOM.waitForReady === 'function') {
379
+ PercyDOM.waitForReady(${config}).then(function(r) { done(r); }).catch(function() { done(); });
380
+ } else { done(); }
381
+ } catch(e) { done(); }
382
+ `;
383
+ }
384
+
385
+ // For page.evaluate (auto-await Promises)
386
+ return `
387
+ if (typeof PercyDOM !== 'undefined' && typeof PercyDOM.waitForReady === 'function') {
388
+ return PercyDOM.waitForReady(${config});
389
+ }
390
+ `;
391
+ }
392
+
329
393
  // Iframe depth constants shared with @percy/dom's serialize-frames. Kept
330
394
  // here so external Percy SDKs (Capybara, Cypress, Playwright, etc.) can
331
395
  // clamp their own pre-CLI configuration to the same bounds the CLI enforces.
@@ -359,6 +423,9 @@
359
423
  DEFAULT_MAX_IFRAME_DEPTH: DEFAULT_MAX_IFRAME_DEPTH,
360
424
  HARD_MAX_IFRAME_DEPTH: HARD_MAX_IFRAME_DEPTH,
361
425
  clampIframeDepth: clampIframeDepth,
426
+ waitForReadyScript: waitForReadyScript,
427
+ getReadinessConfig: getReadinessConfig,
428
+ isReadinessDisabled: isReadinessDisabled,
362
429
  'default': index
363
430
  });
364
431
 
@@ -369,8 +436,10 @@
369
436
  exports["default"] = index;
370
437
  exports.fetchPercyDOM = fetchPercyDOM;
371
438
  exports.flushSnapshots = flushSnapshots;
439
+ exports.getReadinessConfig = getReadinessConfig;
372
440
  exports.getResponsiveWidths = getResponsiveWidths;
373
441
  exports.isPercyEnabled = isPercyEnabled;
442
+ exports.isReadinessDisabled = isReadinessDisabled;
374
443
  exports.logger = logger;
375
444
  exports.percy = info;
376
445
  exports.postBuildEvents = postBuildEvents;
@@ -378,6 +447,7 @@
378
447
  exports.postSnapshot = postSnapshot;
379
448
  exports.request = request;
380
449
  exports.waitForPercyIdle = waitForPercyIdle;
450
+ exports.waitForReadyScript = waitForReadyScript;
381
451
 
382
452
  Object.defineProperty(exports, '__esModule', { value: true });
383
453
 
package/dist/index.js CHANGED
@@ -24,6 +24,12 @@ Object.defineProperty(exports, "flushSnapshots", {
24
24
  return _flushSnapshots.default;
25
25
  }
26
26
  });
27
+ Object.defineProperty(exports, "getReadinessConfig", {
28
+ enumerable: true,
29
+ get: function () {
30
+ return _serializeDom.getReadinessConfig;
31
+ }
32
+ });
27
33
  Object.defineProperty(exports, "getResponsiveWidths", {
28
34
  enumerable: true,
29
35
  get: function () {
@@ -36,6 +42,12 @@ Object.defineProperty(exports, "isPercyEnabled", {
36
42
  return _percyEnabled.default;
37
43
  }
38
44
  });
45
+ Object.defineProperty(exports, "isReadinessDisabled", {
46
+ enumerable: true,
47
+ get: function () {
48
+ return _serializeDom.isReadinessDisabled;
49
+ }
50
+ });
39
51
  Object.defineProperty(exports, "logger", {
40
52
  enumerable: true,
41
53
  get: function () {
@@ -78,6 +90,12 @@ Object.defineProperty(exports, "waitForPercyIdle", {
78
90
  return _percyIdle.default;
79
91
  }
80
92
  });
93
+ Object.defineProperty(exports, "waitForReadyScript", {
94
+ enumerable: true,
95
+ get: function () {
96
+ return _serializeDom.waitForReadyScript;
97
+ }
98
+ });
81
99
  var _logger = _interopRequireDefault(require("./logger.js"));
82
100
  var _percyInfo = _interopRequireDefault(require("./percy-info.js"));
83
101
  var _request = _interopRequireDefault(require("./request.js"));
@@ -90,6 +108,7 @@ var _postBuildEvent = _interopRequireDefault(require("./post-build-event.js"));
90
108
  var _flushSnapshots = _interopRequireDefault(require("./flush-snapshots.js"));
91
109
  var _postScreenshot = _interopRequireDefault(require("./post-screenshot.js"));
92
110
  var _getResponsiveWidths = _interopRequireDefault(require("./get-responsive-widths.js"));
111
+ var _serializeDom = require("./serialize-dom.js");
93
112
  var _default = _interopRequireWildcard(require("./index.js"));
94
113
  exports.default = _default;
95
114
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ exports.getReadinessConfig = getReadinessConfig;
8
+ exports.isReadinessDisabled = isReadinessDisabled;
9
+ exports.waitForReadyScript = waitForReadyScript;
10
+ var _percyInfo = _interopRequireDefault(require("./percy-info.js"));
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ // Returns the readiness config for a snapshot.
13
+ // Priority: per-snapshot options > global percy.config > empty object (triggers balanced default).
14
+ // SDKs obtain percy.config via the healthcheck endpoint in isPercyEnabled().
15
+ function getReadinessConfig(snapshotOptions = {}) {
16
+ 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) || {};
18
+ }
19
+
20
+ // Returns true if readiness should be skipped for this snapshot.
21
+ function isReadinessDisabled(snapshotOptions = {}) {
22
+ let config = getReadinessConfig(snapshotOptions);
23
+ return (config === null || config === void 0 ? void 0 : config.preset) === 'disabled';
24
+ }
25
+
26
+ // Returns a JavaScript code string that SDKs evaluate in the browser
27
+ // to run readiness checks BEFORE serialize.
28
+ //
29
+ // This is the READINESS-ONLY call. Serialize stays as a separate sync call.
30
+ // The two-call pattern:
31
+ // 1. await evaluate(waitForReadyScript(config)) — async, readiness
32
+ // 2. evaluate('return PercyDOM.serialize(options)') — sync, unchanged
33
+ //
34
+ // Usage:
35
+ // // Puppeteer/Playwright (page.evaluate auto-awaits):
36
+ // await page.evaluate(waitForReadyScript(config));
37
+ //
38
+ // // Selenium (executeAsyncScript with callback):
39
+ // driver.execute_async_script(waitForReadyScript(config, { callback: true }));
40
+ //
41
+ // Graceful degradation:
42
+ // - If PercyDOM.waitForReady is not available (old CLI): resolves immediately
43
+ // - If waitForReady throws: resolves immediately (catch swallows the error)
44
+ // - If readiness times out: waitForReady resolves with { timed_out: true }
45
+ //
46
+ // IMPORTANT: The output is intended for CDP / executeScript / executeAsyncScript channels.
47
+ // Do NOT inline this string into HTML — `</script>` sequences in user config would break out
48
+ // of a <script> tag. SDK authors must add HTML escaping before any HTML-inline use.
49
+ function waitForReadyScript(readinessConfig = {}, {
50
+ callback = false
51
+ } = {}) {
52
+ // U+2028 (LINE SEPARATOR) and U+2029 (PARAGRAPH SEPARATOR) are valid in JSON strings but
53
+ // were illegal in JS source string literals before ES2019. Escaping them keeps the emitted
54
+ // script source legal on older engines that may host the SDK eval.
55
+ let config = JSON.stringify(readinessConfig).replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029');
56
+ if (callback) {
57
+ // For executeAsyncScript — last argument is the callback
58
+ return `
59
+ var done = arguments[arguments.length - 1];
60
+ try {
61
+ if (typeof PercyDOM !== 'undefined' && typeof PercyDOM.waitForReady === 'function') {
62
+ PercyDOM.waitForReady(${config}).then(function(r) { done(r); }).catch(function() { done(); });
63
+ } else { done(); }
64
+ } catch(e) { done(); }
65
+ `;
66
+ }
67
+
68
+ // For page.evaluate (auto-await Promises)
69
+ return `
70
+ if (typeof PercyDOM !== 'undefined' && typeof PercyDOM.waitForReady === 'function') {
71
+ return PercyDOM.waitForReady(${config});
72
+ }
73
+ `;
74
+ }
75
+ 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.14-beta.3",
3
+ "version": "1.31.14-beta.4",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -54,5 +54,5 @@
54
54
  "dependencies": {
55
55
  "pac-proxy-agent": "^7.0.2"
56
56
  },
57
- "gitHead": "a17d4a1453c6bef282fd3da38082b670e125a5be"
57
+ "gitHead": "b52f1d2fb6272c0b3694e1e9ff584c5622a118c7"
58
58
  }