@testim/testim-cli 3.260.0 → 3.262.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/testimServicesApi.js +10 -7
- package/executionQueue.js +9 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/player/stepActions/RefreshStepAction.js +7 -4
- package/player/stepActions/baseJsStepAction.js +45 -46
- package/player/stepActions/dropFileStepAction.js +11 -12
- package/player/stepActions/evaluateExpressionStepAction.js +32 -33
- package/player/stepActions/extensionOnlyStepAction.js +3 -4
- package/player/stepActions/extractTextStepAction.js +8 -10
- package/player/stepActions/hoverStepAction.js +3 -3
- package/player/stepActions/locateStepAction.js +39 -34
- package/player/stepActions/mouseStepAction.js +36 -34
- package/player/stepActions/navigationStepAction.js +7 -8
- package/player/stepActions/scrollStepAction.js +22 -22
- package/player/stepActions/stepAction.js +21 -21
- package/player/stepActions/stepActionRegistrar.js +63 -58
- package/player/stepActions/submitStepAction.js +2 -3
- package/player/stepActions/textStepAction.js +14 -14
- package/player/stepActions/textValidationStepAction.js +50 -38
- package/player/stepActions/wheelStepAction.js +5 -11
- package/processHandler.js +2 -0
- package/reports/junitReporter.js +18 -1
- package/runOptions.d.ts +4 -0
- package/runOptions.js +8 -1
- package/runners/TestPlanRunner.js +20 -19
- package/runners/runnerUtils.js +1 -2
- package/testRunHandler.js +18 -9
- package/testRunStatus.js +205 -157
- package/workers/BaseWorker.js +11 -0
- package/workers/WorkerExtension.js +117 -91
- package/workers/WorkerSelenium.js +8 -3
|
@@ -2,28 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
const StepAction = require('./stepAction');
|
|
4
4
|
const requiredUrl = require('url');
|
|
5
|
-
const Promise = require('bluebird');
|
|
6
5
|
|
|
7
6
|
class NavigationStepAction extends StepAction {
|
|
8
|
-
updateBaseUrl(location) {
|
|
7
|
+
async updateBaseUrl(location) {
|
|
9
8
|
const orgUrl = requiredUrl.parse(location);
|
|
10
9
|
const baseLocation = requiredUrl.parse(this.context.recordedBaseUrl);
|
|
11
10
|
const newBaseLocation = requiredUrl.parse(this.context.baseUrl);
|
|
12
11
|
if (orgUrl.host === baseLocation.host && baseLocation.host !== newBaseLocation.host) {
|
|
13
12
|
orgUrl.host = newBaseLocation.host;
|
|
14
13
|
}
|
|
15
|
-
return
|
|
14
|
+
return orgUrl.href;
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
performAction() {
|
|
17
|
+
async performAction() {
|
|
19
18
|
const url = this.context.data.testimNavigationStepDestination || this.context.data.url;
|
|
20
19
|
// Opens a new tab and switches to new tab
|
|
21
20
|
if (this.step.openInNewTab) {
|
|
22
|
-
|
|
21
|
+
await this.driver.client.newWindow(url);
|
|
22
|
+
return;
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
.then(() => {});
|
|
24
|
+
const updatedUrl = await this.updateBaseUrl(url);
|
|
25
|
+
await this.driver.url(updatedUrl);
|
|
27
26
|
}
|
|
28
27
|
}
|
|
29
28
|
|
|
@@ -21,7 +21,7 @@ class ScrollStepAction extends StepAction {
|
|
|
21
21
|
return failureMessage;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
scroll(elementToScrollTo, step, elementToScrollOn) {
|
|
24
|
+
async scroll(elementToScrollTo, step, elementToScrollOn) {
|
|
25
25
|
const expectedY = Math.round(Number(step.isScrollToElement ? step.marginTop : step.y));
|
|
26
26
|
const expectedX = Math.round(Number(step.isScrollToElement ? step.marginLeft : step.x));
|
|
27
27
|
|
|
@@ -39,8 +39,8 @@ class ScrollStepAction extends StepAction {
|
|
|
39
39
|
return scroll.apply(null, arguments)
|
|
40
40
|
`;
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
.executeJSWithArray(scrollCode, [
|
|
42
|
+
try {
|
|
43
|
+
const res = await this.driver.executeJSWithArray(scrollCode, [
|
|
44
44
|
elementToScrollOn,
|
|
45
45
|
elementToScrollTo,
|
|
46
46
|
Boolean(step.isScrollToElement),
|
|
@@ -49,31 +49,31 @@ class ScrollStepAction extends StepAction {
|
|
|
49
49
|
expectedY,
|
|
50
50
|
step.shouldScrollLeft,
|
|
51
51
|
step.shouldScrollTop,
|
|
52
|
-
])
|
|
53
|
-
|
|
54
|
-
if (!res || !res.value) {
|
|
55
|
-
return {
|
|
56
|
-
errorType: constants.SCROLL_ACTION_FAILURE,
|
|
57
|
-
success: false,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const { success, actualX, actualY } = res.value;
|
|
62
|
-
|
|
63
|
-
if (success) {
|
|
64
|
-
return { success: true };
|
|
65
|
-
}
|
|
66
|
-
|
|
52
|
+
]);
|
|
53
|
+
if (!res?.value) {
|
|
67
54
|
return {
|
|
68
55
|
errorType: constants.SCROLL_ACTION_FAILURE,
|
|
69
56
|
success: false,
|
|
70
|
-
resultInfo: { error: this.getFailureString(step, expectedX, expectedY, actualX, actualY) },
|
|
71
57
|
};
|
|
72
|
-
}
|
|
73
|
-
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const { success, actualX, actualY } = res.value;
|
|
61
|
+
|
|
62
|
+
if (success) {
|
|
63
|
+
return { success: true };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
errorType: constants.SCROLL_ACTION_FAILURE,
|
|
68
|
+
success: false,
|
|
69
|
+
resultInfo: { error: this.getFailureString(step, expectedX, expectedY, actualX, actualY) },
|
|
70
|
+
};
|
|
71
|
+
} catch (error) {
|
|
72
|
+
return {
|
|
74
73
|
errorType: constants.SCROLL_ACTION_FAILURE,
|
|
75
74
|
success: false,
|
|
76
|
-
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
scrollOnDocument(step, elementToScrollTo) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const { commonConstants } = require('../../commons/getSessionPlayerRequire');
|
|
4
|
-
const Promise = require('bluebird');
|
|
5
4
|
|
|
6
5
|
/** @typedef {typeof import('clickim/src/background/stepActions/stepAction').StepAction} ClickimStepActionCtor */
|
|
7
6
|
/** @typedef {ConstructorParameters<ClickimStepActionCtor>} ClickimStepActionCtorParams */
|
|
@@ -33,7 +32,7 @@ class StepAction {
|
|
|
33
32
|
return this.stepActionUtils.driver;
|
|
34
33
|
}
|
|
35
34
|
|
|
36
|
-
performAction() {
|
|
35
|
+
async performAction() {
|
|
37
36
|
throw new Error('not implemented');
|
|
38
37
|
}
|
|
39
38
|
|
|
@@ -43,25 +42,26 @@ class StepAction {
|
|
|
43
42
|
}
|
|
44
43
|
|
|
45
44
|
/** @type {ClickimStepAction['execute']} */
|
|
46
|
-
execute(stepActionFactory, step) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
}
|
|
45
|
+
async execute(stepActionFactory, step) {
|
|
46
|
+
try {
|
|
47
|
+
const res = await this.performAction(stepActionFactory, step);
|
|
48
|
+
return { success: true, ...res };
|
|
49
|
+
} catch (err) {
|
|
50
|
+
const errorMsg = err?.message || err?.seleniumStack?.message;
|
|
51
|
+
const displayMsg = err?.displayMessage;
|
|
52
|
+
return {
|
|
53
|
+
success: false,
|
|
54
|
+
reason: errorMsg,
|
|
55
|
+
exception: err,
|
|
56
|
+
errorType: commonConstants.stepResult.ACTION_EXCEPTION,
|
|
57
|
+
resultInfo: {
|
|
58
|
+
exception: `selenium exception: ${errorMsg}`,
|
|
59
|
+
// clickim -> playbackStepResultHandler.js -> FAILURE_REASON_MAPPING -> ACTION_EXCEPTION
|
|
60
|
+
// expects resultInfo.error or resultInfo.reason
|
|
61
|
+
error: displayMsg || errorMsg,
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
'use strict';
|
|
2
4
|
|
|
3
5
|
const LocateStepAction = require('./locateStepAction');
|
|
@@ -22,7 +24,6 @@ const ApiStepAction = require('./apiStepAction');
|
|
|
22
24
|
const ExtractTextStepAction = require('./extractTextStepAction');
|
|
23
25
|
const TdkHybridStepAction = require('./tdkHybridStepAction');
|
|
24
26
|
const PixelValidationStepAction = require('./pixelValidationStepAction');
|
|
25
|
-
|
|
26
27
|
const CliJsStepAction = require('./cliJsStepAction');
|
|
27
28
|
const CliConditionStepAction = require('./cliConditionStepAction');
|
|
28
29
|
const NodePackageStepAction = require('./nodePackageStepAction');
|
|
@@ -36,69 +37,73 @@ function register(stepActionByType, stepActionFactory) {
|
|
|
36
37
|
});
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
'wait-for-simple-ui-verification': PixelValidationStepAction,
|
|
40
|
+
const STEP_ACTION_MAPPING = {
|
|
41
|
+
locate: LocateStepAction,
|
|
42
|
+
scroll: ScrollStepAction,
|
|
43
|
+
mouse: MouseStepAction,
|
|
44
|
+
submit: SubmitStepAction,
|
|
45
|
+
text: TextStepAction,
|
|
46
|
+
'special-key': SpecialKeyStepAction,
|
|
47
|
+
'user-code': JsCodeStepAction,
|
|
48
|
+
'validation-code-step': JsCodeStepAction,
|
|
49
|
+
'wait-for-code-step': JsCodeStepAction,
|
|
50
|
+
'action-code-step': JsCodeStepAction,
|
|
51
|
+
'condition-step': JsConditionStepAction,
|
|
52
|
+
'skip-code-step': JsConditionStepAction,
|
|
53
|
+
'element-code-step': JsConditionStepAction,
|
|
54
|
+
'evaluate-expression': EvaluateExpressionStepAction,
|
|
55
|
+
'text-validation': TextValidationStepAction,
|
|
56
|
+
'wait-for-text-validation': TextValidationStepAction,
|
|
57
|
+
'select-option': SelectOptionStepAction,
|
|
58
|
+
'drop-file': DropFileStepAction,
|
|
59
|
+
'input-file': InputFileStepAction,
|
|
60
|
+
hover: HoverStepAction,
|
|
61
|
+
navigation: NavigationStepAction,
|
|
62
|
+
wheel: WheelStepAction,
|
|
63
|
+
sleep: SleepStepAction,
|
|
64
|
+
refresh: RefreshStepAction,
|
|
65
|
+
'api-validation': ApiStepAction,
|
|
66
|
+
'api-action': ApiStepAction,
|
|
67
|
+
'api-code-step': JsCodeStepAction,
|
|
68
|
+
'extract-text': ExtractTextStepAction,
|
|
69
|
+
'simple-ui-verification': PixelValidationStepAction,
|
|
70
|
+
'wait-for-simple-ui-verification': PixelValidationStepAction,
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
'cli-validation-download-file': ExtensionOnlyStepAction,
|
|
73
|
+
'cli-wait-for-download-file': ExtensionOnlyStepAction,
|
|
74
|
+
'network-validation-step': ExtensionOnlyStepAction,
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
'cli-validation-code-step': CliJsStepAction,
|
|
77
|
+
'cli-wait-for-code-step': CliJsStepAction,
|
|
78
|
+
'cli-action-code-step': CliJsStepAction,
|
|
79
|
+
'cli-api-code-step': CliJsStepAction,
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
'cli-condition-step': CliConditionStepAction,
|
|
82
|
+
'node-package': NodePackageStepAction,
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
'email-code-step': JsCodeStepAction,
|
|
85
|
+
'cli-email-code-step': CliJsStepAction,
|
|
86
|
+
'tdk-hybrid': TdkHybridStepAction,
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
88
|
+
'sfdc-recorded-step': SfdcRecordedStepAction,
|
|
89
|
+
'sfdc-step-login': SfdcStepAction,
|
|
90
|
+
'sfdc-step-logout': SfdcStepAction,
|
|
91
|
+
'sfdc-step-sobjectcreate': SfdcStepAction,
|
|
92
|
+
'sfdc-step-sobjectdelete': SfdcStepAction,
|
|
93
|
+
'sfdc-step-findrecord': SfdcStepAction,
|
|
94
|
+
'sfdc-step-quickaction': SfdcStepAction,
|
|
95
|
+
'sfdc-step-sobjectedit': SfdcStepAction,
|
|
96
|
+
'sfdc-step-sobjectvalidate': SfdcStepAction,
|
|
97
|
+
'sfdc-step-launchapp': SfdcStepAction,
|
|
98
|
+
'sfdc-step-closeconsoletabs': SfdcStepAction,
|
|
99
|
+
'sfdc-step-relatedlistaction': SfdcStepAction,
|
|
100
|
+
};
|
|
101
101
|
|
|
102
|
+
/**
|
|
103
|
+
* @param {import('../webdriver')} driver
|
|
104
|
+
* @param {import('clickim/src/background/stepActions/stepActionFactory').StepActionFactory} stepActionFactory
|
|
105
|
+
*/
|
|
106
|
+
module.exports = function (driver, stepActionFactory, runMode) {
|
|
102
107
|
register(STEP_ACTION_MAPPING, stepActionFactory);
|
|
103
108
|
if (stepActionFactory.registerLocateStepActionUtils) {
|
|
104
109
|
stepActionFactory.registerLocateStepActionUtils(LocateStepAction.getUtils(driver));
|
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
const StepAction = require('./stepAction');
|
|
4
4
|
|
|
5
5
|
class SubmitStepAction extends StepAction {
|
|
6
|
-
performAction() {
|
|
7
|
-
|
|
8
|
-
.then(() => {});
|
|
6
|
+
async performAction() {
|
|
7
|
+
await this.driver.submitForm(this.getTarget().seleniumElement);
|
|
9
8
|
}
|
|
10
9
|
}
|
|
11
10
|
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
const StepAction = require('./stepAction');
|
|
4
4
|
const setTextScript = require('./scripts/setText');
|
|
5
|
-
const Promise = require('bluebird');
|
|
6
5
|
const { codeSnippets } = require('../../commons/getSessionPlayerRequire');
|
|
7
6
|
const dispatchFocus = require('./scripts/focusElement');
|
|
8
7
|
const sessionPlayer = require('../../commons/getSessionPlayerRequire');
|
|
@@ -12,17 +11,18 @@ const constants = sessionPlayer.commonConstants.stepResult;
|
|
|
12
11
|
const setTextDraftJs = codeSnippets?.setTextDraftJs;
|
|
13
12
|
|
|
14
13
|
class TextStepAction extends StepAction {
|
|
15
|
-
setValueNative() {
|
|
14
|
+
async setValueNative() {
|
|
16
15
|
const context = this.context;
|
|
17
16
|
const target = this.getTarget();
|
|
18
17
|
if (!this.step.delayBetweenChars) {
|
|
19
18
|
return this.driver.setValue(target.seleniumElement, context.stepText);
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
await this.driver.elementIdClear(extractElementId(target.seleniumElement));
|
|
22
|
+
return await this.setTextDelayed();
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
setValueJS() {
|
|
25
|
+
async setValueJS() {
|
|
26
26
|
const step = this.step;
|
|
27
27
|
const context = this.context;
|
|
28
28
|
const target = context.data[step.targetId || 'targetId'];
|
|
@@ -33,8 +33,8 @@ class TextStepAction extends StepAction {
|
|
|
33
33
|
return this.driver.executeJS(setTextDraftJs(target.locatedElement, context.stepText));
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
if (!events
|
|
37
|
-
return
|
|
36
|
+
if (!events?.length) {
|
|
37
|
+
return undefined;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
const eventMessage = {
|
|
@@ -59,8 +59,8 @@ class TextStepAction extends StepAction {
|
|
|
59
59
|
// values between 0 and -1 -_-.
|
|
60
60
|
const eventParam = this.driver.isEdge() ? JSON.stringify(eventMessage) : eventMessage;
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
const result = await this.driver.executeCodeAsync(setTextCode, timeout, eventParam);
|
|
63
|
+
return { success: Boolean(result.value?.success) };
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
async setTextDelayed() {
|
|
@@ -75,7 +75,7 @@ class TextStepAction extends StepAction {
|
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
setValueAppendNative() {
|
|
78
|
+
async setValueAppendNative() {
|
|
79
79
|
const keys = [];
|
|
80
80
|
const context = this.context;
|
|
81
81
|
const target = this.getTarget();
|
|
@@ -86,12 +86,12 @@ class TextStepAction extends StepAction {
|
|
|
86
86
|
return this.driver.elementIdValue(extractElementId(target.seleniumElement), keys);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
return
|
|
89
|
+
return this.setTextDelayed();
|
|
90
90
|
}
|
|
91
|
-
|
|
91
|
+
throw new Error('missing selenium element');
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
performAction() {
|
|
94
|
+
async performAction() {
|
|
95
95
|
const target = this.getTarget();
|
|
96
96
|
const forceJsEvent = this.driver.isSafari() &&
|
|
97
97
|
target.locatedElement && target.locatedElement.shadowPath &&
|
|
@@ -101,11 +101,11 @@ class TextStepAction extends StepAction {
|
|
|
101
101
|
if (this.step.nativeEvents) {
|
|
102
102
|
return this.setValueAppendNative();
|
|
103
103
|
}
|
|
104
|
-
return
|
|
104
|
+
return {
|
|
105
105
|
success: false,
|
|
106
106
|
errorType: constants.TEXT_ACTION_FAILURE,
|
|
107
107
|
resultInfo: { error: "'Append Text' is only supported in Native Mode" },
|
|
108
|
-
}
|
|
108
|
+
};
|
|
109
109
|
}
|
|
110
110
|
if (this.step.nativeEvents && !forceJsEvent) {
|
|
111
111
|
return this.setValueNative();
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const Promise = require('bluebird');
|
|
4
3
|
const sessionPlayer = require('../../commons/getSessionPlayerRequire');
|
|
5
4
|
const StepAction = require('./stepAction');
|
|
6
5
|
|
|
@@ -9,49 +8,62 @@ const paramEvaluator = sessionPlayer.stepParamExpressionEvaluator;
|
|
|
9
8
|
const utils = sessionPlayer.utils;
|
|
10
9
|
|
|
11
10
|
class TextValidationStepAction extends StepAction {
|
|
12
|
-
performAction(stepActionFactory) {
|
|
11
|
+
async performAction(stepActionFactory) {
|
|
13
12
|
const step = this.step;
|
|
14
13
|
const context = this.context;
|
|
15
14
|
const target = this.getTarget();
|
|
16
15
|
const frameHandler = this.frameHandler;
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
17
|
+
try {
|
|
18
|
+
const text = await this.stepActionUtils.extractTargetText(target);
|
|
19
|
+
let actual;
|
|
20
|
+
let expected;
|
|
21
|
+
if (paramEvaluator) {
|
|
22
|
+
const evaluation = paramEvaluator.computeExpression(
|
|
23
|
+
step.expression2,
|
|
24
|
+
context,
|
|
25
|
+
this.exportsGlobal,
|
|
26
|
+
this.exportsTest,
|
|
27
|
+
);
|
|
28
|
+
actual = text;
|
|
29
|
+
expected = evaluation.evaluatedText;
|
|
30
|
+
} else {
|
|
31
|
+
const res = await stepActionFactory.executeStep(
|
|
32
|
+
step.expression2,
|
|
33
|
+
context,
|
|
34
|
+
frameHandler,
|
|
35
|
+
this.exportsGlobal,
|
|
36
|
+
this.locateElementPlayer,
|
|
37
|
+
this.exportsTest,
|
|
38
|
+
);
|
|
39
|
+
actual = text;
|
|
40
|
+
expected = res.evaluatedText;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
const compareResult = utils.compareOrMatch(expected, actual);
|
|
44
|
+
if (compareResult) {
|
|
45
|
+
return { success: true };
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
49
48
|
success: false,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
errorType: constants.TEXT_COMPARE_FAILURE,
|
|
50
|
+
resultInfo: { expected: String(expected), actual },
|
|
51
|
+
};
|
|
52
|
+
} catch (err) {
|
|
53
|
+
return {
|
|
54
|
+
success: false,
|
|
55
|
+
errorType: constants.TEXT_COMPARE_FAILURE,
|
|
56
|
+
resultInfo: { expected: expected.toString(), actual },
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
} catch (err) {
|
|
60
|
+
return {
|
|
61
|
+
success: false,
|
|
62
|
+
reason: err.message,
|
|
63
|
+
exception: err,
|
|
64
|
+
shouldRetry: true,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
55
67
|
}
|
|
56
68
|
}
|
|
57
69
|
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const Promise = require('bluebird');
|
|
4
3
|
const StepAction = require('./stepAction');
|
|
5
4
|
const wheelScript = require('./scripts/wheel');
|
|
6
5
|
const { codeSnippets } = require('../../commons/getSessionPlayerRequire');
|
|
7
6
|
|
|
8
7
|
class WheelStepAction extends StepAction {
|
|
9
|
-
performAction() {
|
|
8
|
+
async performAction() {
|
|
10
9
|
const step = this.step;
|
|
11
10
|
const context = this.context;
|
|
12
11
|
const events = step.events;
|
|
13
12
|
|
|
14
|
-
if (!events
|
|
15
|
-
return
|
|
13
|
+
if (!events?.length) {
|
|
14
|
+
return undefined;
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
const eventMessage = {
|
|
@@ -38,13 +37,8 @@ class WheelStepAction extends StepAction {
|
|
|
38
37
|
// values between 0 and -1 -_-.
|
|
39
38
|
const eventParam = this.driver.isEdge() ? JSON.stringify(eventMessage) : eventMessage;
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (result.value && result.value.state === 'success') {
|
|
44
|
-
return { success: true };
|
|
45
|
-
}
|
|
46
|
-
return { success: false };
|
|
47
|
-
});
|
|
40
|
+
const result = await this.driver.executeCodeAsync(wheelCode, timeout, eventParam);
|
|
41
|
+
return { success: result.value?.state === 'success' };
|
|
48
42
|
}
|
|
49
43
|
}
|
|
50
44
|
|
package/processHandler.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
const { promiseTimeout, promiseMap } = require('./utils');
|
|
6
6
|
const logger = require('./commons/logger').getLogger('process-handler');
|
|
7
7
|
|
|
8
|
+
/** @type {Array<() => PromiseLike<void>>} */
|
|
8
9
|
const exitHooks = [];
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -67,6 +68,7 @@ module.exports = function (onExit, _process = process) {
|
|
|
67
68
|
});
|
|
68
69
|
};
|
|
69
70
|
|
|
71
|
+
/** @param {() => PromiseLike<void>} hook */
|
|
70
72
|
module.exports.registerExitHook = function (hook) {
|
|
71
73
|
exitHooks.push(hook);
|
|
72
74
|
};
|
package/reports/junitReporter.js
CHANGED
|
@@ -52,7 +52,17 @@ function getPrintName(testResult) {
|
|
|
52
52
|
const testDataNumber = typeof testData.total === 'number' ? ` - ${testData.index} / ${testData.total} Data set` : '';
|
|
53
53
|
return `${testResult.name}${testDataNumber}`;
|
|
54
54
|
}
|
|
55
|
-
|
|
55
|
+
function getVisitedUrlsList(testResult) {
|
|
56
|
+
if (!testResult.visitedUrlsList) {
|
|
57
|
+
console.log('No URLs found:', 'Please contact our support team or remove the --urls flag from the CLI command');
|
|
58
|
+
}
|
|
59
|
+
const visitedUrls = testResult.visitedUrlsList || '';
|
|
60
|
+
return `${visitedUrls}`;
|
|
61
|
+
}
|
|
62
|
+
function getVisitedUrlsJson(testResult) {
|
|
63
|
+
const visitedUrls = testResult.visitedUrlsJson || '';
|
|
64
|
+
return `${visitedUrls}`;
|
|
65
|
+
}
|
|
56
66
|
async function report(editorUrl, testPlanResults, projectId, branch, classname, options) {
|
|
57
67
|
function createTestCaseObject(testResult) {
|
|
58
68
|
const testResultUrl = utils.getTestUrl(editorUrl, projectId, testResult.testId, testResult.resultId, branch);
|
|
@@ -79,7 +89,14 @@ async function report(editorUrl, testPlanResults, projectId, branch, classname,
|
|
|
79
89
|
if (isSkippedTest(testResult) && utils.isQuarantineAndNotRemoteRun(testResult, options) && featureAvailabilityService.isTestStatusEnabled) {
|
|
80
90
|
testResultObject.skipped = {};
|
|
81
91
|
}
|
|
92
|
+
|
|
82
93
|
testResultObject['system-out'] = testResultUrl;
|
|
94
|
+
|
|
95
|
+
if (options.urls) {
|
|
96
|
+
testResultObject['visited-urls-list'] = getVisitedUrlsList(testResult);
|
|
97
|
+
testResultObject['visited-urls-json'] = getVisitedUrlsJson(testResult);
|
|
98
|
+
}
|
|
99
|
+
|
|
83
100
|
return testResultObject;
|
|
84
101
|
}
|
|
85
102
|
|
package/runOptions.d.ts
CHANGED
|
@@ -281,6 +281,10 @@ interface RunnerOptions extends Partial<Omit<TunnelOptions, 'tunnelOnlyMode' | '
|
|
|
281
281
|
// #region intersections
|
|
282
282
|
intersections: { labels?: string[]; suiteNames?: string[]; suiteIds?: string[] };
|
|
283
283
|
// #endregion
|
|
284
|
+
|
|
285
|
+
// #region visited URLs
|
|
286
|
+
urls?: string;
|
|
287
|
+
// #endregion
|
|
284
288
|
}
|
|
285
289
|
|
|
286
290
|
type Options = |
|