@testim/testim-cli 3.254.0 → 3.256.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 (61) hide show
  1. package/agent/routers/cliJsCode/service.js +11 -8
  2. package/agent/routers/codim/router.test.js +9 -12
  3. package/agent/routers/codim/service.js +16 -16
  4. package/agent/routers/playground/service.js +5 -7
  5. package/cli.js +6 -6
  6. package/cliAgentMode.js +11 -10
  7. package/codim/codim-cli.js +14 -9
  8. package/commons/featureFlags.js +29 -7
  9. package/commons/httpRequest.js +5 -1
  10. package/commons/httpRequestCounters.js +21 -10
  11. package/commons/initializeUserWithAuth.js +7 -4
  12. package/commons/lazyRequire.js +4 -3
  13. package/commons/preloadTests.js +6 -3
  14. package/commons/prepareRunner.js +7 -5
  15. package/commons/prepareRunnerAndTestimStartUtils.js +51 -45
  16. package/commons/runnerFileCache.js +10 -2
  17. package/commons/testimServicesApi.js +36 -5
  18. package/commons/testimTunnel.test.js +2 -1
  19. package/coverage/SummaryToObjectReport.js +0 -1
  20. package/coverage/jsCoverage.js +12 -10
  21. package/inputFileUtils.js +11 -9
  22. package/npm-shrinkwrap.json +214 -471
  23. package/package.json +4 -3
  24. package/player/services/tabService.js +15 -1
  25. package/player/stepActions/apiStepAction.js +49 -43
  26. package/player/stepActions/baseCliJsStepAction.js +19 -14
  27. package/player/stepActions/baseJsStepAction.js +9 -8
  28. package/player/stepActions/dropFileStepAction.js +1 -3
  29. package/player/stepActions/inputFileStepAction.js +10 -8
  30. package/player/stepActions/locateStepAction.js +2 -0
  31. package/player/stepActions/mouseStepAction.js +21 -22
  32. package/player/stepActions/nodePackageStepAction.js +34 -35
  33. package/player/stepActions/stepAction.js +1 -0
  34. package/player/utils/imageCaptureUtils.js +133 -172
  35. package/player/utils/screenshotUtils.js +16 -13
  36. package/player/utils/windowUtils.js +20 -8
  37. package/player/webdriver.js +25 -22
  38. package/processHandler.js +4 -0
  39. package/reports/junitReporter.js +6 -7
  40. package/reports/reporter.js +34 -39
  41. package/runOptions.d.ts +286 -0
  42. package/runOptions.js +60 -45
  43. package/runner.js +64 -24
  44. package/runners/ParallelWorkerManager.js +12 -12
  45. package/runners/TestPlanRunner.js +14 -15
  46. package/runners/buildCodeTests.js +1 -0
  47. package/runners/runnerUtils.js +11 -2
  48. package/services/branchService.js +11 -5
  49. package/services/gridService.js +36 -40
  50. package/services/localRCASaver.js +4 -0
  51. package/testRunStatus.js +8 -5
  52. package/utils/argsUtils.js +86 -0
  53. package/utils/argsUtils.test.js +32 -0
  54. package/utils/fsUtils.js +154 -0
  55. package/utils/index.js +10 -161
  56. package/utils/promiseUtils.js +13 -2
  57. package/utils/stringUtils.js +4 -2
  58. package/utils/stringUtils.test.js +22 -0
  59. package/utils/timeUtils.js +25 -0
  60. package/utils/utils.test.js +0 -41
  61. package/workers/WorkerExtension.js +6 -7
@@ -1,11 +1,14 @@
1
- const Promise = require('bluebird');
2
1
  const _ = require('lodash');
3
2
  const localRunnerCache = require('./runnerFileCache');
4
- const servicesApi = require('./testimServicesApi.js');
3
+ const servicesApi = require('./testimServicesApi');
4
+ const { promiseMap } = require('../utils');
5
5
 
6
6
 
7
7
  const TEN_HOURS = 1000 * 60 * 60 * 10;
8
8
 
