@applitools/core 4.74.2 → 4.75.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.
Files changed (70) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +15 -20
  3. package/dist/automation/abort.js +8 -18
  4. package/dist/automation/close.js +8 -27
  5. package/dist/automation/get-results.js +3 -11
  6. package/dist/automation/utils/make-environment-loggers.js +39 -0
  7. package/dist/automation/utils/to-environment-key.js +6 -1
  8. package/dist/classic/check-and-close.js +26 -69
  9. package/dist/classic/check.js +85 -354
  10. package/dist/classic/get-base-eyes.js +15 -54
  11. package/dist/classic/open-eyes.js +17 -10
  12. package/dist/classic/utils/capture.js +209 -0
  13. package/dist/get-typed-eyes.js +2 -2
  14. package/dist/offline/run-offline-snapshots.js +3 -1
  15. package/dist/tasks/abort.js +32 -0
  16. package/dist/tasks/aborted-check.js +14 -0
  17. package/dist/tasks/classic/capture.js +54 -0
  18. package/dist/tasks/classic/steps.js +51 -0
  19. package/dist/tasks/classic/upload.js +40 -0
  20. package/dist/tasks/close.js +31 -0
  21. package/dist/tasks/fill.js +13 -0
  22. package/dist/tasks/get-results.js +29 -0
  23. package/dist/tasks/graph.js +6 -0
  24. package/dist/tasks/index.js +20 -0
  25. package/dist/tasks/lifecycle.js +101 -0
  26. package/dist/tasks/match.js +109 -0
  27. package/dist/tasks/open.js +38 -0
  28. package/dist/tasks/queries.js +39 -0
  29. package/dist/tasks/types.js +2 -0
  30. package/dist/tasks/ufg/create-render-target.js +16 -0
  31. package/dist/tasks/ufg/recheck.js +49 -0
  32. package/dist/tasks/ufg/render.js +66 -0
  33. package/dist/tasks/ufg/steps.js +51 -0
  34. package/dist/tasks/upload-target.js +10 -0
  35. package/dist/ufg/check-and-close.js +32 -137
  36. package/dist/ufg/check.js +39 -175
  37. package/dist/ufg/get-base-eyes.js +34 -72
  38. package/dist/ufg/open-eyes.js +14 -8
  39. package/package.json +6 -5
  40. package/types/automation/abort.d.ts +2 -3
  41. package/types/automation/close.d.ts +2 -3
  42. package/types/automation/types.d.ts +13 -16
  43. package/types/automation/utils/make-environment-loggers.d.ts +3 -0
  44. package/types/classic/get-base-eyes.d.ts +5 -9
  45. package/types/classic/open-eyes.d.ts +4 -3
  46. package/types/classic/types.d.ts +1 -1
  47. package/types/classic/utils/capture.d.ts +21 -0
  48. package/types/tasks/abort.d.ts +11 -0
  49. package/types/tasks/aborted-check.d.ts +9 -0
  50. package/types/tasks/classic/capture.d.ts +10 -0
  51. package/types/tasks/classic/steps.d.ts +17 -0
  52. package/types/tasks/classic/upload.d.ts +14 -0
  53. package/types/tasks/close.d.ts +9 -0
  54. package/types/tasks/fill.d.ts +8 -0
  55. package/types/tasks/get-results.d.ts +6 -0
  56. package/types/tasks/graph.d.ts +3 -0
  57. package/types/tasks/index.d.ts +3 -0
  58. package/types/tasks/lifecycle.d.ts +23 -0
  59. package/types/tasks/match.d.ts +13 -0
  60. package/types/tasks/open.d.ts +10 -0
  61. package/types/tasks/queries.d.ts +15 -0
  62. package/types/tasks/types.d.ts +187 -0
  63. package/types/tasks/ufg/create-render-target.d.ts +11 -0
  64. package/types/tasks/ufg/recheck.d.ts +20 -0
  65. package/types/tasks/ufg/render.d.ts +15 -0
  66. package/types/tasks/ufg/steps.d.ts +15 -0
  67. package/types/tasks/upload-target.d.ts +5 -0
  68. package/types/ufg/get-base-eyes.d.ts +5 -10
  69. package/types/ufg/open-eyes.d.ts +4 -3
  70. package/types/ufg/types.d.ts +1 -1
