@testim/testim-cli 3.253.0 → 3.255.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 (103) 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 +19 -21
  7. package/agent/routers/codim/service.js +16 -16
  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 +22 -23
  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 +11 -10
  18. package/cliAgentMode.js +8 -8
  19. package/codim/codim-cli.js +20 -17
  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/featureFlags.js +8 -0
  32. package/commons/httpRequest.js +5 -1
  33. package/commons/httpRequestCounters.js +21 -10
  34. package/commons/lazyRequire.js +14 -12
  35. package/commons/logger.js +4 -4
  36. package/commons/performance-logger.js +14 -8
  37. package/commons/preloadTests.js +2 -2
  38. package/commons/prepareRunner.js +4 -2
  39. package/commons/prepareRunnerAndTestimStartUtils.js +40 -42
  40. package/commons/runnerFileCache.js +1 -1
  41. package/commons/socket/baseSocketServiceSocketIO.js +32 -34
  42. package/commons/socket/realDataService.js +6 -5
  43. package/commons/socket/realDataServiceSocketIO.js +4 -4
  44. package/commons/socket/remoteStepService.js +4 -3
  45. package/commons/socket/remoteStepServiceSocketIO.js +11 -12
  46. package/commons/socket/socketService.js +50 -52
  47. package/commons/socket/testResultServiceSocketIO.js +11 -11
  48. package/commons/testimDesiredCapabilitiesBuilder.js +3 -2
  49. package/commons/testimNgrok.js +2 -2
  50. package/commons/testimNgrok.test.js +1 -1
  51. package/commons/testimServicesApi.js +27 -20
  52. package/commons/testimTunnel.test.js +2 -1
  53. package/commons/xhr2.js +97 -100
  54. package/coverage/SummaryToObjectReport.js +0 -1
  55. package/coverage/jsCoverage.js +12 -10
  56. package/errors.js +5 -0
  57. package/fixLocalBuild.js +2 -0
  58. package/inputFileUtils.js +11 -9
  59. package/npm-shrinkwrap.json +2286 -1284
  60. package/package.json +9 -8
  61. package/player/appiumTestPlayer.js +1 -1
  62. package/player/chromeLauncherTestPlayer.js +0 -1
  63. package/player/services/tabService.js +15 -1
  64. package/player/services/tabServiceMock.js +166 -0
  65. package/player/stepActions/locateStepAction.js +2 -0
  66. package/player/stepActions/navigationStepAction.js +11 -10
  67. package/player/stepActions/sleepStepAction.js +4 -5
  68. package/player/stepActions/textStepAction.js +4 -11
  69. package/player/utils/imageCaptureUtils.js +81 -120
  70. package/player/utils/windowUtils.js +4 -3
  71. package/player/webdriver.js +26 -23
  72. package/processHandler.js +3 -3
  73. package/processHandler.test.js +1 -1
  74. package/reports/consoleReporter.js +3 -2
  75. package/reports/junitReporter.js +7 -9
  76. package/reports/reporter.js +34 -39
  77. package/runOptions.d.ts +260 -0
  78. package/runOptions.js +59 -44
  79. package/runner.js +14 -0
  80. package/runners/ParallelWorkerManager.js +9 -10
  81. package/runners/TestPlanRunner.js +142 -78
  82. package/runners/buildCodeTests.js +38 -37
  83. package/runners/runnerUtils.js +3 -3
  84. package/services/gridService.js +36 -40
  85. package/services/lambdatestService.js +3 -5
  86. package/stepPlayers/cliJsStepPlayback.js +22 -17
  87. package/testRunHandler.js +8 -0
  88. package/testRunStatus.js +9 -6
  89. package/utils/argsUtils.js +86 -0
  90. package/utils/argsUtils.test.js +32 -0
  91. package/utils/fsUtils.js +154 -0
  92. package/{utils.js → utils/index.js} +19 -262
  93. package/utils/promiseUtils.js +89 -0
  94. package/utils/stringUtils.js +98 -0
  95. package/utils/stringUtils.test.js +22 -0
  96. package/utils/timeUtils.js +25 -0
  97. package/utils/utils.test.js +27 -0
  98. package/workers/BaseWorker.js +16 -14
  99. package/workers/WorkerAppium.js +1 -1
  100. package/workers/WorkerExtension.js +6 -7
  101. package/workers/WorkerExtensionSingleBrowser.js +4 -4
  102. package/workers/WorkerSelenium.js +5 -2
  103. package/utils.test.js +0 -68
