@testim/testim-cli 3.253.0 → 3.254.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 (79) 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 +15 -14
  7. package/agent/routers/codim/service.js +1 -1
  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 +19 -18
  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 +7 -6
  18. package/cliAgentMode.js +4 -5
  19. package/codim/codim-cli.js +11 -10
  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/lazyRequire.js +10 -9
  32. package/commons/logger.js +4 -4
  33. package/commons/performance-logger.js +14 -8
  34. package/commons/prepareRunnerAndTestimStartUtils.js +6 -7
  35. package/commons/socket/baseSocketServiceSocketIO.js +32 -34
  36. package/commons/socket/realDataService.js +6 -5
  37. package/commons/socket/realDataServiceSocketIO.js +4 -4
  38. package/commons/socket/remoteStepService.js +4 -3
  39. package/commons/socket/remoteStepServiceSocketIO.js +11 -12
  40. package/commons/socket/socketService.js +50 -52
  41. package/commons/socket/testResultServiceSocketIO.js +11 -11
  42. package/commons/testimDesiredCapabilitiesBuilder.js +3 -2
  43. package/commons/testimNgrok.js +2 -2
  44. package/commons/testimNgrok.test.js +1 -1
  45. package/commons/testimServicesApi.js +27 -20
  46. package/commons/xhr2.js +97 -100
  47. package/errors.js +5 -0
  48. package/fixLocalBuild.js +2 -0
  49. package/npm-shrinkwrap.json +2515 -1256
  50. package/package.json +6 -6
  51. package/player/appiumTestPlayer.js +1 -1
  52. package/player/chromeLauncherTestPlayer.js +0 -1
  53. package/player/services/tabServiceMock.js +166 -0
  54. package/player/stepActions/navigationStepAction.js +11 -10
  55. package/player/stepActions/sleepStepAction.js +4 -5
  56. package/player/stepActions/textStepAction.js +4 -11
  57. package/player/utils/windowUtils.js +4 -3
  58. package/player/webdriver.js +1 -1
  59. package/processHandler.js +3 -3
  60. package/processHandler.test.js +1 -1
  61. package/reports/consoleReporter.js +3 -2
  62. package/reports/junitReporter.js +1 -2
  63. package/runOptions.js +6 -6
  64. package/runner.js +13 -0
  65. package/runners/TestPlanRunner.js +142 -74
  66. package/runners/buildCodeTests.js +38 -37
  67. package/runners/runnerUtils.js +3 -3
  68. package/services/lambdatestService.js +3 -5
  69. package/stepPlayers/cliJsStepPlayback.js +22 -17
  70. package/testRunHandler.js +8 -0
  71. package/testRunStatus.js +1 -1
  72. package/{utils.js → utils/index.js} +25 -117
  73. package/utils/promiseUtils.js +78 -0
  74. package/utils/stringUtils.js +96 -0
  75. package/{utils.test.js → utils/utils.test.js} +2 -2
  76. package/workers/BaseWorker.js +16 -14
  77. package/workers/WorkerAppium.js +1 -1
  78. package/workers/WorkerExtensionSingleBrowser.js +4 -4
  79. package/workers/WorkerSelenium.js +5 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testim/testim-cli",
3
- "version": "3.253.0",
3
+ "version": "3.254.0",
4
4
  "description": "Command line interface for running Testing on your CI",
5
5
  "author": "Oren Rubin",