@@ -0,0 +1,209 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.generateBaseScreenshotsAndSettings = exports.isCapturedAsRequested = void 0;
30
+ const nml_client_1 = require("@applitools/nml-client");
31
+ const take_screenshots_1 = require("./take-screenshots");
32
+ const to_base_check_settings_1 = require("../../automation/utils/to-base-check-settings");
33
+ const wait_for_lazy_load_1 = require("../../automation/utils/wait-for-lazy-load");
34
+ const chalk_1 = __importDefault(require("chalk"));
35
+ const utils = __importStar(require("@applitools/utils"));
36
+ const lang = __importStar(require("../../lang"));
37
+ /** Whether the capture keeps `environment` as its exact environment, at the same index. */
38
+ function isCapturedAsRequested(settings, driverEnvironment, environment) {
39
+ return (shouldTakeWebScreenshot(settings, driverEnvironment) &&
40
+ settings.screenshotMode !== 'default' &&
41
+ !('iosDeviceInfo' in environment) &&
42
+ !('androidDeviceInfo' in environment));
43
+ }
44
+ exports.isCapturedAsRequested = isCapturedAsRequested;
45
+ function shouldTakeWebScreenshot(settings, driverEnvironment) {
46
+ var _a;
47
+ return (driverEnvironment.isWeb ||
48
+ !((_a = driverEnvironment.applitoolsLib) === null || _a === void 0 ? void 0 : _a.instrumented) ||
49
+ !!settings.webview ||
50
+ settings.screenshotMode === 'default');
51
+ }
52
+ /**
53
+ * create base targets (array of screenshots) and base settings (array of check settings) for each environment
54
+ */
55
+ async function generateBaseScreenshotsAndSettings(settings, uniqueEnvironments, eyes, logger, driver) {
56
+ const driverEnvironment = await driver.getEnvironment();
57
+ uniqueEnvironments = addMobileDeviceInfo(uniqueEnvironments, driverEnvironment);
58
+ await beforeScreenshot();
59
+ if (shouldTakeWebScreenshot(settings, driverEnvironment)) {
60
+ return await takeWebScreenshot({
61
+ driver,
62
+ settings,
63
+ environments: uniqueEnvironments,
64
+ logger,
65
+ eyes,
66
+ });
67
+ }
68
+ else {
69
+ // take screenshot using NML
70
+ checkConflictingCapabilities();
71
+ return await takeNMLScreenshot({
72
+ driver,
73
+ settings,
74
+ environments: uniqueEnvironments,
75
+ logger,
76
+ eyes,
77
+ });
78
+ }
79
+ async function beforeScreenshot() {
80
+ var _a;
81
+ await driver.currentContext.setScrollingElement((_a = settings.scrollRootElement) !== null && _a !== void 0 ? _a : null);
82
+ if (settings.lazyLoad && driverEnvironment.isWeb) {
83
+ await (0, wait_for_lazy_load_1.waitForLazyLoad)({
84
+ context: driver.currentContext,
85
+ settings: settings.lazyLoad !== true ? settings.lazyLoad : {},
86
+ logger,
87
+ });
88
+ }
89
+ }
90
+ function checkConflictingCapabilities() {
91
+ var _a;
92
+ if ((_a = driverEnvironment.applitoolsLib) === null || _a === void 0 ? void 0 : _a.conflictingCapabilities) {
93
+ const message = lang.applitoolsLibConflictingCapabilitiesWarning({
94
+ conflictingCapabilities: driverEnvironment.applitoolsLib.conflictingCapabilities,
95
+ });
96
+ logger.console.log(chalk_1.default.yellow(message));
97
+ logger.log(message);
98
+ }
99
+ }
100
+ function addMobileDeviceInfo(environments, driverEnvironment) {
101
+ return environments.map(environment => {
102
+ var _a, _b;
103
+ var _c, _d;
104
+ if (utils.types.has(environment, 'iosDeviceInfo')) {
105
+ (_a = (_c = environment.iosDeviceInfo).version) !== null && _a !== void 0 ? _a : (_c.version = driverEnvironment.platformVersion);
106
+ }
107
+ else if (utils.types.has(environment, 'androidDeviceInfo')) {
108
+ (_b = (_d = environment.androidDeviceInfo).version) !== null && _b !== void 0 ? _b : (_d.version = driverEnvironment.platformVersion);
109
+ }
110
+ return environment;
111
+ });
112
+ }
113
+ }
114
+ exports.generateBaseScreenshotsAndSettings = generateBaseScreenshotsAndSettings;
115
+ async function takeWebScreenshot({ driver, settings, environments, logger, eyes, }) {
116
+ let actualEnvironments = environments;
117
+ if (settings.screenshotMode === 'default') {
118
+ const { localEnvironment, renderEnvironments } = await (0, nml_client_1.getNMLEnvironmentsInfo)({
119
+ environments: environments,
120
+ supportedEnvironmentsUrl: eyes.test.supportedEnvironmentsUrl,
121
+ proxy: eyes.test.eyesServer.proxy,
122
+ logger,
123
+ });
124
+ actualEnvironments = localEnvironment ? [localEnvironment] : renderEnvironments;
125
+ }
126
+ const { elementReferences, getBaseCheckSettings } = (0, to_base_check_settings_1.toBaseCheckSettings)({ settings });
127
+ const screenshots = await (0, take_screenshots_1.takeScreenshots)({
128
+ driver,
129
+ settings: {
130
+ ...settings,
131
+ environments: actualEnvironments,
132
+ regionsToCalculate: elementReferences.calculate,
133
+ calculateView: !!settings.pageId,
134
+ domSettings: settings.sendDom ? { proxy: eyes.test.eyesServer.proxy } : undefined,
135
+ },
136
+ logger,
137
+ });
138
+ return screenshots.map(({ calculatedRegions, ...baseTarget }, i) => {
139
+ return {
140
+ baseTarget,
141
+ baseSetting: getBaseCheckSettings({ calculatedRegions }),
142
+ exactEnvironment: actualEnvironments[i],
143
+ };
144
+ });
145
+ }
146
+ async function takeNMLScreenshot({ driver, settings, environments, logger, eyes, }) {
147
+ const nmlClient = await eyes.core.getNMLClient({
148
+ driver,
149
+ settings: { ...eyes.test.eyesServer, supportedEnvironmentsUrl: eyes.test.supportedEnvironmentsUrl },
150
+ logger,
151
+ });
152
+ if (settings.scrollRootElement || settings.region || (0, to_base_check_settings_1.hasCodedRegions)(settings)) {
153
+ //TODO we can skip `preTakeScreenshot` if the element/s already have the attribute `content-desc` (for android)
154
+ // and send it to `takeScreenshot` right away (possibly with `name` attribute for ios as well)
155
+ await nmlClient.preTakeScreenshot({ logger });
156
+ }
157
+ const { elementReferences, getBaseCheckSettings } = (0, to_base_check_settings_1.toBaseCheckSettings)({
158
+ settings: {
159
+ ...settings,
160
+ ...(await (0, to_base_check_settings_1.extractMobileElementsIntoCheckSettings)({ settings, driver, logger })),
161
+ },
162
+ });
163
+ const calculate = elementReferences.calculate;
164
+ if (typeof settings.waitBeforeCapture === 'function') {
165
+ throw new Error('providing functions to waitBeforeCapture is not supported in NML - please use a number instead');
166
+ }
167
+ const screenshots = await nmlClient.takeScreenshots({
168
+ settings: {
169
+ environments: environments,
170
+ fully: settings.fully,
171
+ stitchMode: settings.stitchMode,
172
+ hideScrollbars: settings.hideScrollbars,
173
+ hideCaret: settings.hideCaret,
174
+ overlap: settings.overlap,
175
+ waitBeforeCapture: settings.waitBeforeCapture,
176
+ waitBetweenStitches: settings.waitBetweenStitches,
177
+ lazyLoad: settings.lazyLoad,
178
+ name: settings.name,
179
+ region: elementReferences.target,
180
+ selectorsToFindRegionsFor: calculate.map(({ name }) => name),
181
+ scrollRootElement: elementReferences.scrolling,
182
+ sendDom: settings.sendDom,
183
+ },
184
+ logger,
185
+ });
186
+ return screenshots.map(({ calculateRegions, ...baseTarget }) => {
187
+ var _a, _b;
188
+ const aggregateCalculatedRegions = [];
189
+ calculate.forEach(({ reference }, index) => {
190
+ const regions = calculateRegions === null || calculateRegions === void 0 ? void 0 : calculateRegions[index];
191
+ if (regions) {
192
+ aggregateCalculatedRegions.push({ regions, selector: reference });
193
+ }
194
+ else {
195
+ logger.log(`Regions "${JSON.stringify(reference)}" was not found in the screenshot`);
196
+ }
197
+ });
198
+ if ((_a = baseTarget.dom) === null || _a === void 0 ? void 0 : _a.error) {
199
+ logger.warn('could not fetch DOM: ' + baseTarget.dom.error);
200
+ }
201
+ return {
202
+ baseTarget: { ...baseTarget, dom: (_b = baseTarget.dom) === null || _b === void 0 ? void 0 : _b.url, isTransformed: true },
203
+ baseSetting: getBaseCheckSettings({
204
+ calculatedRegions: aggregateCalculatedRegions,
205
+ }),
206
+ exactEnvironment: baseTarget.environment,
207
+ };
208
+ });
209
+ }
@@ -13,11 +13,11 @@ function makeGetTypedEyes({ type: defaultType, settings: defaultSettings, target
13
13
  return eyes;
14
14
  }
15
15
  else if (type === 'ufg') {
16
- const typedEyes = await cores.ufg.openEyes({ target, settings: defaultSettings, storage: eyes.storage, logger });
16
+ const typedEyes = await cores.ufg.openEyes({ target, settings: defaultSettings, session: eyes.session, logger });
17
17
  return typedEyes;
18
18
  }
19
19
  else {
20
- const typedEyes = await cores.classic.openEyes({ target, settings: defaultSettings, storage: eyes.storage, logger });
20
+ const typedEyes = await cores.classic.openEyes({ target, settings: defaultSettings, session: eyes.session, logger });
21
21
  return typedEyes;
22
22
  }
23
23
  };
