@testim/testim-cli 3.193.0 → 3.194.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.
- package/codim/codim-npm-package/index.ts +1 -0
- package/commons/testimDesiredCapabilitiesBuilder.js +0 -1
- package/commons/testimServicesApi.js +2 -2
- package/npm-shrinkwrap.json +9 -9
- package/package.json +1 -1
- package/player/chromeLauncherTestPlayer.js +5 -2
- package/player/stepActions/apiStepAction.js +1 -0
- package/player/stepActions/salesforceAutoLoginStepAction.js +37 -0
- package/player/stepActions/stepActionRegistrar.js +3 -0
- package/runner.js +6 -2
- package/runners/strategies/BaseStrategy.js +22 -17
- package/runners/strategies/LocalStrategy.js +4 -1
- package/testRunStatus.js +19 -13
|
@@ -193,7 +193,6 @@ function _buildChromiumOptions(opts, browserOptions, testRunConfig, customExtens
|
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
if (isDFGrid(gridInfo) && browserName === 'MicrosoftEdge') {
|
|
196
|
-
delete chromiumOptions.prefs['profile.content_settings.exceptions.clipboard']; // for some reason this breaks
|
|
197
196
|
opts.desiredCapabilities['ms:edgeChromium'] = true;
|
|
198
197
|
}
|
|
199
198
|
|
|
@@ -100,7 +100,7 @@ function saveTestPlanResult(projectId, testPlanId, result) {
|
|
|
100
100
|
return utils.runWithRetries(() => postAuth({ url: '/testPlan/result', body: { projectId, testPlanId, result } }));
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
function updateTestStatus(status, executionId, testId, resultId, startTime, endTime, success, failureReason, config, projectId, remoteRunId, testRetryKey) {
|
|
103
|
+
function updateTestStatus(status, executionId, testId, resultId, startTime, endTime, success, failureReason, config, projectId, remoteRunId, testRetryKey, apiRetries = DEFAULT_REQUEST_RETRY) {
|
|
104
104
|
return utils.runWithRetries(() => putAuth('/result/run/test', {
|
|
105
105
|
runId: executionId,
|
|
106
106
|
testId,
|
|
@@ -115,7 +115,7 @@ function updateTestStatus(status, executionId, testId, resultId, startTime, endT
|
|
|
115
115
|
runnerVersion,
|
|
116
116
|
remoteRunId,
|
|
117
117
|
testRetryKey,
|
|
118
|
-
}),
|
|
118
|
+
}), apiRetries);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
function updateExecutionTests(executionId, runnerStatuses, status, reason, success, startTime, endTime, projectId) {
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1912,9 +1912,9 @@
|
|
|
1912
1912
|
},
|
|
1913
1913
|
"dependencies": {
|
|
1914
1914
|
"@types/node": {
|
|
1915
|
-
"version": "16.11.
|
|
1916
|
-
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.
|
|
1917
|
-
"integrity": "sha512-
|
|
1915
|
+
"version": "16.11.6",
|
|
1916
|
+
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz",
|
|
1917
|
+
"integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w=="
|
|
1918
1918
|
},
|
|
1919
1919
|
"mkdirp": {
|
|
1920
1920
|
"version": "0.5.5",
|
|
@@ -2853,9 +2853,9 @@
|
|
|
2853
2853
|
"integrity": "sha512-GJCAeDBKfREgkBtgrYSf9hQy9kTb3helv0zGdzqhM7iAkW8FA/ZF97VQDbwFiwIT8MQLLOe5VlPZOEvZAqtUAQ=="
|
|
2854
2854
|
},
|
|
2855
2855
|
"electron-to-chromium": {
|
|
2856
|
-
"version": "1.3.
|
|
2857
|
-
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.
|
|
2858
|
-
"integrity": "sha512-
|
|
2856
|
+
"version": "1.3.879",
|
|
2857
|
+
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.879.tgz",
|
|
2858
|
+
"integrity": "sha512-zJo+D9GwbJvM31IdFmwcGvychhk4KKbKYo2GWlsn+C/dxz2NwmbhGJjWwTfFSF2+eFH7VvfA8MCZ8SOqTrlnpw==",
|
|
2859
2859
|
"dev": true
|
|
2860
2860
|
},
|
|
2861
2861
|
"emoji-regex": {
|
|
@@ -5310,9 +5310,9 @@
|
|
|
5310
5310
|
}
|
|
5311
5311
|
},
|
|
5312
5312
|
"estraverse": {
|
|
5313
|
-
"version": "5.
|
|
5314
|
-
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.
|
|
5315
|
-
"integrity": "sha512-
|
|
5313
|
+
"version": "5.3.0",
|
|
5314
|
+
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
|
|
5315
|
+
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="
|
|
5316
5316
|
},
|
|
5317
5317
|
"html-encoding-sniffer": {
|
|
5318
5318
|
"version": "2.0.1",
|
package/package.json
CHANGED
|
@@ -4,9 +4,10 @@ const launcher = require('chrome-launcher');
|
|
|
4
4
|
const desiredCapabilitiesBuilder = require('../commons/testimDesiredCapabilitiesBuilder');
|
|
5
5
|
const utils = require('../utils');
|
|
6
6
|
const httpRequest = require('../commons/httpRequest');
|
|
7
|
+
const { registerExitHook } = require('../processHandler');
|
|
7
8
|
const CDPTestRunner = require('../cdpTestRunner');
|
|
8
9
|
|
|
9
|
-
class
|
|
10
|
+
class LauncherDriver {
|
|
10
11
|
constructor(sessionId) {
|
|
11
12
|
this.sessionId = sessionId;
|
|
12
13
|
this.cdpTestRunner = new CDPTestRunner();
|
|
@@ -24,6 +25,8 @@ class LancherDriver {
|
|
|
24
25
|
this._isAlive = true;
|
|
25
26
|
const browserEndpoint = await httpRequest.get(`http://localhost:${this.chrome.port}/json/version`);
|
|
26
27
|
await this.cdpTestRunner.initSession(browserEndpoint.webSocketDebuggerUrl);
|
|
28
|
+
|
|
29
|
+
registerExitHook(() => this.chrome.kill());
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
isAlive() {
|
|
@@ -49,7 +52,7 @@ class LancherDriver {
|
|
|
49
52
|
class ChromeLauncherTestPlayer {
|
|
50
53
|
constructor(id) {
|
|
51
54
|
this.sessionId = utils.guid();
|
|
52
|
-
this.driver = new
|
|
55
|
+
this.driver = new LauncherDriver(this.sessionId);
|
|
53
56
|
this.id = id;
|
|
54
57
|
}
|
|
55
58
|
|
|
@@ -36,6 +36,7 @@ class ApiStepAction extends StepAction {
|
|
|
36
36
|
headers: context.apiHeaders,
|
|
37
37
|
body: context.apiBody,
|
|
38
38
|
timeout: context.data.maxTotalStepTime,
|
|
39
|
+
omitCookies: step.omitCookies,
|
|
39
40
|
};
|
|
40
41
|
|
|
41
42
|
return (step.sendViaWebApp ? this.runApiInAut(step, context) : this.runApiInBg(eventData))
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const NavigationStepAction = require('./navigationStepAction');
|
|
2
|
+
const Promise = require('bluebird');
|
|
3
|
+
|
|
4
|
+
class SalesforceAutoLoginStepAction extends NavigationStepAction {
|
|
5
|
+
async performAction() {
|
|
6
|
+
let salesforceUrl = this.context.data.testimNavigationStepDestination || this.context.data.url;
|
|
7
|
+
try {
|
|
8
|
+
salesforceUrl = await this.updateBaseUrl(salesforceUrl);
|
|
9
|
+
await this.driver.url(salesforceUrl);
|
|
10
|
+
await Promise.delay(300); // wait a little for the page to load (fixes screenshots and clicking on elements in username verification screen)
|
|
11
|
+
let newUrl = await this.driver.getUrl();
|
|
12
|
+
// Verify username screen
|
|
13
|
+
const isUsernameVerificationNeeded = newUrl.includes(this.step.USERNAME_VERIFICATION_PATH_ID);
|
|
14
|
+
if (isUsernameVerificationNeeded) {
|
|
15
|
+
await this.driver.executeCodeAsync(`
|
|
16
|
+
function ${this.step.handleUsernameVerificationAUTFunc.toString()}
|
|
17
|
+
handleUsernameVerificationAUTFunc();
|
|
18
|
+
var done = arguments[1];
|
|
19
|
+
done();
|
|
20
|
+
`);
|
|
21
|
+
await Promise.delay(500);
|
|
22
|
+
newUrl = await this.driver.getUrl(); // If we managed to continue correctly we want to get the new redirected url
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
success: true,
|
|
26
|
+
newUrl,
|
|
27
|
+
};
|
|
28
|
+
} catch (err) {
|
|
29
|
+
return {
|
|
30
|
+
success: false,
|
|
31
|
+
reason: err.message,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
module.exports = SalesforceAutoLoginStepAction;
|
|
@@ -21,6 +21,7 @@ const RefreshStepAction = require('./RefreshStepAction');
|
|
|
21
21
|
const ApiStepAction = require('./apiStepAction');
|
|
22
22
|
const ExtractTextStepAction = require('./extractTextStepAction');
|
|
23
23
|
const TdkHybridStepAction = require('./tdkHybridStepAction');
|
|
24
|
+
const SalesforceAutoLoginStepAction = require('./salesforceAutoLoginStepAction');
|
|
24
25
|
|
|
25
26
|
const CliJsStepAction = require('./cliJsStepAction');
|
|
26
27
|
const CliConditionStepAction = require('./cliConditionStepAction');
|
|
@@ -92,6 +93,8 @@ module.exports = function (driver, stepActionFactory, runMode) {
|
|
|
92
93
|
'email-code-step': JsCodeStepAction,
|
|
93
94
|
'cli-email-code-step': CliJsStepAction,
|
|
94
95
|
'tdk-hybrid': TdkHybridStepAction,
|
|
96
|
+
|
|
97
|
+
'salesforce-autologin': SalesforceAutoLoginStepAction,
|
|
95
98
|
};
|
|
96
99
|
|
|
97
100
|
const ANDROID_STEP_ACTION_MAPPING = {
|
package/runner.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
/* eslint-disable no-console */
|
|
4
|
-
const { CLI_MODE
|
|
4
|
+
const { CLI_MODE } = require('./commons/constants');
|
|
5
5
|
const Promise = require('bluebird');
|
|
6
6
|
const _ = require('lodash');
|
|
7
7
|
const { EDITOR_URL } = require('./commons/config');
|
|
@@ -309,10 +309,14 @@ async function init(options) {
|
|
|
309
309
|
await labFeaturesService.loadLabFeatures(projectById.id, companyByProjectId.activePlan);
|
|
310
310
|
}
|
|
311
311
|
|
|
312
|
-
if (options.lightweightMode && options.lightweightMode.type === 'highSpeed' && !labFeaturesService.isFeatureAvailableForProject('highSpeedMode')) {
|
|
312
|
+
if (options.lightweightMode && options.lightweightMode.type === 'highSpeed' && (!labFeaturesService.isFeatureAvailableForProject('highSpeedMode') || options.company.planType === 'free')) {
|
|
313
313
|
delete options.lightweightMode;
|
|
314
314
|
}
|
|
315
315
|
|
|
316
|
+
if (options.lightweightMode && options.lightweightMode.type === 'highSpeed') {
|
|
317
|
+
console.log('High-speed mode will ignore step delays. Test artifacts like screenshots and logs will only be saved for failed runs. For more information see our docs: https://help.testim.io/docs/high-speed-mode');
|
|
318
|
+
}
|
|
319
|
+
|
|
316
320
|
gridService.keepAlive.start(project);
|
|
317
321
|
analyticsIdentify(project);
|
|
318
322
|
await setMockNetworkRules(options);
|
|
@@ -51,26 +51,31 @@ class BaseStrategy {
|
|
|
51
51
|
|
|
52
52
|
analyticsTestEnd({
|
|
53
53
|
executionId, projectId, testId, resultId, result, companyId, companyName, projectName, companyPlanType, sessionType, source, user, lightweightMode,
|
|
54
|
+
logger,
|
|
54
55
|
}) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
56
|
+
try {
|
|
57
|
+
const properties = setLightweightAnalytics({
|
|
58
|
+
executionId,
|
|
59
|
+
projectId,
|
|
60
|
+
testId,
|
|
61
|
+
resultId,
|
|
62
|
+
companyId,
|
|
63
|
+
companyName,
|
|
64
|
+
projectName,
|
|
65
|
+
companyPlanType,
|
|
66
|
+
sessionType,
|
|
67
|
+
mockNetworkEnabled: result.wasMockNetworkActivated,
|
|
68
|
+
source: calcSource(source, user),
|
|
69
|
+
}, lightweightMode);
|
|
68
70
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
71
|
+
if (result.success) {
|
|
72
|
+
analytics.trackWithCIUser('test-run-ci-success', properties);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
analytics.trackWithCIUser('test-run-ci-fail', Object.assign({}, properties, { failureReason: result.failureReason }));
|
|
76
|
+
} catch (err) {
|
|
77
|
+
logger.error('failed to update test end analytics', { err });
|
|
72
78
|
}
|
|
73
|
-
analytics.trackWithCIUser('test-run-ci-fail', Object.assign({}, properties, { failureReason: result.failureReason }));
|
|
74
79
|
}
|
|
75
80
|
|
|
76
81
|
runTests(testList, testStatus, executionId, options, branchToUse, authData, workerCount, stopOnError) {
|
|
@@ -95,7 +95,9 @@ class LocalStrategy extends BaseStrategy {
|
|
|
95
95
|
});
|
|
96
96
|
return testStatus.testStartAndReport(wid, executionId, resultId, isRerun, testRetryKey);
|
|
97
97
|
};
|
|
98
|
-
const onTestCompleted = (wid, testId, testResult, sessionId, isRerun) => testStatus.testEndAndReport(wid, testResult, executionId, sessionId, isRerun).
|
|
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(() => {
|
|
99
101
|
const isLocalRun = Boolean(options.useLocalChromeDriver || options.useChromeLauncher);
|
|
100
102
|
if (lightweightMode && lightweightMode.disableResults && isLocalRun) {
|
|
101
103
|
return undefined;
|
|
@@ -161,6 +163,7 @@ class LocalStrategy extends BaseStrategy {
|
|
|
161
163
|
source,
|
|
162
164
|
user,
|
|
163
165
|
lightweightMode,
|
|
166
|
+
logger,
|
|
164
167
|
});
|
|
165
168
|
if (stopOnError && !testResult.success) {
|
|
166
169
|
reject(new StopRunOnError());
|
package/testRunStatus.js
CHANGED
|
@@ -47,7 +47,7 @@ const RunStatus = function (testInfoList, options, testPlanId, branchToUse) {
|
|
|
47
47
|
this.executionStartedPromise = Promise.resolve();
|
|
48
48
|
|
|
49
49
|
const browserNames = utils.getUniqBrowsers(options, testInfoList);
|
|
50
|
-
const runnerMode = options.lightweightMode ? options.lightweightMode.type : options.mode;
|
|
50
|
+
const runnerMode = options.lightweightMode ? options.lightweightMode.type : options.mode;
|
|
51
51
|
this.execConfig = {
|
|
52
52
|
parallel: TESTIM_CONCURRENT_WORKER_COUNT || options.parallel || 1,
|
|
53
53
|
browser: browserNames,
|
|
@@ -277,19 +277,25 @@ RunStatus.prototype.testEnd = function (wid, result, executionId, sessionId, isR
|
|
|
277
277
|
return test;
|
|
278
278
|
};
|
|
279
279
|
|
|
280
|
-
RunStatus.prototype.testEndReport = function (test, executionId, result) {
|
|
280
|
+
RunStatus.prototype.testEndReport = async function (test, executionId, result) {
|
|
281
281
|
const globalParameters = result.exportsGlobal;
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
}
|
|
282
|
+
try {
|
|
283
|
+
try {
|
|
284
|
+
await runHook(this.options.afterTest, Object.assign({}, test, { globalParameters }));
|
|
285
|
+
} catch (err) {
|
|
286
|
+
logger.error('HOOK threw an error', { test: test.testId, err });
|
|
287
|
+
// eslint-disable-next-line no-console
|
|
288
|
+
console.error('HOOK threw an error', err); // show the customer that his hook failed.
|
|
289
|
+
}
|
|
290
|
+
if (this.options.lightweightMode && this.options.lightweightMode.onlyTestIdsNoSuite) {
|
|
291
|
+
return undefined;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return await servicesApi.updateTestStatus('FINISHED', executionId, test.testId, test.resultId, test.startTime, result.endTime, test.success, test.failureReason, null, this.options.project, this.options.remoteRunId, undefined, 5);
|
|
295
|
+
} catch (err) {
|
|
296
|
+
logger.error('Failed to update test finished', { err });
|
|
297
|
+
throw err;
|
|
298
|
+
}
|
|
293
299
|
};
|
|
294
300
|
|
|
295
301
|
RunStatus.prototype.testEndAndReport = function (wid, result, executionId, sessionId, isRerun) {
|