@testim/testim-cli 3.194.0 → 3.198.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 (71) 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 +959 -523
  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/scripts/focusElement.js +5 -3
  20. package/player/stepActions/stepActionRegistrar.js +6 -48
  21. package/player/utils/eyeSdkService.js +230 -0
  22. package/reports/consoleReporter.js +0 -20
  23. package/reports/reporter.js +0 -21
  24. package/runOptions.js +13 -89
  25. package/runner.js +3 -44
  26. package/runners/{strategies/LocalStrategy.js → ParallelWorkerManager.js} +59 -68
  27. package/runners/TestPlanRunner.js +286 -67
  28. package/runners/runnerUtils.js +73 -0
  29. package/services/analyticsService.js +94 -0
  30. package/services/gridService.js +24 -16
  31. package/services/gridService.test.js +21 -21
  32. package/services/lambdatestService.js +1 -1
  33. package/testRunHandler.js +16 -2
  34. package/testRunStatus.js +17 -13
  35. package/utils.js +5 -5
  36. package/workers/BaseWorker.js +39 -39
  37. package/workers/BaseWorker.test.js +1 -1
  38. package/workers/WorkerExtensionSingleBrowser.js +6 -3
  39. package/commons/apkUploader/apkUploader.js +0 -46
  40. package/commons/apkUploader/apkUploaderFactory.js +0 -68
  41. package/commons/apkUploader/deviceFarmApkUploader.js +0 -41
  42. package/commons/apkUploader/saucelabsApkUploader.js +0 -36
  43. package/commons/apkUploader/testObjectApkUploader.js +0 -34
  44. package/player/mobile/mobileTestPlayer.js +0 -80
  45. package/player/mobile/mobileWebDriver.js +0 -155
  46. package/player/mobile/services/frameLocatorMock.js +0 -18
  47. package/player/mobile/services/mobilePortSelector.js +0 -22
  48. package/player/mobile/services/mobileTabService.js +0 -241
  49. package/player/mobile/utils/mobileScreenshotUtils.js +0 -46
  50. package/player/mobile/utils/mobileWindowUtils.js +0 -84
  51. package/player/stepActions/mobile/android/androidLocateStepAction.js +0 -122
  52. package/player/stepActions/mobile/android/androidLongClickStepAction.js +0 -12
  53. package/player/stepActions/mobile/android/androidScrollStepAction.js +0 -134
  54. package/player/stepActions/mobile/android/androidSpecialKeyStepAction.js +0 -22
  55. package/player/stepActions/mobile/android/androidSwipeStepAction.js +0 -32
  56. package/player/stepActions/mobile/androidGlobalActionStepAction.js +0 -12
  57. package/player/stepActions/mobile/androidTapStepAction.js +0 -19
  58. package/player/stepActions/mobile/androidTextChangeStepAction.js +0 -23
  59. package/player/stepActions/mobile/ios/iosLocateStepAction.js +0 -124
  60. package/player/stepActions/mobile/ios/iosScrollStepAction.js +0 -76
  61. package/runners/AnonymousTestPlanRunner.js +0 -106
  62. package/runners/BaseRunner.js +0 -42
  63. package/runners/BaseTestPlanRunner.js +0 -194
  64. package/runners/DeviceFarmRemoteRunner.js +0 -50
  65. package/runners/SchedulerRemoteRunner.js +0 -47
  66. package/runners/strategies/BaseStrategy.js +0 -86
  67. package/runners/strategies/DeviceFarmStrategy.js +0 -195
  68. package/runners/strategies/LocalDeviceFarmStrategy.js +0 -12
  69. package/runners/strategies/LocalTestStrategy.js +0 -14
  70. package/runners/strategies/Strategy.js +0 -17
  71. package/workers/WorkerAppium.js +0 -70
