@testim/testim-cli 3.259.0 → 3.260.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/testimDesiredCapabilitiesBuilder.js +20 -1
- package/npm-shrinkwrap.json +14 -14
- package/package.json +3 -2
- package/player/stepActions/baseJsStepAction.js +2 -2
- package/player/stepActions/cliConditionStepAction.js +1 -1
- package/player/stepActions/cliJsStepAction.js +1 -1
- package/player/stepActions/extensionOnlyStepAction.js +1 -1
- package/player/stepActions/extractTextStepAction.js +4 -7
- package/player/stepActions/hoverStepAction.js +0 -1
- package/player/stepActions/inputFileStepAction.js +0 -1
- package/player/stepActions/jsCodeStepAction.js +1 -2
- package/player/stepActions/jsConditionStepAction.js +1 -2
- package/player/stepActions/locateStepAction.js +17 -17
- package/player/stepActions/pixelValidationStepAction.js +2 -3
- package/player/stepActions/scrollStepAction.js +27 -19
- package/player/stepActions/selectOptionStepAction.js +2 -2
- package/player/stepActions/specialKeyStepAction.js +8 -10
- package/player/stepActions/stepAction.js +5 -5
- package/player/stepActions/stepActionRegistrar.js +0 -1
- package/player/stepActions/submitStepAction.js +1 -2
- package/player/stepActions/tdkHybridStepAction.js +7 -9
- package/player/stepActions/textStepAction.js +1 -0
- package/player/stepActions/textValidationStepAction.js +15 -18
- package/player/stepActions/wheelStepAction.js +9 -10
- package/runOptions.d.ts +7 -0
- package/runOptions.js +12 -0
- package/runOptionsUtils.js +11 -10
- package/workers/WorkerAppium.js +1 -1
|
@@ -41,6 +41,7 @@ const DEFAULT_CHROME_OPTIONS_ARGS = [
|
|
|
41
41
|
'--mute-audio',
|
|
42
42
|
// Skip first run wizards
|
|
43
43
|
'--no-first-run',
|
|
44
|
+
'--disable-back-forward-cache',
|
|
44
45
|
];
|
|
45
46
|
|
|
46
47
|
const getHash = (...str) => crypto.createHash('sha256').update(str.join('')).digest('hex');
|
|
@@ -603,7 +604,10 @@ function buildSeleniumOptions(browserOptions, testName, testRunConfig, gridInfo,
|
|
|
603
604
|
}
|
|
604
605
|
|
|
605
606
|
//testRunConfig not in used for now
|
|
606
|
-
function buildAppiumOptions({ projectType, gridInfo, testRunConfig, nativeApp }) {
|
|
607
|
+
function buildAppiumOptions({ projectType, gridInfo, testRunConfig, nativeApp, options }) {
|
|
608
|
+
const { deviceModel, osVersion, deviceUdid } = options;
|
|
609
|
+
const headspinSelector = {};
|
|
610
|
+
|
|
607
611
|
if (!nativeApp) {
|
|
608
612
|
throw Error('missing mobile app!');
|
|
609
613
|
}
|
|
@@ -637,6 +641,21 @@ function buildAppiumOptions({ projectType, gridInfo, testRunConfig, nativeApp })
|
|
|
637
641
|
default:
|
|
638
642
|
throw Error(`unsupported mobile project ${projectType}`);
|
|
639
643
|
}
|
|
644
|
+
if (deviceModel) {
|
|
645
|
+
headspinSelector.model = deviceModel;
|
|
646
|
+
}
|
|
647
|
+
if (osVersion) {
|
|
648
|
+
headspinSelector.os_version = osVersion;
|
|
649
|
+
}
|
|
650
|
+
if (deviceUdid) {
|
|
651
|
+
headspinSelector.device_id = deviceUdid;
|
|
652
|
+
delete headspinSelector.model;
|
|
653
|
+
delete headspinSelector.os_version;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
if (!_.isEmpty(headspinSelector)) {
|
|
657
|
+
appCaps['headspin:selector'] = headspinSelector;
|
|
658
|
+
}
|
|
640
659
|
return {
|
|
641
660
|
...connection,
|
|
642
661
|
desiredCapabilities: appCaps,
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testim/testim-cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.260.0",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@testim/testim-cli",
|
|
9
|
-
"version": "3.
|
|
9
|
+
"version": "3.260.0",
|
|
10
10
|
"license": "Proprietary",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@applitools/eyes-sdk-core": "13.6.23",
|
|
@@ -12773,9 +12773,9 @@
|
|
|
12773
12773
|
}
|
|
12774
12774
|
},
|
|
12775
12775
|
"node_modules/query-selector-shadow-dom": {
|
|
12776
|
-
"version": "1.0.
|
|
12777
|
-
"resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.
|
|
12778
|
-
"integrity": "sha512-
|
|
12776
|
+
"version": "1.0.1",
|
|
12777
|
+
"resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.1.tgz",
|
|
12778
|
+
"integrity": "sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw=="
|
|
12779
12779
|
},
|
|
12780
12780
|
"node_modules/querystring": {
|
|
12781
12781
|
"version": "0.2.0",
|
|
@@ -13026,9 +13026,9 @@
|
|
|
13026
13026
|
}
|
|
13027
13027
|
},
|
|
13028
13028
|
"node_modules/regenerator-runtime": {
|
|
13029
|
-
"version": "0.13.
|
|
13030
|
-
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.
|
|
13031
|
-
"integrity": "sha512-
|
|
13029
|
+
"version": "0.13.11",
|
|
13030
|
+
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
|
|
13031
|
+
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
|
|
13032
13032
|
},
|
|
13033
13033
|
"node_modules/regex-not": {
|
|
13034
13034
|
"version": "1.0.2",
|
|
@@ -26027,9 +26027,9 @@
|
|
|
26027
26027
|
"integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ=="
|
|
26028
26028
|
},
|
|
26029
26029
|
"query-selector-shadow-dom": {
|
|
26030
|
-
"version": "1.0.
|
|
26031
|
-
"resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.
|
|
26032
|
-
"integrity": "sha512-
|
|
26030
|
+
"version": "1.0.1",
|
|
26031
|
+
"resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.1.tgz",
|
|
26032
|
+
"integrity": "sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw=="
|
|
26033
26033
|
},
|
|
26034
26034
|
"querystring": {
|
|
26035
26035
|
"version": "0.2.0",
|
|
@@ -26235,9 +26235,9 @@
|
|
|
26235
26235
|
}
|
|
26236
26236
|
},
|
|
26237
26237
|
"regenerator-runtime": {
|
|
26238
|
-
"version": "0.13.
|
|
26239
|
-
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.
|
|
26240
|
-
"integrity": "sha512-
|
|
26238
|
+
"version": "0.13.11",
|
|
26239
|
+
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
|
|
26240
|
+
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
|
|
26241
26241
|
},
|
|
26242
26242
|
"regex-not": {
|
|
26243
26243
|
"version": "1.0.2",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testim/testim-cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.260.0",
|
|
4
4
|
"description": "Command line interface for running Testing on your CI",
|
|
5
5
|
"author": "Oren Rubin",
|
|
6
6
|
"contributors": [{
|
|
@@ -119,7 +119,8 @@
|
|
|
119
119
|
"prepare-version": "rm -rf ./deploy && mkdir -p deploy && gulp prepare-version-on-prem",
|
|
120
120
|
"make-onprem-deps": "cp ../../yarn.lock deploy && cd deploy && yarn install --production && bundle-deps",
|
|
121
121
|
"pack-onprem": "yarn prepare-version && yarn make-onprem-deps && cd deploy && npm pack && zip -r testim-cli.zip testim-cli-*.tgz",
|
|
122
|
-
"pack-serve": "yarn pack-onprem && http-server deploy/"
|
|
122
|
+
"pack-serve": "yarn pack-onprem && http-server deploy/",
|
|
123
|
+
"self-test": "cd /tmp && cross-env DEBUG=self-test BUILD_MAX_MEMORY=4096 node /home/circleci/testimio/apps/runner/scripts/selfTest.js"
|
|
123
124
|
},
|
|
124
125
|
"engines": {
|
|
125
126
|
"node": ">= 14.0.0"
|
|
@@ -45,7 +45,7 @@ class BaseJsStepAction extends StepAction {
|
|
|
45
45
|
|
|
46
46
|
executeGetStatus(transactionId) {
|
|
47
47
|
// TODO: Cleanup after dropping IE11/Edge support
|
|
48
|
-
/* eslint-disable prefer-arrow-callback, no-undef, unicorn/prefer-includes */
|
|
48
|
+
/* eslint-disable prefer-arrow-callback, no-undef, unicorn/prefer-includes, no-shadow */
|
|
49
49
|
return this.driver.executeJS(function (transactionId) {
|
|
50
50
|
const sessionItem = 'data-testim-' + transactionId;
|
|
51
51
|
try {
|
|
@@ -63,7 +63,7 @@ class BaseJsStepAction extends StepAction {
|
|
|
63
63
|
throw err;
|
|
64
64
|
}
|
|
65
65
|
}, transactionId);
|
|
66
|
-
/* eslint-enable prefer-arrow-callback, no-undef, unicorn/prefer-includes */
|
|
66
|
+
/* eslint-enable prefer-arrow-callback, no-undef, unicorn/prefer-includes, no-shadow */
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
constructJSFunParams(eventData) {
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
const StepAction = require('./stepAction');
|
|
4
|
-
const Promise = require('bluebird');
|
|
5
4
|
|
|
6
5
|
class ExtractTextStepAction extends StepAction {
|
|
7
|
-
|
|
8
6
|
performAction() {
|
|
9
7
|
const paramName = this.step.extractTextParamName;
|
|
10
8
|
|
|
@@ -12,13 +10,12 @@ class ExtractTextStepAction extends StepAction {
|
|
|
12
10
|
.then(extractedText => {
|
|
13
11
|
this.context.data.exports = this.context.data.exports || {};
|
|
14
12
|
this.context.data.exports[paramName] = extractedText;
|
|
15
|
-
return
|
|
13
|
+
return {
|
|
16
14
|
success: true,
|
|
17
|
-
data: this.context.data
|
|
18
|
-
}
|
|
15
|
+
data: this.context.data,
|
|
16
|
+
};
|
|
19
17
|
});
|
|
20
18
|
}
|
|
21
|
-
|
|
22
19
|
}
|
|
23
20
|
|
|
24
21
|
module.exports = ExtractTextStepAction;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const StepAction = require('./stepAction');
|
|
4
|
-
const _ = require('lodash');
|
|
5
4
|
const logger = require('../../commons/logger').getLogger('input-file-step-action');
|
|
6
5
|
const { codeSnippets, utils } = require('../../commons/getSessionPlayerRequire');
|
|
7
6
|
const { extractElementId, download } = require('../../utils');
|
|
@@ -15,26 +15,26 @@ const {
|
|
|
15
15
|
const DEFAULT_VISIBILITY_RESULT = { opacity: 1, clientRects: {} };
|
|
16
16
|
|
|
17
17
|
function createUtils(driver) {
|
|
18
|
-
return
|
|
19
|
-
|
|
18
|
+
return {
|
|
19
|
+
getFrameIdByTestimFrameId() { },
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
setElementResultDataOnContext(target) {
|
|
22
22
|
return driver.getElement(target.locatedElement)
|
|
23
23
|
.then(seleniumResponse => {
|
|
24
24
|
target.seleniumElement = seleniumResponse.value;
|
|
25
25
|
});
|
|
26
|
-
}
|
|
26
|
+
},
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
getElementRectangle(target) {
|
|
29
29
|
return driver.getElementRect(target);
|
|
30
|
-
}
|
|
30
|
+
},
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
getOffsets(frameHandler) {
|
|
33
33
|
return Promise.resolve([frameHandler.frameOffset || {}]);
|
|
34
|
-
}
|
|
34
|
+
},
|
|
35
35
|
|
|
36
36
|
/** @type {typeof import('clickim/src/background/stepActions/locateStepAction').LocateStepAction['htmlStringToDom']} */
|
|
37
|
-
|
|
37
|
+
htmlStringToDom(htmlString, url, nonBodyElements, bodyTagName, setDomTimeout = true) {
|
|
38
38
|
const virtualConsole = new VirtualConsole();
|
|
39
39
|
const jsdom = new JSDOM(htmlString, {
|
|
40
40
|
virtualConsole,
|
|
@@ -51,9 +51,9 @@ function createUtils(driver) {
|
|
|
51
51
|
}
|
|
52
52
|
window.document.TESTIM_URL = url;
|
|
53
53
|
return window.document;
|
|
54
|
-
}
|
|
54
|
+
},
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
shouldUseNativeVisibilityCheck(locateStep, driver, visibilityUtils, positionUtils) {
|
|
57
57
|
if (locateStep.opacity === 0) {
|
|
58
58
|
return false;
|
|
59
59
|
}
|
|
@@ -73,10 +73,10 @@ function createUtils(driver) {
|
|
|
73
73
|
return featureFlags.flags.useIEWebdriverVisibilityChecks.isEnabled();
|
|
74
74
|
}
|
|
75
75
|
return true;
|
|
76
|
-
}
|
|
76
|
+
},
|
|
77
77
|
|
|
78
78
|
/** @type {typeof import('clickim/src/background/stepActions/locateStepAction').LocateStepAction['isVisible']} */
|
|
79
|
-
|
|
79
|
+
isVisible(target, targetElement, rect, locateStep, frameHandler, allOffsets, dom) {
|
|
80
80
|
const skipVisibilityCheck =
|
|
81
81
|
featureFlags.flags.disableEdgeVisibilityChecks.isEnabled() && driver.isEdge();
|
|
82
82
|
|
|
@@ -86,7 +86,7 @@ function createUtils(driver) {
|
|
|
86
86
|
return driver.isVisible(target.seleniumElement).catch(() => { }).then(() => true);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
const useNativeVisibilityCheck =
|
|
89
|
+
const useNativeVisibilityCheck = this.shouldUseNativeVisibilityCheck(locateStep, driver, visibilityUtils, positionUtils);
|
|
90
90
|
if (useNativeVisibilityCheck) {
|
|
91
91
|
return driver.isVisible(target.seleniumElement);
|
|
92
92
|
}
|
|
@@ -120,12 +120,12 @@ function createUtils(driver) {
|
|
|
120
120
|
return driver.isVisible(target.seleniumElement)
|
|
121
121
|
.catch(() => { })
|
|
122
122
|
.then(handler);
|
|
123
|
-
}
|
|
123
|
+
},
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
scrollToElement(frameHandler, locatedElement) {
|
|
126
126
|
const code = codeSnippets.scrollToElement;
|
|
127
127
|
return driver.execute(code(locatedElement));
|
|
128
|
-
}
|
|
128
|
+
},
|
|
129
129
|
};
|
|
130
130
|
}
|
|
131
131
|
|
|
@@ -5,13 +5,12 @@ const StepAction = require('./stepAction');
|
|
|
5
5
|
const { eyeSdkService } = require('../utils/eyeSdkService');
|
|
6
6
|
const logger = require('../../commons/logger').getLogger('pixel-validation-step-action');
|
|
7
7
|
|
|
8
|
-
|
|
9
8
|
class PixelValidationStepAction extends StepAction {
|
|
10
9
|
async performAction() {
|
|
11
10
|
const { shouldUseVisualGrid, applitoolsSdkConfig: config, testResultId } = this.context;
|
|
12
11
|
this.runContext = this.context.getRunContext(undefined);
|
|
13
|
-
const finalParams =
|
|
14
|
-
const batchId =
|
|
12
|
+
const finalParams = this.runContext.incomingParams?.final || {};
|
|
13
|
+
const batchId = config.batch?.id || testResultId;
|
|
15
14
|
const eyeManager = await eyeSdkService.getManager(shouldUseVisualGrid, this.context.config.applitoolsConcurrency || 5, batchId, this.runContext.applitoolsIntegrationData);
|
|
16
15
|
const targetElementData = this.getTarget() || {};
|
|
17
16
|
let result;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
2
3
|
const StepAction = require('./stepAction');
|
|
3
4
|
const { codeSnippets, commonConstants } = require('../../commons/getSessionPlayerRequire');
|
|
4
5
|
const scroll = require('./scripts/scroll');
|
|
6
|
+
|
|
5
7
|
const constants = commonConstants.stepResult;
|
|
6
8
|
|
|
7
9
|
class ScrollStepAction extends StepAction {
|
|
8
|
-
|
|
9
|
-
getFailureString(step, expectedX, expectedY, actualX, actualY){
|
|
10
|
+
getFailureString(step, expectedX, expectedY, actualX, actualY) {
|
|
10
11
|
if (!step.isScrollToElement) {
|
|
11
12
|
return `Scrolling limit reached. Expected:(y: ${expectedY}, x: ${expectedX}); Actual:(y:${actualY}, x: ${actualX})`;
|
|
12
13
|
}
|
|
13
|
-
let failureMessage =
|
|
14
|
+
let failureMessage = 'Scrolling limit reached';
|
|
14
15
|
if (step.shouldScrollTop) {
|
|
15
16
|
failureMessage += `. Expected top margin: ${expectedY}, actual: ${actualY}`;
|
|
16
17
|
}
|
|
@@ -38,33 +39,41 @@ class ScrollStepAction extends StepAction {
|
|
|
38
39
|
return scroll.apply(null, arguments)
|
|
39
40
|
`;
|
|
40
41
|
|
|
41
|
-
return this.driver
|
|
42
|
-
.
|
|
43
|
-
|
|
42
|
+
return this.driver
|
|
43
|
+
.executeJSWithArray(scrollCode, [
|
|
44
|
+
elementToScrollOn,
|
|
45
|
+
elementToScrollTo,
|
|
46
|
+
Boolean(step.isScrollToElement),
|
|
47
|
+
Boolean(step.isDynamicScroll),
|
|
48
|
+
expectedX,
|
|
49
|
+
expectedY,
|
|
50
|
+
step.shouldScrollLeft,
|
|
51
|
+
step.shouldScrollTop,
|
|
52
|
+
])
|
|
53
|
+
.then(res => {
|
|
54
|
+
if (!res || !res.value) {
|
|
44
55
|
return {
|
|
45
56
|
errorType: constants.SCROLL_ACTION_FAILURE,
|
|
46
57
|
success: false,
|
|
47
|
-
}
|
|
58
|
+
};
|
|
48
59
|
}
|
|
49
60
|
|
|
50
|
-
const {success, actualX, actualY} = res.value;
|
|
61
|
+
const { success, actualX, actualY } = res.value;
|
|
51
62
|
|
|
52
|
-
if(success) {
|
|
53
|
-
return {success: true};
|
|
63
|
+
if (success) {
|
|
64
|
+
return { success: true };
|
|
54
65
|
}
|
|
55
66
|
|
|
56
67
|
return {
|
|
57
68
|
errorType: constants.SCROLL_ACTION_FAILURE,
|
|
58
69
|
success: false,
|
|
59
|
-
resultInfo: {error: this.getFailureString(step, expectedX, expectedY, actualX, actualY)}
|
|
70
|
+
resultInfo: { error: this.getFailureString(step, expectedX, expectedY, actualX, actualY) },
|
|
60
71
|
};
|
|
61
72
|
})
|
|
62
|
-
.catch(() => {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
};
|
|
67
|
-
});
|
|
73
|
+
.catch(() => ({
|
|
74
|
+
errorType: constants.SCROLL_ACTION_FAILURE,
|
|
75
|
+
success: false,
|
|
76
|
+
}));
|
|
68
77
|
}
|
|
69
78
|
|
|
70
79
|
scrollOnDocument(step, elementToScrollTo) {
|
|
@@ -84,7 +93,6 @@ class ScrollStepAction extends StepAction {
|
|
|
84
93
|
this.scrollOnDocument(step, elementToScrollTo) :
|
|
85
94
|
this.scrollOnElement(step, elementToScrollTo);
|
|
86
95
|
}
|
|
87
|
-
|
|
88
96
|
}
|
|
89
97
|
|
|
90
98
|
module.exports = ScrollStepAction;
|
|
@@ -15,7 +15,7 @@ class SelectOptionStepAction extends StepAction {
|
|
|
15
15
|
|
|
16
16
|
const browserMajor = browserAndOS.browserMajor;
|
|
17
17
|
const isSafari = this.driver.isSafari();
|
|
18
|
-
const isShadowed = Boolean(this.step.element
|
|
18
|
+
const isShadowed = Boolean(this.step.element?.isShadowed);
|
|
19
19
|
|
|
20
20
|
// TODO: Remove the special handling for safari < 12 after we upgrade our grid to safari 13.
|
|
21
21
|
// force use js code when element is shadow dom
|
|
@@ -40,7 +40,7 @@ class SelectOptionStepAction extends StepAction {
|
|
|
40
40
|
`;
|
|
41
41
|
|
|
42
42
|
const result = await this.driver.executeJSWithArray(selectOptionCode, [locatedElement, safariSelectOptionDispatchEventOnSelectElement]);
|
|
43
|
-
if (result.value
|
|
43
|
+
if (result.value?.success) {
|
|
44
44
|
return { success: true };
|
|
45
45
|
}
|
|
46
46
|
return { success: false };
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
const { extractElementId } = require('../../utils');
|
|
4
4
|
const StepAction = require('./stepAction');
|
|
5
5
|
const Promise = require('bluebird');
|
|
6
|
+
|
|
6
7
|
const keyMap = {
|
|
7
|
-
8: '\uE008',
|
|
8
|
-
9: '\uE004',
|
|
8
|
+
8: '\uE008', // (Backspace)
|
|
9
|
+
9: '\uE004', // (tab)
|
|
9
10
|
13: '\uE007', // (enter)
|
|
10
11
|
27: '\uE00C', // (esc)
|
|
11
12
|
33: '\uE00E', // (page up)
|
|
@@ -24,23 +25,22 @@ const keyMap = {
|
|
|
24
25
|
120: '\uE039', // (f9)
|
|
25
26
|
121: '\uE03A', // (f10)
|
|
26
27
|
122: '\uE03B', // (f11)
|
|
27
|
-
123: '\uE03C' // (f12)
|
|
28
|
+
123: '\uE03C', // (f12)
|
|
28
29
|
};
|
|
29
30
|
|
|
30
31
|
class SpecialKeyStepAction extends StepAction {
|
|
31
|
-
|
|
32
32
|
setWithValueApi(keys) {
|
|
33
33
|
const target = this.getTarget();
|
|
34
|
-
if (target
|
|
34
|
+
if (target?.seleniumElement) {
|
|
35
35
|
return this.driver.elementIdValue(extractElementId(target.seleniumElement), keys);
|
|
36
36
|
}
|
|
37
|
-
return Promise.reject(new Error(
|
|
37
|
+
return Promise.reject(new Error('missing selenium element'));
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
performAction() {
|
|
41
41
|
const keys = [];
|
|
42
42
|
const keyCode = this.step.events[0].eventData.keyCode;
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
if (keyCode >= 32 && keyCode <= 127) {
|
|
45
45
|
keys.push(String.fromCharCode(keyCode));
|
|
46
46
|
} else {
|
|
@@ -48,8 +48,6 @@ class SpecialKeyStepAction extends StepAction {
|
|
|
48
48
|
}
|
|
49
49
|
return this.setWithValueApi(keys);
|
|
50
50
|
}
|
|
51
|
-
|
|
52
51
|
}
|
|
53
52
|
|
|
54
53
|
module.exports = SpecialKeyStepAction;
|
|
55
|
-
|
|
@@ -45,11 +45,11 @@ class StepAction {
|
|
|
45
45
|
/** @type {ClickimStepAction['execute']} */
|
|
46
46
|
execute(stepActionFactory, step) {
|
|
47
47
|
return Promise.resolve(this.performAction(stepActionFactory, step))
|
|
48
|
-
.then(res =>
|
|
48
|
+
.then(res => Object.assign({ success: true }, res))
|
|
49
49
|
.catch(err => {
|
|
50
|
-
const errorMsg =
|
|
51
|
-
const displayMsg =
|
|
52
|
-
return
|
|
50
|
+
const errorMsg = err?.message || err?.seleniumStack?.message;
|
|
51
|
+
const displayMsg = err?.displayMessage;
|
|
52
|
+
return {
|
|
53
53
|
success: false,
|
|
54
54
|
reason: errorMsg,
|
|
55
55
|
exception: err,
|
|
@@ -60,7 +60,7 @@ class StepAction {
|
|
|
60
60
|
// expects resultInfo.error or resultInfo.reason
|
|
61
61
|
error: displayMsg || errorMsg,
|
|
62
62
|
},
|
|
63
|
-
}
|
|
63
|
+
};
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
66
|
}
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const StepAction = require('./stepAction');
|
|
4
|
-
|
|
5
|
-
const { execute } = require('../../stepPlayers/hybridStepPlayback')
|
|
4
|
+
const { execute } = require('../../stepPlayers/hybridStepPlayback');
|
|
6
5
|
|
|
7
6
|
class TdkHybridStepAction extends StepAction {
|
|
8
|
-
|
|
9
7
|
async performAction() {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
return await execute(
|
|
9
|
+
this.step,
|
|
10
|
+
this.context,
|
|
11
|
+
this.driver,
|
|
12
|
+
this.stepActionUtils.testimServicesApi.authenticationManager.getLoggedUserInfo(),
|
|
13
|
+
this.frameHandler.frameManager
|
|
16
14
|
);
|
|
17
15
|
}
|
|
18
16
|
}
|
|
@@ -10,6 +10,7 @@ const { extractElementId, delay } = require('../../utils');
|
|
|
10
10
|
|
|
11
11
|
const constants = sessionPlayer.commonConstants.stepResult;
|
|
12
12
|
const setTextDraftJs = codeSnippets?.setTextDraftJs;
|
|
13
|
+
|
|
13
14
|
class TextStepAction extends StepAction {
|
|
14
15
|
setValueNative() {
|
|
15
16
|
const context = this.context;
|
|
@@ -1,27 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
'use strict';
|
|
3
2
|
|
|
3
|
+
const Promise = require('bluebird');
|
|
4
4
|
const sessionPlayer = require('../../commons/getSessionPlayerRequire');
|
|
5
|
-
|
|
6
5
|
const StepAction = require('./stepAction');
|
|
6
|
+
|
|
7
7
|
const constants = sessionPlayer.commonConstants.stepResult;
|
|
8
8
|
const paramEvaluator = sessionPlayer.stepParamExpressionEvaluator;
|
|
9
9
|
const utils = sessionPlayer.utils;
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
const Promise = require('bluebird');
|
|
13
|
-
|
|
14
11
|
class TextValidationStepAction extends StepAction {
|
|
15
12
|
performAction(stepActionFactory) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
const step = this.step;
|
|
14
|
+
const context = this.context;
|
|
15
|
+
const target = this.getTarget();
|
|
16
|
+
const frameHandler = this.frameHandler;
|
|
17
|
+
|
|
21
18
|
|
|
22
19
|
return new Promise(resolve => {
|
|
23
|
-
|
|
24
|
-
resolve({ errorType: constants.TEXT_COMPARE_FAILURE, resultInfo
|
|
20
|
+
const onFail = resultInfo => {
|
|
21
|
+
resolve({ errorType: constants.TEXT_COMPARE_FAILURE, resultInfo, success: false });
|
|
25
22
|
};
|
|
26
23
|
this.stepActionUtils.extractTargetText(target)
|
|
27
24
|
.then(text => {
|
|
@@ -29,13 +26,13 @@ class TextValidationStepAction extends StepAction {
|
|
|
29
26
|
const expected = paramEvaluator.computeExpression(step.expression2, context, this.exportsGlobal, this.exportsTest);
|
|
30
27
|
return {
|
|
31
28
|
actual: text,
|
|
32
|
-
expected: expected.evaluatedText
|
|
29
|
+
expected: expected.evaluatedText,
|
|
33
30
|
};
|
|
34
31
|
}
|
|
35
32
|
return stepActionFactory.executeStep(step.expression2, context, frameHandler, this.exportsGlobal, this.locateElementPlayer, this.exportsTest)
|
|
36
33
|
.then(res => ({
|
|
37
34
|
actual: text,
|
|
38
|
-
expected: res.evaluatedText
|
|
35
|
+
expected: res.evaluatedText,
|
|
39
36
|
}));
|
|
40
37
|
})
|
|
41
38
|
.then(({ actual, expected }) => {
|
|
@@ -43,16 +40,16 @@ class TextValidationStepAction extends StepAction {
|
|
|
43
40
|
const compareResult = utils.compareOrMatch(expected, actual);
|
|
44
41
|
return compareResult ?
|
|
45
42
|
resolve({ success: true }) :
|
|
46
|
-
onFail({ expected: String(expected), actual
|
|
43
|
+
onFail({ expected: String(expected), actual });
|
|
47
44
|
} catch (err) {
|
|
48
|
-
return onFail({ expected: expected.toString(), actual
|
|
45
|
+
return onFail({ expected: expected.toString(), actual });
|
|
49
46
|
}
|
|
50
47
|
})
|
|
51
48
|
.catch(err => resolve({
|
|
52
49
|
success: false,
|
|
53
50
|
reason: err.message,
|
|
54
51
|
exception: err,
|
|
55
|
-
shouldRetry: true
|
|
52
|
+
shouldRetry: true,
|
|
56
53
|
}));
|
|
57
54
|
});
|
|
58
55
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
2
3
|
const Promise = require('bluebird');
|
|
3
4
|
const StepAction = require('./stepAction');
|
|
4
5
|
const wheelScript = require('./scripts/wheel');
|
|
5
6
|
const { codeSnippets } = require('../../commons/getSessionPlayerRequire');
|
|
6
7
|
|
|
7
8
|
class WheelStepAction extends StepAction {
|
|
8
|
-
|
|
9
9
|
performAction() {
|
|
10
10
|
const step = this.step;
|
|
11
11
|
const context = this.context;
|
|
@@ -16,12 +16,12 @@ class WheelStepAction extends StepAction {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
const eventMessage = {
|
|
19
|
-
events
|
|
19
|
+
events,
|
|
20
20
|
eventData: {
|
|
21
21
|
modifiers: step.modifiers,
|
|
22
|
-
button: step.button
|
|
22
|
+
button: step.button,
|
|
23
23
|
},
|
|
24
|
-
locatedElement: this.getTarget().locatedElement
|
|
24
|
+
locatedElement: this.getTarget().locatedElement,
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
const timeout = context.data.timeToPlayStep + 3000;
|
|
@@ -29,7 +29,7 @@ class WheelStepAction extends StepAction {
|
|
|
29
29
|
const wheelCode = `
|
|
30
30
|
var getLocatedElement = ${codeSnippets.getLocatedElementCode};
|
|
31
31
|
var wheel = ${wheelScript.toString()};
|
|
32
|
-
var eventData = ${this.driver.isEdge() ?
|
|
32
|
+
var eventData = ${this.driver.isEdge() ? 'JSON.parse(arguments[0])' : 'arguments[0]'};
|
|
33
33
|
var done = arguments[1];
|
|
34
34
|
return wheel.call(null, eventData, done);
|
|
35
35
|
`;
|
|
@@ -40,13 +40,12 @@ class WheelStepAction extends StepAction {
|
|
|
40
40
|
|
|
41
41
|
return this.driver.executeCodeAsync(wheelCode, timeout, eventParam)
|
|
42
42
|
.then(result => {
|
|
43
|
-
if (result.value && result.value.state ===
|
|
44
|
-
return
|
|
43
|
+
if (result.value && result.value.state === 'success') {
|
|
44
|
+
return { success: true };
|
|
45
45
|
}
|
|
46
|
-
return
|
|
46
|
+
return { success: false };
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
|
-
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
module.exports = WheelStepAction;
|
package/runOptions.d.ts
CHANGED
|
@@ -108,6 +108,13 @@ interface RunnerOptions extends Partial<Omit<TunnelOptions, 'tunnelOnlyMode' | '
|
|
|
108
108
|
retentionDays?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
|
|
109
109
|
retries?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20;
|
|
110
110
|
|
|
111
|
+
//# region mobile flags
|
|
112
|
+
deviceModel: string;
|
|
113
|
+
deviceUdid: string;
|
|
114
|
+
osVersion: string;
|
|
115
|
+
// #endregion
|
|
116
|
+
|
|
117
|
+
|
|
111
118
|
// #region Data set based on values from server
|
|
112
119
|
company: {
|
|
113
120
|
companyId: string;
|
package/runOptions.js
CHANGED
|
@@ -210,6 +210,10 @@ program
|
|
|
210
210
|
.option('--set-retention [retention-in-days]', 'set the number of days for results retention')
|
|
211
211
|
.option('--user [user-id]', 'user ID for local Testim-CLI')
|
|
212
212
|
.option('--pass-zero-tests', 'don\'t fail the run if no tests were found')
|
|
213
|
+
//Mobile options
|
|
214
|
+
.option('--device-model [device-model]', 'The device model to use, iPhone 12, Nexus 5X, SM-G900P etc....')
|
|
215
|
+
.option('--device-udid [device-udid]', 'the device unique id')
|
|
216
|
+
.option('--os-version [os-version]', 'The operating system version number')
|
|
213
217
|
|
|
214
218
|
.option('-str --suppress-tms-reporting [suppress-tms-reporting]', 'disable test management reporting', false)
|
|
215
219
|
.option('-tsr --tms-suppress-reporting [tms-suppress-reporting]', 'disable test management reporting', false)
|
|
@@ -1032,6 +1036,10 @@ module.exports = {
|
|
|
1032
1036
|
program.turboMode = true;
|
|
1033
1037
|
}
|
|
1034
1038
|
|
|
1039
|
+
if (program.deviceUdid && (program.deviceModel || program.osVersion)) {
|
|
1040
|
+
throw new ArgError('It is not possible to use --osVersion or --deviceModel with --device-udid. device-udid is unique and cannot be combined with another flag');
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1035
1043
|
if (program.lightweightMode) {
|
|
1036
1044
|
try {
|
|
1037
1045
|
const DEFAULTS = {
|
|
@@ -1148,6 +1156,10 @@ module.exports = {
|
|
|
1148
1156
|
passZeroTests: Boolean(program.passZeroTests),
|
|
1149
1157
|
runQuarantinedTests: Boolean(program.runQuarantinedTests),
|
|
1150
1158
|
|
|
1159
|
+
deviceModel: program.deviceModel,
|
|
1160
|
+
deviceUdid: program.deviceUdid,
|
|
1161
|
+
osVersion: program.osVersion,
|
|
1162
|
+
|
|
1151
1163
|
// Extension
|
|
1152
1164
|
ext: program.ext,
|
|
1153
1165
|
extensionLocation: [program.extensionPath || extHeadlessUrl].flat(),
|
package/runOptionsUtils.js
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
'use strict';
|
|
4
|
+
|
|
4
5
|
const config = require('./commons/config');
|
|
5
6
|
|
|
6
7
|
module.exports = {
|
|
7
8
|
getExtensionsUrl,
|
|
8
9
|
getResolvedExtensionUrl,
|
|
9
|
-
getPlayerUrl
|
|
10
|
-
}
|
|
10
|
+
getPlayerUrl,
|
|
11
|
+
};
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
*
|
|
14
15
|
* @param {Readonly<import("commander").CommanderStatic>} program
|
|
15
16
|
*/
|
|
16
17
|
function getExtensionsUrl(program, useCanonicalURL) {
|
|
17
|
-
const zipFileSuffix = program.canary ?
|
|
18
|
+
const zipFileSuffix = program.canary ? '-master.zip' : '.zip';
|
|
18
19
|
let firefox;
|
|
19
20
|
let chrome;
|
|
20
21
|
if (!useCanonicalURL) {
|
|
@@ -40,11 +41,11 @@ function getResolvedExtensionUrl(program) {
|
|
|
40
41
|
|
|
41
42
|
if (program.browser === 'firefox') {
|
|
42
43
|
return firefox;
|
|
43
|
-
} else if(program.browser === 'chrome') {
|
|
44
|
-
return chrome
|
|
45
|
-
} else {
|
|
46
|
-
return [chrome, firefox];
|
|
47
44
|
}
|
|
45
|
+
if (program.browser === 'chrome') {
|
|
46
|
+
return chrome;
|
|
47
|
+
}
|
|
48
|
+
return [chrome, firefox];
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
/**
|
|
@@ -52,8 +53,8 @@ function getResolvedExtensionUrl(program) {
|
|
|
52
53
|
* @param {Readonly<import("commander").CommanderStatic>} program
|
|
53
54
|
*/
|
|
54
55
|
function getPlayerUrl(program) {
|
|
55
|
-
|
|
56
|
-
const playerUrl = program.canary ? playerUrlPrefix
|
|
56
|
+
const playerUrlPrefix = `${config.BLOB_URL}/extension/sessionPlayer`;
|
|
57
|
+
const playerUrl = program.canary ? `${playerUrlPrefix}-master` : playerUrlPrefix;
|
|
57
58
|
|
|
58
59
|
return playerUrl;
|
|
59
60
|
}
|
package/workers/WorkerAppium.js
CHANGED
|
@@ -30,7 +30,7 @@ class WorkerAppium extends BaseWorker {
|
|
|
30
30
|
const { driver } = appiumTestPlayer;
|
|
31
31
|
const nativeApp = testRunHandler.getNativeAppData();
|
|
32
32
|
const projectType = this.options.projectData.type;
|
|
33
|
-
const capabilities = desiredCapabilitiesBuilder.buildAppiumOptions({ projectType, gridInfo, testRunConfig: this.testRunConfig, nativeApp });
|
|
33
|
+
const capabilities = desiredCapabilitiesBuilder.buildAppiumOptions({ projectType, gridInfo, testRunConfig: this.testRunConfig, nativeApp, options: this.options });
|
|
34
34
|
try {
|
|
35
35
|
//we assume the application is installed on the device. (all headspin allocated devices)
|
|
36
36
|
const activeSession = await driver.remote(capabilities);
|