@@ -7,30 +7,28 @@ const { go, test, describe, before, beforeEach, afterEach, after, text } = requi
7
7
  const { expect } = require('chai');
8
8
 
9
9
  describe('Using hooks', () => {
10
+ before(() => {
11
+ // runs before all tests in this block
12
+ });
10
13
 
11
- before(function() {
12
- // runs before all tests in this block
13
- });
14
+ beforeEach(async () => {
15
+ // runs before each test in this block
16
+ await go('http://demo.testim.io');
17
+ });
14
18
 
15
- beforeEach(async () => {
16
- // runs before each test in this block
17
- await go('http://demo.testim.io');
18
- });
19
-
20
- afterEach(function() {
19
+ afterEach(() => {
21
20
  // runs after each test in this block
22
- });
21
+ });
23
22
 
24
- after(function() {
23
+ after(() => {
25
24
  // runs after all tests in this block
26
- });
25
+ });
27
26
 
28
- test('finds text element', async () => {
27
+ test('finds text element', async () => {
29
28
  // Find an element using a vanilla CSS selector and extract its text
30
- const title = await text('.theme__title___35Wsy');
31
-
32
- // Validate the extracted text
33
- expect(title).to.eq('Madan');
34
- });
35
-
29
+ const title = await text('.theme__title___35Wsy');
30
+
31
+ // Validate the extracted text
32
+ expect(title).to.eq('Madan');
33
+ });
36
34
  });
@@ -8,25 +8,24 @@ const { expect } = require('chai');
8
8
 
9
9
  // Using `.only()`
10
10
  describe.only('Test suite', () => {
11
+ beforeEach(async () => {
12
+ await go('http://demo.testim.io');
13
+ });
11
14
 
12
- beforeEach(async () => {
13
- await go('http://demo.testim.io');
14
- });
15
+ test('finds text element', async () => {
16
+ const title = await text('.theme__title___35Wsy');
17
+ expect(title).to.eq('Madan');
18
+ });
15
19
 
16
- test('finds text element', async () => {
17
- const title = await text('.theme__title___35Wsy');
18
- expect(title).to.eq('Madan');
19
- });
20
-
21
- // Using `skip()`
22
- test.skip('skips this test', async () => {
23
- // this test will not be run
24
- const title = await text('.Gallery__headline-1___2lHj5');
25
- expect(title).to.eq('Your next destination');
26
- });
20
+ // Using `skip()`
21
+ test.skip('skips this test', async () => {
22
+ // this test will not be run
23
+ const title = await text('.Gallery__headline-1___2lHj5');
24
+ expect(title).to.eq('Your next destination');
25
+ });
27
26
  });
28
27
 
