@testim/testim-cli 3.253.0 → 3.254.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 (79) hide show
  1. package/OverrideTestDataBuilder.js +1 -1
  2. package/agent/routers/cliJsCode/index.js +4 -4
  3. package/agent/routers/cliJsCode/router.js +46 -42
  4. package/agent/routers/cliJsCode/service.js +18 -13
  5. package/agent/routers/codim/router.js +14 -17
  6. package/agent/routers/codim/router.test.js +15 -14
  7. package/agent/routers/codim/service.js +1 -1
  8. package/agent/routers/general/index.js +4 -8
  9. package/agent/routers/hybrid/registerRoutes.js +18 -18
  10. package/agent/routers/index.js +7 -7
  11. package/agent/routers/playground/router.js +11 -10
  12. package/agent/routers/playground/service.js +19 -18
  13. package/agent/routers/standalone-browser/registerRoutes.js +10 -10
  14. package/cdpTestRunner.js +4 -3
  15. package/chromiumInstaller.js +4 -5
  16. package/cli/onExit.js +2 -2
  17. package/cli.js +7 -6
  18. package/cliAgentMode.js +4 -5
  19. package/codim/codim-cli.js +11 -10
  20. package/codim/hybrid-utils.js +1 -1
  21. package/codim/measure-perf.js +9 -6
  22. package/codim/template.js/tests/examples/01-simple-text-validation.test.js +6 -6
  23. package/codim/template.js/tests/examples/02-using-locators.test.js +13 -15
  24. package/codim/template.js/tests/examples/03-using-hooks.test.js +17 -19
  25. package/codim/template.js/tests/examples/04-skip-and-only.test.js +16 -17
  26. package/codim/template.js/tests/examples/05-multiple-windows.test.js +16 -17
  27. package/codim/template.js/webpack.config.js +1 -1
  28. package/codim/template.ts/webpack.config.js +3 -3
  29. package/commons/AbortError.js +4 -4
  30. package/commons/detectDebugger.js +4 -2
  31. package/commons/lazyRequire.js +10 -9
  32. package/commons/logger.js +4 -4
  33. package/commons/performance-logger.js +14 -8
  34. package/commons/prepareRunnerAndTestimStartUtils.js +6 -7
  35. package/commons/socket/baseSocketServiceSocketIO.js +32 -34
  36. package/commons/socket/realDataService.js +6 -5
  37. package/commons/socket/realDataServiceSocketIO.js +4 -4
  38. package/commons/socket/remoteStepService.js +4 -3
  39. package/commons/socket/remoteStepServiceSocketIO.js +11 -12
  40. package/commons/socket/socketService.js +50 -52
  41. package/commons/socket/testResultServiceSocketIO.js +11 -11
  42. package/commons/testimDesiredCapabilitiesBuilder.js +3 -2
  43. package/commons/testimNgrok.js +2 -2
  44. package/commons/testimNgrok.test.js +1 -1
  45. package/commons/testimServicesApi.js +27 -20
  46. package/commons/xhr2.js +97 -100
  47. package/errors.js +5 -0
  48. package/fixLocalBuild.js +2 -0
  49. package/npm-shrinkwrap.json +2515 -1256
  50. package/package.json +6 -6
  51. package/player/appiumTestPlayer.js +1 -1
  52. package/player/chromeLauncherTestPlayer.js +0 -1
  53. package/player/services/tabServiceMock.js +166 -0
  54. package/player/stepActions/navigationStepAction.js +11 -10
  55. package/player/stepActions/sleepStepAction.js +4 -5
  56. package/player/stepActions/textStepAction.js +4 -11
  57. package/player/utils/windowUtils.js +4 -3
  58. package/player/webdriver.js +1 -1
  59. package/processHandler.js +3 -3
  60. package/processHandler.test.js +1 -1
  61. package/reports/consoleReporter.js +3 -2
  62. package/reports/junitReporter.js +1 -2
  63. package/runOptions.js +6 -6
  64. package/runner.js +13 -0
  65. package/runners/TestPlanRunner.js +142 -74
  66. package/runners/buildCodeTests.js +38 -37
  67. package/runners/runnerUtils.js +3 -3
  68. package/services/lambdatestService.js +3 -5
  69. package/stepPlayers/cliJsStepPlayback.js +22 -17
  70. package/testRunHandler.js +8 -0
  71. package/testRunStatus.js +1 -1
  72. package/{utils.js → utils/index.js} +25 -117
  73. package/utils/promiseUtils.js +78 -0
  74. package/utils/stringUtils.js +96 -0
  75. package/{utils.test.js → utils/utils.test.js} +2 -2
  76. package/workers/BaseWorker.js +16 -14
  77. package/workers/WorkerAppium.js +1 -1
  78. package/workers/WorkerExtensionSingleBrowser.js +4 -4
  79. package/workers/WorkerSelenium.js +5 -2