@@ -194,7 +194,9 @@ async function runOfflineSnapshots(options) {
194
194
  const lastTarget = targets.pop();
195
195
  try {
196
196
  await uploadResourcePromise;
197
- await Promise.all(targets.map((target, index) => runCheck(eyes, target, index, logger)));
197
+ // The server records steps in arrival order, so replay them one at a time.
198
+ for (const [index, target] of targets.entries())
199
+ await runCheck(eyes, target, index, logger);
198
200
  if (lastTarget) {
199
201
  lastTarget.settings = (0, merge_configs_1.mergeConfigs)(lastTarget.settings, closeSettings);
200
202
  await runCheckAndClose(eyes, lastTarget, targets.length - 1, logger);
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.add = void 0;
4
+ const queries_1 = require("./queries");
5
+ /**
6
+ * Aborts the environment's session as soon as it is open, without waiting for its steps (they read the
7
+ * abort signal), unless an abort is already queued. A pending close or matchAndEnd still gets it; core-base ends a
8
+ * session only once. Kind `dismiss`: if the open is still lazy (nothing needed it), it's discarded and no session
9
+ * opens.
10
+ */
11
+ function add(graph, { inputs, labels }) {
12
+ var _a;
13
+ const { session, env } = labels;
14
+ const [abort] = (0, queries_1.queryTasks)({ session, type: 'abort', env });
15
+ if (abort)
16
+ return abort;
17
+ const open = (0, queries_1.environmentOpen)(labels);
18
+ const deps = { open };
19
+ const logger = (_a = open === null || open === void 0 ? void 0 : open.inputs.logger) !== null && _a !== void 0 ? _a : inputs.logger;
20
+ return graph.add({ type: 'abort', kind: 'dismiss', deps, inputs: { ...inputs, logger }, labels, logger, run });
21
+ }
22
+ exports.add = add;
23
+ async function run(deps, { settings, logger }) {
24
+ var _a, _b;
25
+ try {
26
+ await deps.open.abort({ settings, logger });
27
+ }
28
+ catch (error) {
29
+ logger.warn('Command "abort" received an error during waiting for eyes instances in background', error);
30
+ await ((_b = (_a = error === null || error === void 0 ? void 0 : error.info) === null || _a === void 0 ? void 0 : _a.eyes) === null || _b === void 0 ? void 0 : _b.abort({ settings, logger }));
31
+ }
32
+ }
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.add = void 0;
4
+ /**
5
+ * A check the test was aborted during, before it added its steps: it fails with the abort and is kept by its
6
+ * session, so the environment's getResults rejects with it.
7
+ */
8
+ function add(graph, { inputs, labels }) {
9
+ return graph.add({ type: 'abortedCheck', inputs, labels, keep: labels.session, run });
10
+ }
11
+ exports.add = add;
12
+ async function run(_deps, { error }) {
13
+ throw error;
14
+ }
@@ -0,0 +1,54 @@
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.add = void 0;
27
+ const utils = __importStar(require("@applitools/utils"));
28
+ const capture_1 = require("../../classic/utils/capture");
29
+ const to_environment_key_1 = require("../../automation/utils/to-environment-key");
30
+ const openTask = __importStar(require("../open"));
31
+ /**
32
+ * A classic check's capture of every environment in one pass — they share the driver, whose viewport
33
+ * it resizes per environment. The check awaits it, so the page stays untouched until it's done.
34
+ */
35
+ function add(graph, { inputs, labels }) {
36
+ const { eyes, driver, environments, newTestDelay, logger } = inputs;
37
+ const opens = newTestDelay
38
+ ? environments.map(environment => openTask.add(graph, {
39
+ inputs: { eyes, environment, driver, logger: eyes.getEnvironmentLogger(environment, logger) },
40
+ labels: { session: labels.session, env: (0, to_environment_key_1.toEnvironmentKey)(environment) },
41
+ }))
42
+ : [];
43
+ const deps = Object.fromEntries(opens.map((open, index) => [`open${index}`, open]));
44
+ return graph.add({ type: 'capture', deps, inputs, labels, logger: inputs.logger, run });
45
+ }
46
+ exports.add = add;
47
+ async function run(deps, inputs) {
48
+ const { eyes, driver, settings, environments, newTestDelay, logger } = inputs;
49
+ // if the test is new for any of the environments, we wait for the page to stabaliize before starting the checks. This should prevent us from creating a baseline with a loading spinner or something similar
50
+ if (newTestDelay && Object.values(deps).some(baseEyes => baseEyes.test.isNew)) {
51
+ await utils.general.sleep(newTestDelay);
52
+ }
53
+ return (0, capture_1.generateBaseScreenshotsAndSettings)(settings, environments, eyes, logger, driver);
54
+ }
@@ -0,0 +1,51 @@
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.addCapture = exports.addCheckAndClose = exports.addCheck = void 0;
27
+ const graph_1 = require("../graph");
28
+ const openTask = __importStar(require("../open"));
29
+ const uploadTask = __importStar(require("./upload"));
30
+ const matchTask = __importStar(require("../match"));
31
+ const captureTask = __importStar(require("./capture"));
32
+ const lifecycle_1 = require("../lifecycle");
33
+ /** A check step: its upload, then its match after the environment's previous one. */
34
+ function addCheck(session, env, step) {
35
+ const labels = { session, env };
36
+ openTask.add(graph_1.graph, { inputs: step.open, labels });
37
+ const upload = uploadTask.add(graph_1.graph, { deps: { capture: step.capture }, inputs: step.upload, labels });
38
+ return matchTask.add(graph_1.graph, { deps: { upload }, inputs: step.inputs, labels });
39
+ }
40
+ exports.addCheck = addCheck;
41
+ /** A check step and the close it fuses into: one `matchAndEnd`. */
42
+ function addCheckAndClose(session, env, { settings, ...step }) {
43
+ addCheck(session, env, step);
44
+ (0, lifecycle_1.addClose)(session, env, { settings, logger: step.inputs.logger });
45
+ }
46
+ exports.addCheckAndClose = addCheckAndClose;
47
+ /** A classic check's capture; its steps read their targets from it by index. */
48
+ function addCapture(session, inputs) {
49
+ return captureTask.add(graph_1.graph, { inputs, labels: { session, env: '' } });
50
+ }
51
+ exports.addCapture = addCapture;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.add = void 0;
4
+ const abort_error_1 = require("../../errors/abort-error");
5
+ const upload_target_1 = require("../upload-target");
6
+ const queries_1 = require("../queries");
7
+ /** The slow leg of a classic check step: normalize the captured target and upload its resources. */
8
+ function add(graph, { deps, inputs, labels }) {
9
+ return graph.add({
10
+ type: 'upload',
11
+ deps: { ...deps, open: (0, queries_1.environmentOpen)(labels) },
12
+ inputs,
13
+ labels,
14
+ logger: inputs.logger,
15
+ run,
16
+ });
17
+ }
18
+ exports.add = add;
19
+ /** Resolves `undefined` when the capture failed: the check throws it, and the step is skipped. */
20
+ async function run(deps, { signal, logger, ...step }) {
21
+ const baseEyes = deps.open;
22
+ let target;
23
+ if ('index' in step) {
24
+ let captured;
25
+ try {
26
+ captured = deps.capture;
27
+ }
28
+ catch {
29
+ return undefined;
30
+ }
31
+ const { baseTarget, baseSetting } = captured[step.index];
32
+ target = { target: baseTarget, settings: baseSetting };
33
+ }
34
+ else {
35
+ target = step;
36
+ }
37
+ if ((signal === null || signal === void 0 ? void 0 : signal.aborted) || !baseEyes.running)
38
+ throw new abort_error_1.AbortError('Command "check" was aborted before uploading');
39
+ return (0, upload_target_1.uploadTarget)(baseEyes, target, logger);
40
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.add = void 0;
4
+ const queries_1 = require("./queries");
5
+ /**
6
+ * The environment's terminal close, unless a close, abort or fused match already ends it. Kind `dismiss`: if the
7
+ * open is still lazy (nothing needed it), it's discarded and no session opens.
8
+ */
9
+ function add(graph, { inputs, labels }) {
10
+ var _a;
11
+ const { session, env } = labels;
12
+ const [ending] = ['close', 'abort', 'matchAndEnd'].flatMap(type => (0, queries_1.queryTasks)({ session, type, env }));
13
+ if (ending)
14
+ return ending;
15
+ const open = (0, queries_1.environmentOpen)(labels);
16
+ const deps = { open };
17
+ // After the environment's last step, so a still-unstarted match fuses into this close.
18
+ const after = [(0, queries_1.lastStep)(session, env)];
19
+ const logger = (_a = open === null || open === void 0 ? void 0 : open.inputs.logger) !== null && _a !== void 0 ? _a : inputs.logger;
20
+ return graph.add({ type: 'close', kind: 'dismiss', deps, after, inputs: { ...inputs, logger }, labels, logger, run });
21
+ }
22
+ exports.add = add;
23
+ async function run({ open: baseEyes }, { settings, logger }) {
24
+ try {
25
+ await baseEyes.close({ settings, logger });
26
+ }
27
+ catch (error) {
28
+ logger.warn('Command "close" received an error during performing, trying to perform abort instead', error);
29
+ await baseEyes.abort({ settings, logger });
30
+ }
31
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.add = void 0;
4
+ const queries_1 = require("./queries");
5
+ /**
6
+ * An empty test's environment that still gets a session: as a normal dependent, it activates the lazy open, so
7
+ * the close or abort resting on it can't dismiss it.
8
+ */
9
+ function add(graph, { labels }) {
10
+ const deps = { open: (0, queries_1.environmentOpen)(labels) };
11
+ return graph.add({ type: 'fill', deps, labels, run: async () => { } });
12
+ }
13
+ exports.add = add;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.add = void 0;
4
+ const queries_1 = require("./queries");
5
+ /** The environment's result, once everything else in it has settled. */
6
+ function add(graph, { inputs, labels }) {
7
+ var _a;
8
+ const { session, env } = labels;
9
+ const open = (0, queries_1.environmentOpen)(labels);
10
+ const deps = { open, aborted: (0, queries_1.queryTasks)({ session, type: 'abortedCheck', env })[0] };
11
+ // After every unfinished leaf of the environment's tasks, so the result comes after all of them.
12
+ const after = graph.filter(task => task.labels.session === session && task.labels.env === env && task.dependents.size === 0);
13
+ const logger = (_a = open === null || open === void 0 ? void 0 : open.inputs.logger) !== null && _a !== void 0 ? _a : inputs.logger;
14
+ return graph.add({ type: 'getResults', deps, after, inputs: { ...inputs, logger }, labels, logger, run });
15
+ }
16
+ exports.add = add;
17
+ async function run(deps, { settings, logger }) {
18
+ try {
19
+ // Reading a failed dependency throws its error.
20
+ void deps.aborted;
21
+ const baseEyes = deps.open;
22
+ const [result] = await baseEyes.getResults({ settings, logger });
23
+ return { ...result, environment: baseEyes.test.environment };
24
+ }
25
+ catch (error) {
26
+ logger.fatal('Command "getResults" received an error', error, 'during performing with settings', settings);
27
+ throw error;
28
+ }
29
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.graph = void 0;
4
+ const task_manager_1 = require("@applitools/task-manager");
5
+ /** Core's one task graph — every test is a disjoint tree in it. */
6
+ exports.graph = (0, task_manager_1.makeTaskManager)();
@@ -0,0 +1,20 @@
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.activeEnvironmentKeys = void 0;
18
+ __exportStar(require("./lifecycle"), exports);
19
+ var queries_1 = require("./queries");
20
+ Object.defineProperty(exports, "activeEnvironmentKeys", { enumerable: true, get: function () { return queries_1.activeEnvironmentKeys; } });
@@ -0,0 +1,101 @@
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.addAbortedCheck = exports.getResults = exports.addClose = exports.abortSession = exports.closeSession = exports.declareFillers = exports.declareOpens = void 0;
27
+ const graph_1 = require("./graph");
28
+ const openTask = __importStar(require("./open"));
29
+ const closeTask = __importStar(require("./close"));
30
+ const abortTask = __importStar(require("./abort"));
31
+ const fillTask = __importStar(require("./fill"));
32
+ const getResultsTask = __importStar(require("./get-results"));
33
+ const abortedCheckTask = __importStar(require("./aborted-check"));
34
+ const abort_error_1 = require("../errors/abort-error");
35
+ const to_environment_key_1 = require("../automation/utils/to-environment-key");
36
+ const queries_1 = require("./queries");
37
+ /**
38
+ * Declares the opens of the environments known at openEyes, lazy: the first check needing one opens it,
39
+ * and a close that finds it still unneeded dismisses it, so no empty session is created.
40
+ */
41
+ function declareOpens(eyes, environments, driver, logger) {
42
+ for (const environment of environments) {
43
+ const open = { eyes, environment, driver, logger: eyes.getEnvironmentLogger(environment, logger) };
44
+ openTask.add(graph_1.graph, { inputs: open, labels: { session: eyes.session, env: (0, to_environment_key_1.toEnvironmentKey)(environment) } });
45
+ }
46
+ }
47
+ exports.declareOpens = declareOpens;
48
+ /**
49
+ * Fills an empty test's environments, so it still has a session per environment: the ones its close names
50
+ * (declared here), or else a classic test's declared ones. An empty ufg test that names none opens nothing.
51
+ * Returns the filled environments' opens.
52
+ */
53
+ function declareFillers(eyes, environments, logger) {
54
+ const session = eyes.session;
55
+ if ((0, queries_1.openedEnvironmentKeys)(session).length > 0)
56
+ return [];
57
+ const opens = (environments === null || environments === void 0 ? void 0 : environments.length)
58
+ ? environments.map(environment => openTask.add(graph_1.graph, {
59
+ inputs: { eyes, environment, logger: eyes.getEnvironmentLogger(environment, logger) },
60
+ labels: { session, env: (0, to_environment_key_1.toEnvironmentKey)(environment) },
61
+ }))
62
+ : eyes.type === 'classic'
63
+ ? (0, queries_1.queryTasks)({ session, type: 'open' })
64
+ : [];
65
+ for (const open of opens)
66
+ fillTask.add(graph_1.graph, { labels: open.labels });
67
+ return opens;
68
+ }
69
+ exports.declareFillers = declareFillers;
70
+ /** Closes every environment of the session; a still-unstarted last match fuses into its close. */
71
+ function closeSession(session, inputs) {
72
+ for (const env of (0, queries_1.environmentKeys)(session))
73
+ addClose(session, env, inputs);
74
+ }
75
+ exports.closeSession = closeSession;
76
+ /** Aborts every environment of the session as soon as it is open, without waiting for its steps. */
77
+ function abortSession(session, inputs) {
78
+ for (const env of (0, queries_1.environmentKeys)(session)) {
79
+ abortTask.add(graph_1.graph, { inputs, labels: { session, env } });
80
+ }
81
+ }
82
+ exports.abortSession = abortSession;
83
+ /** Closes the environment after its last step. */
84
+ function addClose(session, env, inputs) {
85
+ closeTask.add(graph_1.graph, { inputs, labels: { session, env } });
86
+ }
87
+ exports.addClose = addClose;
88
+ /** The environment's result, after every unfinished task of it — its last match, close or abort. */
89
+ function getResults(session, env, inputs) {
90
+ return getResultsTask.add(graph_1.graph, { inputs, labels: { session, env } }).promise;
91
+ }
92
+ exports.getResults = getResults;
93
+ /** Records a check the test was aborted during, before it added its steps (see `aborted-check.ts`). */
94
+ function addAbortedCheck(eyes, environments, message, logger) {
95
+ logger.warn(message);
96
+ for (const environment of environments) {
97
+ const error = new abort_error_1.AbortError(message, { userTestId: eyes.test.userTestId, environment });
98
+ abortedCheckTask.add(graph_1.graph, { inputs: { error }, labels: { session: eyes.session, env: (0, to_environment_key_1.toEnvironmentKey)(environment) } });
99
+ }
100
+ }
101
+ exports.addAbortedCheck = addAbortedCheck;