@applitools/core 4.63.1 → 4.64.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/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.64.0](https://github.com/Applitools-Dev/sdk/compare/js/core@4.63.1...js/core@4.64.0) (2026-06-04)
4
+
5
+
6
+ ### Features
7
+
8
+ * auto-accept UFG diffs from infra updates | AD-9583 ([#3797](https://github.com/Applitools-Dev/sdk/issues/3797)) ([fde553c](https://github.com/Applitools-Dev/sdk/commit/fde553c947aa3c040660ef5d07855fa4a1412399))
9
+ * support default match level from renderinfo | AD-13499 ([#3799](https://github.com/Applitools-Dev/sdk/issues/3799)) ([c7e8aeb](https://github.com/Applitools-Dev/sdk/commit/c7e8aeb3f231d9b4e6e368d7ae5f87115c5cad09))
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * source hideCaret from settings.hideCaret in NML classic capture | AD-14053 ([#3878](https://github.com/Applitools-Dev/sdk/issues/3878)) ([f07b4f5](https://github.com/Applitools-Dev/sdk/commit/f07b4f5c90bb9b7de0300cef93f23dc833268a7c))
15
+
16
+
17
+ ### Dependencies
18
+
19
+ * @applitools/nml-client bumped to 1.11.29
20
+
21
+ * @applitools/core-base bumped to 1.35.0
22
+ #### Features
23
+
24
+ * auto-accept UFG diffs from infra updates | AD-9583 ([#3797](https://github.com/Applitools-Dev/sdk/issues/3797)) ([fde553c](https://github.com/Applitools-Dev/sdk/commit/fde553c947aa3c040660ef5d07855fa4a1412399))
25
+ * @applitools/ec-client bumped to 1.12.31
26
+
27
+
3
28
  ## [4.63.1](https://github.com/Applitools-Dev/sdk/compare/js/core@4.63.0...js/core@4.63.1) (2026-05-26)
4
29
 
5
30
 
package/dist/check.js CHANGED
@@ -35,8 +35,8 @@ const chalk_1 = __importDefault(require("chalk"));
35
35
  function makeCheck({ type: defaultType = 'classic', eyes, target: defaultTarget, spec, logger: mainLogger, }) {
36
36
  let stepIndex = 0;
37
37
  return async function check({ type = defaultType, target = defaultTarget, settings, config, logger = mainLogger, } = {}) {
38
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
39
- var _s, _t, _u, _v, _w;
38
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
39
+ var _t, _u, _v, _w, _x;
40
40
  logger = logger.extend(mainLogger, { tags: [`check-${type}-${utils.general.shortid()}`] });
41
41
  settings = { ...config === null || config === void 0 ? void 0 : config.screenshot, ...config === null || config === void 0 ? void 0 : config.check, ...settings };
42
42
  (_a = settings.fully) !== null && _a !== void 0 ? _a : (settings.fully = !settings.region && (!settings.frames || settings.frames.length === 0));
@@ -44,9 +44,9 @@ function makeCheck({ type: defaultType = 'classic', eyes, target: defaultTarget,
44
44
  (_c = settings.hideScrollbars) !== null && _c !== void 0 ? _c : (settings.hideScrollbars = true);
45
45
  (_d = settings.hideCaret) !== null && _d !== void 0 ? _d : (settings.hideCaret = true);
46
46
  settings.overlap = { top: 10, bottom: 50, ...settings === null || settings === void 0 ? void 0 : settings.overlap };
47
- (_e = settings.matchLevel) !== null && _e !== void 0 ? _e : (settings.matchLevel = 'Strict');
48
- (_f = settings.ignoreCaret) !== null && _f !== void 0 ? _f : (settings.ignoreCaret = true);
49
- (_g = settings.sendDom) !== null && _g !== void 0 ? _g : (settings.sendDom = eyes.test.account.rcaEnabled ||
47
+ (_e = settings.matchLevel) !== null && _e !== void 0 ? _e : (settings.matchLevel = (_f = eyes.test.account.defaultMatchLevel) !== null && _f !== void 0 ? _f : 'Strict');
48
+ (_g = settings.ignoreCaret) !== null && _g !== void 0 ? _g : (settings.ignoreCaret = true);
49
+ (_h = settings.sendDom) !== null && _h !== void 0 ? _h : (settings.sendDom = eyes.test.account.rcaEnabled ||
50
50
  settings.matchLevel === 'Layout' ||
51
51
  settings.matchLevel === 'Dynamic' ||
52
52
  settings.enablePatterns ||
@@ -54,26 +54,27 @@ function makeCheck({ type: defaultType = 'classic', eyes, target: defaultTarget,
54
54
  !utils.types.isEmpty(settings.dynamicRegions) ||
55
55
  !utils.types.isEmpty(settings.layoutRegions) ||
56
56
  !utils.types.isEmpty(settings.accessibilitySettings));
57
- (_h = settings.autProxy) !== null && _h !== void 0 ? _h : (settings.autProxy = eyes.test.eyesServer.proxy);
58
- (_j = settings.useDom) !== null && _j !== void 0 ? _j : (settings.useDom = false);
59
- (_k = (_s = settings).matchTimeout) !== null && _k !== void 0 ? _k : (_s.matchTimeout = 0);
57
+ (_j = settings.autProxy) !== null && _j !== void 0 ? _j : (settings.autProxy = eyes.test.eyesServer.proxy);
58
+ (_k = settings.useDom) !== null && _k !== void 0 ? _k : (settings.useDom = settings.sendDom // if we send the dom, it just makes sense to use it (unless the user turned it off)
59
+ );
60
+ (_l = (_t = settings).matchTimeout) !== null && _l !== void 0 ? _l : (_t.matchTimeout = 0);
60
61
  settings.lazyLoad = settings.lazyLoad === true ? {} : settings.lazyLoad;
61
62
  if (settings.lazyLoad) {
62
- (_l = (_t = settings.lazyLoad).scrollLength) !== null && _l !== void 0 ? _l : (_t.scrollLength = defaults_1.DEFAULT_LAZY_LOAD.scrollLength);
63
- (_m = (_u = settings.lazyLoad).waitingTime) !== null && _m !== void 0 ? _m : (_u.waitingTime = defaults_1.DEFAULT_LAZY_LOAD.waitingTime);
64
- (_o = (_v = settings.lazyLoad).maxAmountToScroll) !== null && _o !== void 0 ? _o : (_v.maxAmountToScroll = defaults_1.DEFAULT_LAZY_LOAD.maxAmountToScroll);
63
+ (_m = (_u = settings.lazyLoad).scrollLength) !== null && _m !== void 0 ? _m : (_u.scrollLength = defaults_1.DEFAULT_LAZY_LOAD.scrollLength);
64
+ (_o = (_v = settings.lazyLoad).waitingTime) !== null && _o !== void 0 ? _o : (_v.waitingTime = defaults_1.DEFAULT_LAZY_LOAD.waitingTime);
65
+ (_p = (_w = settings.lazyLoad).maxAmountToScroll) !== null && _p !== void 0 ? _p : (_w.maxAmountToScroll = defaults_1.DEFAULT_LAZY_LOAD.maxAmountToScroll);
65
66
  }
66
67
  settings.stepIndex = stepIndex++;
67
- (_p = settings.waitBetweenStitches) !== null && _p !== void 0 ? _p : (settings.waitBetweenStitches = utils.types.isObject(settings.lazyLoad)
68
+ (_q = settings.waitBetweenStitches) !== null && _q !== void 0 ? _q : (settings.waitBetweenStitches = utils.types.isObject(settings.lazyLoad)
68
69
  ? settings.lazyLoad.waitingTime
69
70
  : defaults_1.DEFAULT_WAIT_BEFORE_CAPTURE);
70
71
  if (settings.mobileOptions) {
71
- (_q = (_w = settings.mobileOptions).keepNavigationBar) !== null && _q !== void 0 ? _q : (_w.keepNavigationBar = false);
72
+ (_r = (_x = settings.mobileOptions).keepNavigationBar) !== null && _r !== void 0 ? _r : (_x.keepNavigationBar = false);
72
73
  }
73
74
  if (settings.matchLevel === 'Content') {
74
75
  logger.console.log(chalk_1.default.yellow(lang.matchLevelContentDeprecatedWarning));
75
76
  }
76
- if ((_r = settings.usedDeprecations) === null || _r === void 0 ? void 0 : _r.length) {
77
+ if ((_s = settings.usedDeprecations) === null || _s === void 0 ? void 0 : _s.length) {
77
78
  void eyes.core.logEvent({
78
79
  settings: {
79
80
  ...eyes.test.eyesServer,
@@ -136,7 +136,7 @@ function makeCheckAndClose({ eyes, target: defaultTarget, environments: defaultE
136
136
  fully: settings.fully,
137
137
  stitchMode: settings.stitchMode,
138
138
  hideScrollbars: settings.hideScrollbars,
139
- hideCaret: settings.hideScrollbars,
139
+ hideCaret: settings.hideCaret,
140
140
  overlap: settings.overlap,
141
141
  waitBeforeCapture: settings.waitBeforeCapture,
142
142
  waitBetweenStitches: settings.waitBetweenStitches,
@@ -347,7 +347,7 @@ async function takeNMLScreenshot({ driver, settings, environments, logger, eyes,
347
347
  fully: settings.fully,
348
348
  stitchMode: settings.stitchMode,
349
349
  hideScrollbars: settings.hideScrollbars,
350
- hideCaret: settings.hideScrollbars,
350
+ hideCaret: settings.hideCaret,
351
351
  overlap: settings.overlap,
352
352
  waitBeforeCapture: settings.waitBeforeCapture,
353
353
  waitBetweenStitches: settings.waitBetweenStitches,
package/dist/ufg/check.js CHANGED
@@ -37,6 +37,7 @@ const chalk_1 = __importDefault(require("chalk"));
37
37
  const take_snapshots_1 = require("./take-snapshots");
38
38
  const create_render_target_from_snapshot_1 = require("./create-render-target-from-snapshot");
39
39
  const to_base_check_settings_1 = require("../automation/utils/to-base-check-settings");
40
+ const to_old_infra_environment_1 = require("./to-old-infra-environment");
40
41
  function makeCheck({ eyes, target: defaultTarget, environments: defaultEnvironments = [], spec, signal, logger: mainLogger, }) {
41
42
  return async function check({ target = defaultTarget, settings = {}, logger = mainLogger, } = {}) {
42
43
  var _a;
@@ -73,7 +74,7 @@ function makeCheck({ eyes, target: defaultTarget, environments: defaultEnvironme
73
74
  snapshots = !utils.types.isArray(target) ? Array(uniqueEnvironments.length).fill(target) : target;
74
75
  }
75
76
  const promises = snapshots.map(async (snapshot, i) => {
76
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
77
+ var _a, _b, _c, _d, _e, _f, _g, _h;
77
78
  const environmentLogger = logger.extend({ tags: [`environment-${utils.general.shortid()}`] });
78
79
  const { target } = snapshot;
79
80
  const environment = uniqueEnvironments[i];
@@ -116,39 +117,44 @@ function makeCheck({ eyes, target: defaultTarget, environments: defaultEnvironme
116
117
  const { elementReferences: selectors, getBaseCheckSettings } = (0, to_base_check_settings_1.toBaseCheckSettings)({
117
118
  settings: snapshot.settings,
118
119
  });
119
- const { renderId, selectorRegions, ...baseTarget } = await ufgClient.render({
120
- target: renderTarget,
121
- settings: {
122
- ...snapshot.settings,
123
- region: (_e = selectors.target) !== null && _e !== void 0 ? _e : snapshot.settings.region,
124
- scrollRootElement: selectors.scrolling,
125
- selectorsToCalculate: selectors.calculate,
126
- includeFullPageSize: Boolean(snapshot.settings.pageId),
127
- environment: { ...environment, environmentId: baseEyes.test.environment.environmentId },
128
- uploadUrl: baseEyes.test.uploadUrl,
129
- stitchingServiceUrl: baseEyes.test.stitchingServiceUrl,
130
- },
131
- signal,
132
- logger: environmentLogger,
133
- });
134
- const baseSettings = getBaseCheckSettings({
135
- calculatedRegions: selectors.calculate.map((_, index) => {
136
- var _a;
137
- return ({
138
- regions: (_a = selectorRegions === null || selectorRegions === void 0 ? void 0 : selectorRegions[index]) !== null && _a !== void 0 ? _a : [],
139
- });
140
- }),
141
- });
142
- baseSettings.renderId = renderId;
143
- baseTarget.source = snapshot.url;
144
- baseTarget.name = snapshot.title;
120
+ const renderForCheck = async (env) => {
121
+ var _a;
122
+ const { renderId, selectorRegions, ...target } = await ufgClient.render({
123
+ target: renderTarget,
124
+ settings: {
125
+ ...snapshot.settings,
126
+ region: (_a = selectors.target) !== null && _a !== void 0 ? _a : snapshot.settings.region,
127
+ scrollRootElement: selectors.scrolling,
128
+ selectorsToCalculate: selectors.calculate,
129
+ includeFullPageSize: Boolean(snapshot.settings.pageId),
130
+ environment: { ...env, environmentId: baseEyes.test.environment.environmentId },
131
+ uploadUrl: baseEyes.test.uploadUrl,
132
+ stitchingServiceUrl: baseEyes.test.stitchingServiceUrl,
133
+ },
134
+ signal,
135
+ logger: environmentLogger,
136
+ });
137
+ const checkSettings = getBaseCheckSettings({
138
+ calculatedRegions: selectors.calculate.map((_, index) => {
139
+ var _a;
140
+ return ({
141
+ regions: (_a = selectorRegions === null || selectorRegions === void 0 ? void 0 : selectorRegions[index]) !== null && _a !== void 0 ? _a : [],
142
+ });
143
+ }),
144
+ });
145
+ checkSettings.renderId = renderId;
146
+ target.source = snapshot.url;
147
+ target.name = snapshot.title;
148
+ return { target, settings: checkSettings };
149
+ };
150
+ const { target: baseTarget, settings: baseSettings } = await renderForCheck(environment);
145
151
  if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
146
152
  environmentLogger.warn('Command "check" was aborted after rendering');
147
153
  throw new abort_error_1.AbortError('Command "check" was aborted after rendering');
148
154
  }
149
155
  else if (!baseEyes.running) {
150
- environmentLogger.warn(`Render on environment with id "${(_f = baseEyes.test.environment) === null || _f === void 0 ? void 0 : _f.environmentId}" was aborted during one of the previous steps`);
151
- throw new abort_error_1.AbortError(`Render on environment with id "${(_g = baseEyes.test.environment) === null || _g === void 0 ? void 0 : _g.environmentId}" was aborted during one of the previous steps`);
156
+ environmentLogger.warn(`Render on environment with id "${(_e = baseEyes.test.environment) === null || _e === void 0 ? void 0 : _e.environmentId}" was aborted during one of the previous steps`);
157
+ throw new abort_error_1.AbortError(`Render on environment with id "${(_f = baseEyes.test.environment) === null || _f === void 0 ? void 0 : _f.environmentId}" was aborted during one of the previous steps`);
152
158
  }
153
159
  if (settings.assumesMutability) {
154
160
  void eyes.core.logEvent({
@@ -166,7 +172,7 @@ function makeCheck({ eyes, target: defaultTarget, environments: defaultEnvironme
166
172
  userTestId: baseEyes.test.userTestId,
167
173
  appId: baseEyes.test.appId,
168
174
  baselineId: baseEyes.test.baselineId,
169
- environmentId: (_h = baseEyes.test.environment) === null || _h === void 0 ? void 0 : _h.environmentId,
175
+ environmentId: (_g = baseEyes.test.environment) === null || _g === void 0 ? void 0 : _g.environmentId,
170
176
  },
171
177
  isNew: baseEyes.test.isNew,
172
178
  resultsUrl: baseEyes.test.resultsUrl,
@@ -182,14 +188,35 @@ function makeCheck({ eyes, target: defaultTarget, environments: defaultEnvironme
182
188
  catch (err) {
183
189
  logger.log('Failed to log invalid check settings', err);
184
190
  }
185
- await baseEyes.check({
191
+ const checkResult = await baseEyes.check({
186
192
  target: { ...baseTarget, isTransformed: true },
187
193
  settings: baseSettings,
188
194
  logger: environmentLogger,
189
195
  });
196
+ if (!checkResult.asExpected && baseEyes.test.shouldRetryWithOldInfra) {
197
+ const oldInfraEnvironment = (0, to_old_infra_environment_1.toOldInfraEnvironment)(environment);
198
+ if (oldInfraEnvironment) {
199
+ // Best-effort: the retry adds an extra render + check, and a transient
200
+ // failure there (old browser version unavailable, render timeout, 5xx)
201
+ // must not abort the environment — the primary check already recorded
202
+ // its step. Swallow and log so the retry can only ever help.
203
+ try {
204
+ const { target, settings } = await renderForCheck(oldInfraEnvironment);
205
+ settings.oldInfraRetry = true;
206
+ await baseEyes.check({
207
+ target: { ...target, isTransformed: true },
208
+ settings,
209
+ logger: environmentLogger,
210
+ });
211
+ }
212
+ catch (error) {
213
+ environmentLogger.warn('Old-infra retry failed; keeping the primary check result', error);
214
+ }
215
+ }
216
+ }
190
217
  }
191
218
  catch (error) {
192
- environmentLogger.error(`Render on environment with id "${(_j = baseEyes.test.environment) === null || _j === void 0 ? void 0 : _j.environmentId}" failed due to an error`, error);
219
+ environmentLogger.error(`Render on environment with id "${(_h = baseEyes.test.environment) === null || _h === void 0 ? void 0 : _h.environmentId}" failed due to an error`, error);
193
220
  if (baseEyes.running && !(signal === null || signal === void 0 ? void 0 : signal.aborted))
194
221
  await baseEyes.abort({ logger: environmentLogger, settings: { reason: error } });
195
222
  }
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toOldInfraEnvironment = void 0;
4
+ const latestToOneBack = {
5
+ chrome: 'chrome-one-version-back',
6
+ firefox: 'firefox-one-version-back',
7
+ safari: 'safari-one-version-back',
8
+ edgechromium: 'edgechromium-one-version-back',
9
+ };
10
+ /**
11
+ * Returns the same UFG environment retargeted at the previous browser/OS version,
12
+ * or `null` if the input is not at a latest-alias environment (already one-version-back,
13
+ * pinned to a specific version, or an unsupported browser).
14
+ */
15
+ function toOldInfraEnvironment(env) {
16
+ if (!isLatest(env))
17
+ return null;
18
+ if ('iosDeviceInfo' in env)
19
+ return { ...env, iosDeviceInfo: { ...env.iosDeviceInfo, version: 'latest-1' } };
20
+ if ('androidDeviceInfo' in env)
21
+ return { ...env, androidDeviceInfo: { ...env.androidDeviceInfo, version: 'latest-1' } };
22
+ if ('chromeEmulationInfo' in env)
23
+ return { ...env, name: 'chrome-one-version-back' };
24
+ return { ...env, name: latestToOneBack[env.name] };
25
+ }
26
+ exports.toOldInfraEnvironment = toOldInfraEnvironment;
27
+ function isLatest(env) {
28
+ if ('iosDeviceInfo' in env)
29
+ return env.iosDeviceInfo.version !== 'latest-1';
30
+ if ('androidDeviceInfo' in env)
31
+ return env.androidDeviceInfo.version !== 'latest-1';
32
+ if ('chromeEmulationInfo' in env)
33
+ return !env.name || env.name === 'chrome';
34
+ return !!env.name && env.name in latestToOneBack;
35
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applitools/core",
3
- "version": "4.63.1",
3
+ "version": "4.64.0",
4
4
  "homepage": "https://applitools.com",
5
5
  "bugs": {
6
6
  "url": "https://github.com/applitools/eyes.sdk.javascript1/issues"
@@ -61,13 +61,13 @@
61
61
  "setup:standalone": "sh -c 'yarn chromedriver --port=4444 --verbose &'"
62
62
  },
63
63
  "dependencies": {
64
- "@applitools/core-base": "1.34.1",
64
+ "@applitools/core-base": "1.35.0",
65
65
  "@applitools/dom-capture": "11.8.1",
66
66
  "@applitools/dom-snapshot": "4.17.2",
67
67
  "@applitools/driver": "1.26.2",
68
- "@applitools/ec-client": "1.12.30",
68
+ "@applitools/ec-client": "1.12.31",
69
69
  "@applitools/logger": "2.2.12",
70
- "@applitools/nml-client": "1.11.28",
70
+ "@applitools/nml-client": "1.11.29",
71
71
  "@applitools/req": "1.10.2",
72
72
  "@applitools/screenshoter": "3.12.21",
73
73
  "@applitools/snippets": "2.9.2",
@@ -0,0 +1,7 @@
1
+ import type { Environment as UFGEnvironment } from '@applitools/ufg-client';
2
+ /**
3
+ * Returns the same UFG environment retargeted at the previous browser/OS version,
4
+ * or `null` if the input is not at a latest-alias environment (already one-version-back,
5
+ * pinned to a specific version, or an unsupported browser).
6
+ */
7
+ export declare function toOldInfraEnvironment(env: UFGEnvironment): UFGEnvironment | null;