6
6
  "contributors": [{
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "lazyDependencies": {
34
34
  "ngrok": "3.4.0",
35
- "webpack": "4.43.0",
35
+ "webpack": "5.74.0",
36
36
  "playwright": "0.12.1",
37
37
  "puppeteer": "2.1.1",
38
38
  "selenium-webdriver": "3.6.0",
@@ -71,23 +71,23 @@
71
71
  "https-proxy-agent": "5.0.0",
72
72
  "istanbul-lib-report": "3.0.0",
73
73
  "istanbul-reports": "3.0.2",
74
- "jimp": "0.16.1",
74
+ "jimp": "0.16.2",
75
75
  "jsdom": "19.0.0",
76
76
  "jsonwebtoken": "8.5.1",
77
77
  "lodash": "4.17.21",
78
78
  "memory-fs": "0.5.0",
79
79
  "memorystream": "0.3.1",
80
80
  "mkdirp": "1.0.4",
81
- "moment": "2.25.3",
81
+ "moment": "2.29.4",
82
82
  "ms": "2.1.2",
83
- "npm": "8.3.0",
83
+ "npm": "8.19.2",
84
84
  "object-hash": "3.0.0",
85
85
  "ora": "5.4.1",
86
86
  "p-retry": "4.6.2",
87
87
  "pako": "1.0.11",
88
88
  "portfinder": "1.0.28",
89
89
  "promise-queue": "2.2.5",
90
- "prompts": "2.3.2",
90
+ "prompts": "2.4.2",
91
91
  "proxy-agent": "5.0.0",
92
92
  "rox-node": "4.9.18",
93
93
  "semver": "7.3.2",
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const webdriverio = require('webdriverio');
4
- const TabService = require('./services/tabService');
4
+ const TabService = require('./services/tabServiceMock');
5
5
  const PortSelector = require('./services/portSelector');
6
6
  const windowCreationListener = require('./services/windowCreationListener');
7
7
  const frameLocatorFactory = require('./services/mobileFrameLocatorMock');
@@ -3,7 +3,6 @@
3
3
  const launcher = require('chrome-launcher');
4
4
  const desiredCapabilitiesBuilder = require('../commons/testimDesiredCapabilitiesBuilder');
5
5
  const utils = require('../utils');
6
- const httpRequest = require('../commons/httpRequest');
7
6
  const { registerExitHook } = require('../processHandler');
8
7
  const CDPTestRunner = require('../cdpTestRunner');
9
8
 
@@ -0,0 +1,166 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @typedef {{
5
+ * attachDebugger(): Promise<any>,
6
+ * detachDebugger(): Promise<any>,
7
+ * onDebuggerDetached(): {},
8
+ * tabId: string,
9
+ * domUtils: { getDOM(): Promise<any> },
10
+ * windowUtils: WindowUtils,
11
+ * imageCaptureUtils: ImageCaptureUtils
12
+ * }} TabUtil
13
+ * */
14
+ /**
15
+ * @typedef {{
16
+ * infoId: any;
17
+ * url: any;
18
+ * title: any;
19
+ * favIconUrl: any;
20
+ * order: any;
21
+ * from: any;
22
+ * isMain: any;
23
+ * openerStepId: any;
24
+ * }} TabInfo
25
+ */
26
+
27
+ class TabService {
28
+ /** @param {import('../webdriver')} driver */
29
+ constructor(driver) {
30
+ this.driver = driver;
31
+ /** @type {Record<string, TabUtil>} */
32
+ this._utils = {};
33
+ /** @type {Record<string, { tabCount: number; tabInfos: Record<string, TabInfo> }>} */
34
+ this.sessionTabs = {};
35
+ /** @type {Record<string, string>} */
36
+ this.pendingTabs = {};
37
+ /** @type {Record<string, Set<any>>} */
38
+ this.addedTabs = {};
39
+ }
40
+
41
+ on() {}
42
+
43
+ tabCount(sessionId) {
44
+ }
45
+
46
+ getAllOpenTabIds(sessionId) {
47
+ }
48
+
49
+ /**
50
+ * Get last tab info for pixel validation
51
+ *
52
+ * @returns last tab info
53
+ */
54
+ getActiveTabInfo(sessionId) {
55
+ }
56
+
57
+ getAllTabIds(sessionId) {
58
+ }
59
+
60
+ isSessionTab(sessionId, tabId) {
61
+ }
62
+
63
+ createSesion(sessionId) {
64
+ }
65
+
66
+ setAddFrameHandlerCallBack(addFrameHandlerCb) {
67
+ }
68
+
69
+ getAllTabInfoStrings(sessionId) {
70
+ }
71
+
72
+ getAllTabInfos(sessionId) {
73
+ }
74
+
75
+ addNewTab(sessionId, tabId, openerStepId, options = {}) {
76
+ }
77
+
78
+ addOpenerStepId(sessionId, tabId, openerStepId) {
79
+ }
80
+ addOpenerStep(sessionId, tabId, openerStep) {
81
+ }
82
+
83
+ fixMissingMainTab(sessionId) {
84
+ }
85
+
86
+ buildTabInfo(sessionId, tabId, order, openerStepId, options = {}) {
87
+ }
88
+
89
+ addTab(sessionId, id, order, openerStepId, options = {}) {
90
+ }
91
+
92
+ getTabUtilsByTabIdAndSessionId(sessionId, tabId) {
93
+ }
94
+
95
+ getTabUtilsByTabId(tabId) {
96
+ }
97
+
98
+ getTabInfo(sessionId, id) {
99
+ }
100
+
101
+ getTabUtils(sessionId, tabInfo) {
102
+ }
103
+
104
+ exactUrlMatch(first, second, allUrls) {
105
+ }
106
+
107
+ singleExactMatchForParts(first, second, allUrls, combinePartsFunction) {
108
+ }
109
+
110
+ isSameTab(sessionId, first, second) {
111
+ }
112
+
113
+ getMainTabInfo(sessionId) {
114
+ }
115
+
116
+ getMainTabUtils(sessionId) {
117
+ }
118
+
119
+ removeTabInfo(sessionId, tabId) {
120
+ }
121
+
122
+ getMainTabId(sessionId) {
123
+ }
124
+
125
+ isMainTabExists(sessionId) {
126
+ }
127
+
128
+ clearAllTabs(sessionId) {
129
+ }
130
+
131
+ clearNonMainTabs(sessionId) {
132
+ }
133
+
134
+ switchTab(tabId, sessionId, { forceSwitch } = { forceSwitch: false }) {
135
+ }
136
+
137
+ getTabDetails(tabId, sessionId, options = {}) {
138
+ }
139
+
140
+ getUnregisteredTabId(sessionId) {
141
+ }
142
+
143
+ waitForTabToOpen(sessionId) {
144
+ }
145
+
146
+ tryToAddTab(sessionId, openerStepId) {
147
+
148
+ }
149
+
150
+ addNewPopup(id, openerStepId) {
151
+ }
152
+
153
+ waitToPendingTabs(id, openerStepId) {
154
+ }
155
+
156
+ isMainTabIncognito() {
157
+ }
158
+
159
+ isInvalidStepVersion(step) {
160
+ }
161
+
162
+ getTabIdByTabInfo(sessionId, step) {
163
+ }
164
+ }
165
+
166
+ module.exports = TabService;
@@ -1,15 +1,14 @@
1
- "use strict";
1
+ 'use strict';
2
2
 
3
3
  const StepAction = require('./stepAction');
4
- const url = require('url');
4
+ const requiredUrl = require('url');
5
5
  const Promise = require('bluebird');
6
6
 
7
7
  class NavigationStepAction extends StepAction {
8
-
9
8
  updateBaseUrl(location) {
10
- let orgUrl = url.parse(location);
11
- const baseLocation = url.parse(this.context.recordedBaseUrl);
12
- const newBaseLocation = url.parse(this.context.baseUrl);
9
+ const orgUrl = requiredUrl.parse(location);
10
+ const baseLocation = requiredUrl.parse(this.context.recordedBaseUrl);
11
+ const newBaseLocation = requiredUrl.parse(this.context.baseUrl);
13
12
  if (orgUrl.host === baseLocation.host && baseLocation.host !== newBaseLocation.host) {
14
13
  orgUrl.host = newBaseLocation.host;
15
14
  }
@@ -18,12 +17,14 @@ class NavigationStepAction extends StepAction {
18
17
 
19
18
  performAction() {
20
19
  const url = this.context.data.testimNavigationStepDestination || this.context.data.url;
21
-
20
+ // Opens a new tab and switches to new tab
21
+ if (this.step.openInNewTab) {
22
+ return this.driver.client.newWindow(url).then(() => {});
23
+ }
22
24
  return this.updateBaseUrl(url)
23
- .then(url => this.driver.url(url))
24
- .then(() => Promise.resolve());
25
+ .then(updatedUrl => this.driver.url(updatedUrl))
26
+ .then(() => {});
25
27
  }
26
-
27
28
  }
28
29
 
29
30
  module.exports = NavigationStepAction;
@@ -1,12 +1,11 @@
1
- "use strict";
1
+ 'use strict';
2
2
 
3
3
  const StepAction = require('./stepAction');
4
- const Promise = require("bluebird");
4
+ const { delay } = require('../../utils');
5
5
 
6
6
  class SleepStepAction extends StepAction {
7
-
8
- performAction() {
9
- return Promise.delay(this.step.durationMS).then(() => Promise.resolve());
7
+ async performAction() {
8
+ await delay(this.step.durationMS);
10
9
  }
11
10
  }
12
11
 
@@ -6,12 +6,10 @@ const Promise = require('bluebird');
6
6
  const { codeSnippets } = require('../../commons/getSessionPlayerRequire');
7
7
  const dispatchFocus = require('./scripts/focusElement');
8
8
  const sessionPlayer = require('../../commons/getSessionPlayerRequire');
9
- const { extractElementId } = require('../../utils');
10
- const util = require('util');
9
+ const { extractElementId, delay } = require('../../utils');
11
10
 
12
11
  const constants = sessionPlayer.commonConstants.stepResult;
13
- const setTextDraftJs = codeSnippets && codeSnippets.setTextDraftJs;
14
- const delay = util.promisify(setTimeout);
12
+ const setTextDraftJs = codeSnippets?.setTextDraftJs;
15
13
  class TextStepAction extends StepAction {
16
14
  setValueNative() {
17
15
  const context = this.context;
@@ -61,12 +59,7 @@ class TextStepAction extends StepAction {
61
59
  const eventParam = this.driver.isEdge() ? JSON.stringify(eventMessage) : eventMessage;
62
60
 
63
61
  return this.driver.executeCodeAsync(setTextCode, timeout, eventParam)
64
- .then(result => {
65
- if (result.value && result.value.success) {
66
- return Promise.resolve({ success: true });
67
- }
68
- return Promise.resolve({ success: false });
69
- });
62
+ .then(result => ({ success: Boolean(result.value?.success) }));
70
63
  }
71
64
 
72
65
  async setTextDelayed() {
@@ -86,7 +79,7 @@ class TextStepAction extends StepAction {
86
79
  const context = this.context;
87
80
  const target = this.getTarget();
88
81
 
89
- if (target && target.seleniumElement) {
82
+ if (target?.seleniumElement) {
90
83
  if (!this.step.delayBetweenChars) {
91
84
  keys.push(Array.from(context.stepText));
92
85
  return this.driver.elementIdValue(extractElementId(target.seleniumElement), keys);
@@ -2,6 +2,7 @@
2
2
 
3
3
  const Promise = require('bluebird');
4
4
  const pRetry = require('p-retry');
5
+ const { delay } = require('../../utils');
5
6
  const { PageNotAvailableError } = require('../../errors');
6
7
  const logger = require('../../commons/logger').getLogger('window-utils');
7
8
 
@@ -72,7 +73,7 @@ class WindowUtils {
72
73
  const shouldRetryNavigation = err.seleniumStack && err.message.includes('method IWebBrowser2::Navigate2() failed');
73
74
  if (shouldRetryNavigation && retries > 0) {
74
75
  logger.warn('selenium navigation failed. retrying to navigate', { err });
75
- await Promise.delay(1500);
76
+ await delay(1500);
76
77
  return navigate(retries - 1);
77
78
  }
78
79
  throw err;
@@ -80,13 +81,13 @@ class WindowUtils {
80
81
  return undefined;
81
82
  }
82
83
 
83
- return Promise.race([navigate(), Promise.delay(NAVIGATION_MAX_TIME)]);
84
+ return Promise.race([navigate(), delay(NAVIGATION_MAX_TIME)]);
84
85
  }
85
86
 
86
87
  reloadTab(timeoutMSec = 15000) {
87
88
  return Promise.race([
88
89
  this.driver.reloadTab(),
89
- Promise.delay(timeoutMSec),
90
+ delay(timeoutMSec),
90
91
  ]);
91
92
  }
92
93
 
@@ -93,7 +93,7 @@ class WebDriver extends WebDriverApi {
93
93
  this.cdpUrl = await getCdpAddress(initResult);
94
94
  perf.log('after getCdpAddress in webdriver.js init');
95
95
  logger.info(`init new session testName: ${testName}`, { sessionId: this.getSessionId(), testResultId });
96
- await Promise.delay(driverDelay);
96
+ await utils.delay(driverDelay);
97
97
  await focus();
98
98
  perf.log('after focus and delay in webdriver.js init');
99
99
  } catch (err) {
package/processHandler.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  'use strict';
4
4
 
5
- const Promise = require('bluebird');
5
+ const { promiseTimeout, promiseMap } = require('./utils');
6
6
  const logger = require('./commons/logger').getLogger('process-handler');
7
7
 
8
8
  const exitHooks = [];
@@ -10,7 +10,7 @@ const exitHooks = [];
10
10
  module.exports = function (onExit, _process = process) {
11
11
  async function cleanup(err) {
12
12
  // give cleanup and socket reports a chance to run
13
- await Promise.all(exitHooks.map(x => x())).timeout(10000).catch(() => {});
13
+ await promiseTimeout(promiseMap(exitHooks, hook => hook()), 10000).catch(() => null);
14
14
  onExit(err);
15
15
  }
16
16
  _process.on('uncaughtException', async (err) => {
@@ -29,7 +29,7 @@ module.exports = function (onExit, _process = process) {
29
29
  // rollout manages promises incorrectly and generates unhandled rejections from within their code
30
30
  logger.fatal('Caught unhandled promise rejection', reason);
31
31
  //TODO(benji) - this is a pretty shitty way to detect this error since rollout can change their API endpoint
32
- if (reason && reason.message && reason.message.includes('ENOTFOUND x-api.rollout.io')) {
32
+ if (reason?.message?.includes('ENOTFOUND x-api.rollout.io')) {
33
33
  // this is not a fatal error - we recover from this in feature-flags service
34
34
  return;
35
35
  }
@@ -1,5 +1,5 @@
1
1
 
2
- const { delay } = require('bluebird');
2
+ const { delay } = require('./utils');
3
3
  const EventEmitter = require('events');
4
4
  const { expect, sinon } = require('../test/utils/testUtils');
5
5
  const processHandler = require('./processHandler');
@@ -2,7 +2,7 @@
2
2
  const chalk = require('chalk');
3
3
  const _ = require('lodash');
4
4
 
5
- const utils = require('../utils.js');
5
+ const utils = require('../utils');
6
6
  const constants = require('../commons/constants');
7
7
  const featureAvailabilityService = require('../commons/featureAvailabilityService');
8
8
  const { getAbortedTests, getFailedTests, getPassedTests, getFailureEvaluatingCount, getSkippedCount } = require('./reporterUtils');
@@ -120,7 +120,8 @@ class ConsoleReporter {
120
120
  if (isCodeMode) {
121
121
  console.log(`Run test plan, Project: ${this.options.project} (Execution ID: ${executionId}):`);
122
122
  } else {
123
- console.log(`Run${this.buildTestPlanName(isAnonymous, testPlanName)} test plan with ${configString}, Project: ${this.options.project}, Branch: ${this.branchToUse} (${executionId})`);
123
+ const sfdcCredentialLog = this.options.sfdcCredential ? ` SfdcCredential: ${this.options.sfdcCredential}` : '';
124
+ console.log(`Run${this.buildTestPlanName(isAnonymous, testPlanName)} test plan with ${configString}, Project: ${this.options.project}, Branch: ${this.branchToUse}${sfdcCredentialLog} (${executionId})`);
124
125
  }
125
126
  this.printWorkerDivider();
126
127
 
@@ -5,11 +5,10 @@
5
5
  const xml2js = require('xml2js');
6
6
  const Promise = require('bluebird');
7
7
  const fs = Promise.promisifyAll(require('fs'));
8
- const utils = require('../utils.js');
8
+ const utils = require('../utils');
9
9
  const {
10
10
  isAbortedTest, isSkippedTest, getFailedTests, isFailedTest, getFailureEvaluatingCount, getSkippedCount, getAbortedTests,
11
11
  } = require('./reporterUtils');
12
- const featureFlags = require('../commons/featureFlags.js');
13
12
  const featureAvailabilityService = require('../commons/featureAvailabilityService');
14
13
 
15
14
  class JunitReporter {
package/runOptions.js CHANGED
@@ -183,12 +183,12 @@ program
183
183
  .option('-h, --headless [headless]', 'run in headless mode')
184
184
  .option('-m, --mode [runner-mode]', 'use extension or selenium mode (extension/selenium/appium)')
185
185
  .option('--branch [branch]', 'branch name', null)
186
- .option('--base-url [base-url]', 'change al test base-url to a specified url')
186
+ .option('--base-url [base-url]', 'change base-url to a specified url for all tests in current execution')
187
187
  .option('--token [token]', 'identification token to testim')
188
188
  .option('--is-regression-baseline-run', 'save doms and run results as regression baseline data')
189
- .option('--parallel [number-of-tests]', 'number of tests to run on parallel')
190
- .option('--before-parallel [number-of-tests]', 'number of tests to run on parallel in the before phase of a test plan')
191
- .option('--after-parallel [number-of-tests]', 'number of tests to run on parallel in the after phase of a test plan')
189
+ .option('--parallel [number-of-tests]', 'number of tests to run in parallel')
190
+ .option('--before-parallel [number-of-tests]', 'number of tests to run in parallel during the before phase of a test plan')
191
+ .option('--after-parallel [number-of-tests]', 'number of tests to run in parallel during the after phase of a test plan')
192
192
  .option('--canary [canary-mode]', 'enable canary mode', false)
193
193
  .option('--test-plan [test-plan-name]', 'test plan to run', collect, [])
194
194
  .option('--test-plan-id [test-plan-id]', 'test plan to run', collect, [])
@@ -203,7 +203,7 @@ program
203
203
  .option('--proxy-for-grid [proxy-for-grid]', 'used together with --proxy to also router grid traffic through a proxy')
204
204
  .option('--result-label [result-label]', 'result label', collect, [])
205
205
  .option('-oen --override-execution-name [execution-name]', 'override the default execution name', '')
206
- .option('--retries [max_num_of_retries]', 'number of retires failure test defaults to not retrying', 0)
206
+ .option('--retries [max_num_of_retries]', 'number of retries on test failure, defaults to 0 (no retries)', 0)
207
207
  .option('--set-retention [retention-in-days]', 'set the number of days for results retention')
208
208
  .option('--user [user-id]', 'user ID for local Testim-CLI')
209
209
  .option('--pass-zero-tests', 'don\'t fail the run if no tests were found')
@@ -347,7 +347,7 @@ program
347
347
  .option('--use-prefeched-data [location]', 'use prefetched data from local cache file, and force using only cached data')
348
348
  .option('--save-rca-locally [path]', 'save root cause analysis assets locally')
349
349
 
350
- .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')
350
+ .option('--exit-code-ignore-failing-tests', 'return exit code of zero when tests fail. non zero exit code will mean a real error occurred')
351
351
 
352
352
  .option('--intersect-with-label [label]', 'Out of the execution\'s test list, run only those tests that have the specified label', collect, [])
353
353
  .option('--intersect-with-suite [suiteName]', 'Out of the execution\'s test list, run only those tests that are included in the specified suite (by suite name)', collect, [])
package/runner.js CHANGED
@@ -118,6 +118,14 @@ function setBranch(options, branchInfoFromServer) {
118
118
  }
119
119
  }
120
120
 
121
+ async function setSfdcCredential(options) {
122
+ const { projectData: { projectId } } = options;
123
+ const branch = branchService.getCurrentBranch();
124
+ if (_.get(options, 'company.activePlan.premiumFeatures.ttaForSalesforce')) {
125
+ options.sfdcCredential = await servicesApi.loadSfdcCredential({ projectId, branch });
126
+ }
127
+ }
128
+
121
129
  function setCompany(options, company) {
122
130
  const { onprem, id, storageBaseUrl, storageType, name, activePlan = {} } = company;
123
131
  if (onprem) {
@@ -194,6 +202,10 @@ async function setMockNetworkRules(options) {
194
202
  }
195
203
  }
196
204
 
205
+ /**
206
+ * @param {Awaited<ReturnType<typeof import('./runOptions')['process']>>} options
207
+ * @param {string=} customExtensionLocalLocation
208
+ */
197
209
  async function runRunner(options, customExtensionLocalLocation) {
198
210
  perf.log('in runner.js runRunner');
199
211
 
@@ -265,6 +277,7 @@ async function init(options) {
265
277
  setBranch(options, branchName);
266
278
  setAllGrids(options, allGrids);
267
279
  setAuthData(options, authData);
280
+ await setSfdcCredential(options);
268
281
 
269
282
  if (!(options.lightweightMode && options.lightweightMode.disableLabs)) {
270
283
  await labFeaturesService.loadLabFeatures(projectById.id, companyByProjectId.activePlan);