@testim/testim-cli 3.195.0 → 3.199.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 (70) hide show
  1. package/README.md +1 -1
  2. package/cli/onExit.js +12 -1
  3. package/cli.js +5 -1
  4. package/commons/constants.js +0 -25
  5. package/commons/featureFlags.js +2 -0
  6. package/commons/npmWrapper.js +46 -14
  7. package/commons/npmWrapper.test.js +182 -6
  8. package/commons/socket/testResultService.js +4 -14
  9. package/commons/testimAnalytics.js +0 -1
  10. package/commons/testimDesiredCapabilitiesBuilder.js +0 -94
  11. package/commons/testimServicesApi.js +9 -79
  12. package/executionQueue.js +7 -4
  13. package/npm-shrinkwrap.json +962 -526
  14. package/package.json +3 -1
  15. package/player/stepActions/baseJsStepAction.js +5 -1
  16. package/player/stepActions/pixelValidationStepAction.js +28 -0
  17. package/player/stepActions/salesforceApexActionStepAction.js +9 -0
  18. package/player/stepActions/salesforceAutoLoginStepAction.js +5 -3
  19. package/player/stepActions/stepActionRegistrar.js +6 -48
  20. package/player/utils/eyeSdkService.js +230 -0
  21. package/reports/consoleReporter.js +29 -44
  22. package/reports/reporter.js +0 -21
  23. package/runOptions.js +13 -89
  24. package/runner.js +3 -44
  25. package/runners/{strategies/LocalStrategy.js → ParallelWorkerManager.js} +59 -68
  26. package/runners/TestPlanRunner.js +292 -67
  27. package/runners/runnerUtils.js +73 -0
  28. package/services/analyticsService.js +94 -0
  29. package/services/gridService.js +24 -16
  30. package/services/gridService.test.js +21 -21
  31. package/services/lambdatestService.js +1 -1
  32. package/testRunHandler.js +23 -2
  33. package/testRunStatus.js +17 -13
  34. package/utils.js +5 -5
  35. package/workers/BaseWorker.js +39 -39
  36. package/workers/BaseWorker.test.js +1 -1
  37. package/workers/WorkerExtensionSingleBrowser.js +6 -3
  38. package/commons/apkUploader/apkUploader.js +0 -46
  39. package/commons/apkUploader/apkUploaderFactory.js +0 -68
  40. package/commons/apkUploader/deviceFarmApkUploader.js +0 -41
  41. package/commons/apkUploader/saucelabsApkUploader.js +0 -36
  42. package/commons/apkUploader/testObjectApkUploader.js +0 -34
  43. package/player/mobile/mobileTestPlayer.js +0 -80
  44. package/player/mobile/mobileWebDriver.js +0 -155
  45. package/player/mobile/services/frameLocatorMock.js +0 -18
  46. package/player/mobile/services/mobilePortSelector.js +0 -22
  47. package/player/mobile/services/mobileTabService.js +0 -241
  48. package/player/mobile/utils/mobileScreenshotUtils.js +0 -46
  49. package/player/mobile/utils/mobileWindowUtils.js +0 -84
  50. package/player/stepActions/mobile/android/androidLocateStepAction.js +0 -122
  51. package/player/stepActions/mobile/android/androidLongClickStepAction.js +0 -12
  52. package/player/stepActions/mobile/android/androidScrollStepAction.js +0 -134
  53. package/player/stepActions/mobile/android/androidSpecialKeyStepAction.js +0 -22
  54. package/player/stepActions/mobile/android/androidSwipeStepAction.js +0 -32
  55. package/player/stepActions/mobile/androidGlobalActionStepAction.js +0 -12
  56. package/player/stepActions/mobile/androidTapStepAction.js +0 -19
  57. package/player/stepActions/mobile/androidTextChangeStepAction.js +0 -23
  58. package/player/stepActions/mobile/ios/iosLocateStepAction.js +0 -124
  59. package/player/stepActions/mobile/ios/iosScrollStepAction.js +0 -76
  60. package/runners/AnonymousTestPlanRunner.js +0 -106
  61. package/runners/BaseRunner.js +0 -42
  62. package/runners/BaseTestPlanRunner.js +0 -194
  63. package/runners/DeviceFarmRemoteRunner.js +0 -50
  64. package/runners/SchedulerRemoteRunner.js +0 -47
  65. package/runners/strategies/BaseStrategy.js +0 -86
  66. package/runners/strategies/DeviceFarmStrategy.js +0 -195
  67. package/runners/strategies/LocalDeviceFarmStrategy.js +0 -12
  68. package/runners/strategies/LocalTestStrategy.js +0 -14
  69. package/runners/strategies/Strategy.js +0 -17
  70. package/workers/WorkerAppium.js +0 -70
