@applitools/ec-client 1.2.33 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,54 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.3.0](https://github.com/applitools/eyes.sdk.javascript1/compare/js/ec-client@1.2.34...js/ec-client@1.3.0) (2023-06-21)
4
+
5
+
6
+ ### Features
7
+
8
+ * put in a queue create tunnel requests which cannot succeed due to a limit ([3309147](https://github.com/applitools/eyes.sdk.javascript1/commit/33091473f3fcbc4dd5fc853624bbe441ce11ce87))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * @applitools/core-base bumped from 1.1.58 to 1.2.0
14
+ #### Features
15
+
16
+ * **js/core-base:** new feature ([dd5705d](https://github.com/applitools/eyes.sdk.javascript1/commit/dd5705d5e99d34f9492e890a0b4af6c52d6b33e3))
17
+
18
+
19
+ #### Bug Fixes
20
+
21
+ * rerelease ([2d46d0c](https://github.com/applitools/eyes.sdk.javascript1/commit/2d46d0c9ee14a72406e60350d4cce92991272afd))
22
+
23
+
24
+
25
+ * @applitools/driver bumped from 1.12.2 to 1.12.3
26
+
27
+ * @applitools/logger bumped from 2.0.3 to 2.0.4
28
+ #### Bug Fixes
29
+
30
+ * fixed issue when extended logger didn't preserve base's handler ([7c5e029](https://github.com/applitools/eyes.sdk.javascript1/commit/7c5e0299522f792aad72b7b3827df31a1ab2d68f))
31
+ * @applitools/socket bumped from 1.1.3 to 1.1.4
32
+
33
+ * @applitools/spec-driver-webdriver bumped from 1.0.34 to 1.0.35
34
+
35
+
36
+ ## [1.2.34](https://github.com/applitools/eyes.sdk.javascript1/compare/js/ec-client@1.2.33...js/ec-client@1.2.34) (2023-06-15)
37
+
38
+
39
+ ### Bug Fixes
40
+
41
+ * solve mismatch between content type and body in some commands ([#1660](https://github.com/applitools/eyes.sdk.javascript1/issues/1660)) ([8d1d486](https://github.com/applitools/eyes.sdk.javascript1/commit/8d1d4863d09af8266e93c59f99fa9f5a497652a9))
42
+
43
+
44
+ ### Dependencies
45
+
46
+ * The following workspace dependencies were updated
47
+ * dependencies
48
+ * @applitools/core-base bumped from 1.1.57 to 1.1.58
49
+ * @applitools/req bumped from 1.3.1 to 1.3.2
50
+ * @applitools/socket bumped from 1.1.2 to 1.1.3
51
+
3
52
  ## [1.2.33](https://github.com/applitools/eyes.sdk.javascript1/compare/js/ec-client-v1.2.32...js/ec-client@1.2.33) (2023-06-13)
4
53
 
5
54
 
@@ -6,7 +6,7 @@ function makeEndSession({ req, tunnels }) {
6
6
  var _a, _b;
7
7
  var _c;
8
8
  logger.log(`Request was intercepted with sessionId:`, session.sessionId);
9
- await req(request.url, { io: { request, response }, logger });
9
+ await req(request.url, { body: null, io: { request, response }, logger });
10
10
  if ((_a = session.tests) === null || _a === void 0 ? void 0 : _a.current) {
11
11
  await session.tests.current.abort({ settings: { testMetadata: session.metadata }, logger });
12
12
  (_b = (_c = session.tests).ended) !== null && _b !== void 0 ? _b : (_c.ended = []);
@@ -72,7 +72,7 @@ function makeExecuteScript({ req, core }) {
72
72
  },
73
73
  logger,
74
74
  });
75
- response.writeHead(200).end(JSON.stringify({ value: null }));
75
+ response.writeHead(200, { 'content-type': 'application/json' }).end(JSON.stringify({ value: null }));
76
76
  return;
77
77
  }
78
78
  else if (requestBody.script === 'applitools:endTest') {
@@ -85,22 +85,24 @@ function makeExecuteScript({ req, core }) {
85
85
  session.tests.ended.push(session.tests.current);
86
86
  session.tests.current = undefined;
87
87
  }
88
- response.writeHead(200).end(JSON.stringify({ value: null }));
88
+ response.writeHead(200, { 'content-type': 'application/json' }).end(JSON.stringify({ value: null }));
89
89
  return;
90
90
  }
91
91
  else if (requestBody.script === 'applitools:getResults') {
92
92
  if ((_q = session.tests) === null || _q === void 0 ? void 0 : _q.ended) {
93
93
  const results = await Promise.all(session.tests.ended.map(test => test.getResults({ logger })));
94
- response.writeHead(200).end(JSON.stringify({ value: results.flat() }));
94
+ response.writeHead(200, { 'content-type': 'application/json' }).end(JSON.stringify({ value: results.flat() }));
95
95
  }
96
96
  else {
97
- response.writeHead(200).end(JSON.stringify({ value: [] }));
97
+ response.writeHead(200, { 'content-type': 'application/json' }).end(JSON.stringify({ value: [] }));
98
98
  }
99
99
  return;
100
100
  }
101
101
  else if (requestBody.script === 'applitools:metadata') {
102
102
  logger.log('Session metadata requested, returning', session.metadata);
103
- response.writeHead(200).end(JSON.stringify({ value: (_r = session.metadata) !== null && _r !== void 0 ? _r : [] }));
103
+ response
104
+ .writeHead(200, { 'content-type': 'application/json' })
105
+ .end(JSON.stringify({ value: (_r = session.metadata) !== null && _r !== void 0 ? _r : [] }));
104
106
  session.metadata = [];
105
107
  return;
106
108
  }
@@ -25,9 +25,15 @@ var __importStar = (this && this.__importStar) || function (mod) {
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.makeTunnelManager = void 0;
27
27
  const req_1 = require("@applitools/req");
28
+ const queue_1 = require("../utils/queue");
28
29
  //@ts-ignore
29
30
  const execution_grid_tunnel_1 = require("@applitools/execution-grid-tunnel");
30
31
  const utils = __importStar(require("@applitools/utils"));
32
+ const RETRY_BACKOFF = [
33
+ ...Array(5).fill(2000),
34
+ ...Array(4).fill(5000),
35
+ 10000, // all next tries with delay 10s
36
+ ];
31
37
  async function makeTunnelManager({ settings, logger, }) {
32
38
  let server;
33
39
  const getTunnelServiceUrl = utils.general.cachify(async () => {
@@ -42,24 +48,8 @@ async function makeTunnelManager({ settings, logger, }) {
42
48
  };
43
49
  return `http://localhost:${port}`;
44
50
  });
45
- const req = (0, req_1.makeReq)({
46
- retry: {
47
- validate: async ({ response }) => {
48
- if (!response)
49
- return false;
50
- const body = await response
51
- .clone()
52
- .json()
53
- .catch(() => null);
54
- return ['CONCURRENCY_LIMIT_REACHED', 'NO_AVAILABLE_TUNNEL_PROXY'].includes(body === null || body === void 0 ? void 0 : body.message);
55
- },
56
- timeout: [
57
- ...Array(5).fill(2000),
58
- ...Array(4).fill(5000),
59
- 10000, // all next tries with delay 10s
60
- ],
61
- },
62
- });
51
+ const req = (0, req_1.makeReq)({});
52
+ const queues = new Map();
63
53
  const pools = new Map();
64
54
  return { create, destroy, acquire, release, close: async () => server === null || server === void 0 ? void 0 : server.close() };
65
55
  async function acquire(credentials) {
@@ -83,24 +73,48 @@ async function makeTunnelManager({ settings, logger, }) {
83
73
  await pool.release(tunnels);
84
74
  }
85
75
  async function create(credentials) {
86
- var _a, _b;
87
76
  if (!(settings === null || settings === void 0 ? void 0 : settings.serverUrl)) {
88
77
  settings !== null && settings !== void 0 ? settings : (settings = {});
89
78
  settings.serverUrl = await getTunnelServiceUrl();
90
79
  }
91
- const response = await req('/tunnels', {
92
- method: 'POST',
93
- baseUrl: settings.serverUrl,
94
- headers: {
95
- 'x-eyes-api-key': credentials.apiKey,
96
- 'x-eyes-server-url': credentials.eyesServerUrl,
97
- },
98
- });
99
- const body = await response.json().catch(() => null);
100
- if (response.status === 201)
101
- return { tunnelId: body, credentials };
102
- logger.error(`Failed to create tunnel with status ${response.status} and code ${(_a = body === null || body === void 0 ? void 0 : body.message) !== null && _a !== void 0 ? _a : 'UNKNOWN_ERROR'}`);
103
- throw new Error(`Failed to create tunnel with code ${(_b = body === null || body === void 0 ? void 0 : body.message) !== null && _b !== void 0 ? _b : 'UNKNOWN_ERROR'}`);
80
+ const queueKey = JSON.stringify(credentials);
81
+ let queue = queues.get(queueKey);
82
+ if (!queue) {
83
+ queue = (0, queue_1.makeQueue)({ logger: logger.extend({ tags: [`queue-${queueKey}`] }) });
84
+ queues.set(queueKey, queue);
85
+ }
86
+ return queue.run(task);
87
+ async function task(signal, attempt = 1) {
88
+ var _a, _b;
89
+ if (signal.aborted)
90
+ return queue.pause;
91
+ const response = await req('/tunnels', {
92
+ method: 'POST',
93
+ baseUrl: settings.serverUrl,
94
+ headers: {
95
+ 'x-eyes-api-key': credentials.apiKey,
96
+ 'x-eyes-server-url': credentials.eyesServerUrl,
97
+ },
98
+ // TODO uncomment when we can throw different abort reasons for task cancelation and timeout abortion
99
+ // signal,
100
+ });
101
+ const body = await response.json().catch(() => null);
102
+ if (['CONCURRENCY_LIMIT_REACHED', 'NO_AVAILABLE_TUNNEL_PROXY'].includes(body === null || body === void 0 ? void 0 : body.message)) {
103
+ queue.cork();
104
+ // after query is corked the task might be aborted
105
+ if (signal.aborted)
106
+ return queue.pause;
107
+ await utils.general.sleep(RETRY_BACKOFF[Math.min(attempt, RETRY_BACKOFF.length - 1)]);
108
+ return task(signal, attempt + 1);
109
+ }
110
+ else {
111
+ queue.uncork();
112
+ if (response.status === 201)
113
+ return { tunnelId: body, credentials };
114
+ logger.error(`Failed to create tunnel with status ${response.status} and code ${(_a = body === null || body === void 0 ? void 0 : body.message) !== null && _a !== void 0 ? _a : 'UNKNOWN_ERROR'}`);
115
+ throw new Error(`Failed to create tunnel with code ${(_b = body === null || body === void 0 ? void 0 : body.message) !== null && _b !== void 0 ? _b : 'UNKNOWN_ERROR'}`);
116
+ }
117
+ }
104
118
  }
105
119
  async function destroy(tunnel) {
106
120
  var _a, _b;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applitools/ec-client",
3
- "version": "1.2.33",
3
+ "version": "1.3.0",
4
4
  "homepage": "https://applitools.com",
5
5
  "bugs": {
6
6
  "url": "https://github.com/applitools/eyes.sdk.javascript1/issues"
@@ -52,13 +52,13 @@
52
52
  "test:it": "MOCHA_GROUP=it run --top-level mocha './test/it/*.spec.ts'"
53
53
  },
54
54
  "dependencies": {
55
- "@applitools/core-base": "1.1.57",
56
- "@applitools/driver": "1.12.2",
55
+ "@applitools/core-base": "1.2.0",
56
+ "@applitools/driver": "1.12.3",
57
57
  "@applitools/execution-grid-tunnel": "2.1.0",
58
- "@applitools/logger": "2.0.3",
59
- "@applitools/req": "1.3.1",
60
- "@applitools/socket": "1.1.2",
61
- "@applitools/spec-driver-webdriver": "1.0.34",
58
+ "@applitools/logger": "2.0.4",
59
+ "@applitools/req": "1.3.2",
60
+ "@applitools/socket": "1.1.4",
61
+ "@applitools/spec-driver-webdriver": "1.0.35",
62
62
  "@applitools/utils": "1.4.0",
63
63
  "abort-controller": "3.0.0",
64
64
  "webdriver": "7",
@@ -72,9 +72,12 @@
72
72
  "@types/selenium-webdriver": "^4.0.19",
73
73
  "@types/yargs": "^17.0.19",
74
74
  "nock": "^13.2.4",
75
- "selenium-webdriver": "^4.1.2"
75
+ "selenium-webdriver": "^4.10.0"
76
76
  },
77
77
  "engines": {
78
78
  "node": ">=12.13.0"
79
+ },
80
+ "publishConfig": {
81
+ "access": "public"
79
82
  }
80
83
  }