9
+ /**
10
+ * @param {import('../runOptions').RunnerOptions} options
11
+ */
9
12
  async function preloadTests(options) {
10
13
  if (!Array.isArray(options.testId) || !options.testId.length) {
11
14
  return {};
@@ -15,7 +18,7 @@ async function preloadTests(options) {
15
18
  projectId: options.project,
16
19
  };
17
20
  return await localRunnerCache.memoize(async () => {
18
- const results = await Promise.map(options.testId, testId => servicesApi.loadTest({ ...opts, testId }), { concurrency: 2 });
21
+ const results = await promiseMap(options.testId, testId => servicesApi.loadTest({ ...opts, testId }), { concurrency: 2 });
19
22
  return _.keyBy(results, 'testData.id');
20
23
  }, 'loadTests', TEN_HOURS, [opts, options.testId])();
21
24
  }
@@ -22,9 +22,10 @@ Promise.resolve().then(() => {
22
22
  global.xhr2 = require('./xhr2'); // this is inside a `then` to not block and let network requests start
23
23
  });
24
24
 
25
+ /** @param {import('../runOptions').RunnerOptions} options */
25
26
  async function prepare(options) {
26
27
  /**
27
- * @type {Promise}
28
+ * @type {globalThis.Promise<void>}
28
29
  */
29
30
  let chromedriverPromise = Promise.resolve();
30
31
 
@@ -35,7 +36,7 @@ async function prepare(options) {
35
36
  chromedriverPromise = prepareRunnerAndTestimStartUtils.prepareChromeDriver(
36
37
  { projectId: options.project, userId: options.user },
37
38
  { chromeBinaryLocation: options.chromeBinaryLocation },
38
- Boolean(options.lightweightMode && options.lightweightMode.general)
39
+ Boolean(options.lightweightMode?.general)
39
40
  );
40
41
  options.useLocalChromeDriver = true;
41
42
  }
@@ -61,14 +62,15 @@ async function prepare(options) {
61
62
 
62
63
  async function prepareMockNetwork(location) {
63
64
  logger.info('prepare MockNetwork', { location });
64
- const rulesJsonBuf = await utils.getSourceAsBuffer(location);
65
+ const _rulesJson = await utils.getSourceAsBuffer(location);
66
+ const rulesJsonBuf = Buffer.isBuffer(_rulesJson) ? _rulesJson : _rulesJson.body;
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`);
67
69
  }
68
70
 
69
71
  let rulesJson;
70
72
  try {
71
- rulesJson = JSON.parse(rulesJsonBuf);
73
+ rulesJson = JSON.parse(rulesJsonBuf.toString('utf-8'));
72
74
  } catch (error) {
73
75
  throw new Error(`${PREPARE_MOCK_NETWORK_ERROR_PREFIX} cannot be parsed.${os.EOL}${error}`);
74
76
  }
@@ -76,7 +78,7 @@ async function prepareMockNetwork(location) {
76
78
  const ajv = new Ajv();
77
79
  const valid = ajv.validate(mockNetworkRuleFileSchema, rulesJson);
78
80
  if (!valid) {
79
- const errors = ajv.errors.map((e, i) => `${++i}) ${e.dataPath} ${e.message}`).join(os.EOL);
81
+ const errors = ajv.errors?.map((e, i) => `${++i}) ${e.dataPath} ${e.message}`).join(os.EOL);
80
82
  throw new Error(`${PREPARE_MOCK_NETWORK_ERROR_PREFIX} is malformed.${os.EOL}${errors}`);
81
83
  }
82
84
 
@@ -1,9 +1,7 @@
1
1
  // @ts-check
2
2
 
3
- // @ts-ignore
4
- const Promise = require('bluebird');
5
3
  const path = require('path');
6
- const fs = Promise.promisifyAll(require('fs'));
4
+ const fs = require('fs');
7
5
  const ms = require('ms');
8
6
  const { serializeError } = require('serialize-error');
9
7
  const { additionalLogDetails } = require('./logUtils');
@@ -11,7 +9,15 @@ const { additionalLogDetails } = require('./logUtils');
11
9
  const config = require('./config');
12
10
  const { ArgError, NpmPermissionsError } = require('../errors');
13
11
  const {
14
- 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,
15
21
  } = require('../utils');
16
22
  const localRunnerCache = require('./runnerFileCache');
17
23
  const logger = require('./logger').getLogger('prepare runner and testim start');
@@ -31,63 +37,58 @@ module.exports = {
31
37
  /**
32
38
  * @param {string} location
33
39
  */
34
- function prepareCustomExtension(location, unlimitedSize = false) {
40
+ async function prepareCustomExtension(location, unlimitedSize = false) {
35
41
  if (!location) {
36
- return Promise.resolve();
42
+ return undefined;
37
43
  }
38
44
 
39
45
  if (isURL(location)) {
40
46
  const destFile = path.join(process.cwd(), location.replace(/^.*[\\\/]/, ''));
41
- return getRemoteFileSizeInMB(location)
42
- .then(contentLength => {
43
- if (contentLength > MAX_CUSTOM_EXT_SIZE_MB && !unlimitedSize) {
44
- throw new ArgError(MAX_CUSTOM_SIZE_ERROR_MSG);
45
- }
46
- return downloadAndSave(location, destFile);
47
- })
48
- .then(() => 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;
49
53
  }
50
54
 
51
55
  const destFile = path.resolve(location);
52
56
  if (!fs.existsSync(destFile)) {
53
- 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}`);
54
58
  }
