@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.
- package/OverrideTestDataBuilder.js +1 -1
- package/agent/routers/cliJsCode/index.js +4 -4
- package/agent/routers/cliJsCode/router.js +46 -42
- package/agent/routers/cliJsCode/service.js +18 -13
- package/agent/routers/codim/router.js +14 -17
- package/agent/routers/codim/router.test.js +15 -14
- package/agent/routers/codim/service.js +1 -1
- package/agent/routers/general/index.js +4 -8
- package/agent/routers/hybrid/registerRoutes.js +18 -18
- package/agent/routers/index.js +7 -7
- package/agent/routers/playground/router.js +11 -10
- package/agent/routers/playground/service.js +19 -18
- package/agent/routers/standalone-browser/registerRoutes.js +10 -10
- package/cdpTestRunner.js +4 -3
- package/chromiumInstaller.js +4 -5
- package/cli/onExit.js +2 -2
- package/cli.js +7 -6
- package/cliAgentMode.js +4 -5
- package/codim/codim-cli.js +11 -10
- package/codim/hybrid-utils.js +1 -1
- package/codim/measure-perf.js +9 -6
- package/codim/template.js/tests/examples/01-simple-text-validation.test.js +6 -6
- package/codim/template.js/tests/examples/02-using-locators.test.js +13 -15
- package/codim/template.js/tests/examples/03-using-hooks.test.js +17 -19
- package/codim/template.js/tests/examples/04-skip-and-only.test.js +16 -17
- package/codim/template.js/tests/examples/05-multiple-windows.test.js +16 -17
- package/codim/template.js/webpack.config.js +1 -1
- package/codim/template.ts/webpack.config.js +3 -3
- package/commons/AbortError.js +4 -4
- package/commons/detectDebugger.js +4 -2
- package/commons/lazyRequire.js +10 -9
- package/commons/logger.js +4 -4
- package/commons/performance-logger.js +14 -8
- package/commons/prepareRunnerAndTestimStartUtils.js +6 -7
- package/commons/socket/baseSocketServiceSocketIO.js +32 -34
- package/commons/socket/realDataService.js +6 -5
- package/commons/socket/realDataServiceSocketIO.js +4 -4
- package/commons/socket/remoteStepService.js +4 -3
- package/commons/socket/remoteStepServiceSocketIO.js +11 -12
- package/commons/socket/socketService.js +50 -52
- package/commons/socket/testResultServiceSocketIO.js +11 -11
- package/commons/testimDesiredCapabilitiesBuilder.js +3 -2
- package/commons/testimNgrok.js +2 -2
- package/commons/testimNgrok.test.js +1 -1
- package/commons/testimServicesApi.js +27 -20
- package/commons/xhr2.js +97 -100
- package/errors.js +5 -0
- package/fixLocalBuild.js +2 -0
- package/npm-shrinkwrap.json +2515 -1256
- package/package.json +6 -6
- package/player/appiumTestPlayer.js +1 -1
- package/player/chromeLauncherTestPlayer.js +0 -1
- package/player/services/tabServiceMock.js +166 -0
- package/player/stepActions/navigationStepAction.js +11 -10
- package/player/stepActions/sleepStepAction.js +4 -5
- package/player/stepActions/textStepAction.js +4 -11
- package/player/utils/windowUtils.js +4 -3
- package/player/webdriver.js +1 -1
- package/processHandler.js +3 -3
- package/processHandler.test.js +1 -1
- package/reports/consoleReporter.js +3 -2
- package/reports/junitReporter.js +1 -2
- package/runOptions.js +6 -6
- package/runner.js +13 -0
- package/runners/TestPlanRunner.js +142 -74
- package/runners/buildCodeTests.js +38 -37
- package/runners/runnerUtils.js +3 -3
- package/services/lambdatestService.js +3 -5
- package/stepPlayers/cliJsStepPlayback.js +22 -17
- package/testRunHandler.js +8 -0
- package/testRunStatus.js +1 -1
- package/{utils.js → utils/index.js} +25 -117
- package/utils/promiseUtils.js +78 -0
- package/utils/stringUtils.js +96 -0
- package/{utils.test.js → utils/utils.test.js} +2 -2
- package/workers/BaseWorker.js +16 -14
- package/workers/WorkerAppium.js +1 -1
- package/workers/WorkerExtensionSingleBrowser.js +4 -4
- 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.
|
|
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": "
|
|
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.
|
|
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.
|
|
81
|
+
"moment": "2.29.4",
|
|
82
82
|
"ms": "2.1.2",
|
|
83
|
-
"npm": "8.
|
|
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.
|
|
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/
|
|
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
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
const StepAction = require('./stepAction');
|
|
4
|
-
const
|
|
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
|
-
|
|
11
|
-
const baseLocation =
|
|
12
|
-
const newBaseLocation =
|
|
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(
|
|
24
|
-
.then(() =>
|
|
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
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
const StepAction = require('./stepAction');
|
|
4
|
-
const
|
|
4
|
+
const { delay } = require('../../utils');
|
|
5
5
|
|
|
6
6
|
class SleepStepAction extends StepAction {
|
|
7
|
-
|
|
8
|
-
|
|
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
|
|
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
|
|
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
|
|
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(),
|
|
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
|
-
|
|
90
|
+
delay(timeoutMSec),
|
|
90
91
|
]);
|
|
91
92
|
}
|
|
92
93
|
|
package/player/webdriver.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
}
|
package/processHandler.test.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const chalk = require('chalk');
|
|
3
3
|
const _ = require('lodash');
|
|
4
4
|
|
|
5
|
-
const utils = require('../utils
|
|
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
|
-
|
|
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
|
|
package/reports/junitReporter.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
190
|
-
.option('--before-parallel [number-of-tests]', 'number of tests to run
|
|
191
|
-
.option('--after-parallel [number-of-tests]', 'number of tests to run
|
|
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
|
|
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', '
|
|
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);
|