29
- describe('Just another test', async() => {
30
- // this describe will not be run since the first describe
31
- // above is using `.only()`
28
+ describe('Just another test', async () => {
29
+ // this describe will not be run since the first describe
30
+ // above is using `.only()`
32
31
  });
@@ -1,4 +1,4 @@
1
- "use strict";
1
+ 'use strict';
2
2
 
3
3
  // Import Testim Dev Kit methods
4
4
  const { go, click, waitForText, withContext, test, l, Locator } = require('testim');
@@ -7,26 +7,25 @@ const { go, click, waitForText, withContext, test, l, Locator } = require('testi
7
7
  Locator.set(require('./locators/locators.js'));
8
8
 
9
9
  test('Working with multiple windows', async () => {
10
- await go("https://the-internet.herokuapp.com/");
10
+ await go('https://the-internet.herokuapp.com/');
11
11
 
12
- await click(l("Multiple_Windows"));
12
+ await click(l('Multiple_Windows'));
13
13
 
14
- // Open a new tab
15
- await click(l("Click_Here"));
14
+ // Open a new tab
15
+ await click(l('Click_Here'));
16
16
 
17
- // Run validation on the main tab
18
- await waitForText(l("Opening_a_new_window"), 'Opening a new window');
19
-
20
- // Import a `waitForText` method in the context of the newly opened tab
21
- // using the `withContext` method (@see https://help.testim.io/docs/with-context)
22
- // Please note we're using an alias since we've already imported `waitForText`
23
- // to be used in the context of the main tab.
24
- const { waitForText: waitForTextForTab } = withContext({
25
- tabUrl: 'https://the-internet.herokuapp.com/windows/new'
26
- });
17
+ // Run validation on the main tab
18
+ await waitForText(l('Opening_a_new_window'), 'Opening a new window');
27
19
 
28
- // Run validation on the newly opened tab
29
- await waitForTextForTab(l("New_Window"), 'New Window');
20
+ // Import a `waitForText` method in the context of the newly opened tab
21
+ // using the `withContext` method (@see https://help.testim.io/docs/with-context)
22
+ // Please note we're using an alias since we've already imported `waitForText`
23
+ // to be used in the context of the main tab.
24
+ const { waitForText: waitForTextForTab } = withContext({
25
+ tabUrl: 'https://the-internet.herokuapp.com/windows/new',
26
+ });
30
27
 
28
+ // Run validation on the newly opened tab
29
+ await waitForTextForTab(l('New_Window'), 'New Window');
31
30
  }); // end of test
32
31
 
@@ -1,4 +1,4 @@
1
1
  module.exports = {
2
2
  mode: 'development', // always run with development and source maps
3
3
  devtool: 'inline-source-map', // always debuggable
4
- };
4
+ };
@@ -8,9 +8,9 @@ module.exports = {
8
8
  loader: 'ts-loader',
9
9
  exclude: /node_modules/,
10
10
  },
11
- ]
11
+ ],
12
12
  },
13
13
  resolve: {
14
- extensions: [".tsx", ".ts", ".js"]
14
+ extensions: ['.tsx', '.ts', '.js'],
15
15
  },
16
- };
16
+ };
@@ -1,12 +1,12 @@
1
1
  'use strict';
2
2
 
3
3
  class AbortError extends Error {
4
- constructor(message = "aborted") {
4
+ constructor(message = 'aborted') {
5
5
  super(message);
6
- this.name = "AbortError";
6
+ this.name = 'AbortError';
7
7
  }
8
8
  }
9
9
 
10
10
  module.exports = {
11
- AbortError
12
- }
11
+ AbortError,
12
+ };
@@ -1,4 +1,5 @@
1
- "use strict";
1
+ 'use strict';
2
+
2
3
  const { DISABLE_DEBUGGER_INFINITE_TIMEOUT } = require('./config');
3
4
 
4
5
  module.exports.isDebuggerConnected = () => {
@@ -12,6 +13,7 @@ module.exports.isDebuggerConnected = () => {
12
13
  return true;
13
14
  }
14
15
  } catch (e) {
15
- return false;
16
+ /* empty */
16
17
  }
18
+ return false;
17
19
  };
@@ -67,6 +67,14 @@ class FeatureFlagsService {
67
67
  Rox.setCustomStringProperty('projectId', projectId);
68
68
  }
69
69
 
70
+ setProjectType(projectType) {
71
+ Rox.setCustomStringProperty('projectType', projectType);
72
+ }
73
+
74
+ setCompanyProductType(productType) {
75
+ Rox.setCustomStringProperty('productType', productType);
76
+ }
77
+
70
78
  setCompanyId(companyId) {
71
79
  Rox.setCustomStringProperty('companyId', companyId);
72
80
  }