55
59
  const fileSize = getLocalFileSizeInMB(destFile);
56
60
  if (fileSize > MAX_CUSTOM_EXT_SIZE_MB && !unlimitedSize) {
57
- return Promise.reject(new ArgError(MAX_CUSTOM_SIZE_ERROR_MSG));
61
+ throw new ArgError(MAX_CUSTOM_SIZE_ERROR_MSG);
58
62
  }
59
- return Promise.resolve(destFile);
63
+ return destFile;
60
64
  }
61
65
 
62
66
 
63
67
  /**
64
68
  * @param {string} url
65
69
  */
66
- function getRemoteFileSizeInMB(url) {
70
+ async function getRemoteFileSizeInMB(url) {
67
71
  const httpRequest = require('./httpRequest');
68
- return httpRequest.head(url)
69
- .then(res => {
70
- const contentLengthHeader = res.headers['content-length'];
71
- const contentLengthBytes = contentLengthHeader ? parseInt(contentLengthHeader, 10) : 0;
72
- return contentLengthBytes / 1000000;
73
- })
74
- .catch(err => {
75
- logger.warn('failed to download custom extension', { err });
76
- throw new ArgError(`Failed to download custom extension from location: ${url}`);
77
- });
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
+ }
78
81
  }
79
82
 
80
83
  /**
81
- *
82
84
  * @param {string[]} locations
83
- *
84
85
  */
