@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
@@ -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;
@@ -10,7 +10,6 @@ const ExtensionTestPlayer = require('../player/extensionTestPlayer');
10
10
  const ChromeLauncherTestPlayer = require('../player/chromeLauncherTestPlayer');
11
11
  const reporter = require('../reports/reporter');
12
12
 
13
- const TEST_START_TIMEOUT_MS = parseInt(process.env.TESTIM_TEST_START_TIMEOUT, 10) || (2 * 60 * 1000);
14
13
 
15
14
  class WorkerExtension extends BaseWorker {
16
15
  initPlayer() {
@@ -65,7 +64,7 @@ class WorkerExtension extends BaseWorker {
65
64
  if (this.options.useChromeLauncher) {
66
65
  const testTimeout = this.options.timeoutWasGiven ?
67
66
  Math.max(10000, this.options.timeout) :
68
- TEST_START_TIMEOUT_MS;
67
+ this.options.testStartTimeout;
69
68
 
70
69
  reporter.onWaitToTestStart(this.id);
71
70
  reporter.onWaitToTestComplete(this.id, this.isCodeMode);
@@ -82,20 +81,20 @@ class WorkerExtension extends BaseWorker {
82
81
  });
83
82
  }
84
83
 
85
- const startStausDetails = { driverUrlFinished: false, testRunHandlerStartedFinished: false }; //for logging / debugging purposes
84
+ const startStatusDetails = { driverUrlFinished: false, testRunHandlerOnStartedHadFinished: false }; //for logging / debugging purposes
86
85
  return new Promise((resolve, reject) => testRunHandler.getRunTestUrl()
87
86
  .then(url => {
88
87
  reporter.onWaitToTestStart(this.id);
89
88
  return Promise.all([
90
- driver.url(url).tap(() => { startStausDetails.driverUrlFinished = true; }).catch(err => {
89
+ driver.url(url).tap(() => { startStatusDetails.driverUrlFinished = true; }).catch(err => {
91
90
  logger.error('error from driver.url', { err, testResultId, executionId, testId, url, urlLength: url.length });
92
91
  throw err;
93
92
  }),
94
- testRunHandler.onStarted(TEST_START_TIMEOUT_MS).tap(() => { startStausDetails.testRunHandlerStartedFinished = true; }),
93
+ testRunHandler.onStarted(this.options.testStartTimeout).tap(() => { startStatusDetails.testRunHandlerOnStartedHadFinished = true; }),
95
94
  ])
96
- .timeout(TEST_START_TIMEOUT_MS, timeoutMessages.TEST_START_TIMEOUT_MSG)
95
+ .timeout(this.options.testStartTimeout, timeoutMessages.TEST_START_TIMEOUT_MSG)
97
96
  .catch(Promise.TimeoutError, () => {
98
- logger.warn('timeout occurred (see log\'s payload). Running checkViaRestAPIIfTestStarted', { testResultId, executionId, testId, ...startStausDetails });
97
+ logger.warn('timeout occurred (see log\'s payload). Running checkViaRestAPIIfTestStarted', { testResultId, executionId, testId, ...startStatusDetails });
99
98
  return testRunHandler.checkViaRestAPIIfTestStarted();
100
99
  });
101
100
  })
@@ -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
  }
package/utils.test.js DELETED
@@ -1,68 +0,0 @@
1
- const chai = require('chai');
2
- const utils = require('./utils');
3
-
4
- const expect = chai.expect;
5
-
6
- describe('utils', () => {
7
- describe('calcPercentile', () => {
8
- it('should calc some precentiles', () => {
9
- // Arrange:
10
- const arr = [4, 5, 1, 2, 7, 8, 3, 6, 9, 10];
11
-
12
- // Act:
13
- const p0 = utils.calcPercentile(arr, 0);
14
- const p50 = utils.calcPercentile(arr, 50);
15
- const p90 = utils.calcPercentile(arr, 90);
16
- const p95 = utils.calcPercentile(arr, 95);
17
- const p100 = utils.calcPercentile(arr, 100);
18
-
19
- // Assert:
20
- expect(p0).to.eql(1);
21
- expect(p50).to.eql(5);
22
- expect(p90).to.eql(9);
23
- expect(p95).to.eql(10);
24
- expect(p100).to.eql(10);
25
- });
26
- });
27
- describe('getTestUrl', () => {
28
- it('should create properly escaped test URL', () => {
29
- expect(utils.getTestUrl('http://localhost:8080', 'project', 'test')).to.equal('http://localhost:8080/#/project/project/branch/master/test/test');
30
- expect(utils.getTestUrl('http://localhost:8080', 'project', 'test', 'result')).to.equal('http://localhost:8080/#/project/project/branch/master/test/test?result-id=result');
31
- expect(utils.getTestUrl('http://localhost:8080', 'project', 'test', 'result', null)).to.equal('http://localhost:8080/#/project/project/branch/master/test/test?result-id=result');
32
- expect(utils.getTestUrl('http://localhost:8080', 'project', 'test', 'result', 'normal-branch-name'))
33
- .to.equal('http://localhost:8080/#/project/project/branch/normal-branch-name/test/test?result-id=result');
34
- expect(utils.getTestUrl('http://localhost:8080', 'project', 'test', 'result', 'branch/with/slashes'))
35
- .to.equal('http://localhost:8080/#/project/project/branch/branch%2Fwith%2Fslashes/test/test?result-id=result');
36
- expect(utils.getTestUrl('http://localhost:8080', 'project', 'test', 'result', 'branch with spaces'))
37
- .to.equal('http://localhost:8080/#/project/project/branch/branch%20with%20spaces/test/test?result-id=result');
38
- expect(utils.getTestUrl('http://localhost:8080', 'project', 'test', 'result', 'encoded%20branch'))
39
- .to.equal('http://localhost:8080/#/project/project/branch/encoded%2520branch/test/test?result-id=result');
40
- });
41
- });
42
-
43
- describe('getArgsOnRemoteRunFailure', () => {
44
- let originalArgv;
45
-
46
- beforeEach(() => {
47
- originalArgv = process.argv;
48
- });
49
-
50
- afterEach(() => {
51
- process.argv = originalArgv;
52
- });
53
-
54
- it('should return undefined if no remote run is current', () => {
55
- process.argv = ['node', 'file.js', '--token', 'token', '--project', 'project-id'];
56
- expect(utils.getArgsOnRemoteRunFailure()).to.be.undefined;
57
- });
58
-
59
- it('should return details if remote run is current', () => {
60
- process.argv = ['node', 'file.js', '--token', 'token', '--project', 'project-id', '--remoteRunId', 'remote-run-id'];
61
- expect(utils.getArgsOnRemoteRunFailure()).to.eql({
62
- remoteRunId: 'remote-run-id',
63
- projectId: 'project-id',
64
- token: 'token',
65
- });
66
- });
67
- });
68
- });