@applitools/core 4.67.2 → 4.68.1

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.
Files changed (40) hide show
  1. package/CHANGELOG.md +187 -0
  2. package/dist/autonomous/create-render-results.js +6 -1
  3. package/dist/autonomous/start-renders.js +16 -7
  4. package/dist/check-and-close.js +7 -1
  5. package/dist/check.js +8 -1
  6. package/dist/classic/utils/extract-default-environments.js +17 -2
  7. package/dist/figma/client/figma-req.js +46 -0
  8. package/dist/figma/client/figma-rest.js +189 -0
  9. package/dist/figma/client/index.js +21 -0
  10. package/dist/figma/figma-images.js +62 -0
  11. package/dist/figma/figma.js +168 -0
  12. package/dist/figma/index.js +27 -0
  13. package/dist/figma/run-figma-check.js +82 -0
  14. package/dist/figma/seam.js +91 -0
  15. package/dist/figma/target-config.js +52 -0
  16. package/dist/figma/types.js +2 -0
  17. package/dist/figma/utils.js +128 -0
  18. package/dist/offline/run-offline-snapshots.js +18 -3
  19. package/dist/open-eyes.js +4 -2
  20. package/dist/ufg/build-accessibility-report-options.js +40 -0
  21. package/dist/ufg/check-and-close.js +14 -5
  22. package/dist/ufg/check.js +10 -1
  23. package/package.json +23 -22
  24. package/types/automation/types.d.ts +9 -0
  25. package/types/autonomous/types.d.ts +1 -0
  26. package/types/check-and-close.d.ts +3 -2
  27. package/types/check.d.ts +3 -2
  28. package/types/figma/client/figma-req.d.ts +9 -0
  29. package/types/figma/client/figma-rest.d.ts +24 -0
  30. package/types/figma/client/index.d.ts +2 -0
  31. package/types/figma/figma-images.d.ts +6 -0
  32. package/types/figma/figma.d.ts +21 -0
  33. package/types/figma/index.d.ts +8 -0
  34. package/types/figma/run-figma-check.d.ts +13 -0
  35. package/types/figma/seam.d.ts +12 -0
  36. package/types/figma/target-config.d.ts +7 -0
  37. package/types/figma/types.d.ts +69 -0
  38. package/types/figma/utils.d.ts +26 -0
  39. package/types/types.d.ts +1 -0
  40. package/types/ufg/build-accessibility-report-options.d.ts +13 -0
@@ -31,6 +31,7 @@ const fs_1 = __importDefault(require("fs"));
31
31
  const path_1 = __importDefault(require("path"));
32
32
  const core_1 = require("../core");
33
33
  const get_ufg_client_1 = require("../ufg/get-ufg-client");
34
+ const build_accessibility_report_options_1 = require("../ufg/build-accessibility-report-options");
34
35
  const to_base_check_settings_1 = require("../automation/utils/to-base-check-settings");
35
36
  const logger_1 = require("@applitools/logger");
36
37
  const chalk_1 = __importDefault(require("chalk"));
@@ -63,7 +64,13 @@ async function runOfflineSnapshots(options) {
63
64
  const offlineLocationPath = path_1.default.resolve(options.offlineLocationPath);
64
65
  const startTime = Date.now();
65
66
  const logger = (_a = options.logger) !== null && _a !== void 0 ? _a : (0, logger_1.makeLogger)({ format: { label: 'offline-exec' } });
66
- const eyesServerSettings = { ...options.config.open, ...options };
67
+ // figmaBaselines/figmaOptions are off-the-wire open config that the open seam resolves and then strips.
68
+ // This replay path bypasses the seam, so strip them once here — figmaOptions carries a Figma access
69
+ // token, and getAccountInfo logs the settings it is called with.
70
+ const openConfig = { ...options.config.open };
71
+ delete openConfig.figmaBaselines;
72
+ delete openConfig.figmaOptions;
73
+ const eyesServerSettings = { ...openConfig, ...options };
67
74
  const core = (0, core_1.makeCore)({ agentId: `js/core-offline/${version()}`, logger });
68
75
  const account = await core.getAccountInfo({ settings: eyesServerSettings });
69
76
  const ufgClient = await (0, get_ufg_client_1.makeGetUFGClient)({ logger })({
@@ -111,7 +118,7 @@ async function runOfflineSnapshots(options) {
111
118
  const fileOpenSettings = await fs_1.default.promises
112
119
  .readFile(path_1.default.join(testPath, 'settings.json'), 'utf-8')
113
120
  .then(JSON.parse);
114
- const openSettings = (0, merge_configs_1.mergeConfigs)(fileOpenSettings, options.config.open);
121
+ const openSettings = (0, merge_configs_1.mergeConfigs)(fileOpenSettings, openConfig);
115
122
  messages.push(`Running test: ${openSettings.testName} (${formatEnvironment(openSettings.environment)})`);
116
123
  return { testPath, openSettings, testLogger };
117
124
  });
@@ -336,10 +343,14 @@ async function runOfflineSnapshots(options) {
336
343
  });
337
344
  }
