@testim/testim-cli 3.252.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 +9 -8
- package/agent/routers/playground/router.js +12 -11
- 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/chrome-launcher.js +6 -6
- package/commons/constants.js +2 -0
- package/commons/detectDebugger.js +4 -2
- package/commons/getSessionPlayerRequire.js +2 -20
- package/commons/initializeUserWithAuth.js +2 -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 +44 -0
- package/commons/testimNgrok.js +2 -2
- package/commons/testimNgrok.test.js +1 -1
- package/commons/testimServicesApi.js +37 -21
- package/commons/xhr2.js +97 -100
- package/credentialsManager.js +17 -20
- package/errors.js +5 -0
- package/fixLocalBuild.js +2 -0
- package/npm-shrinkwrap.json +4455 -1576
- package/package.json +9 -7
- package/player/WebdriverioWebDriverApi.js +7 -2
- package/player/appiumTestPlayer.js +102 -0
- package/player/chromeLauncherTestPlayer.js +0 -1
- package/player/seleniumTestPlayer.js +3 -2
- package/player/services/frameLocator.js +2 -1
- package/player/services/mobileFrameLocatorMock.js +32 -0
- package/player/services/playbackTimeoutCalculator.js +1 -0
- package/player/services/portSelector.js +10 -8
- package/player/services/tabService.js +29 -0
- package/player/services/tabServiceMock.js +166 -0
- package/player/stepActions/navigationStepAction.js +11 -10
- package/player/stepActions/sleepStepAction.js +4 -5
- package/player/stepActions/stepAction.js +15 -1
- package/player/stepActions/textStepAction.js +4 -11
- package/player/utils/stepActionUtils.js +4 -2
- package/player/utils/windowUtils.js +139 -125
- package/player/webdriver.js +40 -26
- package/processHandler.js +3 -3
- package/processHandler.test.js +1 -1
- package/reports/consoleReporter.js +3 -2
- package/reports/debugReporter.js +41 -39
- package/reports/jsonReporter.js +53 -50
- package/reports/junitReporter.js +1 -2
- package/reports/reporter.js +135 -136
- package/runOptions.js +8 -7
- package/runner.js +13 -0
- package/runners/ParallelWorkerManager.js +2 -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 +458 -460
- 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 +29 -20
- package/workers/WorkerAppium.js +123 -0
- package/workers/WorkerExtensionSingleBrowser.js +4 -4
- package/workers/WorkerSelenium.js +5 -2
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
const WebSocket = require('ws');
|
|
4
|
-
const {WEBSOCKET_HOST} = require('../config');
|
|
4
|
+
const { WEBSOCKET_HOST } = require('../config');
|
|
5
5
|
const utils = require('../../utils');
|
|
6
|
-
const logger = require('../logger').getLogger(
|
|
7
|
-
const {EventEmitter} = require('events');
|
|
6
|
+
const logger = require('../logger').getLogger('socket-ng-service');
|
|
7
|
+
const { EventEmitter } = require('events');
|
|
8
8
|
const _ = require('lodash');
|
|
9
9
|
const Promise = require('bluebird');
|
|
10
10
|
const testimCustomToken = require('../testimCustomToken');
|
|
@@ -21,16 +21,16 @@ class SocketService extends EventEmitter {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
onReconnect(projectId) {
|
|
24
|
-
logger.info(
|
|
24
|
+
logger.info('test result websocket re-connect');
|
|
25
25
|
setTimeout(() => this.connect(projectId), WAIT_BETWEEN_RECONNECT_MS);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
formatUrl(url) {
|
|
29
|
-
if(_.startsWith(url,
|
|
29
|
+
if (_.startsWith(url, 'http://')) {
|
|
30
30
|
return _.replace(url, 'http://', 'ws://');
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
if(_.startsWith(url,
|
|
33
|
+
if (_.startsWith(url, 'https://')) {
|
|
34
34
|
return _.replace(url, 'https://', 'wss://');
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -41,50 +41,48 @@ class SocketService extends EventEmitter {
|
|
|
41
41
|
try {
|
|
42
42
|
return JSON.parse(event);
|
|
43
43
|
} catch (err) {
|
|
44
|
-
logger.error(
|
|
44
|
+
logger.error('failed to parse or trigger event', { err });
|
|
45
45
|
}
|
|
46
|
+
return undefined;
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
|
|
49
49
|
connect(projectId) {
|
|
50
50
|
const wsBaseUrl = this.formatUrl(WEBSOCKET_HOST);
|
|
51
51
|
return testimCustomToken.getCustomTokenV3()
|
|
52
|
-
.then(token => {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
.then(token => new Promise((resolve) => {
|
|
53
|
+
const options = {};
|
|
54
|
+
if (global.proxyUri) {
|
|
55
|
+
options.agent = new global.ProxyAgent(global.proxyUri);
|
|
56
|
+
}
|
|
57
|
+
this.ws = new WebSocket(`${wsBaseUrl}?projectId=${projectId}&clientId=${this.clientId}&token=${token}`, options);
|
|
58
|
+
|
|
59
|
+
this.ws.on('open', () => {
|
|
60
|
+
logger.info('websocket opened');
|
|
61
|
+
this.reSendAllExistingFilters();
|
|
62
|
+
if (this.onConnect) {
|
|
63
|
+
this.onConnect();
|
|
64
|
+
}
|
|
65
|
+
return resolve();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
this.ws.on('close', (event) => {
|
|
69
|
+
logger.info('websocket closed', { event });
|
|
70
|
+
if (!this.ws || this.ws.readyState === WebSocket.CLOSED) {
|
|
71
|
+
this.onReconnect(projectId, token, wsBaseUrl);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
this.ws.on('error', (event) => {
|
|
76
|
+
logger.info('websocket error', { event });
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
this.ws.on('message', (event) => {
|
|
80
|
+
const evObject = this.parseEvent(event);
|
|
81
|
+
if (evObject?.type) {
|
|
82
|
+
this.emit(evObject.type, evObject.data);
|
|
57
83
|
}
|
|
58
|
-
this.ws = new WebSocket(`${wsBaseUrl}?projectId=${projectId}&clientId=${this.clientId}&token=${token}`, options);
|
|
59
|
-
|
|
60
|
-
this.ws.on("open", () => {
|
|
61
|
-
logger.info(`websocket opened`);
|
|
62
|
-
this.reSendAllExistingFilters();
|
|
63
|
-
if (this.onConnect) {
|
|
64
|
-
this.onConnect();
|
|
65
|
-
}
|
|
66
|
-
return resolve();
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
this.ws.on("close", (event) => {
|
|
70
|
-
logger.info(`websocket closed`, {event});
|
|
71
|
-
if (!this.ws || this.ws.readyState === WebSocket.CLOSED) {
|
|
72
|
-
this.onReconnect(projectId, token, wsBaseUrl);
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
this.ws.on("error", (event) => {
|
|
77
|
-
logger.info(`websocket error`, {event});
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
this.ws.on("message", (event) => {
|
|
81
|
-
const evObject = this.parseEvent(event);
|
|
82
|
-
if (evObject && evObject.type) {
|
|
83
|
-
this.emit(evObject.type, evObject.data);
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
84
|
});
|
|
87
|
-
});
|
|
85
|
+
}));
|
|
88
86
|
}
|
|
89
87
|
|
|
90
88
|
// this is private because our sockets are supposed to be read-only to
|
|
@@ -99,7 +97,7 @@ class SocketService extends EventEmitter {
|
|
|
99
97
|
try {
|
|
100
98
|
this.ws.send(JSON.stringify(msg));
|
|
101
99
|
} catch (err) {
|
|
102
|
-
logger.error('failed to stringify message for sending', {err});
|
|
100
|
+
logger.error('failed to stringify message for sending', { err });
|
|
103
101
|
}
|
|
104
102
|
}
|
|
105
103
|
|
|
@@ -125,25 +123,25 @@ class SocketService extends EventEmitter {
|
|
|
125
123
|
const eventNameArray = Array.isArray(eventName) ? eventName : [eventName];
|
|
126
124
|
eventNameArray.forEach(name => {
|
|
127
125
|
this.listeners[`${key}:${name}`] = this.listeners[`${key}:${name}`] || [];
|
|
128
|
-
const
|
|
129
|
-
this.listeners[`${key}:${name}`].push(
|
|
130
|
-
this.on(name,
|
|
126
|
+
const _listener = fireIfSameMatchEventMatcher.bind(this);
|
|
127
|
+
this.listeners[`${key}:${name}`].push(_listener);
|
|
128
|
+
this.on(name, _listener);
|
|
131
129
|
});
|
|
132
130
|
}
|
|
133
131
|
|
|
134
132
|
reSendAllExistingFilters() {
|
|
135
133
|
Object.keys(this.filterMap).forEach(key => {
|
|
136
134
|
const filter = this.filterMap[key];
|
|
137
|
-
this.sendMessage({type:
|
|
135
|
+
this.sendMessage({ type: 'add-filter', filter });
|
|
138
136
|
});
|
|
139
137
|
}
|
|
140
138
|
|
|
141
139
|
addFilter(key, query, type, returnFullDocument = false) {
|
|
142
140
|
return new Promise(resolve => {
|
|
143
141
|
const filterId = utils.guid();
|
|
144
|
-
const filter = {query, id: filterId, type, fullDocument: returnFullDocument};
|
|
145
|
-
this.listenOnce(
|
|
146
|
-
this.sendMessage({type:
|
|
142
|
+
const filter = { query, id: filterId, type, fullDocument: returnFullDocument };
|
|
143
|
+
this.listenOnce('add-filter:done', data => data.id === filterId, resolve);
|
|
144
|
+
this.sendMessage({ type: 'add-filter', filter });
|
|
147
145
|
this.filterMap[key] = filter;
|
|
148
146
|
});
|
|
149
147
|
}
|
|
@@ -170,7 +168,7 @@ class SocketService extends EventEmitter {
|
|
|
170
168
|
const typeArray = Array.isArray(type) ? type : [type];
|
|
171
169
|
this.removeListeners(key, typeArray);
|
|
172
170
|
delete this.filterMap[key];
|
|
173
|
-
this.sendMessage({type:
|
|
171
|
+
this.sendMessage({ type: 'remove-filter', filter });
|
|
174
172
|
}
|
|
175
173
|
}
|
|
176
174
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
const Promise = require('bluebird');
|
|
4
4
|
const BaseSocketService = require('./baseSocketServiceSocketIO');
|
|
@@ -10,8 +10,8 @@ class TestResultServiceSocketIO extends BaseSocketService {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
listenToTestResult(resultId, testId, onTestResultStatus) {
|
|
13
|
-
if(this.listerers[resultId]) {
|
|
14
|
-
this._socket.off(
|
|
13
|
+
if (this.listerers[resultId]) {
|
|
14
|
+
this._socket.off('testResult:updated', this.listerers[resultId]);
|
|
15
15
|
delete this.listerers[resultId];
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -21,18 +21,18 @@ class TestResultServiceSocketIO extends BaseSocketService {
|
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
this._socket.on(
|
|
24
|
+
this._socket.on('testResult:updated', this.listerers[resultId]);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
emitJoinRoom(resultId, testId) {
|
|
28
|
-
return this.emitPromise(
|
|
28
|
+
return this.emitPromise('testResult:join', {
|
|
29
29
|
resultId,
|
|
30
|
-
testId
|
|
30
|
+
testId,
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
joinToTestResult(resultId, testId) {
|
|
35
|
-
if(this.rooms[resultId]) {
|
|
35
|
+
if (this.rooms[resultId]) {
|
|
36
36
|
return Promise.resolve();
|
|
37
37
|
}
|
|
38
38
|
this.joinRoom(resultId, testId);
|
|
@@ -40,19 +40,19 @@ class TestResultServiceSocketIO extends BaseSocketService {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
emitLeaveRoom(resultId, testId) {
|
|
43
|
-
return this.emitPromise(
|
|
43
|
+
return this.emitPromise('testResult:leave', {
|
|
44
44
|
resultId,
|
|
45
|
-
testId
|
|
45
|
+
testId,
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
leaveTestResult(resultId, testId) {
|
|
50
|
-
if(!this.listerers[resultId]) {
|
|
50
|
+
if (!this.listerers[resultId]) {
|
|
51
51
|
return Promise.resolve();
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
this.leaveRoom(resultId);
|
|
55
|
-
this._socket.off(
|
|
55
|
+
this._socket.off('testResult:updated', this.listerers[resultId]);
|
|
56
56
|
delete this.listerers[resultId];
|
|
57
57
|
return this.emitLeaveRoom(resultId, testId);
|
|
58
58
|
}
|
|
@@ -602,6 +602,50 @@ function buildSeleniumOptions(browserOptions, testName, testRunConfig, gridInfo,
|
|
|
602
602
|
return opts;
|
|
603
603
|
}
|
|
604
604
|
|
|
605
|
+
//testRunConfig not in used for now
|
|
606
|
+
function buildAppiumOptions({ projectType, gridInfo, testRunConfig, nativeApp }) {
|
|
607
|
+
if (!nativeApp) {
|
|
608
|
+
throw Error('missing mobile app!');
|
|
609
|
+
}
|
|
610
|
+
if (gridInfo.type !== gridTypes.TESTIM_HEADSPIN) {
|
|
611
|
+
throw Error('unsupported grid was detected please make sure to select supported mobile grid');
|
|
612
|
+
}
|
|
613
|
+
const connection = {
|
|
614
|
+
protocol: gridInfo.protocol || 'https',
|
|
615
|
+
hostname: gridInfo.host,
|
|
616
|
+
port: gridInfo.port,
|
|
617
|
+
path: `/v0/${gridInfo.accessToken}/wd/hub`,
|
|
618
|
+
};
|
|
619
|
+
|
|
620
|
+
let appCaps = {};
|
|
621
|
+
switch (projectType) {
|
|
622
|
+
case 'ios':
|
|
623
|
+
appCaps = {
|
|
624
|
+
'appium:bundleId': nativeApp.id,
|
|
625
|
+
platformName: 'iOS',
|
|
626
|
+
'appium:automationName': 'XCUITest',
|
|
627
|
+
};
|
|
628
|
+
break;
|
|
629
|
+
case 'android':
|
|
630
|
+
appCaps = {
|
|
631
|
+
platformName: 'Android',
|
|
632
|
+
'appium:automationName': 'UiAutomator2',
|
|
633
|
+
'appium:appPackage': nativeApp.packageName,
|
|
634
|
+
'appium:appActivity': nativeApp.activity,
|
|
635
|
+
};
|
|
636
|
+
break;
|
|
637
|
+
default:
|
|
638
|
+
throw Error(`unsupported mobile project ${projectType}`);
|
|
639
|
+
}
|
|
640
|
+
return {
|
|
641
|
+
...connection,
|
|
642
|
+
desiredCapabilities: appCaps,
|
|
643
|
+
capabilities: appCaps,
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
|
|
605
647
|
module.exports = {
|
|
606
648
|
buildSeleniumOptions,
|
|
649
|
+
buildAppiumOptions,
|
|
650
|
+
|
|
607
651
|
};
|
package/commons/testimNgrok.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const { ArgError } = require('../errors
|
|
4
|
-
const utils = require('../utils
|
|
3
|
+
const { ArgError } = require('../errors');
|
|
4
|
+
const utils = require('../utils');
|
|
5
5
|
const lazyRequire = require('./lazyRequire');
|
|
6
6
|
const logger = require('./logger').getLogger('testimNgrok');
|
|
7
7
|
|
|
@@ -6,7 +6,7 @@ const _ = require('lodash');
|
|
|
6
6
|
const testimCustomToken = require('./testimCustomToken');
|
|
7
7
|
const constants = require('./constants');
|
|
8
8
|
const Promise = require('bluebird');
|
|
9
|
-
const utils = require('../utils
|
|
9
|
+
const utils = require('../utils');
|
|
10
10
|
const config = require('./config');
|
|
11
11
|
const httpRequest = require('./httpRequest');
|
|
12
12
|
|
|
@@ -21,7 +21,7 @@ function getTokenHeader() {
|
|
|
21
21
|
return testimCustomToken.getCustomTokenV3()
|
|
22
22
|
.then(brearToken => {
|
|
23
23
|
if (!brearToken) {
|
|
24
|
-
|
|
24
|
+
throw new Error('Failed to get token from server');
|
|
25
25
|
}
|
|
26
26
|
return { Authorization: `Bearer ${brearToken}` };
|
|
27
27
|
});
|
|
@@ -43,6 +43,7 @@ function postAuth({
|
|
|
43
43
|
});
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
// eslint-disable-next-line default-param-last
|
|
46
47
|
function postAuthFormData(url, fields, files, headers = {}, timeout) {
|
|
47
48
|
return getTokenHeader()
|
|
48
49
|
.then(tokenHeaders => {
|
|
@@ -83,6 +84,12 @@ function getTestPlan(projectId, testPlanNames) {
|
|
|
83
84
|
}));
|
|
84
85
|
}
|
|
85
86
|
|
|
87
|
+
async function loadSfdcCredential({ branch, projectId }) {
|
|
88
|
+
const branchData = await pRetry(() => getWithAuth(`/branch/branchData/${branch}`, {
|
|
89
|
+
projectId,
|
|
90
|
+
}), { retries: DEFAULT_REQUEST_RETRY });
|
|
91
|
+
return branchData?.sfdcCredential;
|
|
92
|
+
}
|
|
86
93
|
|
|
87
94
|
function loadTest({ testId, branch, projectId, skipSharedSteps = false, useBranchMap = true }) {
|
|
88
95
|
return pRetry(() => getWithAuth(`/test/${testId}`, {
|
|
@@ -160,6 +167,7 @@ function reportExecutionStarted({
|
|
|
160
167
|
});
|
|
161
168
|
}
|
|
162
169
|
|
|
170
|
+
// eslint-disable-next-line default-param-last
|
|
163
171
|
function reportExecutionFinished(status, executionId, projectId, success, tmsOptions = {}, remoteRunId, resultExtraData) {
|
|
164
172
|
const endTime = Date.now();
|
|
165
173
|
|
|
@@ -172,7 +180,7 @@ function reportExecutionFinished(status, executionId, projectId, success, tmsOpt
|
|
|
172
180
|
tmsOptions,
|
|
173
181
|
remoteRunId,
|
|
174
182
|
resultExtraData,
|
|
175
|
-
}), {
|
|
183
|
+
}), { retries: DEFAULT_REQUEST_RETRY });
|
|
176
184
|
}
|
|
177
185
|
|
|
178
186
|
async function getTestPlanTestList(projectId, names, planIds, branch, intersections) {
|
|
@@ -181,7 +189,7 @@ async function getTestPlanTestList(projectId, names, planIds, branch, intersecti
|
|
|
181
189
|
body: { projectId, names, planIds, branch, intersections },
|
|
182
190
|
// people who send insane lists get a timeout :(
|
|
183
191
|
timeout: 120000,
|
|
184
|
-
}), {
|
|
192
|
+
}), { retries: DEFAULT_REQUEST_RETRY });
|
|
185
193
|
}
|
|
186
194
|
|
|
187
195
|
function getSuiteTestList({
|
|
@@ -202,11 +210,11 @@ function getSuiteTestList({
|
|
|
202
210
|
testConfigIds,
|
|
203
211
|
intersections,
|
|
204
212
|
},
|
|
205
|
-
}), {
|
|
213
|
+
}), { retries: DEFAULT_REQUEST_RETRY });
|
|
206
214
|
}
|
|
207
215
|
|
|
208
216
|
function getUsageForCurrentBillingPeriod(projectId) {
|
|
209
|
-
return pRetry(() => getWithAuth(`/plan/project/${projectId}/usage-current-billing-period`), {
|
|
217
|
+
return pRetry(() => getWithAuth(`/plan/project/${projectId}/usage-current-billing-period`), { retries: DEFAULT_REQUEST_RETRY })
|
|
210
218
|
.catch((error) => {
|
|
211
219
|
logger.error('failed getting usage for current billing period', { projectId, error });
|
|
212
220
|
return undefined;
|
|
@@ -214,11 +222,11 @@ function getUsageForCurrentBillingPeriod(projectId) {
|
|
|
214
222
|
}
|
|
215
223
|
|
|
216
224
|
function isTestResultCompleted(resultId, projectId, testRetryKey) {
|
|
217
|
-
return pRetry(() => getWithAuth(`/result/${resultId}/isComplete`, { projectId, testRetryKey }), {
|
|
225
|
+
return pRetry(() => getWithAuth(`/result/${resultId}/isComplete`, { projectId, testRetryKey }), { retries: DEFAULT_REQUEST_RETRY });
|
|
218
226
|
}
|
|
219
227
|
|
|
220
228
|
function getTestResults(testId, resultId, projectId, branch) {
|
|
221
|
-
return pRetry(() => getWithAuth(`/test/v2/${testId}/result/${resultId}`, { projectId, branch }), {
|
|
229
|
+
return pRetry(() => getWithAuth(`/test/v2/${testId}/result/${resultId}`, { projectId, branch }), { retries: DEFAULT_REQUEST_RETRY });
|
|
222
230
|
}
|
|
223
231
|
|
|
224
232
|
function keepAliveGrid(projectId, slots) {
|
|
@@ -248,11 +256,11 @@ function getHybridGridProvider(body) {
|
|
|
248
256
|
function getGridByName(companyId, projectId, gridName, browser, executionId) {
|
|
249
257
|
return pRetry(() => getWithAuth('/grid/name', {
|
|
250
258
|
companyId, projectId, name: gridName, browser, executionId, reqId: utils.guid(),
|
|
251
|
-
}), {
|
|
259
|
+
}), { retries: DEFAULT_REQUEST_RETRY });
|
|
252
260
|
}
|
|
253
261
|
|
|
254
262
|
function getGridById(companyId, projectId, gridId, browser, executionId) {
|
|
255
|
-
return pRetry(() => getWithAuth(`/grid/${gridId}`, { companyId, projectId, browser, executionId, reqId: utils.guid() }), {
|
|
263
|
+
return pRetry(() => getWithAuth(`/grid/${gridId}`, { companyId, projectId, browser, executionId, reqId: utils.guid() }), { retries: DEFAULT_REQUEST_RETRY });
|
|
256
264
|
}
|
|
257
265
|
|
|
258
266
|
|
|
@@ -267,7 +275,7 @@ async function initializeUserWithAuth({ projectId, token, branchName, lightweigh
|
|
|
267
275
|
lightweightMode,
|
|
268
276
|
localGrid,
|
|
269
277
|
},
|
|
270
|
-
}), {
|
|
278
|
+
}), { retries: DEFAULT_REQUEST_RETRY });
|
|
271
279
|
} catch (e) {
|
|
272
280
|
logger.error('error initializing info from server', e);
|
|
273
281
|
if (e && e.message && e.message.includes('Bad Request')) {
|
|
@@ -289,7 +297,14 @@ async function getEditorUrl() {
|
|
|
289
297
|
return config.EDITOR_URL;
|
|
290
298
|
}
|
|
291
299
|
try {
|
|
292
|
-
return await pRetry(() => getWithAuth('/system-info/editor-url'), {
|
|
300
|
+
return await pRetry(() => getWithAuth('/system-info/editor-url'), {
|
|
301
|
+
retries: DEFAULT_REQUEST_RETRY,
|
|
302
|
+
onFailedAttempt: error => {
|
|
303
|
+
if (error.attemptNumber >= DEFAULT_REQUEST_RETRY) {
|
|
304
|
+
throw error;
|
|
305
|
+
}
|
|
306
|
+
},
|
|
307
|
+
});
|
|
293
308
|
} catch (err) {
|
|
294
309
|
logger.error('cannot retrieve editor-url from server');
|
|
295
310
|
return 'https://app.testim.io';
|
|
@@ -297,16 +312,16 @@ async function getEditorUrl() {
|
|
|
297
312
|
}
|
|
298
313
|
|
|
299
314
|
function getAllGrids(companyId) {
|
|
300
|
-
return pRetry(() => getWithAuth('/grid', { companyId }), {
|
|
315
|
+
return pRetry(() => getWithAuth('/grid', { companyId }), { retries: DEFAULT_REQUEST_RETRY });
|
|
301
316
|
}
|
|
302
317
|
|
|
303
|
-
const fetchLambdatestConfig = async () => pRetry(() => getWithAuth('/grid/lt/config'), {
|
|
318
|
+
const fetchLambdatestConfig = async () => pRetry(() => getWithAuth('/grid/lt/config'), { retries: DEFAULT_REQUEST_RETRY });
|
|
304
319
|
|
|
305
|
-
const getLabFeaturesByProjectId = async (projectId) => pRetry(() => getWithAuth(`/labFeature/v2/project/${projectId}`), {
|
|
320
|
+
const getLabFeaturesByProjectId = async (projectId) => pRetry(() => getWithAuth(`/labFeature/v2/project/${projectId}`), { retries: DEFAULT_REQUEST_RETRY });
|
|
306
321
|
|
|
307
322
|
|
|
308
323
|
function getRealData(projectId, channel, query) {
|
|
309
|
-
return pRetry(() => getWithAuth(`/real-data/${channel}?${query}&projectId=${projectId}`), {
|
|
324
|
+
return pRetry(() => getWithAuth(`/real-data/${channel}?${query}&projectId=${projectId}`), { retries: DEFAULT_REQUEST_RETRY });
|
|
310
325
|
}
|
|
311
326
|
|
|
312
327
|
function updateTestResult(projectId, resultId, testId, testResult, remoteRunId) {
|
|
@@ -319,7 +334,7 @@ function updateTestResult(projectId, resultId, testId, testResult, remoteRunId)
|
|
|
319
334
|
testResult,
|
|
320
335
|
remoteRunId,
|
|
321
336
|
},
|
|
322
|
-
}), {
|
|
337
|
+
}), { retries: DEFAULT_REQUEST_RETRY });
|
|
323
338
|
}
|
|
324
339
|
|
|
325
340
|
function clearTestResult(projectId, resultId, testId, testResult) {
|
|
@@ -331,7 +346,7 @@ function clearTestResult(projectId, resultId, testId, testResult) {
|
|
|
331
346
|
testId,
|
|
332
347
|
testResult,
|
|
333
348
|
},
|
|
334
|
-
}), {
|
|
349
|
+
}), { retries: DEFAULT_REQUEST_RETRY });
|
|
335
350
|
}
|
|
336
351
|
|
|
337
352
|
function saveRemoteStep(projectId, resultId, stepId, remoteStep) {
|
|
@@ -343,7 +358,7 @@ function saveRemoteStep(projectId, resultId, stepId, remoteStep) {
|
|
|
343
358
|
stepId,
|
|
344
359
|
remoteStep,
|
|
345
360
|
},
|
|
346
|
-
}), {
|
|
361
|
+
}), { retries: DEFAULT_REQUEST_RETRY });
|
|
347
362
|
}
|
|
348
363
|
|
|
349
364
|
function relativize(uri) {
|
|
@@ -384,7 +399,7 @@ function uploadArtifact(projectId, testId, testResultId, content, subType, mimeT
|
|
|
384
399
|
|
|
385
400
|
return pRetry(() => postAuthFormData(`/storage${storagePath}`, {}, files, {
|
|
386
401
|
'X-Asset-Encoding': 'gzip',
|
|
387
|
-
}), {
|
|
402
|
+
}), { retries: DEFAULT_REQUEST_RETRY }).then(() => storagePath);
|
|
388
403
|
}
|
|
389
404
|
|
|
390
405
|
const uploadRunDataArtifact = _.memoize(async (projectId, testId, testResultId, runData) => {
|
|
@@ -434,7 +449,7 @@ function addTestRetry({
|
|
|
434
449
|
runId,
|
|
435
450
|
testResult,
|
|
436
451
|
},
|
|
437
|
-
}), {
|
|
452
|
+
}), { retries: DEFAULT_REQUEST_RETRY });
|
|
438
453
|
}
|
|
439
454
|
|
|
440
455
|
/**
|
|
@@ -509,6 +524,7 @@ module.exports = {
|
|
|
509
524
|
initializeUserWithAuth: Promise.method(initializeUserWithAuth),
|
|
510
525
|
addTestRetry,
|
|
511
526
|
getHybridGridProvider,
|
|
527
|
+
loadSfdcCredential,
|
|
512
528
|
loadTest,
|
|
513
529
|
isTestResultCompleted,
|
|
514
530
|
getApplitoolsIntegrationData,
|