@@ -1,195 +0,0 @@
1
- 'use strict';
2
-
3
- const Promise = require('bluebird');
4
- const _ = require('lodash');
5
- const { CLI_MODE, runnerTestStatus } = require('../../commons/constants');
6
- const BaseStrategy = require('./BaseStrategy');
7
- const config = require('../../commons/config');
8
- const { deviceFarm, testRunStatus } = require('../../commons/constants');
9
- const logger = require('../../commons/logger').getLogger('deviceFarm-strategy');
10
- const utils = require('../../utils');
11
- const RealDataService = require('../../commons/socket/realDataService');
12
- const { getBrowserWithRetries: getDeviceWithRetries } = require('../../workers/workerUtils');
13
- const { GetBrowserError, ArgError } = require('../../errors');
14
- const { getAppCaps } = require('../../commons/apkUploader/apkUploaderFactory');
15
- const reporter = require('../../reports/reporter');
16
- const BaseWorker = require('../../workers/BaseWorker');
17
-
18
- const testimServicesApi = require('../../commons/testimServicesApi');
19
- const gridService = require('../../services/gridService');
20
-
21
- const MAX_EXECUTION_TIMEOUT = 150 * 60 * 1000; //150 min is the maximum allowed by device farm
22
- const STATUS_CHECK_INTERVAL = 20000;
23
-
24
- const DF_RUN_STATUS = deviceFarm.status;
25
- const DF_RUN_RESULT = deviceFarm.result;
26
- const TESTIM_RUN_STATUS = testRunStatus;
27
-
28
- class DeviceFarmStrategy extends BaseStrategy {
29
- constructor() {
30
- super();
31
- this.lastDeviceFarmStatus = DF_RUN_STATUS.INITIALIZING;
32
- }
33
-
34
- getDeviceFarmRunStatus(projectId, runArn) {
35
- return testimServicesApi.getDeviceFarmRun(projectId, runArn)
36
- .then(runInfo => {
37
- if (this.lastDeviceFarmStatus !== runInfo.status) {
38
- logger.info(`DeviceFarm run status changed from: ${this.lastDeviceFarmStatus} to ${runInfo.status}`);
39
- this.lastDeviceFarmStatus = runInfo.status;
40
- }
41
- if ([DF_RUN_STATUS.COMPLETED, DF_RUN_STATUS.STOPPING].includes(runInfo.status)) {
42
- return runInfo;
43
- }
44
- throw new Error('still running');
45
- });
46
- }
47
-
48
- convertTestResultObjectStatusToReportFormat(executionResults) {
49
- Object.keys(executionResults).forEach(resultId => {
50
- executionResults[resultId].status = executionResults[resultId].success ? runnerTestStatus.PASSED : runnerTestStatus.FAILED;
51
- });
52
- return executionResults;
53
- }
54
-
55
- convertTestResultArrayStatusToReportFormat(executionResults) {
56
- executionResults.forEach(result => {
57
- result.status = result.success ? runnerTestStatus.PASSED : runnerTestStatus.FAILED;
58
- });
59
- return executionResults;
60
- }
61
-
62
- buildConfiguration(testList) {
63
- const { overrideTestConfig } = _.uniqBy(testList, 'overrideTestConfig.name')[0];
64
- if (_.isEmpty(overrideTestConfig)) {
65
- return {};
66
- }
67
- const configuration = Object.assign({}, overrideTestConfig);
68
- const [platformName, platformVersion] = configuration.os.split(' ');
69
-
70
- return {
71
- platformName,
72
- deviceName: configuration.browser,
73
- platformVersion,
74
- };
75
- }
76
-
77
- buildDeviceFarmConfiguration(options) {
78
- const validateOptionKeys = (option) => {
79
- const { deviceName, platformVersion /*platformName, appiumVersion,*/ } = option;
80
- return deviceName && platformVersion;
81
- };
82
- const mapOptionToConfig = (option) => ({
83
- deviceName: option.deviceName,
84
- platformVersion: option.platformVersion,
85
- });
86
-
87
- if (_.isArray(options)) {
88
- return options.filter(validateOptionKeys).map(mapOptionToConfig);
89
- }
90
- return validateOptionKeys(options) ? mapOptionToConfig(options) : {};
91
- }
92
-
93
- runTests(testList, testStatus, executionId, options, branchToUse, authData, workerCount, stopOnError) {
94
- if (testList && testList.length === 0) {
95
- return Promise.resolve();
96
- }
97
- const executionResults = {};
98
- const projectId = options.project;
99
- const companyId = options.company.companyId;
100
- const workerId = BaseWorker.getWorkerId();
101
- const testResultId = '';
102
-
103
- const getBrowserTimeout = options.browserTimeout;
104
- const newBrowserWaitTimeout = options.newBrowserWaitTimeout;
105
-
106
- const configuration = this.buildConfiguration(testList);
107
- if (_.isEmpty(configuration)) {
108
- return Promise.reject(new ArgError('--test-config is missing or not properly used'));
109
- }
110
-
111
- const realDataService = new RealDataService();
112
- const releaseSlotOnTestFinished = true;
113
- const callbacksForGetDeviceRetryLogic = {
114
- getBrowserOnce() {
115
- reporter.onGetSession(workerId, `for execution ${executionId}`, CLI_MODE.APPIUM);
116
- return gridService.getGridSlot(configuration.platformName, executionId, testResultId, () => {}, options, workerId);
117
- },
118
- testPlayerFactory: () => {}, // no factory since this is a remote run
119
- releaseSlotOnTestFinished,
120
- };
121
- const deviceFetchConfig = {
122
- totalTimeoutDuration: newBrowserWaitTimeout,
123
- singleGetBrowserDuration: getBrowserTimeout,
124
- projectId,
125
- workerId,
126
- reporter,
127
- };
128
- return realDataService.init(projectId)
129
- .then(() => getDeviceWithRetries(callbacksForGetDeviceRetryLogic, deviceFetchConfig)).then(gridInfo => {
130
- const allowedRemoteRunEnv = Object.keys(config);
131
- const env = _.reduce(process.env, (envObj, value, key) => {
132
- if (allowedRemoteRunEnv.includes(key)) {
133
- envObj[key] = value;
134
- }
135
- return envObj;
136
- }, {});
137
-
138
- const remoteRunObject = {
139
- gridInfo,
140
- testList,
141
- echoedOptions: {
142
- disableWindowAnimation: options.disableWindowAnimation,
143
- baseUrl: options.baseUrl,
144
- },
145
- };
146
- const projectArn = gridInfo.arn;
147
- const { appArn } = getAppCaps(gridInfo);
148
- reporter.onWaitForDevice(workerId, executionId);
149
- realDataService.joinToTestResultsByRunId(executionId, projectId);
150
- return testimServicesApi.createDeviceFarmRun(companyId, projectId, projectArn, appArn, configuration, branchToUse, executionId, env, remoteRunObject);
151
- }).then(run => {
152
- realDataService.listenToTestResultsByRunId(executionId, testResult => {
153
- const prevTestResult = executionResults[testResult.id];
154
- const mergedTestResult = _.merge({}, prevTestResult, testResult, { resultId: testResult.id });
155
- if (!prevTestResult || prevTestResult.status !== testResult.status) {
156
- if ([TESTIM_RUN_STATUS.RUNNING].includes(testResult.status)) {
157
- testStatus.testStart(workerId, executionId, mergedTestResult.id);
158
- }
159
- if ([TESTIM_RUN_STATUS.COMPLETED].includes(testResult.status)) {
160
- testStatus.testEnd(workerId, Object.assign({}, mergedTestResult), executionId);
161
- }
162
- }
163
- executionResults[testResult.id] = mergedTestResult;
164
- });
165
- return utils.runWithRetries(
166
- () => this.getDeviceFarmRunStatus(projectId, run.arn), MAX_EXECUTION_TIMEOUT, STATUS_CHECK_INTERVAL);
167
- })
168
- .then(runInfo => {
169
- if ([DF_RUN_RESULT.SKIPPED].includes(runInfo.result) &&
170
- runInfo.deviceSelectionResult &&
171
- runInfo.deviceSelectionResult.matchedDevicesCount === 0) {
172
- console.log('Device Farm Error: The device in your configuration is not supported');
173
- }
174
- if ([DF_RUN_RESULT.STOPPED].includes(runInfo.result)) {
175
- console.log('Device Farm Error: The test has been stopped. Please try running it again in a few minutes');
176
- }
177
- if ([DF_RUN_RESULT.ERRORED].includes(runInfo.result)) {
178
- console.log(`Device Farm Error: ${runInfo.message}`);
179
- return testStatus.markAllQueuedTests(executionId, runnerTestStatus.ABORTED, 'aborted', false);
180
- }
181
- // Results from socket (currently unused).
182
- this.convertTestResultObjectStatusToReportFormat(executionResults);
183
- // Results from server.
184
- return testimServicesApi.getRealData(projectId, 'testResult', `runId=${executionId}&sort=runOrder`)
185
- .then(res => this.convertTestResultArrayStatusToReportFormat(res.data.docs));
186
- })
187
- .catch(GetBrowserError, err => testStatus.markAllQueuedTests(executionId, runnerTestStatus.FAILED, err.message, false))
188
- .finally(() => {
189
- realDataService.stopListenToTestResultsByRunId();
190
- return gridService.releaseGridSlot(workerId, projectId);
191
- });
192
- }
193
- }
194
-
195
- module.exports = DeviceFarmStrategy;
@@ -1,12 +0,0 @@
1
- 'use strict';
2
-
3
- const LocalStrategy = require('./LocalStrategy');
4
-
5
- class LocalDeviceFarmStrategy extends LocalStrategy {
6
- startWorker(worker, options, onTestStarted, onTestCompleted, executionId, onGridSlot, onTestIgnored) {
7
- const releaseSlotOnTestFinished = false;
8
- worker.start(options, onTestStarted, onTestCompleted, executionId, onGridSlot, onTestIgnored, releaseSlotOnTestFinished);
9
- }
10
- }
11
-
12
- module.exports = LocalDeviceFarmStrategy;
@@ -1,14 +0,0 @@
1
- 'use strict';
2
-
3
- const LocalStrategy = require('./LocalStrategy');
4
- const perf = require('../../commons/performance-logger');
5
-
6
- class LocalTestStrategy extends LocalStrategy {
7
- startWorker(worker, options, onTestStarted, onTestCompleted, executionId, onGridSlot, onTestIgnored) {
8
- const releaseSlotOnTestFinished = true;
9
- perf.log('right before worker.start in startWorker');
10
- worker.start(options, onTestStarted, onTestCompleted, executionId, onGridSlot, onTestIgnored, releaseSlotOnTestFinished);
11
- }
12
- }
13
-
14
- module.exports = LocalTestStrategy;
@@ -1,17 +0,0 @@
1
- const LocalDeviceFarmStrategy = require('./LocalDeviceFarmStrategy');
2
- const LocalTestStrategy = require('./LocalTestStrategy');
3
- const DeviceFarmStrategy = require('./DeviceFarmStrategy');
4
- const {CLI_MODE} = require('../../commons/constants');
5
-
6
- module.exports = (options, customExtensionLocalLocation) => {
7
- const {projectData, gridData, mode} = options;
8
- if (["android", "ios"].includes(projectData.type) && gridData.type === "testimMobile") {
9
- options.mode = CLI_MODE.APPIUM;
10
- return new DeviceFarmStrategy();
11
- }
12
- if (["android", "ios"].includes(projectData.type) && mode === CLI_MODE.DEVICE_FARM_APPIUM) {
13
- return new LocalDeviceFarmStrategy();
14
- }
15
-
16
- return new LocalTestStrategy(customExtensionLocalLocation);
17
- };
@@ -1,70 +0,0 @@
1
- "use strict";
2
-
3
- const {CLI_MODE} = require('../commons/constants');
4
- const BaseWorker = require('./BaseWorker');
5
- const {timeoutMessages} = require('../commons/constants');
6
- const logger = require('../commons/logger').getLogger("worker-selenium");
7
- const Promise = require('bluebird');
8
- const exec = Promise.promisify(require('child_process').exec);
9
- const reporter = require("../reports/reporter");
10
- const MobileTestPlayer = require('../player/mobile/mobileTestPlayer');
11
- const { manifestVersion } = require('../commons/getSessionPlayerRequire');
12
-
13
- class WorkerAppium extends BaseWorker {
14
- initPlayer(testRunHandler) {
15
- const { projectData } = this.options;
16
- return new MobileTestPlayer(this.id, testRunHandler.getRunParams(), projectData.type);
17
- }
18
-
19
- async getBrowserOnce(testRunHandler, customExtensionLocalLocation, player, gridInfo) {
20
- reporter.onGetSession(this.id, this.testName, testRunHandler.getRunMode());
21
- player.clearSessionTabs();
22
- const { driver } = player;
23
-
24
- try {
25
- await driver.init(this.options, gridInfo, testRunHandler.getNativeAppData(), this.testName, this.testResultId);
26
- return player.addTab();
27
- } catch (err) {
28
- logger.error(`failed to get device/app (message=${err.message})`, { err });
29
- throw err;
30
- }
31
- }
32
-
33
- runTestCleanup() {
34
- const { mode } = this.options;
35
-
36
- if(mode === CLI_MODE.DEVICE_FARM_APPIUM) {
37
- return exec("adb shell pm clear $DEVICEFARM_APP_NAME");
38
- }
39
- return Promise.resolve();
40
- }
41
-
42
- runTestOnce(testRunHandler, player) {
43
- const version = manifestVersion || "runner";
44
- let that = this;
45
-
46
- reporter.onWaitToTestComplete(this.id, this.isCodeMode);
47
-
48
- function runSeleniumTest() {
49
- return new Promise(resolve => player.sessionPlayer.playByTestId(that.testId, that.executionId, that.testResultId, that.baseUrl, that.userData, version, resolve, false, that.overrideTestConfigId, that.branch))
50
- .timeout(that.testRunTimeout, timeoutMessages.TEST_COMPLETE_TIMEOUT_MSG)
51
- .catch(Promise.TimeoutError, err => {
52
- player.sessionPlayer.stopPlayingOnTestTimeout && player.sessionPlayer.stopPlayingOnTestTimeout();
53
- throw err;
54
- })
55
- .then(testResult => {
56
- testResult.stepsResults = null;
57
- return Promise.resolve(testResult);
58
- });
59
- }
60
-
61
- return super.runTestOnce(testRunHandler, player)
62
- .then(() => runSeleniumTest())
63
- .catch(err => {
64
- logger.error("failed to run test once", {err: err});
65
- return Promise.reject(err);
66
- });
67
- }
68
- }
69
-
70
- module.exports = WorkerAppium;