338
345
  async function render(target, logger) {
339
- var _a;
346
+ var _a, _b;
340
347
  const { elementReferences: selectors, getBaseCheckSettings } = (0, to_base_check_settings_1.toBaseCheckSettings)({
341
348
  settings: target.settings,
342
349
  });
350
+ // Only request a report when the check configures an accessibility standard.
351
+ const accessibilityReportOptions = target.settings.accessibilitySettings
352
+ ? (0, build_accessibility_report_options_1.buildAccessibilityReportOptions)({ accessibilityOptions: account.accessibilityOptions })
353
+ : undefined;
343
354
  const { renderId, selectorRegions, ...baseTarget } = await ufgClient.render({
344
355
  target: target.target,
345
356
  settings: {
@@ -351,6 +362,7 @@ async function runOfflineSnapshots(options) {
351
362
  environment: target.settings.environment,
352
363
  uploadUrl: account.uploadUrl,
353
364
  stitchingServiceUrl: account.stitchingServiceUrl,
365
+ accessibilityReportOptions,
354
366
  },
355
367
  logger,
356
368
  });
@@ -365,6 +377,9 @@ async function runOfflineSnapshots(options) {
365
377
  baseSettings.renderId = renderId;
366
378
  // baseSettings.stepIndex = index
367
379
  baseTarget.source = target.target.source; // TODO verify
380
+ // Fall back to the minted upload URL when the render result carries no report location.
381
+ if (accessibilityReportOptions === null || accessibilityReportOptions === void 0 ? void 0 : accessibilityReportOptions.uploadUrl)
382
+ (_b = baseTarget.accessibilityReportLocation) !== null && _b !== void 0 ? _b : (baseTarget.accessibilityReportLocation = accessibilityReportOptions.uploadUrl);
368
383
  // baseTarget.name = snapshot.title // TODO figure out
369
384
  const mergedCheckSettings = (0, merge_configs_1.mergeConfigs)(baseSettings, options.config.check);
370
385
  return { mergedCheckSettings, baseTarget };
package/dist/open-eyes.js CHANGED
@@ -33,6 +33,7 @@ const check_and_close_1 = require("./check-and-close");
33
33
  const close_1 = require("./close");
34
34
  const abort_1 = require("./abort");
35
35
  const get_eyes_results_1 = require("./get-eyes-results");
36
+ const seam_1 = require("./figma/seam");
36
37
  const populate_eyes_server_settings_1 = require("./utils/populate-eyes-server-settings");
37
38
  const utils = __importStar(require("@applitools/utils"));
38
39
  const core_base_1 = require("@applitools/core-base");
@@ -110,6 +111,7 @@ function makeOpenEyes({ type: defaultType = 'classic', clients, batch, removeDup
110
111
  logger.warn(`gitBranchingTimestamp is an invalid ISO date string: ${settings.gitBranchingTimestamp}`);
111
112
  settings.gitBranchingTimestamp = undefined;
112
113
  }
114
+ await (0, seam_1.applyFigmaBaselines)(settings, logger);
113
115
  (_x = settings.bypassCSP) !== null && _x !== void 0 ? _x : (settings.bypassCSP = utils.general.getEnvValue('BYPASS_CSP', 'boolean') === true || undefined);
114
116
  const driver = target && (await (0, driver_1.makeDriver)({ spec, driver: target, logger, customConfig: settings }));
115
117
  if (settings.bypassCSP) {
@@ -182,8 +184,8 @@ function makeOpenEyes({ type: defaultType = 'classic', clients, batch, removeDup
182
184
  var _a, _b;
183
185
  return ({
184
186
  getTypedEyes,
185
- check: (0, check_1.makeCheck)({ type, eyes, target: driver, spec, logger }),
186
- checkAndClose: (0, check_and_close_1.makeCheckAndClose)({ type, eyes, target: driver, spec, logger }),
187
+ check: (0, check_1.makeCheck)({ type, eyes, target: driver, environments: settings.environments, spec, logger }),
188
+ checkAndClose: (0, check_and_close_1.makeCheckAndClose)({ type, eyes, target: driver, environments: settings.environments, spec, logger }),
187
189
  close: (0, close_1.makeClose)({ eyes, environments: (_a = config === null || config === void 0 ? void 0 : config.check) === null || _a === void 0 ? void 0 : _a.environments, logger }),
188
190
  abort: (0, abort_1.makeAbort)({ eyes, environments: (_b = config === null || config === void 0 ? void 0 : config.check) === null || _b === void 0 ? void 0 : _b.environments, logger }),
189
191
  getResults: (0, get_eyes_results_1.makeGetEyesResults)({ eyes, logger }),
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.buildAccessibilityReportOptions = void 0;
27
+ const utils = __importStar(require("@applitools/utils"));
28
+ const REPORT_ID_PLACEHOLDER = '__report_id__';
29
+ /**
30
+ * Builds the `accessibilityReportOptions` render option: forwards `runOptions` verbatim and fills the
31
+ * `uploadUrl` template's `__report_id__` with a fresh random id. Returns `undefined` when the account
32
+ * has no accessibility options.
33
+ */
34
+ function buildAccessibilityReportOptions({ accessibilityOptions, reportId = utils.general.guid(), }) {
35
+ if (!accessibilityOptions)
36
+ return undefined;
37
+ const uploadUrl = accessibilityOptions.uploadUrl.split(REPORT_ID_PLACEHOLDER).join(encodeURIComponent(reportId));
38
+ return { axeCoreOptions: accessibilityOptions.runOptions, uploadUrl };
39
+ }
40
+ exports.buildAccessibilityReportOptions = buildAccessibilityReportOptions;
@@ -37,6 +37,7 @@ const lang = __importStar(require("../lang"));
37
37
  const chalk_1 = __importDefault(require("chalk"));
38
38
  const take_snapshots_1 = require("./take-snapshots");
39
39
  const create_render_target_from_snapshot_1 = require("./create-render-target-from-snapshot");
40
+ const build_accessibility_report_options_1 = require("./build-accessibility-report-options");
40
41
  function makeCheckAndClose({ eyes, target: defaultTarget, environments: defaultEnvironments = [], spec, signal, logger: mainLogger, }) {
41
42
  return async function checkAndClose({ target = defaultTarget, settings = {}, logger = mainLogger, } = {}) {
42
43
  var _a;
@@ -72,7 +73,7 @@ function makeCheckAndClose({ eyes, target: defaultTarget, environments: defaultE
72
73
  snapshots = !utils.types.isArray(target) ? Array(uniqueEnvironments.length).fill(target) : target;
73
74
  }
74
75
  const promises = snapshots.map(async (snapshot, i) => {
75
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
76
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
76
77
  const environmentLogger = logger.extend({ tags: [`environment-${utils.general.shortid()}`] });
77
78
  const { target } = snapshot;
78
79
  const environment = uniqueEnvironments[i];
@@ -115,6 +116,10 @@ function makeCheckAndClose({ eyes, target: defaultTarget, environments: defaultE
115
116
  const { elementReferences: selectors, getBaseCheckSettings } = (0, to_base_check_settings_1.toBaseCheckSettings)({
116
117
  settings: snapshot.settings,
117
118
  });
119
+ // Only request a report when the check configures an accessibility standard.
120
+ const accessibilityReportOptions = settings.accessibilitySettings
121
+ ? (0, build_accessibility_report_options_1.buildAccessibilityReportOptions)({ accessibilityOptions: eyes.test.account.accessibilityOptions })
122
+ : undefined;
118
123
  const { renderId, selectorRegions, ...baseTarget } = await ufgClient.render({
119
124
  target: renderTarget,
120
125
  settings: {
@@ -126,6 +131,7 @@ function makeCheckAndClose({ eyes, target: defaultTarget, environments: defaultE
126
131
  environment: { ...environment, environmentId: baseEyes.test.environment.environmentId },
127
132
  uploadUrl: baseEyes.test.uploadUrl,
128
133
  stitchingServiceUrl: baseEyes.test.stitchingServiceUrl,
134
+ accessibilityReportOptions,
129
135
  },
130
136
  signal,
131
137
  logger: environmentLogger,
@@ -141,13 +147,16 @@ function makeCheckAndClose({ eyes, target: defaultTarget, environments: defaultE
141
147
  baseSettings.renderId = renderId;
142
148
  baseTarget.source = snapshot.url;
143
149
  baseTarget.name = snapshot.title;
150
+ // Fall back to the minted upload URL when the render result carries no report location.
151
+ if (accessibilityReportOptions === null || accessibilityReportOptions === void 0 ? void 0 : accessibilityReportOptions.uploadUrl)
152
+ (_f = baseTarget.accessibilityReportLocation) !== null && _f !== void 0 ? _f : (baseTarget.accessibilityReportLocation = accessibilityReportOptions.uploadUrl);
144
153
  if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
145
154
  environmentLogger.warn('Command "check" was aborted after rendering');
146
155
  throw new abort_error_1.AbortError('Command "check" was aborted after rendering');
147
156
  }
148
157
  else if (!baseEyes.running) {
149
- 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`);
150
- 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`);
158
+ environmentLogger.warn(`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`);
159
+ throw new abort_error_1.AbortError(`Render on environment with id "${(_h = baseEyes.test.environment) === null || _h === void 0 ? void 0 : _h.environmentId}" was aborted during one of the previous steps`);
151
160
  }
152
161
  if (settings.assumesMutability) {
153
162
  void eyes.core.logEvent({
@@ -165,7 +174,7 @@ function makeCheckAndClose({ eyes, target: defaultTarget, environments: defaultE
165
174
  userTestId: baseEyes.test.userTestId,
166
175
  appId: baseEyes.test.appId,
167
176
  baselineId: baseEyes.test.baselineId,
168
- environmentId: (_h = baseEyes.test.environment) === null || _h === void 0 ? void 0 : _h.environmentId,
177
+ environmentId: (_j = baseEyes.test.environment) === null || _j === void 0 ? void 0 : _j.environmentId,
169
178
  },
170
179
  isNew: baseEyes.test.isNew,
171
180
  resultsUrl: baseEyes.test.resultsUrl,
@@ -182,7 +191,7 @@ function makeCheckAndClose({ eyes, target: defaultTarget, environments: defaultE
182
191
  });
183
192
  }
184
193
  catch (error) {
185
- 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);
194
+ environmentLogger.error(`Render on environment with id "${(_k = baseEyes.test.environment) === null || _k === void 0 ? void 0 : _k.environmentId}" failed due to an error`, error);
186
195
  if (baseEyes.running && !(signal === null || signal === void 0 ? void 0 : signal.aborted))
187
196
  await baseEyes.abort({ logger: environmentLogger, settings: { reason: error } });
188
197
  }
package/dist/ufg/check.js CHANGED
@@ -38,6 +38,7 @@ 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
40
  const to_old_infra_environment_1 = require("./to-old-infra-environment");
41
+ const build_accessibility_report_options_1 = require("./build-accessibility-report-options");
41
42
  function makeCheck({ eyes, target: defaultTarget, environments: defaultEnvironments = [], spec, signal, logger: mainLogger, }) {
42
43
  // Sessions whose old-infra retry chain has ended: once a retry doesn't confirm an old-infra match,
43
44
  // the backend stops expecting retries, so we must stop sending them. baseEyes is cached per
@@ -122,7 +123,11 @@ function makeCheck({ eyes, target: defaultTarget, environments: defaultEnvironme
122
123
  settings: snapshot.settings,
123
124
  });
124
125
  const renderForCheck = async (env) => {
125
- var _a;
126
+ var _a, _b;
127
+ // Only request a report when the check configures an accessibility standard.
128
+ const accessibilityReportOptions = settings.accessibilitySettings
129
+ ? (0, build_accessibility_report_options_1.buildAccessibilityReportOptions)({ accessibilityOptions: eyes.test.account.accessibilityOptions })
130
+ : undefined;
126
131
  const { renderId, selectorRegions, ...target } = await ufgClient.render({
127
132
  target: renderTarget,
128
133
  settings: {
@@ -134,6 +139,7 @@ function makeCheck({ eyes, target: defaultTarget, environments: defaultEnvironme
134
139
  environment: { ...env, environmentId: baseEyes.test.environment.environmentId },
135
140
  uploadUrl: baseEyes.test.uploadUrl,
136
141
  stitchingServiceUrl: baseEyes.test.stitchingServiceUrl,
142
+ accessibilityReportOptions,
137
143
  },
138
144
  signal,
139
145
  logger: environmentLogger,
@@ -149,6 +155,9 @@ function makeCheck({ eyes, target: defaultTarget, environments: defaultEnvironme
149
155
  checkSettings.renderId = renderId;
150
156
  target.source = snapshot.url;
151
157
  target.name = snapshot.title;
158
+ // Fall back to the minted upload URL when the render result carries no report location.
159
+ if (accessibilityReportOptions === null || accessibilityReportOptions === void 0 ? void 0 : accessibilityReportOptions.uploadUrl)
160
+ (_b = target.accessibilityReportLocation) !== null && _b !== void 0 ? _b : (target.accessibilityReportLocation = accessibilityReportOptions.uploadUrl);
152
161
  return { target, settings: checkSettings };
153
162
  };
154
163
  const { target: baseTarget, settings: baseSettings } = await renderForCheck(environment);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applitools/core",
3
- "version": "4.67.2",
3
+ "version": "4.68.1",
4
4
  "homepage": "https://applitools.com",
5
5
  "bugs": {
6
6
  "url": "https://github.com/applitools/eyes.sdk.javascript1/issues"
@@ -61,19 +61,20 @@
61
61
  "setup:standalone": "sh -c 'yarn chromedriver --port=4444 --verbose &'"
62
62
  },
63
63
  "dependencies": {
64
- "@applitools/core-base": "1.37.0",
65
- "@applitools/dom-capture": "11.8.4",
66
- "@applitools/dom-snapshot": "4.17.8",
67
- "@applitools/driver": "1.26.7",
68
- "@applitools/ec-client": "1.12.40",
69
- "@applitools/logger": "2.3.0",
70
- "@applitools/nml-client": "1.11.38",
71
- "@applitools/req": "1.11.2",
72
- "@applitools/screenshoter": "3.12.26",
73
- "@applitools/snippets": "2.9.5",
74
- "@applitools/socket": "1.3.15",
75
- "@applitools/ufg-client": "1.22.5",
76
- "@applitools/utils": "1.15.1",
64
+ "@applitools/core-base": "1.38.1",
65
+ "@applitools/dom-capture": "11.8.5",
66
+ "@applitools/dom-snapshot": "4.17.9",
67
+ "@applitools/driver": "1.26.8",
68
+ "@applitools/ec-client": "1.12.42",
69
+ "@applitools/image": "1.3.1",
70
+ "@applitools/logger": "2.3.1",
71
+ "@applitools/nml-client": "1.11.40",
72
+ "@applitools/req": "1.11.3",
73
+ "@applitools/screenshoter": "3.12.28",
74
+ "@applitools/snippets": "2.9.6",
75
+ "@applitools/socket": "1.3.16",
76
+ "@applitools/ufg-client": "1.23.1",
77
+ "@applitools/utils": "1.15.2",
77
78
  "abort-controller": "3.0.0",
78
79
  "chalk": "4.1.2",
79
80
  "node-fetch": "2.6.7",
@@ -83,13 +84,13 @@
83
84
  },
84
85
  "devDependencies": {
85
86
  "@applitools/bongo": "^5.10.0",
86
- "@applitools/spec-driver-playwright": "^1.9.7",
87
- "@applitools/spec-driver-puppeteer": "^1.8.7",
88
- "@applitools/spec-driver-selenium": "^1.8.7",
89
- "@applitools/spec-driver-webdriver": "^1.6.7",
90
- "@applitools/test-server": "^1.4.6",
87
+ "@applitools/spec-driver-playwright": "^1.9.8",
88
+ "@applitools/spec-driver-puppeteer": "^1.8.8",
89
+ "@applitools/spec-driver-selenium": "^1.8.8",
90
+ "@applitools/spec-driver-webdriver": "^1.6.8",
91
+ "@applitools/test-server": "^1.4.7",
91
92
  "@applitools/test-utils": "^1.5.17",
92
- "@applitools/tunnel-client": "^1.12.2",
93
+ "@applitools/tunnel-client": "^1.12.3",
93
94
  "@swc-node/register": "^1.6.8",
94
95
  "@types/mocha": "^10.0.7",
95
96
  "@types/node": "^12.20.55",
@@ -120,10 +121,10 @@
120
121
  "puppeteer": true,
121
122
  "ws>bufferutil": false,
122
123
  "ws>utf-8-validate": false,
123
- "@applitools/core-base>@applitools/image>sharp": false,
124
124
  "@swc-node/register>@swc/core": false,
125
125
  "selenium-webdriver>ws>bufferutil": false,
126
- "selenium-webdriver>ws>utf-8-validate": false
126
+ "selenium-webdriver>ws>utf-8-validate": false,
127
+ "@applitools/image>sharp": false
127
128
  }
128
129
  }
129
130
  }
@@ -3,6 +3,7 @@ import type * as BaseCore from '@applitools/core-base/types';
3
3
  import { type SpecType, type Driver, type ElementReference, type ContextReference } from '@applitools/driver';
4
4
  import { type NMLClient, type NMLClientSettings } from '@applitools/nml-client';
5
5
  import { type Logger } from '@applitools/logger';
6
+ import type { FigmaOptions } from '../figma/types';
6
7
  export type * from '@applitools/core-base/types';
7
8
  export type DriverTarget<TSpec extends SpecType> = TSpec['driver'] | Driver<TSpec>;
8
9
  export type Target<TSpec extends SpecType> = DriverTarget<TSpec> | BaseCore.Target;
@@ -180,4 +181,12 @@ export type OpenSettings = BaseCore.OpenSettings & {
180
181
  disableBrokerUrlCache?: boolean;
181
182
  environments?: Environment[];
182
183
  bypassCSP?: boolean;
184
+ /**
185
+ * @internal Resolved in core's open-eyes (the Figma seam) before session creation and stripped
186
+ * from the wire config — it is not part of the cross-language wire contract, but is available to
187
+ * every SDK that routes its opens through core.
188
+ */
189
+ figmaBaselines?: string | Record<string, string | string[]>;
190
+ /** @internal Read and stripped by the Figma seam during open, like `figmaBaselines` — never reaches the wire. */
191
+ figmaOptions?: FigmaOptions;
183
192
  };
@@ -71,6 +71,7 @@ export type StartedRender = {
71
71
  settings: UFGCore.SafeCheckSettings;
72
72
  environment: UFGCore.ExactEnvironment;
73
73
  account: UFGCore.Account;
74
+ accessibilityReportLocation?: string;
74
75
  };
75
76
  export type RenderResult = {
76
77
  status: 'rendering' | 'rendered' | 'error';
@@ -1,14 +1,15 @@
1
- import type { Target, DriverTarget, Eyes, Config, CheckSettings, CloseSettings } from './types';
1
+ import type { Target, DriverTarget, Eyes, Config, CheckSettings, CloseSettings, Environment } from './types';
2
2
  import { type Logger } from '@applitools/logger';
3
3
  import { type SpecType, type SpecDriver } from '@applitools/driver';
4
4
  type Options<TSpec extends SpecType, TType extends 'classic' | 'ufg'> = {
5
5
  type?: TType;
6
6
  eyes: Eyes<TSpec, TType>;
7
7
  target?: DriverTarget<TSpec>;
8
+ environments?: Environment[];
8
9
  spec?: SpecDriver<TSpec>;
9
10
  logger: Logger;
10
11
  };
11
- export declare function makeCheckAndClose<TSpec extends SpecType, TDefaultType extends 'classic' | 'ufg'>({ type: defaultType, eyes, target: defaultTarget, spec, logger: mainLogger, }: Options<TSpec, TDefaultType>): <TType extends "classic" | "ufg" = TDefaultType>({ type, target, settings, config, logger, }?: {
12
+ export declare function makeCheckAndClose<TSpec extends SpecType, TDefaultType extends 'classic' | 'ufg'>({ type: defaultType, eyes, target: defaultTarget, environments: openEnvironments, spec, logger: mainLogger, }: Options<TSpec, TDefaultType>): <TType extends "classic" | "ufg" = TDefaultType>({ type, target, settings, config, logger, }?: {
12
13
  type?: TType | undefined;
13
14
  target?: Target<TSpec, TType> | undefined;
14
15
  settings?: (CheckSettings<TSpec, TDefaultType> & CloseSettings<TDefaultType> & CheckSettings<TSpec, TType> & CloseSettings<TType>) | undefined;
package/types/check.d.ts CHANGED
@@ -1,14 +1,15 @@
1
- import type { Target, DriverTarget, Eyes, Config, CheckSettings } from './types';
1
+ import type { Target, DriverTarget, Eyes, Config, CheckSettings, Environment } from './types';
2
2
  import { type Logger } from '@applitools/logger';
3
3
  import { type SpecType, type SpecDriver } from '@applitools/driver';
4
4
  type Options<TSpec extends SpecType, TType extends 'classic' | 'ufg'> = {
5
5
  type?: TType;
6
6
  eyes: Eyes<TSpec, TType>;
7
7
  target?: DriverTarget<TSpec>;
8
+ environments?: Environment[];
8
9
  spec?: SpecDriver<TSpec>;
9
10
  logger: Logger;
10
11
  };
11
- export declare function makeCheck<TSpec extends SpecType, TDefaultType extends 'classic' | 'ufg'>({ type: defaultType, eyes, target: defaultTarget, spec, logger: mainLogger, }: Options<TSpec, TDefaultType>): <TType extends "classic" | "ufg" = TDefaultType>({ type, target, settings, config, logger, }?: {
12
+ export declare function makeCheck<TSpec extends SpecType, TDefaultType extends 'classic' | 'ufg'>({ type: defaultType, eyes, target: defaultTarget, environments: openEnvironments, spec, logger: mainLogger, }: Options<TSpec, TDefaultType>): <TType extends "classic" | "ufg" = TDefaultType>({ type, target, settings, config, logger, }?: {
12
13
  type?: TType | undefined;
13
14
  target?: Target<TSpec, TType> | undefined;
14
15
  settings?: CheckSettings<TSpec, TType> | undefined;
@@ -0,0 +1,9 @@
1
+ import { type Req, type Proxy } from '@applitools/req';
2
+ import { type Logger } from '@applitools/logger';
3
+ export declare const FIGMA_API = "https://api.figma.com/v1";
4
+ export type FigmaReqOptions = {
5
+ proxy?: Proxy;
6
+ logger?: Logger;
7
+ maxRateLimitWaitSeconds?: number;
8
+ };
9
+ export declare function makeFigmaReq({ proxy, logger, maxRateLimitWaitSeconds }?: FigmaReqOptions): Req;
@@ -0,0 +1,24 @@
1
+ import { type Logger } from '@applitools/logger';
2
+ import type { Proxy, Req } from '@applitools/req';
3
+ import type { FigmaImageResult, FigmaNodeMetadata } from '../types';
4
+ export type FigmaRestOptions = {
5
+ tempPath?: string;
6
+ nodesCacheTtlSeconds?: number;
7
+ maxRateLimitWaitSeconds?: number;
8
+ /** Serve from the on-disk caches only; throw on any miss. */
9
+ skipApi?: boolean;
10
+ proxy?: Proxy;
11
+ /** Defaults to `makeFigmaReq(…)`; tests inject a stub. */
12
+ req?: Req;
13
+ logger?: Logger;
14
+ };
15
+ /**
16
+ * Cache names are hashed because Figma node ids are not filename-safe — an instance node id looks like
17
+ * `I1:2;3:4`, and `:` / `;` are illegal on Windows.
18
+ *
19
+ * `test/fixtures/figma-cache/seed.mjs` mirrors both functions — keep them in sync.
20
+ */
21
+ export declare function figmaNodesCacheFileName(fileId: string, uniqueNodeIds: string[]): string;
22
+ export declare function figmaImageCacheFileName(fileId: string, nodeId: string, lastModifiedUnix: number): string;
23
+ export declare function fetchFigmaMetadata(urls: string[], accessToken: string, opts?: FigmaRestOptions): Promise<FigmaNodeMetadata[]>;
24
+ export declare function fetchFigmaImages(urls: string[], accessToken: string, opts?: FigmaRestOptions): Promise<FigmaImageResult[]>;
@@ -0,0 +1,2 @@
1
+ export * from './figma-req';
2
+ export * from './figma-rest';
@@ -0,0 +1,6 @@
1
+ export declare function createPlaceholderPng(width: number, height: number, tempPath: string): Promise<string>;
2
+ export declare function createPaddedDesignImage(imagePath: string, width: number, height: number, minSize: number, tempPath: string): Promise<{
3
+ imagePath: string;
4
+ width: number;
5
+ height: number;
6
+ }>;
@@ -0,0 +1,21 @@
1
+ import { type Logger } from '@applitools/logger';
2
+ import type { Proxy, Req } from '@applitools/req';
3
+ import type { OpenSettings } from '../automation/types';
4
+ import { type FigmaMode } from './utils';
5
+ import type { FigmaViewportOptions, FigmaBaselineDeps } from './types';
6
+ export declare function setFigmaBaselineFlow(figmaUrls: string[], originalConfig: Partial<OpenSettings>, deps: FigmaBaselineDeps, mode?: Exclude<FigmaMode, 'disabled'>, viewportOpts?: FigmaViewportOptions, logger?: Logger): Promise<Partial<OpenSettings>>;
7
+ export declare function setFigmaBaseline(configuration: Partial<OpenSettings>, figmaBaselines: string | Record<string, string | string[]>, opts?: {
8
+ accessToken?: string;
9
+ maxRateLimitWaitSeconds?: number;
10
+ nodesCacheTtlSeconds?: number;
11
+ tempPath?: string;
12
+ mode?: FigmaMode;
13
+ maxViewportHeight?: number;
14
+ minViewportSize?: number | null;
15
+ /** Serve from the disk caches only; throw on any miss. */
16
+ skipApi?: boolean;
17
+ proxy?: Proxy;
18
+ /** Defaults to the client's own req; tests inject a stub. */
19
+ req?: Req;
20
+ logger?: Logger;
21
+ }): Promise<void>;
@@ -0,0 +1,8 @@
1
+ export * from './types';
2
+ export * from './utils';
3
+ export * from './target-config';
4
+ export * from './client';
5
+ export * from './figma-images';
6
+ export * from './figma';
7
+ export { runFigmaCheck } from './run-figma-check';
8
+ export { applyFigmaBaselines } from './seam';
@@ -0,0 +1,13 @@
1
+ import type { FigmaReferenceConfig } from './types';
2
+ /**
3
+ * Establishes/updates the Figma-reference baseline via a throwaway headless classic image test (checks
4
+ * each PNG, closes, deletes the result — the saved baseline persists). Uses core's own API, not the
5
+ * eyes layer (core cannot depend on `@applitools/eyes`).
6
+ */
7
+ export declare function runFigmaCheck(config: FigmaReferenceConfig, checks: Array<{
8
+ imagePath: string;
9
+ tag: string;
10
+ }>): Promise<{
11
+ isNew: boolean;
12
+ diffs: boolean;
13
+ }>;
@@ -0,0 +1,12 @@
1
+ import type { OpenSettings } from '../automation/types';
2
+ import { type Logger } from '@applitools/logger';
3
+ import { setFigmaBaseline } from './figma';
4
+ /**
5
+ * @internal
6
+ * Resolves the `figmaBaselines` / `figmaOptions` open config once per open, then always strips both — they
7
+ * are off-the-wire and must never be logged or sent. The resolver mutates `settings` in place.
8
+ *
9
+ * The only place the Figma feature reads the environment; everything below it takes parameters. Each
10
+ * `figmaOptions` field wins over its env fallback.
11
+ */
12
+ export declare function applyFigmaBaselines(settings: Partial<OpenSettings>, logger: Logger, resolve?: typeof setFigmaBaseline): Promise<void>;
@@ -0,0 +1,7 @@
1
+ import type { OpenSettings, Environment } from '../automation/types';
2
+ import { type FigmaMode } from './utils';
3
+ import type { FigmaNodeMetadata, FigmaViewport, FigmaBaselineLink } from './types';
4
+ export declare const DEFAULT_MAX_VIEWPORT_HEIGHT = 800;
5
+ export declare const PLACEHOLDER_TAG = "(no design)";
6
+ export declare function deduplicateBrowsers(environments: Environment[], targetWidth: number, targetHeight: number): Environment[];
7
+ export declare function buildTargetTestConfig(originalConfig: Partial<OpenSettings>, metadata: FigmaNodeMetadata, figmaViewport: FigmaViewport, baselineLink: FigmaBaselineLink | null, mode: FigmaMode): Partial<OpenSettings>;
@@ -0,0 +1,69 @@
1
+ import type { OpenSettings } from '../automation/types';
2
+ import type { FigmaMode } from './utils';
3
+ /**
4
+ * The user-facing `figmaOptions` open config. Precedence is per field, not per object: a field set here
5
+ * wins, one left unset falls back to that field's environment variable where it has one; `README.md`
6
+ * holds the per-field mapping.
7
+ *
8
+ * `APPLITOOLS_FIGMA_SKIP_API` has no field by design — it is a CI/debug switch, not a user option.
9
+ */
10
+ export type FigmaOptions = FigmaViewportOptions & {
11
+ mode?: FigmaMode;
12
+ accessToken?: string;
13
+ maxRateLimitWaitSeconds?: number;
14
+ nodesCacheTtlSeconds?: number;
15
+ tempPath?: string;
16
+ };
17
+ export type FigmaNodeRef = {
18
+ fileId: string;
19
+ nodeId: string;
20
+ };
21
+ export type FigmaNodeMetadata = {
22
+ name: string;
23
+ type: string;
24
+ width: number;
25
+ height: number;
26
+ revision: string;
27
+ lastModifiedAt: string;
28
+ };
29
+ export type FigmaImageResult = {
30
+ imagePath: string;
31
+ metadata: FigmaNodeMetadata;
32
+ };
33
+ export type FigmaViewport = {
34
+ width: number;
35
+ height: number;
36
+ };
37
+ export type FigmaViewportOptions = {
38
+ maxViewportHeight?: number;
39
+ /**
40
+ * One dimension, not a width/height pair: the same floor applies to both axes independently, so 320
41
+ * means "at least 320 wide AND at least 320 tall". `null` disables the floor.
42
+ */
43
+ minViewportSize?: number | null;
44
+ };
45
+ export type FigmaBaselineLink = {
46
+ figmaEnvName: string;
47
+ useLatestEnvBaseline: boolean;
48
+ };
49
+ /** The throwaway Figma-reference test's config: a subset of core `OpenSettings` plus `saveNewTests` (maps to close's `updateBaselineIfNew`). */
50
+ export type FigmaReferenceConfig = Partial<OpenSettings> & {
51
+ saveNewTests?: boolean;
52
+ };
53
+ export type FigmaBaselineDeps = {
54
+ fetchFigmaImages: (figmaUrls: string[]) => Promise<FigmaImageResult[]>;
55
+ fetchFigmaMetadata: (figmaUrls: string[]) => Promise<FigmaNodeMetadata[]>;
56
+ createPlaceholderImage: (width: number, height: number) => Promise<string>;
57
+ padDesignImage: (imagePath: string, width: number, height: number, minViewportSize: number) => Promise<{
58
+ imagePath: string;
59
+ width: number;
60
+ height: number;
61
+ }>;
62
+ runFigmaCheck: (config: FigmaReferenceConfig, checks: Array<{
63
+ imagePath: string;
64
+ tag: string;
65
+ }>) => Promise<{
66
+ isNew: boolean;
67
+ diffs: boolean;
68
+ }>;
69
+ };
@@ -0,0 +1,26 @@
1
+ import type { FigmaNodeRef, FigmaNodeMetadata, FigmaViewport } from './types';
2
+ export declare function isFigmaUrl(url: string): boolean;
3
+ export declare function parseFigmaNodeUrl(url: string): FigmaNodeRef;
4
+ /**
5
+ * The tag becomes the Eyes baseline step name, and Eyes matches steps by name, so it must derive only from
6
+ * stable identity. Figma's "Copy link to selection" appends a `t=` param that differs on every copy —
7
+ * keeping it means re-copying the link renames the step and orphans its accepted baseline.
8
+ *
9
+ * Drop only `t`: `node-id` is what distinguishes two frames of the same file, so stripping the whole query
10
+ * would give every frame in a file the same step name.
11
+ */
12
+ export declare function figmaStepTag(figmaUrl: string): string;
13
+ export declare function resolveFigmaUrls(figmaBaselines: string | Record<string, string | string[]>, testName: string | undefined): string[] | null;
14
+ export declare const FIGMA_MODES: readonly ["figma-baseline", "test-baseline", "auto-baseline", "disabled"];
15
+ export type FigmaMode = (typeof FIGMA_MODES)[number];
16
+ export declare function resolveFigmaMode(value: string | undefined): FigmaMode;
17
+ export declare function figmaMetadataToProperties(metadata: FigmaNodeMetadata, mode: FigmaMode): Array<{
18
+ name: string;
19
+ value: string;
20
+ }>;
21
+ export declare function boundingViewport(viewports: FigmaViewport[]): FigmaViewport;
22
+ export declare function computeFigmaViewport(stepViewports: FigmaViewport[], maxViewportHeight: number): FigmaViewport;
23
+ export declare function paddedDesignSize(width: number, height: number, minSize: number): {
24
+ width: number;
25
+ height: number;
26
+ };
package/types/types.d.ts CHANGED
@@ -8,6 +8,7 @@ import { type Logger } from '@applitools/logger';
8
8
  import { type ECClient, type ECClientSettings } from '@applitools/ec-client';
9
9
  export { ECClient };
10
10
  export * from './automation/types';
11
+ export type { FigmaOptions } from './figma/types';
11
12
  export { DEFAULT_CONCURRENCY } from '@applitools/core-base';
12
13
  export type TypedCore<TSpec extends SpecType, TType extends 'classic' | 'ufg'> = TType extends 'ufg' ? UFGCore.Core<TSpec> : ClassicCore.Core<TSpec>;
13
14
  export type TypedEyes<TSpec extends SpecType, TType extends 'classic' | 'ufg'> = TType extends 'ufg' ? UFGCore.Eyes<TSpec> : ClassicCore.Eyes<TSpec>;
@@ -0,0 +1,13 @@
1
+ import { type Account } from '@applitools/core-base';
2
+ /**
3
+ * Builds the `accessibilityReportOptions` render option: forwards `runOptions` verbatim and fills the
4
+ * `uploadUrl` template's `__report_id__` with a fresh random id. Returns `undefined` when the account
5
+ * has no accessibility options.
6
+ */
7
+ export declare function buildAccessibilityReportOptions({ accessibilityOptions, reportId, }: {
8
+ accessibilityOptions?: Account['accessibilityOptions'];
9
+ reportId?: string;
10
+ }): {
11
+ axeCoreOptions: unknown;
12
+ uploadUrl: string;
13
+ } | undefined;