@applitools/core 4.56.2 → 4.56.3

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,59 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.56.3](https://github.com/Applitools-Dev/sdk/compare/js/core@4.56.2...js/core@4.56.3) (2026-03-01)
4
+
5
+
6
+ ### Performance Improvements
7
+
8
+ * use sharp to accelerate png performance in all js packages ([#3547](https://github.com/Applitools-Dev/sdk/issues/3547)) ([6e3c7b9](https://github.com/Applitools-Dev/sdk/commit/6e3c7b9e34815f470032ece52a161001592ad1b1))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * @applitools/dom-snapshot bumped to 4.15.9
14
+ #### Bug Fixes
15
+
16
+ * expand CSS vars in CSSOM-injected style tags | FLD-4106 ([0821f9e](https://github.com/Applitools-Dev/sdk/commit/0821f9e7f6b20ec05387a8523dc0254bac22591b))
17
+ * @applitools/image bumped to 1.2.7
18
+ #### Performance Improvements
19
+
20
+ * use sharp to accelerate png performance in all js packages ([#3547](https://github.com/Applitools-Dev/sdk/issues/3547)) ([6e3c7b9](https://github.com/Applitools-Dev/sdk/commit/6e3c7b9e34815f470032ece52a161001592ad1b1))
21
+ * @applitools/screenshoter bumped to 3.12.14
22
+ #### Performance Improvements
23
+
24
+ * use sharp to accelerate png performance in all js packages ([#3547](https://github.com/Applitools-Dev/sdk/issues/3547)) ([6e3c7b9](https://github.com/Applitools-Dev/sdk/commit/6e3c7b9e34815f470032ece52a161001592ad1b1))
25
+
26
+
27
+
28
+ * @applitools/nml-client bumped to 1.11.17
29
+ #### Performance Improvements
30
+
31
+ * use sharp to accelerate png performance in all js packages ([#3547](https://github.com/Applitools-Dev/sdk/issues/3547)) ([6e3c7b9](https://github.com/Applitools-Dev/sdk/commit/6e3c7b9e34815f470032ece52a161001592ad1b1))
32
+
33
+
34
+
35
+ * @applitools/ufg-client bumped to 1.19.2
36
+ #### Performance Improvements
37
+
38
+ * use sharp to accelerate png performance in all js packages ([#3547](https://github.com/Applitools-Dev/sdk/issues/3547)) ([6e3c7b9](https://github.com/Applitools-Dev/sdk/commit/6e3c7b9e34815f470032ece52a161001592ad1b1))
39
+
40
+
41
+
42
+ * @applitools/core-base bumped to 1.31.3
43
+ #### Performance Improvements
44
+
45
+ * use sharp to accelerate png performance in all js packages ([#3547](https://github.com/Applitools-Dev/sdk/issues/3547)) ([6e3c7b9](https://github.com/Applitools-Dev/sdk/commit/6e3c7b9e34815f470032ece52a161001592ad1b1))
46
+
47
+
48
+
49
+ * @applitools/ec-client bumped to 1.12.19
50
+ #### Performance Improvements
51
+
52
+ * use sharp to accelerate png performance in all js packages ([#3547](https://github.com/Applitools-Dev/sdk/issues/3547)) ([6e3c7b9](https://github.com/Applitools-Dev/sdk/commit/6e3c7b9e34815f470032ece52a161001592ad1b1))
53
+
54
+
55
+
56
+
3
57
  ## [4.56.2](https://github.com/Applitools-Dev/sdk/compare/js/core@4.56.1...js/core@4.56.2) (2026-02-16)
4
58
 
5
59
 
package/README.md ADDED
@@ -0,0 +1,200 @@
1
+ # @applitools/core
2
+
3
+ The core SDK package that orchestrates visual testing via two distinct check strategies: **Classic** and **UFG** (Ultrafast Grid).
4
+
5
+ ---
6
+
7
+ ## Check Strategies Overview
8
+
9
+ Both strategies share the same entry point (`src/check.ts`) which normalizes settings and then delegates to the appropriate typed implementation based on the `type` parameter (`'classic'` or `'ufg'`).
10
+
11
+ ```
12
+ eyes.check()
13
+ └── src/check.ts ← normalizes settings, resolves type
14
+ ├── classic/check.ts ← screenshot-based flow
15
+ └── ufg/check.ts ← DOM snapshot + cloud rendering flow
16
+ ```
17
+
18
+ ---
19
+
20
+ ## Classic Check
21
+
22
+ **Concept**: Capture a screenshot locally (in the test runner's browser/device) and send it to Applitools for comparison against the baseline.
23
+
24
+ ### Flow
25
+
26
+ ```
27
+ check()
28
+
29
+ ├── [driver target?]
30
+ │ │
31
+ │ ├── beforeScreenshot()
32
+ │ │ ├── setScrollingElement
33
+ │ │ └── waitForLazyLoad (if enabled)
34
+ │ │
35
+ │ ├── [web or native?]
36
+ │ │ ├── takeWebScreenshot()
37
+ │ │ │ ├── takeScreenshot() ← scrolls, stitches, captures PNG
38
+ │ │ │ └── takeDomCapture() ← captures DOM (if sendDom=true)
39
+ │ │ │
40
+ │ │ └── takeNMLScreenshot()
41
+ │ │ └── nmlClient.takeScreenshots() ← native mobile (NML)
42
+ │ │
43
+ │ └── [matchTimeout set?]
44
+ │ ├── YES → checkEnvironment() synchronously, retry until passes
45
+ │ └── NO → checkInTheBackground() ← fire-and-forget, non-blocking
46
+
47
+ └── [image target?]
48
+ └── checkInTheBackground() ← directly queue pre-captured image
49
+ ```
50
+
51
+ ### Key files
52
+
53
+ | File | Purpose |
54
+ |------|---------|
55
+ | `src/classic/check.ts` | Orchestrates the classic check flow |
56
+ | `src/classic/utils/take-screenshots.ts` | Takes the screenshot and optional DOM capture |
57
+ | `src/classic/utils/take-dom-capture.ts` | Captures the page DOM for RCA |
58
+ | `src/automation/utils/take-screenshot.ts` | Low-level screenshot + stitching logic |
59
+
60
+ ### What happens on each check
61
+
62
+ 1. **Settings normalization** — applied in `src/check.ts` (defaults for `fully`, `matchLevel`, `sendDom`, etc.)
63
+ 2. **Scroll root / lazy load** — the driver scrolls and waits for deferred content
64
+ 3. **Screenshot** — a full-page or viewport PNG is captured locally
65
+ 4. **DOM capture** (optional) — if `sendDom=true`, the serialized DOM is captured for Root Cause Analysis (RCA)
66
+ 5. **Session open** (lazy) — `getBaseEyes()` opens the Applitools test session on first use
67
+ 6. **Upload + compare** — `baseEyes.check()` uploads the image+DOM and triggers comparison
68
+
69
+ ### matchTimeout behavior
70
+
71
+ When `matchTimeout > 0`, the SDK retries the entire screenshot→compare cycle until the result matches expectations or the timeout expires. This blocks the test execution thread and is designed to tolerate transient UI states (e.g., loading spinners).
72
+
73
+ ### Background queuing
74
+
75
+ When `matchTimeout = 0` (default), checks are queued as background promises. The test thread is not blocked. `eyes.close()` awaits all queued jobs before resolving results.
76
+
77
+ ---
78
+
79
+ ## UFG Check (Ultrafast Grid)
80
+
81
+ **Concept**: Capture a DOM snapshot locally, upload it to the Applitools rendering farm (UFG - Ultrafast Grid), which renders it in multiple browsers and devices in the cloud and then compares each rendered image against the baseline.
82
+
83
+ ### Flow
84
+
85
+ ```
86
+ check()
87
+
88
+ ├── getUFGClient() ← initialize methods for UFG purposes
89
+
90
+ ├── [driver target?]
91
+ │ └── takeSnapshots()
92
+ │ ├── setScrollingElement
93
+ │ ├── takeDomSnapshots() ← serialized DOM + resources
94
+ │ │ └── (per environment: browser widths, layout breakpoints)
95
+ │ └── driver.getUrl() / getTitle() / getUserAgent()
96
+
97
+ ├── [for each snapshot × environment]
98
+ │ ├── createRenderTargetFromSnapshot()
99
+ │ │ └── ufgClient.uploadResources() ← CSS, fonts, images → UFG CDN
100
+ │ │
101
+ │ ├── getBaseEyes() ← open test session (lazy, per environment)
102
+ │ │
103
+ │ ├── ufgClient.render()
104
+ │ │ └── UFG renders DOM in target browser/device → returns rendered image
105
+ │ │
106
+ │ └── baseEyes.check() ← compare rendered image against baseline
107
+
108
+ └── all environment promises queued in eyes.storage
109
+ ```
110
+
111
+ ### Key files
112
+
113
+ | File | Purpose |
114
+ |------|---------|
115
+ | `src/ufg/check.ts` | Orchestrates the UFG check flow |
116
+ | `src/ufg/take-snapshots.ts` | Takes DOM snapshots per environment |
117
+ | `src/ufg/create-render-target-from-snapshot.ts` | Uploads resources to UFG CDN, builds render target |
118
+ | `src/ufg/utils/take-dom-snapshots.ts` | Serializes DOM including cross-frame content |
119
+
120
+ ### What happens on each check
121
+
122
+ 1. **Settings normalization** — same as Classic (`src/check.ts`)
123
+ 2. **DOM snapshot** — the page's full DOM (HTML, CSS, iframes) is serialized and resources are collected
124
+ 3. **Resource upload** — CSS, fonts, images are uploaded to the UFG CDN (cached by URL to avoid re-uploads)
125
+ 4. **Render request** — sent to the UFG rendering farm per target environment (browser + viewport or device)
126
+ 5. **Session open** (lazy, per environment) — `getBaseEyes()` opens one Applitools session per environment
127
+ 6. **Compare** — `baseEyes.check()` receives the rendered image reference (`renderId`) and triggers comparison
128
+
129
+ ### Environment targeting
130
+
131
+ UFG supports rendering in multiple environments per check:
132
+
133
+ ```ts
134
+ settings.environments = [
135
+ { name: 'chrome', width: 1280, height: 800 },
136
+ { name: 'firefox', width: 1280, height: 800 },
137
+ { chromeEmulationInfo: { deviceName: 'Pixel 4 XL' } },
138
+ { iosDeviceInfo: { deviceName: 'iPhone 12', version: 'latest' } },
139
+ ]
140
+ ```
141
+
142
+ Each environment produces one independent test session, one render, and one comparison result.
143
+
144
+ ### Layout breakpoints
145
+
146
+ UFG supports `layoutBreakpoints` — the DOM is snapshotted at each specified viewport width to capture responsive layout differences, and UFG renders each environment at the closest matching breakpoint.
147
+
148
+ ---
149
+
150
+ ## Classic vs UFG: Key Differences
151
+
152
+ | Aspect | Classic | UFG |
153
+ |--------|---------|-----|
154
+ | **What's captured locally** | Screenshot (PNG) | DOM snapshot (HTML/CSS/resources) |
155
+ | **Where rendering happens** | Local driver (real browser) | Applitools cloud (UFG rendering farm) |
156
+ | **Multi-environment** | Takes one screenshot, reuses for all envs | Renders separately per environment |
157
+ | **Native mobile** | Supported via NML (real devices) | Supported via cloud device emulation |
158
+ | **DOM capture** | Optional (for RCA) | Always — it's the input |
159
+ | **Concurrency usage** | One slot per environment | One slot per environment |
160
+ | **matchTimeout** | Supported (retry loop) | Not supported |
161
+ | **Scroll/stitch** | Done locally by the SDK | Done by UFG renderer |
162
+
163
+ ---
164
+
165
+ ## Environment Terminology
166
+
167
+ Two distinct environment shapes flow through classic check. Confusing them is the source of a known bug.
168
+
169
+ | Name | TypeScript type | Shape | Where it comes from |
170
+ |------|----------------|-------|---------------------|
171
+ | **Requested environment** (also called *unique environment*) | `RenderEnvironment` | `{iosDeviceInfo: {deviceName: 'iPhone 12'}}` or `{name: 'chrome', width: 1280, height: 800}` | Comes from `settings.environments` (user input). After `uniquifyEnvironments()`, duplicates get a synthetic `environmentId` to map to separate sessions. |
172
+ | **Actual / exact environment** | `ExactEnvironment` | `{environmentId, deviceName, os, viewportSize, requested: <RenderEnvironment>}` | Returned by `takeWebScreenshot` / `takeNMLScreenshot` after the device is resolved. The flat shape that `core-base` and the Applitools server understand. Always has `requested` pointing back to the original `RenderEnvironment`. |
173
+
174
+ **Key invariant:** `toEnvironmentKey(exactEnvironment)` === `toEnvironmentKey(requestedEnvironment)` because `toEnvironmentKey` uses `env.requested ?? env`. This is how the `makeGetBaseEyes` cache correctly matches an early session-open (keyed on the requested environment) to the later check (keyed on the exact environment).
175
+
176
+ **Known bug:** In the `matchTimeout` path, `base.openEyes` is called with the *requested* environment (`{iosDeviceInfo: ...}`) instead of the *exact* environment (`{deviceName, os, viewportSize, ...}`). `core-base/server/requests.ts` reads the flat fields (`os`, `deviceName`, `viewportSize`) which are `undefined` on the requested form, so the session opens on the server with empty environment info. This only affects NML (iOS/Android native) environments since web environments are not transformed and `exactEnvironment === requestedEnvironment`.
177
+
178
+ ---
179
+
180
+ ## Session Lifecycle (Both Strategies)
181
+
182
+ Sessions are opened **lazily** — the Applitools test session is not created during `openEyes()`, but on the first `getBaseEyes()` call within a check. This avoids charging concurrency for tests that open but never check.
183
+
184
+ ```
185
+ openEyes() → creates in-memory Eyes object, no server call
186
+ check() → getBaseEyes() → POST /api/sessions (first time only)
187
+ check() → getBaseEyes() → returns cached session (subsequent calls)
188
+ close() / abort() → closes all open sessions, awaits all queued jobs
189
+ ```
190
+
191
+ ---
192
+
193
+ ## Storage Model
194
+
195
+ Both strategies push check promises into `eyes.storage`, a `Map<environmentKey, {eyes, jobs[]}>`:
196
+
197
+ - `eyes` — a controlled promise resolving to the base eyes session
198
+ - `jobs` — array of check promises for that environment
199
+
200
+ `close()` waits for all jobs across all environments before collecting results.
@@ -1,8 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.makeGetNMLClient = void 0;
3
+ exports.makeGetNMLClient = exports.clearNMLClients = void 0;
4
4
  const nml_client_1 = require("@applitools/nml-client");
5
5
  const clients = new Map();
6
+ // for tests
7
+ function clearNMLClients() {
8
+ clients.clear();
9
+ }
10
+ exports.clearNMLClients = clearNMLClients;
6
11
  function makeGetNMLClient({ client, logger: mainLogger }) {
7
12
  return {
8
13
  getNMLClient,
@@ -96,19 +96,31 @@ function makeCheck({ eyes, target: defaultTarget, environments: defaultEnvironme
96
96
  } while (!asExpected && Date.now() - start < settings.matchTimeout);
97
97
  }
98
98
  else {
99
+ // Eagerly start opening sessions for web environments while screenshots are being taken.
100
+ // NML environments are excluded because their exact environment shape (deviceName, os,
101
+ // viewportSize) is only resolved after generateBaseScreenshotsAndSettings() returns, and
102
+ // using the unique env shape would open the session with wrong/empty fields.
103
+ const environmentLoggers = new Map();
104
+ uniqueEnvironments
105
+ .filter(env => !('iosDeviceInfo' in env) && !('androidDeviceInfo' in env))
106
+ .forEach(environment => {
107
+ const environmentLogger = logger.extend({ tags: [`environment-${utils.general.shortid()}`] });
108
+ environmentLoggers.set((0, to_environment_key_1.toEnvironmentKey)(environment), environmentLogger);
109
+ void getBaseEyes({ environment, driver, logger: environmentLogger });
110
+ });
99
111
  // generate base targets (images to be compared) and settings for each environment
100
112
  const baseScreenshotsAndSettings = await generateBaseScreenshotsAndSettings(settings, uniqueEnvironments, eyes, logger, driver);
101
113
  // when no match timeout is set, queue all environment checks against the server without stalling the client test execution
102
114
  baseScreenshotsAndSettings.forEach(({ exactEnvironment: environment, baseSetting, baseTarget }) => {
103
- checkInTheBackground(environment, baseTarget, baseSetting);
115
+ checkInTheBackground(environment, baseTarget, baseSetting, environmentLoggers.get((0, to_environment_key_1.toEnvironmentKey)(environment)));
104
116
  });
105
117
  }
106
118
  }
107
119
  else {
108
120
  uniqueEnvironments.forEach(environment => checkInTheBackground(environment, target, settings));
109
121
  }
110
- function checkInTheBackground(environment, target, settings) {
111
- putInStorage(environment, eyes, checkEnvironment({ eyes, driver, target, environment, signal, logger, settings }));
122
+ function checkInTheBackground(environment, target, settings, environmentLogger) {
123
+ putInStorage(environment, eyes, checkEnvironment({ eyes, driver, target, environment, signal, logger, settings, environmentLogger }));
112
124
  }
113
125
  };
114
126
  function putInStorage(environment, eyes, promise) {
@@ -155,9 +167,9 @@ async function logAmmutabilityIfNeeded({ eyes, baseEyes, settings, }) {
155
167
  settings.assumesMutability = false; // prevent from logging this message again for the same check
156
168
  }
157
169
  }
158
- async function checkEnvironment({ eyes, driver, target, environment, signal, logger, settings, }) {
170
+ async function checkEnvironment({ eyes, driver, target, environment, signal, logger, settings, environmentLogger: providedEnvironmentLogger, }) {
159
171
  var _a, _b;
160
- const environmentLogger = logger.extend({ tags: [`environment-${utils.general.shortid()}`] });
172
+ const environmentLogger = providedEnvironmentLogger !== null && providedEnvironmentLogger !== void 0 ? providedEnvironmentLogger : logger.extend({ tags: [`environment-${utils.general.shortid()}`] });
161
173
  environmentLogger.log('Command "check" is called with settings', settings);
162
174
  try {
163
175
  if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
package/dist/index.js CHANGED
@@ -26,14 +26,14 @@ var __importStar = (this && this.__importStar) || function (mod) {
26
26
  return result;
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.MissingApiKeyError = exports.logs = exports.formatters = void 0;
29
+ exports.MissingApiKeyError = exports.checkNetwork = exports.logs = exports.formatters = void 0;
30
30
  __exportStar(require("./types"), exports);
31
31
  __exportStar(require("./core"), exports);
32
- __exportStar(require("./universal/core-server"), exports);
33
- __exportStar(require("./universal/core-server-process"), exports);
34
32
  __exportStar(require("./autonomous/core"), exports);
35
33
  __exportStar(require("@applitools/driver/dist/debug"), exports);
36
34
  exports.formatters = __importStar(require("./utils/format-results"));
37
35
  exports.logs = __importStar(require("./troubleshoot/logs"));
36
+ var check_network_1 = require("./troubleshoot/check-network");
37
+ Object.defineProperty(exports, "checkNetwork", { enumerable: true, get: function () { return check_network_1.checkNetwork; } });
38
38
  var core_base_1 = require("@applitools/core-base");
39
39
  Object.defineProperty(exports, "MissingApiKeyError", { enumerable: true, get: function () { return core_base_1.MissingApiKeyError; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applitools/core",
3
- "version": "4.56.2",
3
+ "version": "4.56.3",
4
4
  "homepage": "https://applitools.com",
5
5
  "bugs": {
6
6
  "url": "https://github.com/applitools/eyes.sdk.javascript1/issues"
@@ -32,8 +32,7 @@
32
32
  "./package.json": "./package.json"
33
33
  },
34
34
  "bin": {
35
- "eyes-check-network": "./dist/troubleshoot/check-network.js",
36
- "eyes-core": "./dist/cli/cli.js"
35
+ "eyes-check-network": "./dist/troubleshoot/check-network.js"
37
36
  },
38
37
  "main": "./dist/index.js",
39
38
  "types": "./types/index.d.ts",
@@ -48,11 +47,9 @@
48
47
  "lint": "run --top-level eslint '**/*.ts'",
49
48
  "build": "yarn build:dist",
50
49
  "build:dist": "run --top-level tsc --project ./tsconfig.build.json",
51
- "build:bin": "bash ../../../scripts/build-binary-local.sh core",
52
- "test": "run --top-level mocha './test/**/*.spec.ts' --exclude './test/bin/**' --exclude './test/e2e/mocha-sync/**' --parallel --jobs ${MOCHA_JOBS:-15} --exit --require ./test/mocha-global-setup.js",
50
+ "test": "run --top-level mocha './test/**/*.spec.ts' --exclude './test/e2e/mocha-sync/**' --parallel --jobs ${MOCHA_JOBS:-15} --exit --require ./test/mocha-global-setup.js",
53
51
  "test:local": "MOCHA_OMIT_TAGS=sauce,browserstack run test",
54
52
  "test:sauce": "MOCHA_ONLY_TAGS=sauce,browserstack run test",
55
- "test:bin": "MOCHA_GROUP=bin run --top-level mocha './test/bin/**/*.spec.ts' --parallel --jobs ${MOCHA_JOBS:-15} --require ./test/mocha-global-setup.js",
56
53
  "test:e2e": "MOCHA_GROUP=e2e run --top-level mocha './test/e2e/**/*.spec.ts' --exclude './test/e2e/mocha-sync/**' --parallel --jobs ${MOCHA_JOBS:-15} --exit --require ./test/mocha-global-setup.js",
57
54
  "test:it": "MOCHA_GROUP=it run --top-level mocha './test/it/**/*.spec.ts' --require ./test/mocha-global-setup.js",
58
55
  "test:e2e:sync": "MOCHA_GROUP=e2e SYNC=true run --top-level mocha './test/e2e/mocha-sync/**/*.spec.ts' --exit --require ./test/mocha-global-setup.js",
@@ -61,29 +58,24 @@
61
58
  "setup:standalone": "sh -c 'yarn chromedriver --port=4444 --verbose &'"
62
59
  },
63
60
  "dependencies": {
64
- "@applitools/core-base": "1.31.2",
61
+ "@applitools/core-base": "1.31.3",
65
62
  "@applitools/dom-capture": "11.6.9",
66
- "@applitools/dom-snapshot": "4.15.8",
63
+ "@applitools/dom-snapshot": "4.15.9",
67
64
  "@applitools/driver": "1.25.1",
68
- "@applitools/ec-client": "1.12.18",
65
+ "@applitools/ec-client": "1.12.19",
69
66
  "@applitools/logger": "2.2.8",
70
- "@applitools/nml-client": "1.11.16",
67
+ "@applitools/nml-client": "1.11.17",
71
68
  "@applitools/req": "1.8.8",
72
- "@applitools/screenshoter": "3.12.13",
69
+ "@applitools/screenshoter": "3.12.14",
73
70
  "@applitools/snippets": "2.7.0",
74
71
  "@applitools/socket": "1.3.9",
75
- "@applitools/spec-driver-webdriver": "1.5.6",
76
- "@applitools/ufg-client": "1.19.1",
72
+ "@applitools/ufg-client": "1.19.2",
77
73
  "@applitools/utils": "1.14.1",
78
- "@types/ws": "8.5.5",
79
74
  "abort-controller": "3.0.0",
80
75
  "chalk": "4.1.2",
81
76
  "node-fetch": "2.6.7",
82
77
  "semver": "7.6.2",
83
- "throat": "6.0.2",
84
- "webdriver": "7.31.1",
85
- "ws": "8.17.1",
86
- "yargs": "17.7.2"
78
+ "throat": "6.0.2"
87
79
  },
88
80
  "devDependencies": {
89
81
  "@applitools/bongo": "^5.10.0",
@@ -96,7 +88,6 @@
96
88
  "@types/node": "^12.20.55",
97
89
  "@types/selenium-webdriver": "^4.1.2",
98
90
  "@types/semver": "^7.5.8",
99
- "@types/yargs": "^17.0.22",
100
91
  "chromedriver": "^131.0.5",
101
92
  "crypto": "^1.0.1",
102
93
  "nock": "^13.3.2",
@@ -115,7 +106,10 @@
115
106
  "chromedriver": true,
116
107
  "puppeteer": true,
117
108
  "ws>bufferutil": false,
118
- "ws>utf-8-validate": false
109
+ "ws>utf-8-validate": false,
110
+ "@applitools/core-base>@applitools/image>sharp": false,
111
+ "selenium-webdriver>ws>bufferutil": false,
112
+ "selenium-webdriver>ws>utf-8-validate": false
119
113
  }
120
114
  }
121
115
  }
@@ -5,6 +5,7 @@ type Options = {
5
5
  client?: NMLClient;
6
6
  logger: Logger;
7
7
  };
8
+ export declare function clearNMLClients(): void;
8
9
  export declare function makeGetNMLClient({ client, logger: mainLogger }: Options): {
9
10
  getNMLClient: ({ driver, settings, logger, }: {
10
11
  driver: Driver<SpecType>;
package/types/index.d.ts CHANGED
@@ -1,10 +1,9 @@
1
1
  export * from './types';
2
2
  export * from './core';
3
- export * from './universal/core-server';
4
- export * from './universal/core-server-process';
5
3
  export * from './autonomous/core';
6
4
  export { type SpecType, type SpecDriver, type Selector } from '@applitools/driver';
7
5
  export * from '@applitools/driver/dist/debug';
8
6
  export * as formatters from './utils/format-results';
9
7
  export * as logs from './troubleshoot/logs';
8
+ export { checkNetwork } from './troubleshoot/check-network';
10
9
  export { MissingApiKeyError } from '@applitools/core-base';
package/dist/cli/cli.js DELETED
@@ -1,160 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
- if (k2 === undefined) k2 = k;
5
- var desc = Object.getOwnPropertyDescriptor(m, k);
6
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
- desc = { enumerable: true, get: function() { return m[k]; } };
8
- }
9
- Object.defineProperty(o, k2, desc);
10
- }) : (function(o, m, k, k2) {
11
- if (k2 === undefined) k2 = k;
12
- o[k2] = m[k];
13
- }));
14
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
- Object.defineProperty(o, "default", { enumerable: true, value: v });
16
- }) : function(o, v) {
17
- o["default"] = v;
18
- });
19
- var __importStar = (this && this.__importStar) || function (mod) {
20
- if (mod && mod.__esModule) return mod;
21
- var result = {};
22
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
23
- __setModuleDefault(result, mod);
24
- return result;
25
- };
26
- var __importDefault = (this && this.__importDefault) || function (mod) {
27
- return (mod && mod.__esModule) ? mod : { "default": mod };
28
- };
29
- Object.defineProperty(exports, "__esModule", { value: true });
30
- /* eslint no-console: off */
31
- const core_server_1 = require("../universal/core-server");
32
- const core_server_process_1 = require("../universal/core-server-process");
33
- const logs_1 = require("../troubleshoot/logs");
34
- const check_network_1 = require("../troubleshoot/check-network");
35
- const yargs_1 = __importDefault(require("yargs"));
36
- const utils = __importStar(require("@applitools/utils"));
37
- const fs_1 = __importDefault(require("fs"));
38
- void yargs_1.default
39
- .example([
40
- ['eyes universal', 'Run Eyes Universal server on default port (21077)'],
41
- ['eyes universal --fork', 'Run Eyes Universal server in a forked process'],
42
- ['eyes universal --port 8080', 'Run Eyes Universal server on port 8080'],
43
- ['eyes universal --no-singleton', 'Run Eyes Universal server on a non-singleton mode'],
44
- ['eyes universal --shutdown-mode stdin', 'Run Eyes Universal server which will close once stdin stream will end'],
45
- ['eyes check-network', ''],
46
- ])
47
- .version(JSON.parse(fs_1.default.readFileSync(require.resolve('../../package.json'), 'utf-8')).version)
48
- .command({
49
- command: 'universal',
50
- builder: yargs => yargs.options({
51
- port: {
52
- description: 'run server on a specific port.',
53
- type: 'number',
54
- default: 21077,
55
- },
56
- singleton: {
57
- description: 'runs server on a singleton mode. It will prevent the server to start in case the same server is already started.',
58
- type: 'boolean',
59
- default: true,
60
- },
61
- fork: {
62
- description: 'runs server in a forked process.',
63
- type: 'boolean',
64
- default: false,
65
- },
66
- debug: {
67
- description: 'runs server in a debug mode.',
68
- type: 'boolean',
69
- default: false,
70
- },
71
- 'port-resolution-mode': {
72
- describe: 'preferred algorithm to solve port collisions.\n"lazy" mode will not try find free port.\n"random" mode will run on a random port.\n"next" mode will run on next free port after the given one.',
73
- alias: 'port-resolution',
74
- type: 'string',
75
- default: 'next',
76
- },
77
- 'shutdown-mode': {
78
- describe: 'preferred algorithm to automatically kill the process.\n"lazy" mode will end the process once the idle timeout ran out after the last client is disconnected from the server.\n"stdin" mode will end the process once its stdin stream got to its end.',
79
- alias: 'shutdown',
80
- type: 'string',
81
- default: 'lazy',
82
- },
83
- 'idle-timeout': {
84
- description: 'time in minutes for server to stay responsible in case of idle.',
85
- type: 'number',
86
- default: 15,
87
- coerce: value => value * 60 * 1000,
88
- },
89
- cert: {
90
- description: 'path to the certificate file.',
91
- alias: 'cert-path',
92
- type: 'string',
93
- implies: 'key',
94
- },
95
- key: {
96
- description: 'path to the key file.',
97
- alias: 'key-path',
98
- type: 'string',
99
- implies: 'cert',
100
- },
101
- config: {
102
- description: 'json string to use instead of cli arguments',
103
- type: 'string',
104
- coerce: JSON.parse,
105
- },
106
- maskLog: {
107
- description: 'mask sensitive information in the log',
108
- type: 'boolean',
109
- default: false,
110
- },
111
- }),
112
- handler: async (args) => {
113
- if (args.fork) {
114
- const { port } = await (0, core_server_process_1.makeCoreServerProcess)({ ...args, fork: false, isProcess: true });
115
- // eslint-disable-next-line no-console
116
- console.log(port); // NOTE: this is a part of the generic protocol
117
- }
118
- else {
119
- void (0, core_server_1.makeCoreServer)({ ...args, ...args.config, isProcess: true });
120
- }
121
- },
122
- })
123
- .command({
124
- command: 'logs [input]',
125
- builder: yargs => yargs.options({
126
- input: {
127
- description: 'log input to process',
128
- type: 'string',
129
- },
130
- structure: {
131
- description: 'group logs by tag names',
132
- type: 'boolean',
133
- },
134
- analyze: {
135
- description: 'group logs by tag names',
136
- type: 'boolean',
137
- },
138
- }),
139
- handler: async (args) => {
140
- var _a;
141
- const input = (_a = args.input) !== null && _a !== void 0 ? _a : (await utils.streams.toBuffer(process.stdin)).toString('utf8');
142
- const logs = (0, logs_1.parseLogs)(input);
143
- if (args.analyze) {
144
- console.log(JSON.stringify((0, logs_1.analyzeLogs)((0, logs_1.structureLogs)(logs)), null, 2));
145
- }
146
- else if (args.structure) {
147
- console.log(JSON.stringify((0, logs_1.structureLogs)(logs), null, 2));
148
- }
149
- else {
150
- console.log(JSON.stringify(logs, null, 2));
151
- }
152
- },
153
- })
154
- .command({
155
- command: 'check-network',
156
- handler: async () => {
157
- await (0, check_network_1.checkNetwork)();
158
- },
159
- })
160
- .wrap(yargs_1.default.terminalWidth()).argv;
@@ -1,31 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.makeCoreServerProcess = void 0;
7
- const child_process_1 = require("child_process");
8
- const path_1 = __importDefault(require("path"));
9
- function makeCoreServerProcess(options) {
10
- return new Promise((resolve, reject) => {
11
- const server = (0, child_process_1.fork)(path_1.default.resolve(__dirname, '../../dist/cli/cli.js'), ['universal', `--config=${JSON.stringify(options)}`], {
12
- stdio: [options.shutdownMode === 'stdin' ? 'inherit' : 'ignore', 'ignore', 'ignore', 'ipc'],
13
- ...options.forkOptions,
14
- });
15
- const timeout = setTimeout(() => {
16
- reject(new Error(`Server didn't respond for 10s after being started`));
17
- server.kill();
18
- }, 60000);
19
- server.on('error', reject);
20
- server.once('message', ({ name, payload }) => {
21
- var _a;
22
- if (name === 'port') {
23
- resolve({ port: payload.port, close: () => server.kill() });
24
- clearTimeout(timeout);
25
- (_a = server.channel) === null || _a === void 0 ? void 0 : _a.unref();
26
- }
27
- });
28
- server.unref();
29
- });
30
- }
31
- exports.makeCoreServerProcess = makeCoreServerProcess;