package/runOptions.js CHANGED
@@ -72,11 +72,9 @@ const printUsage = () => {
72
72
  return line.includes('--player-path') || line.includes('--player-require-path');
73
73
  }
74
74
 
75
- function isTestObject(line) {
75
+ function isScheduler(line) {
76
76
  return (
77
- line.includes('--testObject') ||
78
77
  line.includes('--executionId') ||
79
- line.includes('--testObject2') ||
80
78
  line.includes('--source') ||
81
79
  line.includes('--resultId') ||
82
80
  line.includes('--remoteRunId') ||
@@ -84,15 +82,6 @@ const printUsage = () => {
84
82
  );
85
83
  }
86
84
 
87
- function isAwsDF(line) {
88
- return (
89
- line.includes('--aws-project-arn') ||
90
- line.includes('--aws-region') ||
91
- line.includes('--aws-access-key-id') ||
92
- line.includes('--aws-secret-access-key')
93
- );
94
- }
95
-
96
85
  function isWebdriverTimeout(line) {
97
86
  return (
98
87
  line.includes('--get-browser-timeout') ||
@@ -116,6 +105,10 @@ const printUsage = () => {
116
105
  return line.includes('--save-rca-locally');
117
106
  }
118
107
 
108
+ function isExitCodeIgnoreFailingTests(line) {
109
+ return line.includes('--exit-code-ignore-failing-tests');
110
+ }
111
+
119
112
  program.help((txt) => {
120
113
  const lines = txt.split('\n');
121
114
  return lines
@@ -125,12 +118,12 @@ const printUsage = () => {
125
118
  !isParamsJsonOption(ln) &&
126
119
  !isDefaultHelpLine(ln) &&
127
120
  !isPlayerOption(ln) &&
128
- !isTestObject(ln) &&
121
+ !isScheduler(ln) &&
129
122
  !isMonitorPerformance(ln) &&
130
123
  !isUserId(ln) &&
131
- !isAwsDF(ln) &&
132
124
  !isWebdriverTimeout(ln) &&
133
- !isSaveRCALocally(ln)
125
+ !isSaveRCALocally(ln) &&
126
+ !isExitCodeIgnoreFailingTests(ln)
134
127
  )
135
128
  .join('\n');
136
129
  });
@@ -304,9 +297,6 @@ program
304
297
  .option('--disable-sockets', 'Disable CLI sockets', false)
305
298
 
306
299
  // Remote run options
307
- .option('--testObject [test-object]', '', '')
308
- .option('--remoteRunObject [remote-run-object]', '', '')
309
- .option('--testObject2 [test-object]', '', '')
310
300
  .option('--executionId [execution-id]', '', '')
311
301
  .option('--remoteRunId [remote-run-id]', '', '')
312
302
  .option('--schedulerId [scheduler-id]', '', '')
@@ -319,17 +309,6 @@ program
319
309
  .option('--agent-port [agent-port]', 'set agent port', Number, 42543)
320
310
  .option('--agent-bind [agent-host-bind]', 'set agent host bind', '127.0.0.1')
321
311
 
322
- // Mobile options
323
- .option('--apk-location [apk-local-location]', 'application apk location')
324
- .option('--ipa-location [ipa-local-location]', 'application ipa location')
325
- .option('--apk-timeout [apk-upload-timeout]', 'upload apk timeout in milliseconds', 15 * 60 * 1000)
326
- .option('--ipa-timeout [ipa-upload-timeout]', 'upload ipa timeout in milliseconds', 15 * 60 * 1000)
327
- .option('--disable-window-animation [disable-window-animation]', 'disable window animation by setting Appium capability', false)
328
-
329
- .option('--device-udid [device-udid]', 'device udid')
330
- .option('--device-name [device-name]', 'device name', 'mobile')
331
- .option('--vendor-app-id [vendor-app-id]', 'use existing application id instead of upload new app')
332
-
333
312
  .option('--chrome-extra-prefs [chrome-extra-prefs]', 'add extra chrome preferences', '')
334
313
  .option('--chrome-extra-args [chrome-extra-args]', 'add extra chrome arguments separated by \',\'', '')
335
314
  .option('--chrome-block-location [chrome-block-location]', 'block chrome geolocation', false)
@@ -342,17 +321,13 @@ program
342
321
  .option('--version [version]', 'print the current version of the Testim CLI and exit', false)
343
322
  .option('--monitor-performance', 'collect test playback performance data')
344
323
 
345
- // AWS DF
346
- .option('--aws-project-arn [projectArn]', 'projectArn', '')
347
- .option('--aws-region [region]', 'region', 'us-west-2')
348
- .option('--aws-access-key-id [accessKeyId]', 'accessKeyId', '')
349
- .option('--aws-secret-access-key [secretAccessKey]', 'secretAccessKey', '')
350
-
351
324
  .option('--high-speed', 'run in high speed mode')
352
325
  .option('--lightweight-mode [settings]', 'run lightweight mode')
353
326
  .option('--create-prefeched-data [location]', 'prefech data into local cache file')
354
327
  .option('--use-prefeched-data [location]', 'use prefeched data from local cache file, and force using only cached data')
355
328
  .option('--save-rca-locally [path]', 'save root cause analysis assets locally')
329
+
330
+ .option('--exit-code-ignore-failing-tests', 'dont return non zero exit code when tests fail. non zero exit code will mean a real error occurred')
356
331
  .parse(process.argv);
357
332
 
358
333
  module.exports = {
@@ -814,7 +789,7 @@ module.exports = {
814
789
  return Promise.reject(new ArgError('parallel could not be a negative number or not number, --parallel <number-of-tests>'));
815
790
  }
816
791
 
817
- if ([CLI_MODE.EXTENSION, CLI_MODE.SELENIUM, CLI_MODE.APPIUM, CLI_MODE.DEVICE_FARM_APPIUM].indexOf(program.mode) === -1) {
792
+ if ([CLI_MODE.EXTENSION, CLI_MODE.SELENIUM].indexOf(program.mode) === -1) {
818
793
  return Promise.reject(new ArgError(`runner mode <${program.mode}> is not supported`));
819
794
  }
820
795
 
@@ -825,38 +800,11 @@ module.exports = {
825
800
  if (
826
801
  !program.browser &&
827
802
  !isTestConfigSpecified &&
828
- !isTestPlanSpecified &&
829
- !program.testObject2
803
+ !isTestPlanSpecified
830
804
  ) {
831
805
  program.browser = 'chrome';
832
806
  }
833
807
 
834
- if (program.testObject) {
835
- try {
836
- program.testObject = JSON.parse(program.testObject);
837
- } catch (err) {
838
- return Promise.reject(new ArgError(`failed to parse testObject string error: ${err.message}`));
839
- }
840
- }
841
-
842
- if (program.testObject2) {
843
- try {
844
- const obj = decodeURIComponent(program.testObject2);
845
- program.testObject = JSON.parse(obj);
846
- } catch (err) {
847
- return Promise.reject(new ArgError(`failed to parse testObject string error: ${err.message}`));
848
- }
849
- }
850
-
851
- if (program.remoteRunObject) {
852
- try {
853
- const obj = decodeURIComponent(program.remoteRunObject);
854
- program.remoteRunObject = JSON.parse(obj);
855
- } catch (err) {
856
- return Promise.reject(new ArgError(`failed to parse remoteRunObject string error: ${err.message}`));
857
- }
858
- }
859
-
860
808
  if (program.testPlan && program.testPlan.length === 0 && program.testPlanId && program.testPlanId.length === 0) {
861
809
  if (
862
810
  typeof program.host !== 'string' &&
@@ -950,9 +898,6 @@ module.exports = {
950
898
  } else {
951
899
  program.files = [];
952
900
  }
953
- if (program.apkLocation && program.ipaLocation) {
954
- return Promise.reject(new ArgError('cannot set --apk-location and --ipa-location. please choose the one compatible with your project type'));
955
- }
956
901
 
957
902
  if (program.setRetention && !_.inRange(_.parseInt(program.setRetention), 1, 11)) {
958
903
  return Promise.reject(new ArgError('Please provide the number of days that the test results will be retained for (--set-retention must be a whole number between 1 to 10)'));
@@ -1119,7 +1064,6 @@ module.exports = {
1119
1064
  testobjectSauce: program.testobjectSauce,
1120
1065
  gridUsername: program.gridUsername,
1121
1066
  gridPassword: program.gridPassword,
1122
- vendorAppId: program.vendorAppId,
1123
1067
  overrideExecutionName: program.overrideExecutionName,
1124
1068
 
1125
1069
  tmsSuppressReporting: Boolean(program.suppressTmsReporting) || Boolean(program.tmsSuppressReporting),
@@ -1186,9 +1130,7 @@ module.exports = {
1186
1130
  codeCoverageInclude: program.codeCoverageInclude,
1187
1131
 
1188
1132
  // Remote run options
1189
- testObject: program.testObject,
1190
1133
  executionId: program.executionId,
1191
- remoteRunObject: program.remoteRunObject,
1192
1134
  remoteRunId: program.remoteRunId,
1193
1135
  schedulerId: program.schedulerId,
1194
1136
  source: program.source,
@@ -1200,19 +1142,6 @@ module.exports = {
1200
1142
  w3cCapabilities: program.w3cCapabilities,
1201
1143
  oldCapabilities: program.oldCapabilities,
1202
1144
 
1203
- //APK options
1204
- apkLocation: program.apkLocation,
1205
- apkTimeout: program.apkTimeout,
1206
-
1207
- // IPA options
1208
- ipaLocation: program.ipaLocation,
1209
- ipaTimeout: program.ipaTimeout,
1210
-
1211
- disableWindowAnimation: program.disableWindowAnimation,
1212
-
1213
- deviceUdid: program.deviceUdid,
1214
- deviceName: program.deviceName,
1215
-
1216
1145
  chromeBlockLocation: program.chromeBlockLocation,
1217
1146
  chromeUserDataDir: program.chromeUserDataDir,
1218
1147
  retries: program.retries,
@@ -1226,16 +1155,11 @@ module.exports = {
1226
1155
 
1227
1156
  user: program.user,
1228
1157
 
1229
- awsProjectArn: program.awsProjectArn,
1230
- awsRegion: program.awsRegion,
1231
-
1232
- awsAccessKeyId: program.awsAccessKeyId,
1233
- awsSecretAccessKey: program.awsSecretAccessKey,
1234
-
1235
1158
  lightweightMode: program.lightweightMode,
1236
1159
  createPrefechedData: program.createPrefechedData,
1237
1160
 
1238
1161
  saveRCALocally: program.saveRcaLocally,
1162
+ exitCodeIgnoreFailingTests: program.exitCodeIgnoreFailingTests,
1239
1163
 
1240
1164
  disableSockets: program.disableSockets,
1241
1165
  });
package/runner.js CHANGED
@@ -15,16 +15,13 @@ const npmDriver = require('./testimNpmDriver.js');
15
15
  const analytics = require('./commons/testimAnalytics');
16
16
  const branchService = require('./services/branchService');
17
17
  const gridService = require('./services/gridService');
18
- const strategySelector = require('./runners/strategies/Strategy');
19
18
  const { ArgError, QuotaDepletedError } = require('./errors');
20
19
  const featureFlags = require('./commons/featureFlags');
21
20
  const perf = require('./commons/performance-logger');
22
21
  const { prepareMockNetwork, initializeUserWithAuth } = require('./commons/prepareRunner');
23
- const { hasTestPlanFlag } = require('./utils');
24
22
 
25
23
  const FREE_PLAN_MINIMUM_BROWSER_TIMEOUT = 30 * 60 * 1000;
26
24
 
27
- const AnonymousTestPlanRunner = require('./runners/AnonymousTestPlanRunner');
28
25
  const TestPlanRunner = require('./runners/TestPlanRunner');
29
26
  const labFeaturesService = require('./services/labFeaturesService');
30
27
  const featureAvailabilityService = require('./commons/featureAvailabilityService');
@@ -85,17 +82,6 @@ function validateCliAccount(options) {
85
82
  });
86
83
  }
87
84
 
88
- function validateRemoteRunAccount(options) {
89
- return validateProjectQuotaNotDepleted(options)
90
- .catch(err => {
91
- if (err instanceof QuotaDepletedError) {
92
- return Promise.reject(err);
93
- }
94
- logger.error('could not validate remote run account', { err });
95
- return undefined;
96
- });
97
- }
98
-
99
85
  function analyticsIdentify(projectId) {
100
86
  const authData = testimCustomToken.getTokenV3UserData();
101
87
  return analytics.identify({
@@ -138,7 +124,7 @@ function setCompany(options, company) {
138
124
  const { onprem, id, storageBaseUrl, storageType, name, activePlan = {} } = company;
139
125
  if (onprem) {
140
126
  const { mode, extensionPath, ext, playerPath } = options;
141
- if ([CLI_MODE.SELENIUM, CLI_MODE.APPIUM].includes(mode) && !playerPath) {
127
+ if ([CLI_MODE.SELENIUM].includes(mode) && !playerPath) {
142
128
  return Promise.reject(new ArgError('in selenium on prem mode --player-path must be provided'));
143
129
  }
144
130
  if (mode === 'extension' && !extensionPath && !ext) {
@@ -214,32 +200,13 @@ async function setMockNetworkRules(options) {
214
200
 
215
201
  function runRunner(options, customExtensionLocalLocation) {
216
202
  perf.log('in runner.js runRunner');
217
- const branchToUse = branchService.getCurrentBranch();
218
203
 
219
- const selectedStrategy = strategySelector(options, customExtensionLocalLocation);
220
- const {
221
- remoteRunObject, testObject, executionId, project, remoteRunId, useLocalChromeDriver, useChromeLauncher,
222
- } = options;
223
-
224
- if (testObject && executionId) {
225
- const SchedulerRemoteRunner = require('./runners/SchedulerRemoteRunner');
226
- const schedulerRemoteRunner = new SchedulerRemoteRunner(selectedStrategy);
227
- return validateRemoteRunAccount(options)
228
- .then(() => schedulerRemoteRunner.runTest(options, branchToUse));
229
- }
204
+ const { project, remoteRunId, useLocalChromeDriver, useChromeLauncher } = options;
230
205
 
231
206
  if (!remoteRunId) {
232
207
  options.source = (useLocalChromeDriver || useChromeLauncher) ? 'cli-local' : 'cli';
233
208
  }
234
209
 
235
- if (remoteRunObject && executionId) {
236
- const { testList, gridInfo } = remoteRunObject;
237
- const DeviceFarmRemoteRunner = require('./runners/DeviceFarmRemoteRunner');
238
- const deviceFarmRemoteRunner = new DeviceFarmRemoteRunner(selectedStrategy);
239
- return validateRemoteRunAccount(options)
240
- .then(() => deviceFarmRemoteRunner.runTest(executionId, testList, gridInfo, branchToUse, options));
241
- }
242
-
243
210
  npmDriver.checkNpmVersion();
244
211
  perf.log('in runner.js after checkNpmVersion');
245
212
 
@@ -247,15 +214,7 @@ function runRunner(options, customExtensionLocalLocation) {
247
214
  .log('in runRunner before tunnel.connect')
248
215
  .then(() => tunnel.connect(options, testimCustomToken.getTokenV3UserData()))
249
216
  .log('in runRunner after tunnel.connect')
250
- .then(() => {
251
- if (hasTestPlanFlag(options)) {
252
- const testPlanRunner = new TestPlanRunner(selectedStrategy);
253
- return testPlanRunner.runTestPlans(options, branchToUse);
254
- }
255
- const anonymousTestPlanRunner = new AnonymousTestPlanRunner(selectedStrategy);
256
- perf.log('right before runAnonymousTestPlan');
257
- return anonymousTestPlanRunner.runAnonymousTestPlan(options, branchToUse);
258
- })
217
+ .then(() => new TestPlanRunner(customExtensionLocalLocation).run(options))
259
218
  .log('before tunnel.disconnect')
260
219
  .tap(() => tunnel.disconnect(options))
261
220
  .tap(() => gridService.keepAlive.end(project))
@@ -1,53 +1,43 @@
1
1
  'use strict';
2
2
 
3
- const Promise = require('bluebird');
4
-
5
- const utils = require('../../utils');
6
- const logger = require('../../commons/logger').getLogger('local-strategy');
7
- const { CLI_MODE } = require('../../commons/constants');
8
- const BaseStrategy = require('./BaseStrategy');
9
- const config = require('../../commons/config');
10
- const ExecutionQueue = require('../../executionQueue');
11
-
12
- const testimCustomToken = require('../../commons/testimCustomToken');
13
- const testResultService = require('../../commons/socket/testResultService');
14
- const labFeaturesService = require('../../services/labFeaturesService');
15
- const perf = require('../../commons/performance-logger');
16
- const { StopRunOnError } = require('../../errors');
17
-
18
- require('../../player/webdriver'); // preload
19
-
20
- class LocalStrategy extends BaseStrategy {
3
+ const utils = require('../utils');
4
+ const logger = require('../commons/logger').getLogger('parallel-worker-manager');
5
+ const { CLI_MODE } = require('../commons/constants');
6
+ const analyticsService = require('../services/analyticsService');
7
+ const config = require('../commons/config');
8
+ const ExecutionQueue = require('../executionQueue');
9
+
10
+ const testimCustomToken = require('../commons/testimCustomToken');
11
+ const testimServicesApi = require('../commons/testimServicesApi');
12
+ const labFeaturesService = require('../services/labFeaturesService');
13
+ const perf = require('../commons/performance-logger');
14
+ const { StopRunOnError } = require('../errors');
15
+
16
+ require('../player/webdriver'); // preload
17
+
18
+ class ParallelWorkerManager {
21
19
  constructor(customExtensionLocalLocation) {
22
- super();
23
20
  this.customExtensionLocalLocation = customExtensionLocalLocation;
24
21
  }
25
22
 
26
- startWorker(worker, options, onTestStarted, onTestCompleted, executionId, onGridSlot, onTestIgnored) {
27
- throw new Error('need to implement');
28
- }
29
-
30
23
  getWorkerType(mode) {
31
24
  switch (mode) {
32
25
  case CLI_MODE.SELENIUM:
33
- return require('../../workers/WorkerSelenium');
34
- case CLI_MODE.APPIUM:
35
- case CLI_MODE.DEVICE_FARM_APPIUM:
36
- return require('../../workers/WorkerAppium');
26
+ return require('../workers/WorkerSelenium');
37
27
  default:
38
28
  if (labFeaturesService.isFeatureAvailableForProject('useSameBrowserForMultiTests')) {
39
- return require('../../workers/WorkerExtensionSingleBrowser');
29
+ return require('../workers/WorkerExtensionSingleBrowser');
40
30
  }
41
- return require('../../workers/WorkerExtension');
31
+ return require('../workers/WorkerExtension');
42
32
  }
43
33
  }
44
34
 
45
- createWorkers(count, queue, mode) {
35
+ createWorkers(count, queue, mode, ...args) {
46
36
  const Worker = this.getWorkerType(mode);
47
37
  const createWorker = () => {
48
38
  try {
49
39
  perf.log('before new Worker', mode);
50
- return new Worker(queue, this.customExtensionLocalLocation);
40
+ return new Worker(queue, ...args);
51
41
  } finally {
52
42
  perf.log('after new Worker', mode);
53
43
  }
@@ -56,9 +46,9 @@ class LocalStrategy extends BaseStrategy {
56
46
  return Array.from(new Array(count), createWorker);
57
47
  }
58
48
 
59
- runTests(testList, testStatus, executionId, options, branchToUse, authData, workerCount, stopOnError) {
49
+ async runTests(testList, testStatus, executionId, options, branchToUse, authData, workerCount, stopOnError) {
60
50
  if (testList && testList.length === 0) {
61
- return Promise.resolve();
51
+ return undefined;
62
52
  }
63
53
 
64
54
  const runAndWaitToComplete = token => new Promise((resolve, reject) => {
@@ -72,13 +62,13 @@ class LocalStrategy extends BaseStrategy {
72
62
  const companyName = options.company && options.company.name;
73
63
  const source = options.source || 'cli';
74
64
  const user = options.user;
75
- const companyPlanType = options.company && options.company.planType;
65
+ const companyPlan = options.company && options.company.planType;
76
66
  const projectName = options.projectData && options.projectData.name;
77
67
  const lightweightMode = options.lightweightMode;
78
68
  const sessionType = utils.getSessionType(options);
79
69
 
80
70
  const onTestStarted = (wid, testId, resultId, isRerun, testRetryKey) => {
81
- this.analyticsTestStart({
71
+ analyticsService.analyticsTestStart({
82
72
  authData,
83
73
  executionId,
84
74
  projectId,
@@ -87,7 +77,7 @@ class LocalStrategy extends BaseStrategy {
87
77
  companyId,
88
78
  companyName,
89
79
  projectName,
90
- companyPlanType,
80
+ companyPlan,
91
81
  sessionType,
92
82
  source,
93
83
  user,
@@ -95,13 +85,8 @@ class LocalStrategy extends BaseStrategy {
95
85
  });
96
86
  return testStatus.testStartAndReport(wid, executionId, resultId, isRerun, testRetryKey);
97
87
  };
98
- const onTestCompleted = (wid, testId, testResult, sessionId, isRerun) => testStatus.testEndAndReport(wid, testResult, executionId, sessionId, isRerun).catch(err => {
99
- logger.error('testEndAndReport threw an error', { err });
100
- }).then(() => {
101
- const isLocalRun = Boolean(options.useLocalChromeDriver || options.useChromeLauncher);
102
- if (lightweightMode && lightweightMode.disableResults && isLocalRun) {
103
- return undefined;
104
- }
88
+
89
+ const onTestCompleted = async (wid, testId, testResult, sessionId, isRerun) => {
105
90
  const update = {};
106
91
  if (lightweightMode && lightweightMode.onlyTestIdsNoSuite) {
107
92
  update.show = true;
@@ -137,18 +122,15 @@ class LocalStrategy extends BaseStrategy {
137
122
  } else if (options.saucelabs) {
138
123
  update.gridName = 'saucelabs-from-options';
139
124
  }
140
- if (Object.keys(update).length > 0 && testId && testResult.resultId) {
141
- return testResultService.updateTestResult(projectId, testResult.resultId, testId, update).catch(err => {
142
- logger.error('failed to update test result additional info (logs and grid-info)', { err });
143
- });
144
- }
145
- return undefined;
146
- }).then(() => {
125
+
126
+ await testStatus.testEndAndReport(wid, testResult, executionId, sessionId, isRerun, update)
127
+ .catch(err => logger.error('testEndAndReport threw an error', { err }));
128
+
147
129
  if (isRerun) {
148
130
  return undefined;
149
131
  }
150
132
  combinedTestResults[testResult.resultId] = testResult;
151
- this.analyticsTestEnd({
133
+ analyticsService.analyticsTestEnd({
152
134
  authData,
153
135
  executionId,
154
136
  projectId,
@@ -158,7 +140,7 @@ class LocalStrategy extends BaseStrategy {
158
140
  companyId,
159
141
  companyName,
160
142
  projectName,
161
- companyPlanType,
143
+ companyPlan,
162
144
  sessionType,
163
145
  source,
164
146
  user,
@@ -167,15 +149,15 @@ class LocalStrategy extends BaseStrategy {
167
149
  });
168
150
  if (stopOnError && !testResult.success) {
169
151
  reject(new StopRunOnError());
170
- return Promise.reject(new StopRunOnError());
152
+ throw new StopRunOnError();
171
153
  }
172
154
  const completedTests = Object.keys(combinedTestResults).length;
173
155
  if (completedTests === testCount) {
174
156
  resolve(combinedTestResults);
175
157
  return undefined;
176
158
  }
177
- return Promise.resolve();
178
- });
159
+ return undefined;
160
+ };
179
161
 
180
162
  const onTestIgnored = (wid, testResult) => {
181
163
  combinedTestResults[testResult.resultId] = testResult;
@@ -185,6 +167,7 @@ class LocalStrategy extends BaseStrategy {
185
167
  resolve(combinedTestResults);
186
168
  }
187
169
  };
170
+
188
171
  const onGridSlot = (executionId, resultId, gridInfo) => testStatus.onGridSlot(executionId, resultId, gridInfo);
189
172
 
190
173
  options.userData = {
@@ -198,25 +181,33 @@ class LocalStrategy extends BaseStrategy {
198
181
  servicesUrl: config.SERVICES_HOST,
199
182
  };
200
183
  perf.log('in localStrategy before createWorker');
201
- this.createWorkers(workerCount, executionQueue, options.mode)
184
+ this.createWorkers(workerCount, executionQueue, options.mode, options, this.customExtensionLocalLocation, executionId, onTestStarted, onTestCompleted, onGridSlot, onTestIgnored)
202
185
  .forEach((worker, index) => {
203
- perf.log('before schedule startWorker after createWorker');
186
+ perf.log('before schedule worker.run after createWorkers');
204
187
  schedule(() => {
205
- this.startWorker(worker, options, onTestStarted, onTestCompleted, executionId, onGridSlot, onTestIgnored);
188
+ perf.log('right before worker.run');
189
+ worker.run();
206
190
  }, index);
207
191
  });
208
- function schedule(fn, index) {
209
- if (index === 0) {
210
- fn();
211
- } else {
212
- setTimeout(fn, index * config.START_WORKER_DELAY_MS);
213
- }
214
- }
215
192
  });
216
193
 
217
- return testimCustomToken.getCustomTokenV3()
218
- .then(token => runAndWaitToComplete(token));
194
+ try {
195
+ const token = await testimCustomToken.getCustomTokenV3();
196
+ return await runAndWaitToComplete(token);
197
+ } catch (err) {
198
+ logger.error('failed running parallel workers', { executionId, err });
199
+ throw err;
200
+ }
201
+ }
202
+ }
203
+
204
+
205
+ function schedule(fn, index) {
206
+ if (index === 0) {
207
+ fn();
208
+ } else {
209
+ setTimeout(fn, index * config.START_WORKER_DELAY_MS);
219
210
  }
220
211
  }
221
212
 
222
- module.exports = LocalStrategy;
213
+ module.exports = ParallelWorkerManager;