@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.
@@ -119,6 +119,7 @@ type ApiCallOptions = {
119
119
  headers?: Headers;
120
120
  body?: string;
121
121
  sendViaWebApp?: boolean;
122
+ omitCookies?: boolean;
122
123
  }
123
124
 
124
125
  export enum GeneratedValueTypes {
@@ -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
- }), DEFAULT_REQUEST_RETRY);
118
+ }), apiRetries);
119
119
  }
120
120
 
121
121
  function updateExecutionTests(executionId, runnerStatuses, status, reason, success, startTime, endTime, projectId) {
@@ -1912,9 +1912,9 @@
1912
1912
  },
1913
1913
  "dependencies": {
1914
1914
  "@types/node": {
1915
- "version": "16.11.4",
1916
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.4.tgz",
1917
- "integrity": "sha512-TMgXmy0v2xWyuCSCJM6NCna2snndD8yvQF67J29ipdzMcsPa9u+o0tjF5+EQNdhcuZplYuouYqpc4zcd5I6amQ=="
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.878",
2857
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.878.tgz",
2858
- "integrity": "sha512-O6yxWCN9ph2AdspAIszBnd9v8s11hQx8ub9w4UGApzmNRnoKhbulOWqbO8THEQec/aEHtvy+donHZMlh6l1rbA==",
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.2.0",
5314
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
5315
- "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ=="
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testim/testim-cli",
3
- "version": "3.193.0",
3
+ "version": "3.194.0",
4
4
  "description": "Command line interface for running Testing on your CI",
5
5
  "author": "Oren Rubin",
6
6
  "contributors": [{
@@ -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 LancherDriver {
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 LancherDriver(this.sessionId);
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, gridTypes } = require('./commons/constants');
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
- const properties = setLightweightAnalytics({
56
- executionId,
57
- projectId,
58
- testId,
59
- resultId,
60
- companyId,
61
- companyName,
62
- projectName,
63
- companyPlanType,
64
- sessionType,
65
- mockNetworkEnabled: result.wasMockNetworkActivated,
66
- source: calcSource(source, user),
67
- }, lightweightMode);
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
- if (result.success) {
70
- analytics.trackWithCIUser('test-run-ci-success', properties);
71
- return;
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).then(() => {
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
- return runHook(this.options.afterTest, Object.assign({}, test, { globalParameters }))
283
- .then(() => {
284
- if (this.options.lightweightMode && this.options.lightweightMode.onlyTestIdsNoSuite) {
285
- return undefined;
286
- }
287
- return servicesApi.updateTestStatus('FINISHED', executionId, test.testId, test.resultId, test.startTime, result.endTime, test.success, test.failureReason, null, this.options.project, this.options.remoteRunId);
288
- })
289
- .catch(err => {
290
- logger.error('Failed to update test finished', { err });
291
- throw err;
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) {