85
86
  function prepareExtension(locations) {
86
87
  logger.info('prepare extension', { locations });
87
88
 
88
89
  const fullLocations = locations.map(location => ({ location, path: getSourcePath(location) }));
89
90
  return localRunnerCache.memoize(
90
- () => Promise.map(fullLocations, ({ location, path }) => getSource(location, path)),
91
+ () => promiseMap(fullLocations, ({ location, path }) => getSource(location, path)),
91
92
  'prepareExtension',
92
93
  MSEC_IN_HALF_DAY,
93
94
  fullLocations
@@ -131,25 +132,23 @@ async function prepareChromeDriver(userDetails = {}, driverOptions = {}, skipIsR
131
132
  }
132
133
  }
133
134
 
134
- function getPlayerVersion() {
135
+ async function getPlayerVersion() {
135
136
  const url = `${config.BLOB_URL}/extension/sessionPlayer_LATEST_RELEASE`;
136
- return download(url)
137
- .then(res => res.body.toString('utf8'));
137
+ const res = await download(url);
138
+ return res.body.toString('utf8');
138
139
  }
139
140
 
140
141
  /**
141
142
  * @param {string} location
142
- * @param {string | undefined} canary
143
- *
144
- * @returns {Promise<string>}
143
+ * @param {boolean=} canary
145
144
  */
146
- function getPlayerLocation(location, canary) {
145
+ async function getPlayerLocation(location, canary) {
147
146
  if (!isURL(location) || (isURL(location) && canary) || config.IS_ON_PREM) {
148
- return Promise.resolve(location);
147
+ return location;
149
148
  }
150
149
 
151
- return getPlayerVersion()
152
- .then(ver => `${location}-${ver}`);
150
+ const ver = await getPlayerVersion();
151
+ return `${location}-${ver}`;
153
152
  }
154
153
 
155
154
  function getSessionPlayerFolder() {
@@ -178,13 +177,20 @@ async function downloadAndUnzip(loc, playerFileName, isRetry = false) {
178
177
  }
179
178
  }
180
179
 
181
- function preparePlayer(location, canary) {
180
+ /**
181
+ * @param {string} location
182
+ * @param {boolean=} canary
183
+ */
184
+ async function preparePlayer(location, canary) {
182
185
  logger.info('prepare player', { location, canary });
183
186
  const playerFileName = getPlayerDestination();
184
187
  return localRunnerCache.memoize(
185
- () => getPlayerLocation(location, canary)
186
- .then(loc => downloadAndUnzip(loc, playerFileName))
187
- .then(() => ({})),
188
+ async () => {
189
+ const loc = await getPlayerLocation(location, canary);
190
+ await downloadAndUnzip(loc, playerFileName);
191
+ // return a truthy value, so the caching has a value, and doesn't ignore
192
+ return {};
193
+ },
188
194
  'preparePlayer',
189
195
  MSEC_IN_HALF_DAY,
190
196
  [location, canary, playerFileName]
@@ -79,7 +79,15 @@ function decrypt(key, buffer) {
79
79
  const decrypted = decipher.update(encryptedText);
80
80
  return JSON.parse(Buffer.concat([decrypted, decipher.final()]));
81
81
  }
82
- // argument less memoize for functions with a global cache name
82
+ /**
83
+ * argument-less memoize for functions with a global cache name
84
+ * @template T
85
+ * @param {() => PromiseLike<T>} fn
86
+ * @param {string} fnName
87
+ * @param {number=} duration
88
+ * @param {*} parameters
89
+ * @returns {() => Promise<Awaited<T>>}
90
+ */
83
91
  function memoize(fn, fnName, duration = THREE_HOURS, parameters = undefined) {
84
92
  return Promise.method(async () => {
85
93
  if (!cacheEnabled) {
@@ -96,7 +104,7 @@ function memoize(fn, fnName, duration = THREE_HOURS, parameters = undefined) {
96
104
  }
97
105
  logger.debug('cache miss:', { fnName });
98
106
  if (!cacheMissAllowed) {
99
- throw new Error(`Attemped to rebuild cache for ${originalFnName}. cache miss is not allowed with current run configuration`);
107
+ throw new Error(`Attempted to rebuild cache for ${originalFnName}. cache miss is not allowed with current run configuration`);
100
108
  }
101
109
  const value = await fn();
102
110
  if (value) {
@@ -192,6 +192,27 @@ async function getTestPlanTestList(projectId, names, planIds, branch, intersecti
192
192
  }), { retries: DEFAULT_REQUEST_RETRY });
193
193
  }
194
194
 
195
+ /**
196
+ * @param {{
197
+ * projectId: string;
198
+ * labels: string[];
199
+ * testIds: string[];
200
+ * testNames: string[];
201
+ * testConfigNames?: string[];
202
+ * suiteNames: string[];
203
+ * suiteIds: string[];
204
+ * branch: string;
205
+ * rerunFailedByRunId?: string;
206
+ * testConfigIds?: string[];
207
+ * intersections: import('../runOptions').RunnerOptions['intersections'];
208
+ * }} param0
209
+ * @returns {globalThis.Promise<{
210
+ * tests: any[][];
211
+ * branch?: string;
212
+ * runName?: string;
213
+ * runExists?: boolean;
214
+ * }>}
215
+ */
195
216
  function getSuiteTestList({
196
217
  projectId, labels, testIds, testNames, testConfigNames, suiteNames, suiteIds, branch, rerunFailedByRunId, testConfigIds, intersections,
197
218
  }) {
@@ -263,7 +284,17 @@ function getGridById(companyId, projectId, gridId, browser, executionId) {
263
284
  return pRetry(() => getWithAuth(`/grid/${gridId}`, { companyId, projectId, browser, executionId, reqId: utils.guid() }), { retries: DEFAULT_REQUEST_RETRY });
264
285
  }
265
286
 
266
-
287
+ /**
288
+ * @param {{ projectId: string; token: string; branchName: string; lightweightMode?: import('../runOptions').LightweightSettings; localGrid: boolean; }} param0
289
+ * @returns {globalThis.Promise<{
290
+ * authData: { token: string; refreshToken: string; uid: string; ngrokToken?: string; isNgrokWhitelisted?: boolean; };
291
+ * editorConfig: { editorUrl: string };
292
+ * companyByProjectId: Awaited<ReturnType<import('services/src/company/companyService')['getCompanyByProjectIdUsingCache']>>;
293
+ * projectById: NonNullable<Awaited<ReturnType<import('services/src/commons/testimCache')['project']['getById']>>>;
294
+ * allGrids: import('services/src/commons/mongo/models/grid').RawGrid[];
295
+ * branchName: string | import('services/src/commons/mongo/models/branchesData').RawBranchesData | null;
296
+ * }>}
297
+ */
267
298
  async function initializeUserWithAuth({ projectId, token, branchName, lightweightMode, localGrid }) {
268
299
  try {
269
300
  return await pRetry(() => httpRequest.post({
@@ -278,14 +309,14 @@ async function initializeUserWithAuth({ projectId, token, branchName, lightweigh
278
309
  }), { retries: DEFAULT_REQUEST_RETRY });
279
310
  } catch (e) {
280
311
  logger.error('error initializing info from server', e);
281
- if (e && e.message && e.message.includes('Bad Request')) {
312
+ if (e?.message?.includes('Bad Request')) {
282
313
  throw new ArgError(
283
314
  'Error trying to retrieve CLI token. ' +
284
315
  'Your CLI token and project might not match. ' +
285
316
  'Please make sure to pass `--project` and `--token` that' +
286
317
  ' match to each other or make sure they match in your ~/.testim file.');
287
318
  }
288
- if (e && e.code && e.code.includes('ENOTFOUND')) {
319
+ if (e?.code?.includes('ENOTFOUND')) {
289
320
  throw new ArgError('Due to network connectivity issues, Testim CLI has been unable to connect to the Testim backend.');
290
321
  }
291
322
  throw e;
@@ -415,7 +446,7 @@ const updateTestDataArtifact = _.memoize(async (projectId, testId, testResultId,
415
446
  }
416
447
  const removeHiddenParamsInTestData = () => {
417
448
  const testDataValueClone = _.clone(testData);
418
- if (projectDefaults && projectDefaults.hiddenParams) {
449
+ if (projectDefaults?.hiddenParams) {
419
450
  const { hiddenParams } = projectDefaults;
420
451
  (hiddenParams || []).forEach((param) => {
421
452
  if (testDataValueClone[param]) {
@@ -521,7 +552,7 @@ module.exports = {
521
552
  getLabFeaturesByProjectId,
522
553
  uploadRunDataArtifact: Promise.method(uploadRunDataArtifact),
523
554
  updateTestDataArtifact: Promise.method(updateTestDataArtifact),
524
- initializeUserWithAuth: Promise.method(initializeUserWithAuth),
555
+ initializeUserWithAuth,
525
556
  addTestRetry,
526
557
  getHybridGridProvider,
527
558
  loadSfdcCredential,
@@ -66,7 +66,8 @@ describe('testimTunnel', () => {
66
66
 
67
67
  it('should handle connect errors', async () => {
68
68
  ltConnectStub.rejects('error');
69
- await expect(testimTunnel.connect({ tunnel: true, gridData: { type: 'testimLambdaTest', tunnel: 'lambdatest' } })).to.be.rejectedWith('Failed to start tunnel. Please contact support@testim.io');
69
+ const connectPromise = testimTunnel.connect({ tunnel: true, gridData: { type: 'testimLambdaTest', tunnel: 'lambdatest' } });
70
+ await expect(connectPromise).to.be.rejectedWith('Failed to start tunnel. Please contact support@testim.io');
70
71
  });
71
72
  });
72
73
 
@@ -1,7 +1,6 @@
1
1
  'use strict';
2
2
 
3
3
  const { ReportBase } = require('istanbul-lib-report');
4
- const _ = require('lodash');
5
4
 
6
5
  class SummaryToObjectReport extends ReportBase {
7
6
  constructor(opts) {
@@ -1,19 +1,20 @@
1
1
  'use strict';
2
2
 
3
- const _ = require('lodash');
4
- const Bluebird = require('bluebird');
5
- const servicesApi = require('../commons/testimServicesApi'); const Promise = require('bluebird');
6
- const fs = Promise.promisifyAll(require('fs'));
3
+ const servicesApi = require('../commons/testimServicesApi');
4
+ const Promise = require('bluebird');
5
+ const fs = require('fs');
6
+ const fsPromises = require('fs/promises');
7
7
  const path = require('path');
8
8
  const mkdirp = require('mkdirp');
9
9
  const lazyRequire = require('../commons/lazyRequire');
10
10
  const libReport = require('istanbul-lib-report');
11
11
  const reports = require('istanbul-reports');
12
12
  const SummaryToObjectReport = require('./SummaryToObjectReport');
13
- const { ArgError } = require('../errors');
14
13
  const ora = require('ora');
15
14
  const moment = require('moment');
16
15
  const TestExclude = require('test-exclude');
16
+ const { ArgError } = require('../errors');
17
+ const { promiseMap } = require('../utils');
17
18
 
18
19
  const logger = require('../commons/logger').getLogger('test-run-status');
19
20
 
@@ -77,7 +78,7 @@ module.exports.remapCoverage = async (options, storagePath, sourceMaps) => {
77
78
  }
78
79
  const parsedPath = rewritePath(storagePath, sourcePath);
79
80
  await mkdirp(path.parse(parsedPath).dir);
80
- await fs.writeFileAsync(parsedPath, sourceMapObject.sourcesContent[index]);
81
+ await fsPromises.writeFile(parsedPath, sourceMapObject.sourcesContent[index]);
81
82
  }));
82
83
  }));
83
84
  };
@@ -173,11 +174,11 @@ const collectAndMergeJsCoverageData = async (projectId, branch, runId) => {
173
174
  const realDataRes = await servicesApi.getRealData(projectId, 'testResult', `runId=${runId}`);
174
175
  const testResults = realDataRes.data.docs;
175
176
 
176
- await Bluebird.map(
177
- _.flatten(testResults.map((testResult) => testResult.JSCoverageURLS || [])),
177
+ await promiseMap(
178
+ testResults.flatMap((testResult) => testResult.JSCoverageURLS || []),
178
179
  async (coverageURL) => {
179
180
  const data = await servicesApi.getS3Artifact(coverageURL, 90000);
180
- await Bluebird.map(data, async (cov) => {
181
+ await promiseMap(data, async (cov) => {
181
182
  if (!covUrlMap.has(cov.url)) {
182
183
  let text = cov.text;
183
184
  if (cov.sourceUrl) {
@@ -195,7 +196,8 @@ const collectAndMergeJsCoverageData = async (projectId, branch, runId) => {
195
196
  delete cov.text;
196
197
  mergedCoverages = mergeProcessCovs([mergedCoverages, { result: [cov] }]);
197
198
  });
198
- }, { concurrency: DOWNLOAD_COVERAGE_DATA_CONCURRENCY }
199
+ },
200
+ { concurrency: DOWNLOAD_COVERAGE_DATA_CONCURRENCY }
199
201
  );
200
202
 
201
203
  return { covUrlMap, mergedCoverages };
package/inputFileUtils.js CHANGED
@@ -1,10 +1,12 @@
1
1
  'use strict';
2
2
 
3
3
  const httpRequest = require('./commons/httpRequest');
4
- const Promise = require('bluebird');
5
- const fs = Promise.promisifyAll(require('fs'));
4
+ const fsPromises = require('fs/promises');
6
5
  const os = require('os');
7
- const logger = require('./commons/logger').getLogger('input-file-utils');
6
+ const { promiseMap } = require('./utils');
7
+ const { getLogger } = require('./commons/logger');
8
+
9
+ const logger = getLogger('input-file-utils');
8
10
 
9
11
  function getVisibleElementScript(positionAndSize = {
10
12
  width: '2px', height: '2px', left: '0px', top: '400px',
@@ -77,22 +79,22 @@ async function downloadFile(fileUrl, fileName) {
77
79
  }
78
80
 
79
81
  const localFileLocation = `${os.tmpdir()}/${fileName}`;
80
- await fs.writeFileAsync(localFileLocation, body);
82
+ await fsPromises.writeFile(localFileLocation, body);
81
83
  return localFileLocation;
82
84
  }
83
85
 
84
86
  function downloadFiles(fileUrls) {
85
- return Promise.map(fileUrls, file => downloadFile(file.url, file.name));
87
+ return promiseMap(fileUrls, file => downloadFile(file.url, file.name));
86
88
  }
87
89
 
88
90
  function uploadFileToGrid(localFileLocation, uploadFileFn) {
89
91
  return uploadFileFn(localFileLocation);
90
92
  }
91
93
 
92
- function downloadFilesAndUploadToGrid(fileUrls, uploadFileFn) {
93
- return downloadFiles(fileUrls)
94
- .then(filesOnDisk => Promise.map(filesOnDisk, localFileLocation => uploadFileToGrid(localFileLocation, uploadFileFn)))
95
- .then(gridLocalFiles => Array.isArray(gridLocalFiles) && gridLocalFiles.map(gridLocalFile => gridLocalFile && gridLocalFile.value));
94
+ async function downloadFilesAndUploadToGrid(fileUrls, uploadFileFn) {
95
+ const filesOnDisk = await downloadFiles(fileUrls);
96
+ const gridLocalFiles = await promiseMap(filesOnDisk, localFileLocation => uploadFileToGrid(localFileLocation, uploadFileFn));
97
+ return Array.isArray(gridLocalFiles) && gridLocalFiles.map(gridLocalFile => gridLocalFile?.value);
96
98
  }
97
99
 
98
100
  module.exports = {