package/testRunHandler.js CHANGED
@@ -111,6 +111,10 @@ class TestRun {
111
111
  return this._branch;
112
112
  }
113
113
 
114
+ getSfdcCredential() {
115
+ return this._options.sfdcCredential;
116
+ }
117
+
114
118
  getRemoteRunId() {
115
119
  return this._remoteRunId;
116
120
  }
@@ -203,6 +207,10 @@ class TestRun {
203
207
  runRequestParams.localRCASaver = this._options.localRCASaver;
204
208
  }
205
209
 
210
+ if (this.getSfdcCredential()) {
211
+ runRequestParams.sfdcCredential = this.getSfdcCredential();
212
+ }
213
+
206
214
  return runRequestParams;
207
215
  }
208
216
 
package/testRunStatus.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  const constants = require('./commons/constants');
4
4
  const { TESTIM_CONCURRENT_WORKER_COUNT } = require('./commons/config');
5
- const utils = require('./utils.js');
5
+ const utils = require('./utils');
6
6
  const reporter = require('./reports/reporter.js');
7
7
  const servicesApi = require('./commons/testimServicesApi.js');
8
8
  const gridService = require('./services/gridService');
@@ -1,16 +1,18 @@
1
1
  'use strict';
2
2
 
3
+ const os = require('os');
4
+ const _ = require('lodash');
5
+ const path = require('path');
3
6
  const moment = require('moment');
4
7
  const pRetry = require('p-retry');
5
- const _ = require('lodash');
6
8
  const Promise = require('bluebird');
7
- const fs = Promise.promisifyAll(require('fs'));
8
- const { W3C_ELEMENT_ID } = require('./player/constants');
9
- const { sessionType, testStatus: testStatusConst } = require('./commons/constants');
10
- const path = require('path');
11
- const httpRequest = require('./commons/httpRequest');
12
9
  const decompress = require('decompress');
13
- const os = require('os');
10
+ const fs = Promise.promisifyAll(require('fs'));
11
+ const stringUtils = require('./stringUtils');
12
+ const promiseUtils = require('./promiseUtils');
13
+ const httpRequest = require('../commons/httpRequest');
14
+ const { W3C_ELEMENT_ID } = require('../player/constants');
15
+ const { sessionType, testStatus: testStatusConst } = require('../commons/constants');
14
16
 
15
17
  const HOMEDIR = os.homedir();
16
18
  const TESTIM_BROWSER_DIR = path.join(HOMEDIR, '.testim-browser-profile');
