@testim/testim-cli 3.241.0 → 3.244.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/commons/testimAnalytics.js +8 -3
- package/commons/testimServicesApi.js +14 -16
- package/npm-shrinkwrap.json +1051 -923
- package/package.json +4 -4
- package/player/services/playbackTimeoutCalculator.js +26 -25
- package/player/stepActions/evaluateExpressionStepAction.js +7 -7
- package/player/stepActions/scripts/doClick.js +3 -1
- package/player/stepActions/scripts/html5dragAction.js +3 -1
- package/player/stepActions/scripts/html5dragActionV2.js +3 -1
- package/player/stepActions/scripts/runCode.js +23 -6
- package/player/stepActions/scripts/scroll.js +1 -6
- package/player/stepActions/scripts/setText.js +4 -1
- package/processHandler.js +12 -9
- package/processHandler.test.js +56 -0
- package/testRunStatus.js +0 -8
- package/utils.js +2 -6
- package/utils.test.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testim/testim-cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.244.0",
|
|
4
4
|
"description": "Command line interface for running Testing on your CI",
|
|
5
5
|
"author": "Oren Rubin",
|
|
6
6
|
"contributors": [{
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"multer": "1.4.4"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@applitools/eyes-sdk-core": "13.
|
|
51
|
-
"@applitools/visual-grid-client": "15.
|
|
50
|
+
"@applitools/eyes-sdk-core": "13.6.23",
|
|
51
|
+
"@applitools/visual-grid-client": "15.12.34",
|
|
52
52
|
"@testim/coralogix-logger": "1.1.27-beta.1",
|
|
53
53
|
"@testim/webdriverio": "0.0.5",
|
|
54
54
|
"abort-controller": "3.0.0",
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
"test": "IS_UNIT_TEST=1 ../../node_modules/mocha/bin/_mocha --timeout 2000 --reporter spec --exit --recursive \"./src/**/*.test.js\" --exclude ./src/codim/template.js/tests/examples/**/*.test.js",
|
|
117
117
|
"test:watch": "IS_UNIT_TEST=1 ../../node_modules/mocha/bin/_mocha --timeout 2000 --exit --recursive \"./src/**/*.test.js\" --exclude ./src/codim/template.js/tests/examples/**/*.test.js --watch",
|
|
118
118
|
"test:cov": "nyc --reporter=lcov --reporter=text yarn test",
|
|
119
|
-
"upload-bundle-s3": "scripts/upload.js",
|
|
119
|
+
"upload-bundle-s3": "ts-node-transpile-only scripts/upload.js",
|
|
120
120
|
"prepare-version": "rm -rf ./deploy && mkdir -p deploy && gulp prepare-version-on-prem",
|
|
121
121
|
"make-onprem-deps": "cp ../../yarn.lock deploy && cd deploy && yarn install --production && bundle-deps",
|
|
122
122
|
"pack-onprem": "yarn prepare-version && yarn make-onprem-deps && cd deploy && npm pack && zip -r testim-cli.zip testim-cli-*.tgz",
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
3
|
const _ = require('lodash');
|
|
4
|
-
const logger = require('../../commons/logger').getLogger('playback-timeout-calculator');
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
const COMMUNICATION_BUFFER_TIME = 1000;
|
|
6
|
+
const UI_VERIFICATION_STEPS = ['simple-ui-verification', 'wait-for-simple-ui-verification'];
|
|
7
7
|
|
|
8
8
|
class PlaybackTimeoutCalculator {
|
|
9
|
-
|
|
10
9
|
constructor(isDebuggerConnected) {
|
|
11
10
|
this.resetStepVariables();
|
|
12
11
|
this.resetRetryVariables();
|
|
@@ -18,13 +17,13 @@ class PlaybackTimeoutCalculator {
|
|
|
18
17
|
this.totalStepTime = totalStepTime || 0;
|
|
19
18
|
this.totalStepTimesReport = [];
|
|
20
19
|
this.currentRetryTimesReport = {};
|
|
21
|
-
|
|
20
|
+
const now = Date.now();
|
|
22
21
|
this.currentRetryStart = now;
|
|
23
22
|
this.lastUpdateTime = now;
|
|
24
23
|
}
|
|
25
24
|
|
|
26
25
|
resetRetryVariables() {
|
|
27
|
-
|
|
26
|
+
const now = Date.now();
|
|
28
27
|
this.currentRetryStart = now;
|
|
29
28
|
this.lastUpdateTime = now;
|
|
30
29
|
this.totalStepTimesReport.push(this.currentRetryTimesReport);
|
|
@@ -32,7 +31,7 @@ class PlaybackTimeoutCalculator {
|
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
initStepRun(stepPlayback) {
|
|
35
|
-
|
|
34
|
+
const getRetryTimeoutSuggestions = (totalStepTime) => {
|
|
36
35
|
const timeToPlayStep = this.getTotalStepTimeLeftToPlay(stepPlayback, totalStepTime);
|
|
37
36
|
const MINIMAL_RETRY_TIME = 5000;
|
|
38
37
|
if (timeToPlayStep <= MINIMAL_RETRY_TIME) {
|
|
@@ -42,7 +41,7 @@ class PlaybackTimeoutCalculator {
|
|
|
42
41
|
};
|
|
43
42
|
stepPlayback.setStartTimestamp();
|
|
44
43
|
const totalStepTime = this.getTotalStepRunTime(stepPlayback);
|
|
45
|
-
|
|
44
|
+
const currentRetryTimes = [...UI_VERIFICATION_STEPS, 'custom-validation'].includes(stepPlayback.stepType) ? [totalStepTime] : getRetryTimeoutSuggestions(totalStepTime);
|
|
46
45
|
this.resetStepVariables(totalStepTime, currentRetryTimes);
|
|
47
46
|
stepPlayback.context.data.maxTotalStepTime = totalStepTime;
|
|
48
47
|
}
|
|
@@ -57,9 +56,12 @@ class PlaybackTimeoutCalculator {
|
|
|
57
56
|
}
|
|
58
57
|
|
|
59
58
|
getTotalStepRunTime(stepPlayback) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
const HALF_HOUR_IN_MS = 30 * 60 * 1000;
|
|
60
|
+
let fallbackTimeout = stepPlayback.context.config.stepTimeout;
|
|
61
|
+
if (UI_VERIFICATION_STEPS.includes(stepPlayback.stepType)) {
|
|
62
|
+
fallbackTimeout = stepPlayback.context.config.applitoolsStepTimeout || HALF_HOUR_IN_MS;
|
|
63
|
+
}
|
|
64
|
+
return (stepPlayback.step.useStepTimeout && stepPlayback.step.stepTimeout) ? stepPlayback.step.stepTimeout : fallbackTimeout;
|
|
63
65
|
}
|
|
64
66
|
getTotalStepTimeLeftToPlay(stepPlayback, totalStepTime = this.totalStepTime) {
|
|
65
67
|
const playTimeSoFar = Date.now() - stepPlayback.startTimestamp;
|
|
@@ -71,7 +73,7 @@ class PlaybackTimeoutCalculator {
|
|
|
71
73
|
this.getTotalStepTimeLeftToPlay(stepPlayback);
|
|
72
74
|
}
|
|
73
75
|
getTotalCurrentRetryTimeLeft(stepPlayback) {
|
|
74
|
-
|
|
76
|
+
const totalRetryTime = Date.now() - this.currentRetryStart;
|
|
75
77
|
return this.getCurrentRetryTime(stepPlayback) - totalRetryTime + COMMUNICATION_BUFFER_TIME;
|
|
76
78
|
}
|
|
77
79
|
getTabTimeout(stepPlayback) {
|
|
@@ -97,7 +99,6 @@ class PlaybackTimeoutCalculator {
|
|
|
97
99
|
}
|
|
98
100
|
|
|
99
101
|
return (stepPlayback.step.events.length * timePerEvent) + buffer;
|
|
100
|
-
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
getActionTimeout(stepPlayback) {
|
|
@@ -108,10 +109,10 @@ class PlaybackTimeoutCalculator {
|
|
|
108
109
|
const actionType = stepPlayback.step.type;
|
|
109
110
|
const MIN_ACTION_PLAYBACK_TIME = 30000;
|
|
110
111
|
|
|
111
|
-
|
|
112
|
-
if (actionType ===
|
|
112
|
+
let actionTime;
|
|
113
|
+
if (actionType === 'sleep') {
|
|
113
114
|
actionTime = stepPlayback.step.durationMS + SLEEP_ERROR_MARGIN_MS;
|
|
114
|
-
} else if (actionType ===
|
|
115
|
+
} else if (actionType === 'android-scroll') {
|
|
115
116
|
actionTime = Math.max(this.calcAndroidScrollTimeout(stepPlayback), MIN_ACTION_PLAYBACK_TIME);
|
|
116
117
|
} else {
|
|
117
118
|
actionTime = Math.max(this.getTotalStepTimeLeftToPlay(stepPlayback), MIN_ACTION_PLAYBACK_TIME);
|
|
@@ -120,34 +121,34 @@ class PlaybackTimeoutCalculator {
|
|
|
120
121
|
}
|
|
121
122
|
|
|
122
123
|
setStepPhaseTime(phase) {
|
|
123
|
-
|
|
124
|
-
|
|
124
|
+
const now = Date.now();
|
|
125
|
+
const totalTime = now - this.lastUpdateTime;
|
|
125
126
|
this.lastUpdateTime = now;
|
|
126
127
|
this.currentRetryTimesReport[phase] = totalTime;
|
|
127
128
|
}
|
|
128
129
|
|
|
129
130
|
reportGetTabTime() {
|
|
130
|
-
this.setStepPhaseTime(
|
|
131
|
+
this.setStepPhaseTime('tab');
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
reportGetFrameTime() {
|
|
134
|
-
this.setStepPhaseTime(
|
|
135
|
+
this.setStepPhaseTime('frame');
|
|
135
136
|
}
|
|
136
137
|
|
|
137
138
|
reportCalcConditionTime() {
|
|
138
|
-
this.setStepPhaseTime(
|
|
139
|
+
this.setStepPhaseTime('condition');
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
reportPreLocateActionsTime() {
|
|
142
|
-
this.setStepPhaseTime(
|
|
143
|
+
this.setStepPhaseTime('pre-locate');
|
|
143
144
|
}
|
|
144
145
|
|
|
145
146
|
reportFindElementsTime() {
|
|
146
|
-
this.setStepPhaseTime(
|
|
147
|
+
this.setStepPhaseTime('locate');
|
|
147
148
|
}
|
|
148
149
|
|
|
149
150
|
reportStepActionTime() {
|
|
150
|
-
this.setStepPhaseTime(
|
|
151
|
+
this.setStepPhaseTime('action');
|
|
151
152
|
}
|
|
152
153
|
}
|
|
153
154
|
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
2
3
|
const Promise = require('bluebird');
|
|
3
4
|
const sessionPlayer = require('../../commons/getSessionPlayerRequire');
|
|
4
5
|
const StepAction = require('./stepAction');
|
|
6
|
+
|
|
5
7
|
const constants = sessionPlayer.commonConstants.stepResult;
|
|
6
8
|
const { stepParamBuilder } = sessionPlayer;
|
|
7
9
|
const logger = require('../../commons/logger').getLogger('evaluate-expression-step-action');
|
|
8
10
|
const _ = require('lodash');
|
|
9
11
|
|
|
10
12
|
class EvaluateExpressionStepAction extends StepAction {
|
|
11
|
-
|
|
12
13
|
execute() {
|
|
13
14
|
const step = this.step;
|
|
14
15
|
const context = this.context;
|
|
@@ -25,8 +26,8 @@ class EvaluateExpressionStepAction extends StepAction {
|
|
|
25
26
|
|
|
26
27
|
const params = ['context', ...incomingParams.as.functionParameters];
|
|
27
28
|
const args = [context, ...incomingParams.as.functionArguments];
|
|
28
|
-
const expressionToEvaluate = step.subType ===
|
|
29
|
-
const code = (
|
|
29
|
+
const expressionToEvaluate = step.subType === 'text' ? `'${step.expression.replace(/'/g, "\\\'")}'` : step.expression;
|
|
30
|
+
const code = (`return ${expressionToEvaluate}`).replace(/\n/g, '\\n');
|
|
30
31
|
const textEvaluateFunction = Function.apply(Function, params.concat([code]));
|
|
31
32
|
const evaluatedText = textEvaluateFunction.apply(null, args);
|
|
32
33
|
|
|
@@ -38,8 +39,8 @@ class EvaluateExpressionStepAction extends StepAction {
|
|
|
38
39
|
|
|
39
40
|
const result = {
|
|
40
41
|
success: true,
|
|
41
|
-
evaluatedText
|
|
42
|
-
data: context.data
|
|
42
|
+
evaluatedText,
|
|
43
|
+
data: context.data,
|
|
43
44
|
};
|
|
44
45
|
|
|
45
46
|
resolve(result);
|
|
@@ -48,7 +49,6 @@ class EvaluateExpressionStepAction extends StepAction {
|
|
|
48
49
|
}
|
|
49
50
|
});
|
|
50
51
|
}
|
|
51
|
-
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
module.exports = EvaluateExpressionStepAction;
|
|
@@ -3,23 +3,40 @@
|
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
5
|
const runCode = function (eventData, preCompiledCode) {
|
|
6
|
+
typeof Object.tstassign !== 'function' && (Object.tstassign = function (n, t) {
|
|
7
|
+
'use strict';
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
if (n == null) throw new TypeError('Cannot convert undefined or null to object'); for (var r = Object(n), e = 1; e < arguments.length; e++) { var o = arguments[e]; if (o != null) for (var a in o)Object.prototype.hasOwnProperty.call(o, a) && (r[a] = o[a]); } return r;
|
|
10
|
+
});
|
|
11
|
+
Object.assign = typeof Object.assign !== 'function' ? Object.tstassign : Object.assign;
|
|
9
12
|
|
|
10
13
|
function appendToStorage(name, data) {
|
|
11
14
|
const sessionItem = 'data-testim-' + name;
|
|
15
|
+
|
|
16
|
+
const nativeFuncErrMsg = 'Native sessionStorage is not available';
|
|
17
|
+
function isNativeFunction(fn) {
|
|
18
|
+
if (!fn || !fn.toString) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
return fn.toString().indexOf('[native code]') > -1;
|
|
22
|
+
}
|
|
12
23
|
try {
|
|
24
|
+
if (![window.sessionStorage.setItem, window.sessionStorage.getItem].every(isNativeFunction)) {
|
|
25
|
+
throw new Error(nativeFuncErrMsg);
|
|
26
|
+
}
|
|
13
27
|
const oldData = JSON.parse(window.sessionStorage.getItem(sessionItem) || '{}');
|
|
14
28
|
const newData = Object.tstassign({}, oldData, data);
|
|
15
29
|
window.sessionStorage.setItem(sessionItem, JSON.stringify(newData));
|
|
16
30
|
} catch (err) {
|
|
17
|
-
// any
|
|
31
|
+
// any variation QuotaExceededError from browsers
|
|
18
32
|
const isQuotaExceededError = err.message.toLowerCase().indexOf('quota') > -1;
|
|
33
|
+
const isNativeFunctionError = err.message === nativeFuncErrMsg;
|
|
34
|
+
|
|
19
35
|
if (err.message.indexOf('sessionStorage') > -1 || // Chrome + Firefox
|
|
20
36
|
err.message.indexOf('The operation is insecure') > -1 || // Safari
|
|
21
37
|
err.message.indexOf('SecurityError') > -1 || // Edge
|
|
22
|
-
isQuotaExceededError
|
|
38
|
+
isQuotaExceededError ||
|
|
39
|
+
isNativeFunctionError
|
|
23
40
|
) {
|
|
24
41
|
var storage = document.head.querySelector('#testim-storage-backup');
|
|
25
42
|
if (!storage) {
|
|
@@ -30,13 +47,13 @@ const runCode = function (eventData, preCompiledCode) {
|
|
|
30
47
|
const oldData = JSON.parse(storage.getAttribute(sessionItem) || '{}');
|
|
31
48
|
const newData = Object.tstassign({}, oldData, data);
|
|
32
49
|
storage.setAttribute(sessionItem, JSON.stringify(newData));
|
|
33
|
-
if (isQuotaExceededError) {
|
|
50
|
+
if (isQuotaExceededError || isNativeFunctionError) {
|
|
34
51
|
try {
|
|
35
52
|
window.sessionStorage.removeItem(sessionItem);
|
|
36
53
|
} catch (e) {
|
|
37
54
|
// Prevents future retries from looking in sessionStorage with old data
|
|
38
55
|
}
|
|
39
|
-
window.TSTA.useFallbackStorage = true;
|
|
56
|
+
(window.TSTA = window.TSTA || {}).useFallbackStorage = true;
|
|
40
57
|
}
|
|
41
58
|
return;
|
|
42
59
|
}
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
/* eslint-disable no-var */
|
|
3
|
-
/* eslint-disable no-redeclare */
|
|
4
|
-
/* eslint-disable object-shorthand */
|
|
5
|
-
/* eslint-disable one-var */
|
|
6
|
-
/* eslint-disable operator-linebreak */
|
|
1
|
+
/* globals getLocatedElement, elementScrollTo */
|
|
7
2
|
|
|
8
3
|
'use strict';
|
|
9
4
|
|
package/processHandler.js
CHANGED
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
|
+
const Promise = require('bluebird');
|
|
5
6
|
const logger = require('./commons/logger').getLogger('process-handler');
|
|
6
7
|
|
|
7
8
|
const exitHooks = [];
|
|
8
|
-
const Promise = require('bluebird');
|
|
9
9
|
|
|
10
|
-
module.exports = function (onExit) {
|
|
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
13
|
await Promise.all(exitHooks.map(x => x())).timeout(10000).catch(() => {});
|
|
14
14
|
onExit(err);
|
|
15
15
|
}
|
|
16
|
-
|
|
16
|
+
_process.on('uncaughtException', async (err) => {
|
|
17
17
|
logger.error('Caught exception', { err });
|
|
18
18
|
console.log('Uncaught exception');
|
|
19
19
|
if (err.message) {
|
|
@@ -25,7 +25,7 @@ module.exports = function (onExit) {
|
|
|
25
25
|
await cleanup(err);
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
_process.on('unhandledRejection', (reason) => {
|
|
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
|
|
@@ -37,11 +37,11 @@ module.exports = function (onExit) {
|
|
|
37
37
|
throw reason;
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
_process.on('rejectionHandled', () => {
|
|
41
41
|
logger.error('Caught rejection handled');
|
|
42
42
|
});
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
_process.once('SIGTERM', () => {
|
|
45
45
|
const msg = 'Runner aborted - SIGTERM event';
|
|
46
46
|
const err = new Error(msg);
|
|
47
47
|
logger.error(msg);
|
|
@@ -49,7 +49,7 @@ module.exports = function (onExit) {
|
|
|
49
49
|
throw err;
|
|
50
50
|
});
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
_process.once('SIGINT', () => {
|
|
53
53
|
const msg = 'Runner aborted - SIGINT event';
|
|
54
54
|
const err = new Error(msg);
|
|
55
55
|
logger.error(msg);
|
|
@@ -58,12 +58,15 @@ module.exports = function (onExit) {
|
|
|
58
58
|
});
|
|
59
59
|
|
|
60
60
|
// One time self-call is expected :(
|
|
61
|
-
|
|
61
|
+
_process.once('exit', (e) => {
|
|
62
62
|
onExit(e);
|
|
63
63
|
});
|
|
64
64
|
};
|
|
65
65
|
|
|
66
|
-
|
|
67
66
|
module.exports.registerExitHook = function (hook) {
|
|
68
67
|
exitHooks.push(hook);
|
|
69
68
|
};
|
|
69
|
+
|
|
70
|
+
module.exports.reset = function () {
|
|
71
|
+
exitHooks.splice(0, exitHooks.length);
|
|
72
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
|
|
2
|
+
const { delay } = require('bluebird');
|
|
3
|
+
const EventEmitter = require('events');
|
|
4
|
+
const { expect, sinon } = require('../test/utils/testUtils');
|
|
5
|
+
const processHandler = require('./processHandler');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Process extends EventEmitter {
|
|
9
|
+
constructor() {
|
|
10
|
+
super();
|
|
11
|
+
this.stdout = new EventEmitter();
|
|
12
|
+
this.stderr = new EventEmitter();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
describe('testimTunnel', () => {
|
|
17
|
+
let process;
|
|
18
|
+
let onExitMock;
|
|
19
|
+
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
process = new Process();
|
|
22
|
+
onExitMock = sinon.spy();
|
|
23
|
+
processHandler(onExitMock, process);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
afterEach(async () => {
|
|
27
|
+
await delay(10);
|
|
28
|
+
expect(onExitMock).to.have.been.calledOnce;
|
|
29
|
+
processHandler.reset();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
it('should register a SIGTERM handler', (done) => {
|
|
34
|
+
processHandler.registerExitHook(done);
|
|
35
|
+
expect(() => process.emit('SIGTERM')).to.throw('Runner aborted - SIGTERM event');
|
|
36
|
+
});
|
|
37
|
+
it('should register a SIGINT handler', (done) => {
|
|
38
|
+
processHandler.registerExitHook(done);
|
|
39
|
+
expect(() => process.emit('SIGINT')).to.throw('Runner aborted - SIGINT event');
|
|
40
|
+
});
|
|
41
|
+
it('should register a unhandledRejection handler', () => {
|
|
42
|
+
expect(() => process.emit('unhandledRejection', new Error('reason'))).to.throw('reason');
|
|
43
|
+
onExitMock();
|
|
44
|
+
});
|
|
45
|
+
it('should register a uncaughtException handler', (done) => {
|
|
46
|
+
processHandler.registerExitHook(done);
|
|
47
|
+
expect(() => process.emit('uncaughtException', new Error())).not.to.throw();
|
|
48
|
+
});
|
|
49
|
+
it('should do nothing on rejectionHandled', () => {
|
|
50
|
+
expect(() => process.emit('rejectionHandled')).not.to.throw();
|
|
51
|
+
onExitMock();
|
|
52
|
+
});
|
|
53
|
+
it('should register a exit handler', () => {
|
|
54
|
+
expect(() => process.emit('exit')).not.to.throw();
|
|
55
|
+
});
|
|
56
|
+
});
|
package/testRunStatus.js
CHANGED
|
@@ -17,7 +17,6 @@ const { calculateCoverage } = require('./coverage/jsCoverage');
|
|
|
17
17
|
const featureAvailabilityService = require('./commons/featureAvailabilityService');
|
|
18
18
|
const featureFlags = require('./commons/featureFlags');
|
|
19
19
|
const { mapFilesToLocalDrive } = require('./services/localRCASaver');
|
|
20
|
-
const { removeHiddenParamsInTestData } = require('./commons/testimServicesApi');
|
|
21
20
|
|
|
22
21
|
const gitBranch = utils.getEnvironmentGitBranch();
|
|
23
22
|
const gitCommit = process.env.GIT_COMMIT || process.env.CIRCLE_SHA1 || process.env.TRAVIS_COMMIT;
|
|
@@ -125,13 +124,6 @@ RunStatus.prototype.addRetryTestResult = async function ({
|
|
|
125
124
|
|
|
126
125
|
this.testRunStatus[newResultId] = newTestResult;
|
|
127
126
|
|
|
128
|
-
const { projectData } = this.options;
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if (newTestResult.config.testData) {
|
|
132
|
-
newTestResult.config.testData = removeHiddenParamsInTestData(newTestResult.config.testData, projectData.defaults);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
127
|
return servicesApi.addTestRetry({
|
|
136
128
|
projectId,
|
|
137
129
|
runId: executionId,
|
package/utils.js
CHANGED
|
@@ -71,20 +71,16 @@ function getRunConfigByBrowserName(browser, saucelabs, browserstack) {
|
|
|
71
71
|
return _.merge(selectedBrowser, selectedOS);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
function handleAngularURIComponent(part) {
|
|
75
|
-
return part.replace(/(~|\/)/g, m => ({ '~': '~~', '/': '~2F' }[m]));
|
|
76
|
-
}
|
|
77
|
-
|
|
78
74
|
function getTestUrl(editorUrl, projectId, testId, resultId, branch) {
|
|
79
75
|
let testUrl = '';
|
|
80
|
-
branch = branch ?
|
|
76
|
+
branch = branch ? encodeURIComponent(branch) : 'master';
|
|
81
77
|
if (projectId && testId) {
|
|
82
78
|
testUrl = `${editorUrl}/#/project/${projectId}/branch/${branch}/test/${testId}`;
|
|
83
79
|
if (resultId) {
|
|
84
80
|
testUrl += `?result-id=${resultId}`;
|
|
85
81
|
}
|
|
86
82
|
}
|
|
87
|
-
return
|
|
83
|
+
return testUrl;
|
|
88
84
|
}
|
|
89
85
|
|
|
90
86
|
function isPromise(obj) {
|
package/utils.test.js
CHANGED
|
@@ -32,7 +32,7 @@ describe('utils', () => {
|
|
|
32
32
|
expect(utils.getTestUrl('http://localhost:8080', 'project', 'test', 'result', 'normal-branch-name'))
|
|
33
33
|
.to.equal('http://localhost:8080/#/project/project/branch/normal-branch-name/test/test?result-id=result');
|
|
34
34
|
expect(utils.getTestUrl('http://localhost:8080', 'project', 'test', 'result', 'branch/with/slashes'))
|
|
35
|
-
.to.equal('http://localhost:8080/#/project/project/branch/branch
|
|
35
|
+
.to.equal('http://localhost:8080/#/project/project/branch/branch%2Fwith%2Fslashes/test/test?result-id=result');
|
|
36
36
|
expect(utils.getTestUrl('http://localhost:8080', 'project', 'test', 'result', 'branch with spaces'))
|
|
37
37
|
.to.equal('http://localhost:8080/#/project/project/branch/branch%20with%20spaces/test/test?result-id=result');
|
|
38
38
|
expect(utils.getTestUrl('http://localhost:8080', 'project', 'test', 'result', 'encoded%20branch'))
|