@@ -79,7 +79,7 @@ function post({
79
79
  .catch(logErrorAndRethrow('failed to post request', { url }));
80
80
  }
81
81
 
82
- function postFullRes(url, body, headers = {}, timeout = DEFAULT_REQUEST_TIMEOUT, retry) {
82
+ function postFullRes(url, body, headers = {}, timeout = DEFAULT_REQUEST_TIMEOUT, retry = 0) {
83
83
  const request = superagent
84
84
  .post(url)
85
85
  .send(body)
@@ -215,6 +215,10 @@ function put(url, body, headers = {}, timeout = DEFAULT_REQUEST_TIMEOUT) {
215
215
  .catch(logErrorAndRethrow('failed to put request', { url }));
216
216
  }
217
217
 
218
+ /**
219
+ * @param {string} url
220
+ * @returns {Promise<superagent.Response>}
221
+ */
218
222
  function download(url) {
219
223
  logger.info('start to download', { url });
220
224
 
@@ -1,10 +1,11 @@
1
- 'use strit';
1
+ 'use strict';
2
2
 
3
- const { sum } = require('lodash');
4
- const Bluebird = require('bluebird');
5
- const dns = require('dns');
6
3
  const _ = require('lodash');
7
4
  const config = require('./config');
5
+ const dns = require('dns').promises;
6
+ const Bluebird = require('bluebird');
7
+ const { sum } = require('lodash');
8
+ const { promiseMap } = require('../utils/promiseUtils');
8
9
 
9
10
  const logger = require('./logger').getLogger('http-request-counters');
10
11
 
@@ -18,7 +19,7 @@ const testNetworkConnectivity = async () => {
18
19
  const hostnames = ['www.google.com', 'www.facebook.com', 'www.microsoft.com', 'testim.io'];
19
20
  try {
20
21
  // If any of these domains resolve we consider the connectivity to be ok
21
- const result = Boolean(await Bluebird.any(hostnames.map(host => dns.promises.lookup(host))));
22
+ const result = Boolean(await promiseMap(hostnames, host => dns.lookup(host)));
22
23
  if (!result) {
23
24
  networkConnectivityTestFailed = true;
24
25
  }
@@ -40,18 +41,28 @@ const ttl = 60 * 1000 * 15;
40
41
 
41
42
  module.exports.makeCounters = () => {
42
43
  const counters = {
43
- call: new Map(),
44
- success: new Map(),
45
- fail: new Map(),
44
+ /** @type {Map<string, number>} */ call: new Map(),
45
+ /** @type {Map<string, number>} */ success: new Map(),
46
+ /** @type {Map<string, number>} */ fail: new Map(),
46
47
  };
48
+ /**
49
+ * @param {counters[keyof counters]} counter
50
+ * @param {string} key
51
+ */
47
52
  function update(counter, key) {
48
53
  const result = counter.get(key) || 0;
49
54
  counter.set(key, result + 1);
50
55
  setTimeout(() => {
51
- const result = counter.get(key) || 1;
52
- counter.set(key, result - 1);
56
+ const _result = counter.get(key) || 1;
57
+ counter.set(key, _result - 1);
53
58
  }, ttl);
54
59
  }
60
+ /**
61
+ * @template T, TArgs
62
+ * @param {(...args: TArgs) => T} fn
63
+ * @param {string=} name
64
+ * @return {(...args: TArgs) => Bluebird<Awaited<T>>}
65
+ */
55
66
  function wrapWithMonitoring(fn, name = fn.name) {
56
67
  return Bluebird.method(async function (...args) {
57
68
  update(counters.call, name);
@@ -1,13 +1,13 @@
1
- "use strict";
1
+ 'use strict';
2
2
 
3
- const Bluebird = require('bluebird');
4
3
  const npmWrapper = require('./npmWrapper');
5
4
  const ora = require('ora');
6
5
  const path = require('path');
7
- const logger = require('./logger').getLogger("lazy-require");
6
+ const logger = require('./logger').getLogger('lazy-require');
8
7
  const { getCliLocation } = require('../utils');
9
- const { requireWithFallback } = require("./requireWithFallback")
8
+ const { requireWithFallback } = require('./requireWithFallback');
10
9
 
10
+ // eslint-disable-next-line import/no-dynamic-require
11
11
  const packageJson = require(path.resolve(getCliLocation(), 'package.json'));
12
12
  const ongoingCalls = new Map();
13
13
 
@@ -29,14 +29,14 @@ module.exports = async function memoizedLazyRequireApi(dependency, options = {})
29
29
  }
30
30
  return requiredModule;
31
31
  } catch (error) {
32
- logger.warn("failed to install dependency lazily", {dependency, err: error});
32
+ logger.warn('failed to install dependency lazily', { dependency, err: error });
33
33
  const depVersionToInstall = getVersionOfLazyDep(dependency);
34
34
  const depWithVersions = `${dependency}@${depVersionToInstall}`;
35
35
 
36
36
  const removeGlobal = process.argv.includes('npx');
37
- const globalFlag = removeGlobal ? '' : '-g '
37
+ const globalFlag = removeGlobal ? '' : '-g ';
38
38
  const errorMessage = `Installation of ${dependency} failed. This typically means you are running an out-of-date version of Node.js or NPM.` +
39
- `Please manually install by running the following command: npm install ${globalFlag}${depWithVersions}`
39
+ `Please manually install by running the following command: npm install ${globalFlag}${depWithVersions}`;
40
40
 
41
41
  if (spinner) {
42
42
  spinner.fail(errorMessage);
@@ -52,12 +52,12 @@ async function memoizedLazyRequire(identifier, options = {}) {
52
52
  }
53
53
 
54
54
  ongoingCalls.set(identifier, lazyRequireImpl(identifier, options));
55
- ongoingCalls.get(identifier).catch(err => {
55
+ ongoingCalls.get(identifier).catch(() => {
56
56
  ongoingCalls.delete(identifier);
57
57
  });
58
58
 
59
59
  return ongoingCalls.get(identifier);
60
- };
60
+ }
61
61
 
62
62
  async function lazyRequireImpl(dependency) {
63
63
  const packageLocally = npmWrapper.getPackageIfInstalledLocally(dependency);
@@ -75,10 +75,12 @@ async function lazyRequireImpl(dependency) {
75
75
  return requireWithFallback(dependency);
76
76
  }
77
77
 
78
- function installAllLazyDependencies() {
78
+ async function installAllLazyDependencies() {
79
79
  const allLazyDependencies = Object.keys(packageJson.lazyDependencies);
80
80
 
81
- return Bluebird.each(allLazyDependencies, dep => lazyRequireImpl(dep));
81
+ for (const dep of allLazyDependencies) {
82
+ await lazyRequireImpl(dep);
83
+ }
82
84
  }
83
85
 
84
86
  if (require.main === module) {
@@ -94,7 +96,7 @@ function getVersionOfLazyDep(dependencyToFind) {
94
96
  .find(([dep]) => dep === dependencyToFind);
95
97
 
96
98
  if (!depEntry) {
97
- throw new Error("The given package name is not lazyDependencies");
99
+ throw new Error('The given package name is not lazyDependencies');
98
100
  }
99
101
 
100
102
  return depEntry[1];
package/commons/logger.js CHANGED
@@ -53,7 +53,7 @@ function getStreamsAndWaitForFlushPromise() {
53
53
  const [transports, waitForFlush] = getStreamsAndWaitForFlushPromise();
54
54
  const level = config.LOGGER_DEBUG ? 'debug' : 'info';
55
55
  const defaultMeta = {};
56
- if (isLocal.indexOf('@echo') === -1) {
56
+ if (!isLocal.includes('@echo')) {
57
57
  Object.assign(defaultMeta, devFlags());
58
58
 
59
59
  } else {
@@ -149,13 +149,13 @@ class Logger {
149
149
  this.innerLog('crit', msg, data);
150
150
  }
151
151
 
152
- innerLog(level, msg, data = {}) {
152
+ innerLog(logLevel, msg, data = {}) {
153
153
  try {
154
- this._logger.log(level, Object.assign({ meta: data }, { message: msg }, addExecutionMetadata(data.executionId)));
154
+ this._logger.log(logLevel, Object.assign({ meta: data }, { message: msg }, addExecutionMetadata(data.executionId)));
155
155
  } catch (err) {
156
156
  try {
157
157
  this._logger.log('crit', Object.assign({ message: `failed to log message ${err.message}, ${err.stack}` }, addExecutionMetadata(data.executionId)));
158
- } catch (err) {
158
+ } catch (_err) {
159
159
  // well what can we do
160
160
  }
161
161
  }
@@ -1,7 +1,9 @@
1
- "use strict";
1
+ /* eslint-disable no-console */
2
+
3
+ 'use strict';
2
4
 
3
5
  const MEASURE_TESTIM_CLI_PERFORMANCE = process.env.MEASURE_TESTIM_CLI_PERFORMANCE;
4
- let epoch = Date.now();
6
+ const epoch = Date.now();
5
7
  let last = Date.now();
6
8
 
7
9
  module.exports = {
@@ -9,7 +11,7 @@ module.exports = {
9
11
  if (!MEASURE_TESTIM_CLI_PERFORMANCE) {
10
12
  return;
11
13
  }
12
- let time = Date.now();
14
+ const time = Date.now();
13
15
  console.log(`${time - epoch}\t\t\t${time - last}\t\t\t`, ...args);
14
16
  last = time;
15
17
  },
@@ -25,7 +27,9 @@ module.exports = {
25
27
  }
26
28
  },
27
29
  patchPromisePrototype() {
28
- Promise.prototype.log = function log (message) {
30
+ // TODO: Stop monkey patching shit
31
+ // eslint-disable-next-line no-extend-native
32
+ Promise.prototype.log = function log(message) {
29
33
  if (!MEASURE_TESTIM_CLI_PERFORMANCE) {
30
34
  return this;
31
35
  }
@@ -40,7 +44,7 @@ module.exports = {
40
44
  return this;
41
45
  }
42
46
  return this.tap(() => module.exports.log(message));
43
- }
47
+ };
44
48
  },
45
49
  measureRequireTimes() {
46
50
  if (!MEASURE_TESTIM_CLI_PERFORMANCE) {
@@ -48,12 +52,14 @@ module.exports = {
48
52
  }
49
53
  const {
50
54
  performance,
51
- PerformanceObserver
55
+ PerformanceObserver,
52
56
  } = require('perf_hooks');
53
57
  const mod = require('module');
54
58
 
55
59
  // Monkey patch the require function
56
60
  mod.Module.prototype.require = performance.timerify(mod.Module.prototype.require);
61
+ // TODO: Stop monkey patching shit
62
+ // eslint-disable-next-line no-global-assign
57
63
  require = performance.timerify(require);
58
64
 
59
65
  // Activate the observer
@@ -65,8 +71,8 @@ module.exports = {
65
71
  obs.disconnect();
66
72
  });
67
73
  obs.observe({ entryTypes: ['function'], buffered: true });
68
- }
69
- }
74
+ },
75
+ };
70
76
 
71
77
  // ew ~ Benji
72
78
  module.exports.patchPromisePrototype();
@@ -1,5 +1,5 @@
1
- const Promise = require('bluebird');
2
1
  const _ = require('lodash');
2
+ const { promiseMap } = require('../utils');
3
3
  const localRunnerCache = require('./runnerFileCache');
4
4
  const servicesApi = require('./testimServicesApi.js');
5
5
 
@@ -15,7 +15,7 @@ async function preloadTests(options) {
15
15
  projectId: options.project,
16
16
  };
17
17
  return await localRunnerCache.memoize(async () => {
18
- const results = await Promise.map(options.testId, testId => servicesApi.loadTest({ ...opts, testId }), { concurrency: 2 });
18
+ const results = await promiseMap(options.testId, testId => servicesApi.loadTest({ ...opts, testId }), { concurrency: 2 });
19
19
  return _.keyBy(results, 'testData.id');
20
20
  }, 'loadTests', TEN_HOURS, [opts, options.testId])();
21
21
  }
@@ -24,7 +24,7 @@ Promise.resolve().then(() => {
24
24
 
25
25
  async function prepare(options) {
26
26
  /**
27
- * @type {Promise}
27
+ * @type {globalThis.Promise<void>}
28
28
  */
29
29
  let chromedriverPromise = Promise.resolve();
30
30
 
@@ -35,7 +35,7 @@ async function prepare(options) {
35
35
  chromedriverPromise = prepareRunnerAndTestimStartUtils.prepareChromeDriver(
36
36
  { projectId: options.project, userId: options.user },
37
37
  { chromeBinaryLocation: options.chromeBinaryLocation },
38
- Boolean(options.lightweightMode && options.lightweightMode.general)
38
+ Boolean(options.lightweightMode?.general)
39
39
  );
40
40
  options.useLocalChromeDriver = true;
41
41
  }
@@ -61,6 +61,8 @@ async function prepare(options) {
61
61
 
62
62
  async function prepareMockNetwork(location) {
63
63
  logger.info('prepare MockNetwork', { location });
64
+ /** @type {Buffer} */
65
+ // @ts-expect-error There seems to be an actual bug in case the location is a URL.
64
66
  const rulesJsonBuf = await utils.getSourceAsBuffer(location);
65
67
  if (rulesJsonBuf.byteLength > MAX_RULE_FILE_SIZE_IN_MB * 1000000) {
66
68
  throw new Error(`${PREPARE_MOCK_NETWORK_ERROR_PREFIX} exceeded ${MAX_RULE_FILE_SIZE_IN_MB}MB`);
@@ -1,10 +1,7 @@
1
1
  // @ts-check
2
2
 
3
- // @ts-ignore
4
- const Promise = require('bluebird');
5
3
  const path = require('path');
6
- const os = require('os');
7
- const fs = Promise.promisifyAll(require('fs'));
4
+ const fs = require('fs');
8
5
  const ms = require('ms');
9
6
  const { serializeError } = require('serialize-error');
10
7
  const { additionalLogDetails } = require('./logUtils');
@@ -12,7 +9,15 @@ const { additionalLogDetails } = require('./logUtils');
12
9
  const config = require('./config');
13
10
  const { ArgError, NpmPermissionsError } = require('../errors');
14
11
  const {
15
- getCliLocation, isURL, downloadAndSave, getSource, getLocalFileSizeInMB, download, unzipFile, getSourcePath,
12
+ getCliLocation,
13
+ isURL,
14
+ downloadAndSave,
15
+ getSource,
16
+ getLocalFileSizeInMB,
17
+ download,
18
+ unzipFile,
19
+ getSourcePath,
20
+ promiseMap,
16
21
  } = require('../utils');
17
22
  const localRunnerCache = require('./runnerFileCache');
18
23
  const logger = require('./logger').getLogger('prepare runner and testim start');
@@ -32,63 +37,58 @@ module.exports = {
32
37
  /**
33
38
  * @param {string} location
34
39
  */
35
- function prepareCustomExtension(location, unlimitedSize = false) {
40
+ async function prepareCustomExtension(location, unlimitedSize = false) {
36
41
  if (!location) {
37
- return Promise.resolve();
42
+ return undefined;
38
43
  }
39
44
 
40
45
  if (isURL(location)) {
41
46
  const destFile = path.join(process.cwd(), location.replace(/^.*[\\\/]/, ''));
42
- return getRemoteFileSizeInMB(location)
43
- .then(contentLength => {
44
- if (contentLength > MAX_CUSTOM_EXT_SIZE_MB && !unlimitedSize) {
45
- return Promise.reject(new ArgError(MAX_CUSTOM_SIZE_ERROR_MSG));
46
- }
47
- return downloadAndSave(location, destFile);
48
- })
49
- .then(() => Promise.resolve(destFile));
47
+ const contentLength = await getRemoteFileSizeInMB(location);
48
+ if (contentLength > MAX_CUSTOM_EXT_SIZE_MB && !unlimitedSize) {
49
+ throw new ArgError(MAX_CUSTOM_SIZE_ERROR_MSG);
50
+ }
51
+ await downloadAndSave(location, destFile);
52
+ return destFile;
50
53
  }
51
54
 
52
55
  const destFile = path.resolve(location);
53
56
  if (!fs.existsSync(destFile)) {
54
- return Promise.reject(new ArgError(`Failed to find custom extension in location: ${destFile}`));
57
+ throw new ArgError(`Failed to find custom extension in location: ${destFile}`);
55
58
  }
56
59
  const fileSize = getLocalFileSizeInMB(destFile);
57
60
  if (fileSize > MAX_CUSTOM_EXT_SIZE_MB && !unlimitedSize) {
58
- return Promise.reject(new ArgError(MAX_CUSTOM_SIZE_ERROR_MSG));
61
+ throw new ArgError(MAX_CUSTOM_SIZE_ERROR_MSG);
59
62
  }
60
- return Promise.resolve(destFile);
63
+ return destFile;
61
64
  }
62
65
 
63
66
 
64
67
  /**
65
68
  * @param {string} url
66
69
  */
67
- function getRemoteFileSizeInMB(url) {
70
+ async function getRemoteFileSizeInMB(url) {
68
71
  const httpRequest = require('./httpRequest');
69
- return httpRequest.head(url)
70
- .then(res => {
71
- const contentLengthHeader = res.headers['content-length'];
72
- const contentLengthBytes = contentLengthHeader ? parseInt(contentLengthHeader, 10) : 0;
73
- return Promise.resolve(contentLengthBytes / 1000000);
74
- })
75
- .catch(err => {
76
- logger.warn('failed to download custom extension', { err });
77
- return Promise.reject(new ArgError(`Failed to download custom extension from location: ${url}`));
78
- });
72
+ try {
73
+ const res = await httpRequest.head(url);
74
+ const contentLengthHeader = res.headers['content-length'];
75
+ const contentLengthBytes = contentLengthHeader ? parseInt(contentLengthHeader, 10) : 0;
76
+ return contentLengthBytes / 1000000;
77
+ } catch (err) {
78
+ logger.warn('failed to download custom extension', { err });
79
+ throw new ArgError(`Failed to download custom extension from location: ${url}`);
80
+ }
79
81
  }
80
82
 
81
83
  /**
82
- *
83
84
  * @param {string[]} locations
84
- *
85
85
  */
86
86
  function prepareExtension(locations) {
87
87
  logger.info('prepare extension', { locations });
88
88
 
89
89
  const fullLocations = locations.map(location => ({ location, path: getSourcePath(location) }));
90
90
  return localRunnerCache.memoize(
91
- () => Promise.map(fullLocations, ({ location, path }) => getSource(location, path)),
91
+ () => promiseMap(fullLocations, ({ location, path }) => getSource(location, path)),
92
92
  'prepareExtension',
93
93
  MSEC_IN_HALF_DAY,
94
94
  fullLocations
@@ -132,25 +132,23 @@ async function prepareChromeDriver(userDetails = {}, driverOptions = {}, skipIsR
132
132
  }
133
133
  }
134
134
 
135
- function getPlayerVersion() {
135
+ async function getPlayerVersion() {
136
136
  const url = `${config.BLOB_URL}/extension/sessionPlayer_LATEST_RELEASE`;
137
- return download(url)
138
- .then(res => Promise.resolve(res.body.toString('utf8')));
137
+ const res = await download(url);
138
+ return res.body.toString('utf8');
139
139
  }
140
140
 
141
141
  /**
142
142
  * @param {string} location
143
143
  * @param {string | undefined} canary
144
- *
145
- * @returns {Promise<string>}
146
144
  */
147
- function getPlayerLocation(location, canary) {
145
+ async function getPlayerLocation(location, canary) {
148
146
  if (!isURL(location) || (isURL(location) && canary) || config.IS_ON_PREM) {
149
- return Promise.resolve(location);
147
+ return location;
150
148
  }
151
149
 
152
- return getPlayerVersion()
153
- .then(ver => Promise.resolve(`${location}-${ver}`));
150
+ const ver = await getPlayerVersion();
151
+ return `${location}-${ver}`;
154
152
  }
155
153
 
156
154
  function getSessionPlayerFolder() {
@@ -179,7 +177,7 @@ async function downloadAndUnzip(loc, playerFileName, isRetry = false) {
179
177
  }
180
178
  }
181
179
 
182
- function preparePlayer(location, canary) {
180
+ async function preparePlayer(location, canary) {
183
181
  logger.info('prepare player', { location, canary });
184
182
  const playerFileName = getPlayerDestination();
185
183
  return localRunnerCache.memoize(