@@ -43,6 +45,7 @@ const BROWSERS = [
43
45
  { browserName: 'Firefox', bs: { browser: 'Firefox', browser_version: '89' }, sl: { browserName: 'firefox', version: '89.0' }, browserValue: 'firefox' },
44
46
  { browserName: 'Safari', bs: { browser: 'Safari' }, sl: { browserName: 'safari' }, browserValue: 'safari' },
45
47
  { browserName: 'Edge', bs: { browser: 'Edge', browser_version: '18' }, sl: { browserName: 'MicrosoftEdge', version: '18.17763' }, browserValue: 'edge' },
48
+ // eslint-disable-next-line max-len
46
49
  { browserName: 'Edge Chromium', bs: { browser: 'Edge', browser_version: '94' }, sl: { browserName: 'MicrosoftEdge', version: '94' }, synonyms: ['edge-chromium'], browserValue: 'edge-chromium', seleniumName: 'MicrosoftEdge' },
47
50
  { browserName: 'Internet Explorer 11', bs: { browser: 'IE', browser_version: '11' }, sl: { browserName: 'internet explorer', version: '11.0' }, synonyms: ['ie11'], browserValue: 'ie11' },
48
51
  { browserName: 'Browser', bs: {}, sl: { browserName: 'Browser' }, browserValue: 'browser' },
@@ -53,7 +56,7 @@ const BROWSERS = [
53
56
 
54
57
  function getRunConfigByBrowserName(browser, saucelabs, browserstack) {
55
58
  browser = browser.toLowerCase();
56
- const selectedBrowser = BROWSERS.find(b => b.browserName.toLowerCase() === browser || browser.indexOf(b.synonyms) > -1) || BROWSERS[0];
59
+ const selectedBrowser = BROWSERS.find(b => b.browserName.toLowerCase() === browser || browser.includes(b.synonyms)) || BROWSERS[0];
57
60
 
58
61
  // BS and SL do not support Linux for newer browser, so use Windows instead.
59
62
  let selectedOS = OSS.find(x => x.osName === 'Windows 10');
@@ -75,22 +78,6 @@ function getRunConfigByBrowserName(browser, saucelabs, browserstack) {
75
78
  return _.merge(selectedBrowser, selectedOS);
76
79
  }
77
80
 
78
- function getTestUrl(editorUrl, projectId, testId, resultId, branch) {
79
- let testUrl = '';
80
- branch = branch ? encodeURIComponent(branch) : 'master';
81
- if (projectId && testId) {
82
- testUrl = `${editorUrl}/#/project/${projectId}/branch/${branch}/test/${testId}`;
83
- if (resultId) {
84
- testUrl += `?result-id=${resultId}`;
85
- }
86
- }
87
- return testUrl;
88
- }
89
-
90
- function isPromise(obj) {
91
- return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function' && typeof obj.catch === 'function';
92
- }
93
-
94
81
  function getDuration(ms) {
95
82
  const duration = moment.duration(ms);
96
83
  return `${duration.hours()}:${duration.minutes()}:${duration.seconds()}.${duration.milliseconds()}`;
@@ -102,7 +89,8 @@ function getDurationSec(ms) {
102
89
 
103
90
  function getRunnerVersion() {
104
91
  try {
105
- const pack = require(`${__dirname}/package.json`);
92
+ /** @type {import('../../package.json')} */
93
+ const pack = require(`${__dirname}/../package.json`); // eslint-disable-line import/no-dynamic-require
106
94
  return pack.version;
107
95
  } catch (err) {
108
96
  return '';
@@ -111,7 +99,8 @@ function getRunnerVersion() {
111
99
 
112
100
  function getEnginesVersion() {
113
101
  try {
114
- const pack = require(`${__dirname}/package.json`);
102
+ /** @type {import('../../package.json')} */
103
+ const pack = require(`${__dirname}/../package.json`); // eslint-disable-line import/no-dynamic-require
115
104
  return pack.engines.node;
116
105
  } catch (err) {
117
106
  return '';
@@ -120,7 +109,8 @@ function getEnginesVersion() {
120
109
 
121
110
  async function getEnginesVersionAsync() {
122
111
  try {
123
- const pack = JSON.parse(await fs.readFileAsync(`${__dirname}/package.json`));
112
+ /** @type {import('../../package.json')} */
113
+ const pack = JSON.parse(await fs.readFileAsync(`${__dirname}/../package.json`));
124
114
  return pack.engines.node;
125
115
  } catch (err) {
126
116
  return '';
@@ -138,19 +128,6 @@ function getUniqBrowsers(options, testList) {
138
128
  return [options.browser.toLowerCase()];
139
129
  }
140
130
 
141
- function randomString(length) {
142
- const a = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890';
143
- const index = (Math.random() * (a.length - 1)).toFixed(0);
144
- return length > 0 ? a[index] + randomString(length - 1) : '';
145
- }
146
-
147
- function blueBirdify(fn) {
148
- return new Promise((resolve, reject) =>
149
- fn()
150
- .then(x => resolve(x))
151
- .catch(y => reject(y)));
152
- }
153
-
154
131
  function removePropertyFromObject(obj, propName, cmpFunction) {
155
132
  for (const prop in obj) {
156
133
  if (obj.hasOwnProperty(prop)) {
@@ -169,72 +146,18 @@ function getCliLocation() {
169
146
  return process.cwd(); // fall back on the current working directory
170
147
  }
171
148
  if (require.main.filename.includes('/src') || require.main.filename.includes('\\src') || process.env.IS_UNIT_TEST) {
172
- cliLocation = path.resolve(__dirname, '../');
149
+ cliLocation = path.resolve(__dirname, '../../');
173
150
  } else {
174
- cliLocation = __dirname;
151
+ cliLocation = path.resolve(__dirname, '../');
175
152
  }
176
153
 
177
154
  return cliLocation;
178
155
  }
179
156
 
180
- function buildBasicHeader(userName, password) {
181
- const userAndPasswordBase64 = Buffer.from(`${userName}:${password}`).toString('base64');
182
- return `Basic ${userAndPasswordBase64}`;
183
- }
184
-
185
157
  function extractElementId(element) {
186
158
  return element.ELEMENT || element[W3C_ELEMENT_ID];
187
159
  }
188
160
 
189
- function isURL(path) {
190
- const legacyPattern = /^(https?:\/\/)/i;
191
-
192
- // https://gist.github.com/dperini/729294 (validator.js based on).
193
- const pattern = new RegExp(
194
- '^' +
195
- // protocol identifier (optional)
196
- // short syntax // still required
197
- '(?:(?:(?:https?|ftp):)?\\/\\/)' +
198
- // user:pass BasicAuth (optional)
199
- '(?:\\S+(?::\\S*)?@)?' +
200
- '(?:' +
201
- // IP address exclusion
202
- // private & local networks
203
- '(?!(?:10|127)(?:\\.\\d{1,3}){3})' +
204
- '(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})' +
205
- '(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})' +
206
- // IP address dotted notation octets
207
- // excludes loopback network 0.0.0.0
208
- // excludes reserved space >= 224.0.0.0
209
- // excludes network & broadcast addresses
210
- // (first & last IP address of each class)
211
- '(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])' +
212
- '(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}' +
213
- '(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))' +
214
- '|' +
215
- // host & domain names, may end with dot
216
- // can be replaced by a shortest alternative
217
- // (?![-_])(?:[-\\w\\u00a1-\\uffff]{0,63}[^-_]\\.)+
218
- '(?:' +
219
- '(?:' +
220
- '[a-z0-9\\u00a1-\\uffff]' +
221
- '[a-z0-9\\u00a1-\\uffff_-]{0,62}' +
222
- ')?' +
223
- '[a-z0-9\\u00a1-\\uffff]\\.' +
224
- ')+' +
225
- // TLD identifier name, may end with dot
226
- '(?:[a-z\\u00a1-\\uffff]{2,}\\.?)' +
227
- ')' +
228
- // port number (optional)
229
- '(?::\\d{2,5})?' +
230
- // resource path (optional)
231
- '(?:[/?#]\\S*)?' +
232
- '$', 'i'
233
- );
234
-
235
- return legacyPattern.test(path) || pattern.test(path);
236
- }
237
-
238
161
  const DOWNLOAD_RETRY = 3;
239
162
  const download = async (url) => pRetry(() => httpRequest.download(url), { retries: DOWNLOAD_RETRY });
240
163
 
@@ -255,7 +178,7 @@ const copy = async (readFile, destFile) => new Promise((resolve, reject) => {
255
178
  }
256
179
  });
257
180
  function getSourcePath(location, fileName) {
258
- if (isURL(location)) {
181
+ if (stringUtils.isURL(location)) {
259
182
  return fileName || path.join(process.cwd(), location.replace(/^.*[\\\/]/, ''));
260
183
  }
261
184
 
@@ -264,7 +187,7 @@ function getSourcePath(location, fileName) {
264
187
 
265
188
  const getSource = async (location, fileName) => {
266
189
  const destFile = getSourcePath(location, fileName);
267
- if (isURL(location)) {
190
+ if (stringUtils.isURL(location)) {
268
191
  return downloadAndSave(location, destFile);
269
192
  }
270
193
 
@@ -272,7 +195,7 @@ const getSource = async (location, fileName) => {
272
195
  };
273
196
 
274
197
  const getSourceAsBuffer = async (location) => {
275
- if (isURL(location)) {
198
+ if (stringUtils.isURL(location)) {
276
199
  return download(location);
277
200
  }
278
201
  return fs.readFileAsync(location);
@@ -304,16 +227,6 @@ function getPlanType(plan) {
304
227
  return 'free';
305
228
  }
306
229
 
307
- /**
308
- * @param time {number} in ms
309
- * @returns {Promise}
310
- */
311
- function delay(time) {
312
- return new Promise(((resolve) => {
313
- setTimeout(resolve, time);
314
- }));
315
- }
316
-
317
230
  const calcPercentile = (arr, percentile) => {
318
231
  if (arr.length === 0) return 0;
319
232
  if (typeof percentile !== 'number') throw new TypeError('p must be a number');
@@ -327,7 +240,7 @@ const calcPercentile = (arr, percentile) => {
327
240
  return arr[index];
328
241
  };
329
242
 
330
- const hasTestPlanFlag = (options) => (options.testPlan && options.testPlan.length) || (options.testPlanIds && options.testPlanIds.length);
243
+ const hasTestPlanFlag = (options) => Boolean(options.testPlan?.length || options.testPlanIds?.length);
331
244
 
332
245
  const isRemoteRun = (options) => options.resultId && options.source === 'remote-run';
333
246
 
@@ -396,22 +309,16 @@ function getArgsOnRemoteRunFailure() {
396
309
  module.exports = {
397
310
  TESTIM_BROWSER_DIR,
398
311
  removePropertyFromObject,
399
- getTestUrl,
400
312
  getDuration,
401
313
  getDurationSec,
402
314
  getRunnerVersion,
403
315
  getEnginesVersion,
404
316
  getEnginesVersionAsync,
405
- isPromise,
406
317
  getEnvironmentGitBranch,
407
318
  getUniqBrowsers,
408
- guid: (n = 16) => randomString(n),
409
319
  getRunConfigByBrowserName,
410
- blueBirdify,
411
- buildBasicHeader,
412
320
  extractElementId,
413
321
  getCliLocation,
414
- isURL,
415
322
  download,
416
323
  downloadAndSave,
417
324
  copy,
@@ -427,7 +334,8 @@ module.exports = {
427
334
  isQuarantineAndNotRemoteRun,
428
335
  groupTestsByRetries,
429
336
  getPlanType,
430
- delay,
431
337
  getCdpAddressForHost,
432
338
  getArgsOnRemoteRunFailure,
339
+ ...promiseUtils,
340
+ ...stringUtils,
433
341
  };
@@ -0,0 +1,78 @@
1
+ // @ts-check
2
+
3
+ const Bluebird = require('bluebird');
4
+ const { TimeoutError } = require('../errors');
5
+
6
+ function isPromise(obj) {
7
+ return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function' && typeof obj.catch === 'function';
8
+ }
9
+
10
+ /**
11
+ * @deprecated This is horrifying. Please stop what you are doing and think about what you just considered!
12
+ * @template T
13
+ * @param {() => Promise<T>} fn
14
+ * @returns {Bluebird<T>}
15
+ */
16
+ function blueBirdify(fn) {
17
+ return new Bluebird((resolve, reject) =>
18
+ fn()
19
+ .then(x => resolve(x))
20
+ .catch(y => reject(y)));
21
+ }
22
+
23
+ /**
24
+ * @param time {number} in ms
25
+ * @returns {Promise}
26
+ */
27
+ function delay(time) {
28
+ return new Promise(((resolve) => {
29
+ setTimeout(resolve, time);
30
+ }));
31
+ }
32
+
33
+ /**
34
+ * @template T
35
+ * @param {Promise<T> | undefined} promise
36
+ * @param {number} timeout
37
+ * @param {string=} errMsg
38
+ */
39
+ function promiseTimeout(promise, timeout, errMsg = 'Timeout Error') {
40
+ return Promise.race([
41
+ promise,
42
+ delay(timeout).then(() => { throw new TimeoutError(errMsg); }),
43
+ ]);
44
+ }
45
+
46
+ /**
47
+ * @template T, U
48
+ * @param {ArrayLike<T> | Iterable<T>} arr
49
+ * @param {(item: T, index: number) => PromiseLike<U>} handler
50
+ */
51
+ function promiseMap(arr, handler) {
52
+ return Promise.all(Array.from(arr, handler));
53
+ }
54
+
55
+ /**
56
+ * @template ErrT, T
57
+ * @param {(callback: (err: ErrT, result: T) => void) => void} resolver
58
+ * @returns {Promise<T>}
59
+ */
60
+ function promiseFromCallback(resolver) {
61
+ return new Promise((resolve, reject) => {
62
+ resolver((err, result) => {
63
+ if (err) {
64
+ return reject(err);
65
+ }
66
+ return resolve(result);
67
+ });
68
+ });
69
+ }
70
+
71
+ module.exports = {
72
+ isPromise,
73
+ blueBirdify,
74
+ delay,
75
+ promiseTimeout,
76
+ promiseMap,
77
+ promiseFromCallback,
78
+ };
@@ -0,0 +1,96 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * @param {number} length
5
+ * @returns {string}
6
+ */
7
+ function randomString(length) {
8
+ const a = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890';
9
+ const index = (Math.random() * (a.length - 1)).toFixed(0);
10
+ return length > 0 ? a[index] + randomString(length - 1) : '';
11
+ }
12
+
13
+ /**
14
+ * @param {string} editorUrl
15
+ * @param {string} projectId
16
+ * @param {string} testId
17
+ * @param {string | undefined} resultId
18
+ * @param {string} branch
19
+ */
20
+ function getTestUrl(editorUrl, projectId, testId, resultId, branch) {
21
+ let testUrl = '';
22
+ branch = branch ? encodeURIComponent(branch) : 'master';
23
+ if (projectId && testId) {
24
+ testUrl = `${editorUrl}/#/project/${projectId}/branch/${branch}/test/${testId}`;
25
+ if (resultId) {
26
+ testUrl += `?result-id=${resultId}`;
27
+ }
28
+ }
29
+ return testUrl;
30
+ }
31
+
32
+ /**
33
+ * @param {string} userName
34
+ * @param {string} password
35
+ */
36
+ function buildBasicHeader(userName, password) {
37
+ const userAndPasswordBase64 = Buffer.from(`${userName}:${password}`).toString('base64');
38
+ return `Basic ${userAndPasswordBase64}`;
39
+ }
40
+
41
+ /** @param {string} path */
42
+ function isURL(path) {
43
+ const legacyPattern = /^(https?:\/\/)/i;
44
+
45
+ // https://gist.github.com/dperini/729294 (validator.js based on).
46
+ const pattern = new RegExp(
47
+ '^' +
48
+ // protocol identifier (optional)
49
+ // short syntax // still required
50
+ '(?:(?:(?:https?|ftp):)?\\/\\/)' +
51
+ // user:pass BasicAuth (optional)
52
+ '(?:\\S+(?::\\S*)?@)?' +
53
+ '(?:' +
54
+ // IP address exclusion
55
+ // private & local networks
56
+ '(?!(?:10|127)(?:\\.\\d{1,3}){3})' +
57
+ '(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})' +
58
+ '(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})' +
59
+ // IP address dotted notation octets
60
+ // excludes loopback network 0.0.0.0
61
+ // excludes reserved space >= 224.0.0.0
62
+ // excludes network & broadcast addresses
63
+ // (first & last IP address of each class)
64
+ '(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])' +
65
+ '(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}' +
66
+ '(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))' +
67
+ '|' +
68
+ // host & domain names, may end with dot
69
+ // can be replaced by a shortest alternative
70
+ // (?![-_])(?:[-\\w\\u00a1-\\uffff]{0,63}[^-_]\\.)+
71
+ '(?:' +
72
+ '(?:' +
73
+ '[a-z0-9\\u00a1-\\uffff]' +
74
+ '[a-z0-9\\u00a1-\\uffff_-]{0,62}' +
75
+ ')?' +
76
+ '[a-z0-9\\u00a1-\\uffff]\\.' +
77
+ ')+' +
78
+ // TLD identifier name, may end with dot
79
+ '(?:[a-z\\u00a1-\\uffff]{2,}\\.?)' +
80
+ ')' +
81
+ // port number (optional)
82
+ '(?::\\d{2,5})?' +
83
+ // resource path (optional)
84
+ '(?:[/?#]\\S*)?' +
85
+ '$', 'i'
86
+ );
87
+
88
+ return legacyPattern.test(path) || pattern.test(path);
89
+ }
90
+
91
+ module.exports = {
92
+ isURL,
93
+ getTestUrl,
94
+ buildBasicHeader,
95
+ guid: (n = 16) => randomString(n),
96
+ };
@@ -1,5 +1,5 @@
1
- const chai = require('chai');
2
- const utils = require('./utils');
1
+ const chai = require('chai'); // eslint-disable-line import/no-extraneous-dependencies
2
+ const utils = require('./index');
3
3
 
4
4
  const expect = chai.expect;
5
5
 
@@ -1,6 +1,5 @@
1
1
  'use strict';
2
2
 
3
- const Bluebird = require('bluebird');
4
3
  const moment = require('moment');
5
4
  const pRetry = require('p-retry');
6
5
  const ms = require('ms');
@@ -128,8 +127,7 @@ class BaseWorker {
128
127
  let gridInfo = await pRetry(async () => {
129
128
  const startTime = Date.now();
130
129
  try {
131
- return await Bluebird.resolve(this.getSlotOnce(testRunHandler))
132
- .timeout(this.options.getBrowserTimeout, timeoutMessages.GET_BROWSER_TIMEOUT_MSG);
130
+ return await utils.promiseTimeout(this.getSlotOnce(testRunHandler), this.options.getBrowserTimeout, timeoutMessages.GET_BROWSER_TIMEOUT_MSG);
133
131
  } catch (error) {
134
132
  logger.error('error getting grid slot', { error, testId: this.testId, testResultId: this.testResultId, executionId: this.executionId });
135
133
  failedGetSlotAttempts++;
@@ -156,11 +154,13 @@ class BaseWorker {
156
154
  this.options.gridData.host = gridInfo.host;
157
155
  this.options.gridData.failedGetBrowserAttempts = failedGetBrowserAttempts;
158
156
  const getSessionTimeout = this.setSessionTimeout();
159
- const getBrowserRes = await Bluebird.resolve()
160
- .log('before getBrowserOnce')
161
- .then(() => this.getBrowserOnce(testRunHandler, customExtensionLocalLocation, player, gridInfo))
162
- .log('after getBrowserOnce')
163
- .timeout(getSessionTimeout, timeoutMessages.GET_BROWSER_TIMEOUT_MSG);
157
+ perf.log('before getBrowserOnce');
158
+ const getBrowserRes = await utils.promiseTimeout(
159
+ this.getBrowserOnce(testRunHandler, customExtensionLocalLocation, player, gridInfo),
160
+ getSessionTimeout,
161
+ timeoutMessages.GET_BROWSER_TIMEOUT_MSG,
162
+ );
163
+ perf.log('after getBrowserOnce');
164
164
  reporter.onGetBrowserSuccess(this.id, projectId);
165
165
  return player || getBrowserRes;
166
166
  } catch (error) {
@@ -243,7 +243,7 @@ class BaseWorker {
243
243
  const testRetryKey = testRunHandler.getRetryKey();
244
244
  testResult.testRetryKey = testRetryKey;
245
245
  await this.onTestCompleted(this.id, this.testId, testResult, sessionId, shouldRerun);
246
- if (this.executionQueue.hasMoreTests() && !(this.options.lightweightMode && this.options.lightweightMode.general)) {
246
+ if (this.executionQueue.hasMoreTests() && !this.options.lightweightMode?.general) {
247
247
  await utils.delay(DELAY_BETWEEN_TESTS);
248
248
  }
249
249
  await this.runTestCleanup();
@@ -264,11 +264,11 @@ class BaseWorker {
264
264
  return await runTestAndCalcResult(testRunHandler, shouldRerun);
265
265
  }
266
266
  return await runNextTest();
267
- } catch (err) {
268
- if (err instanceof StopRunOnError) {
267
+ } catch (error) {
268
+ if (error instanceof StopRunOnError) {
269
269
  return undefined;
270
270
  }
271
- logger.error('failed to process test result', { err });
271
+ logger.error('failed to process test result', { error });
272
272
  runNextTest();
273
273
  return undefined;
274
274
  }
@@ -342,7 +342,7 @@ class BaseWorker {
342
342
  }
343
343
  logger.warn('error on run', { err });
344
344
 
345
- const projectId = this.userData && this.userData.projectId;
345
+ const projectId = this.userData?.projectId;
346
346
  const { errorType, reason } = buildError(err, wasNetworkHealthy);
347
347
  testimServicesApi.updateTestResult(projectId, this.testResultId, this.testId, {
348
348
  status: testRunStatus.COMPLETED,
@@ -358,7 +358,7 @@ class BaseWorker {
358
358
  const recoverTestResults = async (runError, testRunHandler) => {
359
359
  const testId = this.testId;
360
360
  const resultId = this.testResultId;
361
- const projectId = this.userData && this.userData.projectId;
361
+ const projectId = this.userData?.projectId;
362
362
  const branch = this.branch;
363
363
  if (!testId || !resultId || !projectId || !branch) {
364
364
  // Not enough data to call the API
@@ -409,6 +409,7 @@ class BaseWorker {
409
409
  });
410
410
 
411
411
  const testRunHandler = this.executionQueue.getNext();
412
+
412
413
  if (!testRunHandler) { // no more tests to run
413
414
  return this.onQueueCompleted();
414
415
  }
@@ -418,6 +419,7 @@ class BaseWorker {
418
419
  this.overrideTestConfigId = testRunHandler.getOverrideTestConfigId();
419
420
  this.testRunConfig = testRunHandler.getRunConfig();
420
421
  this.branch = testRunHandler.getBranch();
422
+
421
423
  return runTestAndCalcResult(testRunHandler);
422
424
  }
423
425
  }
@@ -113,7 +113,7 @@ class WorkerAppium extends BaseWorker {
113
113
  }
114
114
  try {
115
115
  await super.runTestOnce(testRunHandler, appiumTestPlayer);
116
- await runAppiumTest.call(this);
116
+ return await runAppiumTest.call(this);
117
117
  } catch (err) {
118
118
  logger.error('failed to run test once', { err });
119
119
  throw err;
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const Bluebird = require('bluebird');
3
+ const { delay } = require('../utils');
4
4
  const { releasePlayer } = require('./workerUtils');
5
5
  const WorkerExtension = require('./WorkerExtension');
6
6
  const perf = require('../commons/performance-logger');
@@ -14,7 +14,7 @@ class WorkerExtensionSingleBrowser extends WorkerExtension {
14
14
  if (!this.testPlayer) {
15
15
  return;
16
16
  }
17
- await releasePlayer(this.id, this.releaseSlotOnTestFinished, this.userData && this.userData.projectId, this.testPlayer);
17
+ await releasePlayer(this.id, this.releaseSlotOnTestFinished, this.userData?.projectId, this.testPlayer);
18
18
  this.testPlayer = null;
19
19
  }
20
20
 
@@ -58,8 +58,8 @@ class WorkerExtensionSingleBrowser extends WorkerExtension {
58
58
  await this.onQueueCompleted();
59
59
  return;
60
60
  }
61
- if (this.options.lightweightMode && this.options.lightweightMode.general) {
62
- await Bluebird.delay(DELAY_BETWEEN_TESTS);
61
+ if (this.options.lightweightMode?.general) {
62
+ await delay(DELAY_BETWEEN_TESTS);
63
63
  }
64
64
  }
65
65
  }
@@ -92,12 +92,15 @@ class WorkerSelenium extends BaseWorker {
92
92
  sessionPlayer.playbackManager.executionName = testRunHandler.getExecutionName();
93
93
 
94
94
  sessionPlayer.setLightweightMode(this.options.lightweightMode);
95
+ if (testRunHandler.getSfdcCredential()) {
96
+ sessionPlayer.setSfdcCredential(testRunHandler.getSfdcCredential());
97
+ }
95
98
  if (sessionPlayerInit.localAssetService) {
96
99
  sessionPlayerInit.localAssetService.initialize({ serverUrl: this.options.localRCASaver });
97
100
  }
98
101
 
99
102
  let preloadedTest = null;
100
- if (this.options.lightweightMode && this.options.lightweightMode.preloadTests) {
103
+ if (this.options.lightweightMode?.preloadTests) {
101
104
  const preloadedTests = await preloadTests(this.options);
102
105
  preloadedTest = preloadedTests[this.testId];
103
106
  }
@@ -208,7 +211,7 @@ class WorkerSelenium extends BaseWorker {
208
211
  function setupCliPerformanceMonitoring(sessionPlayer) {
209
212
  const { playback } = sessionPlayerInit.commonConstants;
210
213
  function monitorEvent(event) {
211
- sessionPlayer.playbackManager.on(event, (...args) => {
214
+ sessionPlayer.playbackManager.on(event, () => {
212
215
  perf.log(`Got event ${event}`);
213
216
  });
214
217
  }