@testim/testim-cli 3.254.0 → 3.256.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/agent/routers/cliJsCode/service.js +11 -8
- package/agent/routers/codim/router.test.js +9 -12
- package/agent/routers/codim/service.js +16 -16
- package/agent/routers/playground/service.js +5 -7
- package/cli.js +6 -6
- package/cliAgentMode.js +11 -10
- package/codim/codim-cli.js +14 -9
- package/commons/featureFlags.js +29 -7
- package/commons/httpRequest.js +5 -1
- package/commons/httpRequestCounters.js +21 -10
- package/commons/initializeUserWithAuth.js +7 -4
- package/commons/lazyRequire.js +4 -3
- package/commons/preloadTests.js +6 -3
- package/commons/prepareRunner.js +7 -5
- package/commons/prepareRunnerAndTestimStartUtils.js +51 -45
- package/commons/runnerFileCache.js +10 -2
- package/commons/testimServicesApi.js +36 -5
- package/commons/testimTunnel.test.js +2 -1
- package/coverage/SummaryToObjectReport.js +0 -1
- package/coverage/jsCoverage.js +12 -10
- package/inputFileUtils.js +11 -9
- package/npm-shrinkwrap.json +214 -471
- package/package.json +4 -3
- package/player/services/tabService.js +15 -1
- package/player/stepActions/apiStepAction.js +49 -43
- package/player/stepActions/baseCliJsStepAction.js +19 -14
- package/player/stepActions/baseJsStepAction.js +9 -8
- package/player/stepActions/dropFileStepAction.js +1 -3
- package/player/stepActions/inputFileStepAction.js +10 -8
- package/player/stepActions/locateStepAction.js +2 -0
- package/player/stepActions/mouseStepAction.js +21 -22
- package/player/stepActions/nodePackageStepAction.js +34 -35
- package/player/stepActions/stepAction.js +1 -0
- package/player/utils/imageCaptureUtils.js +133 -172
- package/player/utils/screenshotUtils.js +16 -13
- package/player/utils/windowUtils.js +20 -8
- package/player/webdriver.js +25 -22
- package/processHandler.js +4 -0
- package/reports/junitReporter.js +6 -7
- package/reports/reporter.js +34 -39
- package/runOptions.d.ts +286 -0
- package/runOptions.js +60 -45
- package/runner.js +64 -24
- package/runners/ParallelWorkerManager.js +12 -12
- package/runners/TestPlanRunner.js +14 -15
- package/runners/buildCodeTests.js +1 -0
- package/runners/runnerUtils.js +11 -2
- package/services/branchService.js +11 -5
- package/services/gridService.js +36 -40
- package/services/localRCASaver.js +4 -0
- package/testRunStatus.js +8 -5
- package/utils/argsUtils.js +86 -0
- package/utils/argsUtils.test.js +32 -0
- package/utils/fsUtils.js +154 -0
- package/utils/index.js +10 -161
- package/utils/promiseUtils.js +13 -2
- package/utils/stringUtils.js +4 -2
- package/utils/stringUtils.test.js +22 -0
- package/utils/timeUtils.js +25 -0
- package/utils/utils.test.js +0 -41
- package/workers/WorkerExtension.js +6 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testim/testim-cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.256.0",
|
|
4
4
|
"description": "Command line interface for running Testing on your CI",
|
|
5
5
|
"author": "Oren Rubin",
|
|
6
6
|
"contributors": [{
|
|
@@ -83,6 +83,7 @@
|
|
|
83
83
|
"npm": "8.19.2",
|
|
84
84
|
"object-hash": "3.0.0",
|
|
85
85
|
"ora": "5.4.1",
|
|
86
|
+
"p-limit": "4.0.0",
|
|
86
87
|
"p-retry": "4.6.2",
|
|
87
88
|
"pako": "1.0.11",
|
|
88
89
|
"portfinder": "1.0.28",
|
|
@@ -111,8 +112,8 @@
|
|
|
111
112
|
"testim": "cli.js"
|
|
112
113
|
},
|
|
113
114
|
"scripts": {
|
|
114
|
-
"test": "
|
|
115
|
-
"test:
|
|
115
|
+
"test": "yarn test:pattern './src/**/*.test.js'",
|
|
116
|
+
"test:pattern": "IS_UNIT_TEST=1 ../../node_modules/mocha/bin/_mocha --timeout 2000 --exit --recursive --exclude ./src/codim/template.js/tests/examples/**/*.test.js --watch-files 'src'",
|
|
116
117
|
"test:cov": "nyc --reporter=lcov --reporter=text yarn test",
|
|
117
118
|
"upload-bundle-s3": "ts-node-transpile-only scripts/upload.js",
|
|
118
119
|
"prepare-version": "rm -rf ./deploy && mkdir -p deploy && gulp prepare-version-on-prem",
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
'use strict';
|
|
2
4
|
|
|
3
5
|
const sessionPlayer = require('../../commons/getSessionPlayerRequire');
|
|
@@ -36,8 +38,20 @@ const logger = require('../../commons/logger').getLogger('tab-service');
|
|
|
36
38
|
* from: any;
|
|
37
39
|
* isMain: any;
|
|
38
40
|
* openerStepId: any;
|
|
41
|
+
* openerOriginalStepId?: any;
|
|
42
|
+
* isClosed?: boolean;
|
|
43
|
+
* currentUrl?: any;
|
|
44
|
+
* lastUpdatedUrl?: any;
|
|
39
45
|
* }} TabInfo
|
|
40
46
|
*/
|
|
47
|
+
/**
|
|
48
|
+
* @typedef {{
|
|
49
|
+
* tabCount: number;
|
|
50
|
+
* tabInfos: Record<string, TabInfo>;
|
|
51
|
+
* lastActiveTabInfo?: any;
|
|
52
|
+
* currentTab?: any;
|
|
53
|
+
* }} SessionTab
|
|
54
|
+
*/
|
|
41
55
|
|
|
42
56
|
class TabService {
|
|
43
57
|
/** @param {import('../webdriver')} driver */
|
|
@@ -45,7 +59,7 @@ class TabService {
|
|
|
45
59
|
this.driver = driver;
|
|
46
60
|
/** @type {Record<string, TabUtil>} */
|
|
47
61
|
this._utils = {};
|
|
48
|
-
/** @type {Record<string,
|
|
62
|
+
/** @type {Record<string, SessionTab>} */
|
|
49
63
|
this.sessionTabs = {};
|
|
50
64
|
/** @type {Record<string, string>} */
|
|
51
65
|
this.pendingTabs = {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
'use strict';
|
|
2
4
|
|
|
3
|
-
const Promise = require('bluebird');
|
|
4
5
|
const StepAction = require('./stepAction');
|
|
5
6
|
|
|
6
7
|
const sessionPlayer = require('../../commons/getSessionPlayerRequire');
|
|
@@ -9,23 +10,28 @@ const constants = sessionPlayer.commonConstants.stepResult;
|
|
|
9
10
|
const apiCall = sessionPlayer.apiCall;
|
|
10
11
|
|
|
11
12
|
class ApiStepAction extends StepAction {
|
|
12
|
-
runApiInAut(eventData) {
|
|
13
|
+
async runApiInAut(eventData) {
|
|
13
14
|
eventData.withCredentials = true;
|
|
14
15
|
const timeout = this.context.data.timeToPlayStep + 3000;
|
|
15
|
-
|
|
16
|
-
.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
try {
|
|
17
|
+
const autRes = await this.driver.executeCodeAsync(apiCall, timeout, eventData);
|
|
18
|
+
const resp = autRes?.value;
|
|
19
|
+
return resp || {};
|
|
20
|
+
} catch (err) {
|
|
21
|
+
if (err?.message?.includes('Javascript execution context no longer exists')) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
'The page refreshed or changed while executing this step. Please consider unchecking "Send via web page" if this is expected.');
|
|
24
|
+
}
|
|
25
|
+
throw err;
|
|
26
|
+
}
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
runApiInBg(eventData) {
|
|
25
|
-
return new Promise(resolve => apiCall(eventData, resolve));
|
|
30
|
+
return new Promise(resolve => { apiCall(eventData, resolve); });
|
|
26
31
|
}
|
|
27
32
|
|
|
28
|
-
performAction() {
|
|
33
|
+
async performAction() {
|
|
34
|
+
/** @type {import('clickim/src/common/models/apiStep').ApiStep} */
|
|
29
35
|
const step = this.step;
|
|
30
36
|
const context = this.context;
|
|
31
37
|
|
|
@@ -41,44 +47,44 @@ class ApiStepAction extends StepAction {
|
|
|
41
47
|
fileUrls: context.fileUrls,
|
|
42
48
|
};
|
|
43
49
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
resultInfo,
|
|
59
|
-
shouldRetry: false,
|
|
60
|
-
success: false,
|
|
61
|
-
reason: 'Connection problem',
|
|
62
|
-
errorType: constants.API_REQUEST_NETWORK_ERROR,
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
return {
|
|
66
|
-
result,
|
|
67
|
-
resultInfo,
|
|
68
|
-
shouldRetry: false,
|
|
69
|
-
success: true,
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
|
|
50
|
+
let resp;
|
|
51
|
+
if (step.sendViaWebApp) {
|
|
52
|
+
resp = await this.runApiInAut(eventData);
|
|
53
|
+
} else {
|
|
54
|
+
resp = await this.runApiInBg(eventData);
|
|
55
|
+
}
|
|
56
|
+
const result = resp.result || {};
|
|
57
|
+
const resultInfo = {
|
|
58
|
+
method: step.method,
|
|
59
|
+
status: result.status,
|
|
60
|
+
url: step.url,
|
|
61
|
+
};
|
|
62
|
+
if (resp.success) {
|
|
63
|
+
if (result.status === 0) {
|
|
73
64
|
return {
|
|
74
65
|
result,
|
|
75
66
|
resultInfo,
|
|
76
67
|
shouldRetry: false,
|
|
77
68
|
success: false,
|
|
78
|
-
reason:
|
|
79
|
-
errorType:
|
|
69
|
+
reason: 'Connection problem',
|
|
70
|
+
errorType: constants.API_REQUEST_NETWORK_ERROR,
|
|
80
71
|
};
|
|
81
|
-
}
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
result,
|
|
75
|
+
resultInfo,
|
|
76
|
+
shouldRetry: false,
|
|
77
|
+
success: true,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
result,
|
|
82
|
+
resultInfo,
|
|
83
|
+
shouldRetry: false,
|
|
84
|
+
success: false,
|
|
85
|
+
reason: result.error || sessionPlayer.commonConstants.error.REQUEST_TIMED_OUT,
|
|
86
|
+
errorType: result.error ? constants.API_FAILURE : constants.API_REQUEST_NETWORK_ERROR,
|
|
87
|
+
};
|
|
82
88
|
}
|
|
83
89
|
}
|
|
84
90
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const BaseJsStepAction = require('./baseJsStepAction');
|
|
4
|
-
const
|
|
4
|
+
const Bluebird = require('bluebird');
|
|
5
5
|
const service = require('../../agent/routers/cliJsCode/service');
|
|
6
6
|
const sessionPlayer = require('../../commons/getSessionPlayerRequire');
|
|
7
7
|
const _ = require('lodash');
|
|
@@ -9,16 +9,16 @@ const _ = require('lodash');
|
|
|
9
9
|
const constants = sessionPlayer.commonConstants.stepResult;
|
|
10
10
|
|
|
11
11
|
class BaseCliJsStepAction extends BaseJsStepAction {
|
|
12
|
-
executeCliCode() {
|
|
12
|
+
async executeCliCode() {
|
|
13
13
|
const { step, context } = this;
|
|
14
14
|
const isMobile = this.stepActionUtils.driver.isMobile;
|
|
15
15
|
const hasCliAction = _(context).get('company.activePlan.premiumFeatures.cliAction');
|
|
16
16
|
|
|
17
17
|
if (!hasCliAction && !isMobile) {
|
|
18
|
-
return
|
|
18
|
+
return {
|
|
19
19
|
success: 'skipped',
|
|
20
20
|
reason: 'CLI action is not enabled in your current plan',
|
|
21
|
-
}
|
|
21
|
+
};
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
const { code, id } = step;
|
|
@@ -28,21 +28,26 @@ class BaseCliJsStepAction extends BaseJsStepAction {
|
|
|
28
28
|
data: context.data,
|
|
29
29
|
};
|
|
30
30
|
const runTimeout = context.data.timeToPlayStep;
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
const data = await service.runCodeWithPackages(code, id, incomingParams, contextData, testResultId, retryIndex, stepResultId, runTimeout);
|
|
32
|
+
return await this.checkCodeResponse(data);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
performAction() {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
async performAction() {
|
|
36
|
+
try {
|
|
37
|
+
return await this.executeCliCode();
|
|
38
|
+
} catch (err) {
|
|
39
|
+
if (err instanceof Bluebird.TimeoutError) {
|
|
40
|
+
return {
|
|
41
|
+
success: false,
|
|
42
|
+
errorType: constants.ACTION_TIMEOUT,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
42
46
|
success: false,
|
|
43
47
|
reason: err.message,
|
|
44
48
|
exception: err,
|
|
45
|
-
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
46
51
|
}
|
|
47
52
|
}
|
|
48
53
|
|
|
@@ -44,7 +44,8 @@ class BaseJsStepAction extends StepAction {
|
|
|
44
44
|
}
|
|
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
49
|
return this.driver.executeJS(function (transactionId) {
|
|
49
50
|
const sessionItem = 'data-testim-' + transactionId;
|
|
50
51
|
try {
|
|
@@ -62,14 +63,15 @@ class BaseJsStepAction extends StepAction {
|
|
|
62
63
|
throw err;
|
|
63
64
|
}
|
|
64
65
|
}, transactionId);
|
|
66
|
+
/* eslint-enable prefer-arrow-callback, no-undef, unicorn/prefer-includes */
|
|
65
67
|
}
|
|
66
68
|
|
|
67
69
|
constructJSFunParams(eventData) {
|
|
68
70
|
const incomingParams = eventData.incomingParams;
|
|
69
71
|
|
|
70
72
|
const params = [
|
|
71
|
-
|
|
72
|
-
|
|
73
|
+
'context', ...incomingParams.as.functionParameters,
|
|
74
|
+
'exports', 'exportsTest', 'exportsGlobal',
|
|
73
75
|
];
|
|
74
76
|
|
|
75
77
|
const args = [eventData.context, ...incomingParams.as.functionArguments];
|
|
@@ -142,7 +144,7 @@ class BaseJsStepAction extends StepAction {
|
|
|
142
144
|
const useExperimentalPreCompilation = featureFlags.flags.experimentalPreCodeCompilation.isEnabled();
|
|
143
145
|
const experimentalAsyncCustomCode = featureFlags.flags.experimentalAsyncCustomCode.isEnabled();
|
|
144
146
|
const rawParams = this.constructJSFunParams(eventMessage);
|
|
145
|
-
const hasLocateParams = rawParams.function.args.some(x => Boolean(x
|
|
147
|
+
const hasLocateParams = rawParams.function.args.some(x => Boolean(x?.locatedElement));
|
|
146
148
|
let funcToRunString = 'undefined';
|
|
147
149
|
if (useExperimentalPreCompilation) {
|
|
148
150
|
const paramNames = rawParams.function.params.slice(0, -1);
|
|
@@ -236,7 +238,7 @@ class BaseJsStepAction extends StepAction {
|
|
|
236
238
|
}
|
|
237
239
|
|
|
238
240
|
checkCodeResponse(resp) {
|
|
239
|
-
return resp
|
|
241
|
+
return resp?.success ? this.codeExecDone(resp) : this.codeExecFailed(resp);
|
|
240
242
|
}
|
|
241
243
|
|
|
242
244
|
performAction() {
|
|
@@ -264,15 +266,14 @@ class BaseJsStepAction extends StepAction {
|
|
|
264
266
|
return this.driver.getBrowserAndOS()
|
|
265
267
|
.then(browserAndOS => {
|
|
266
268
|
Object.assign(eventMessage, { browser: browserAndOS.browser, browserMajor: browserAndOS.browserMajor });
|
|
267
|
-
return
|
|
269
|
+
return this.context.isPendingPromise ? undefined : this.executeInAut(eventMessage);
|
|
268
270
|
})
|
|
269
|
-
.then(() => (this.context.isPendingPromise ? Promise.resolve() : this.executeInAut(eventMessage)))
|
|
270
271
|
.then(() => this.checkStatus(eventMessage.transactionId))
|
|
271
272
|
.then(resp => this.checkCodeResponse(resp));
|
|
272
273
|
}
|
|
273
274
|
|
|
274
275
|
handleExecutionError(err) {
|
|
275
|
-
const canExtractError = err
|
|
276
|
+
const canExtractError = err?.seleniumStack && err.seleniumStack.type === 'JavaScriptError' &&
|
|
276
277
|
err.seleniumStack.orgStatusMessage;
|
|
277
278
|
|
|
278
279
|
if (canExtractError) {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const Promise = require('bluebird');
|
|
4
3
|
const StepAction = require('./stepAction');
|
|
5
4
|
const logger = require('../../commons/logger').getLogger('drop-file-step-action');
|
|
6
5
|
const downloadFileAndFireDropEvent = require('./scripts/dropEvent');
|
|
@@ -27,8 +26,7 @@ class DropFileStepAction extends StepAction {
|
|
|
27
26
|
return downloadFileAndFireDropEvent.apply(null, arguments)
|
|
28
27
|
`;
|
|
29
28
|
|
|
30
|
-
return this.driver.executeJSWithArray(dropFileCode, [target.locatedElement, fileUrls])
|
|
31
|
-
.then(() => Promise.resolve());
|
|
29
|
+
return this.driver.executeJSWithArray(dropFileCode, [target.locatedElement, fileUrls]).then(() => {});
|
|
32
30
|
});
|
|
33
31
|
}
|
|
34
32
|
}
|
|
@@ -55,16 +55,18 @@ class InputFileStepAction extends StepAction {
|
|
|
55
55
|
const invalidStateMsg = 'invalid element state: Element is not currently interactable and may not be manipulated';
|
|
56
56
|
const mustBeVisibleMsg = 'Element must not be hidden, disabled or read-only';
|
|
57
57
|
const notReachableByKeyboard = 'is not reachable by keyboard';
|
|
58
|
+
/** @type {string} */
|
|
58
59
|
const errorMsg = err ? err.message : '';
|
|
59
60
|
// Workaround move element if element is not visible or disabled
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
61
|
+
if (
|
|
62
|
+
errorMsg === invalidStateMsg ||
|
|
63
|
+
errorMsg.startsWith(mustBeVisibleMsg) ||
|
|
64
|
+
errorMsg.startsWith(edgeErrorEditableMessage) ||
|
|
65
|
+
errorMsg.startsWith(edgeErrorFocusableMessage) ||
|
|
66
|
+
errorMsg.startsWith(safariErrorVisibleMessage) ||
|
|
67
|
+
errorMsg.includes(notReachableByKeyboard) ||
|
|
68
|
+
errorMsg.includes(elementNotInteractable) ||
|
|
69
|
+
errorMsg.includes(elementNotPointerOrKeyboardInteractable)
|
|
68
70
|
) {
|
|
69
71
|
await this.forceInputToBeVisible(target);
|
|
70
72
|
await this.uploadFiles(gridLocalFiles, target);
|
|
@@ -33,6 +33,7 @@ function createUtils(driver) {
|
|
|
33
33
|
return Promise.resolve([frameHandler.frameOffset || {}]);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/** @type {typeof import('clickim/src/background/stepActions/locateStepAction').LocateStepAction['htmlStringToDom']} */
|
|
36
37
|
static htmlStringToDom(htmlString, url, nonBodyElements, bodyTagName, setDomTimeout = true) {
|
|
37
38
|
const virtualConsole = new VirtualConsole();
|
|
38
39
|
const jsdom = new JSDOM(htmlString, {
|
|
@@ -74,6 +75,7 @@ function createUtils(driver) {
|
|
|
74
75
|
return true;
|
|
75
76
|
}
|
|
76
77
|
|
|
78
|
+
/** @type {typeof import('clickim/src/background/stepActions/locateStepAction').LocateStepAction['isVisible']} */
|
|
77
79
|
static isVisible(target, targetElement, rect, locateStep, frameHandler, allOffsets, dom) {
|
|
78
80
|
const skipVisibilityCheck =
|
|
79
81
|
featureFlags.flags.disableEdgeVisibilityChecks.isEnabled() && driver.isEdge();
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const StepAction = require('./stepAction');
|
|
2
|
-
const Promise = require('bluebird');
|
|
3
2
|
const html5dndAction = require('./scripts/html5dragAction');
|
|
4
3
|
const html5dndActionV2 = require('./scripts/html5dragActionV2');
|
|
5
4
|
const doClickScript = require('./scripts/doClick');
|
|
@@ -30,7 +29,7 @@ class MouseStepAction extends StepAction {
|
|
|
30
29
|
const timeout = context.data.timeToPlayStep + 3000;
|
|
31
30
|
const events = step.events;
|
|
32
31
|
|
|
33
|
-
if (!events
|
|
32
|
+
if (!events?.length) {
|
|
34
33
|
return Promise.resolve();
|
|
35
34
|
}
|
|
36
35
|
|
|
@@ -58,12 +57,12 @@ class MouseStepAction extends StepAction {
|
|
|
58
57
|
|
|
59
58
|
return this.driver.executeCodeAsync(doClickCode, timeout, eventParam)
|
|
60
59
|
.then(result => {
|
|
61
|
-
if (result.value
|
|
62
|
-
return
|
|
60
|
+
if (result.value?.success) {
|
|
61
|
+
return { success: true };
|
|
63
62
|
}
|
|
64
|
-
return
|
|
63
|
+
return { success: false };
|
|
65
64
|
})
|
|
66
|
-
.catch(err =>
|
|
65
|
+
.catch(err => ({
|
|
67
66
|
success: false,
|
|
68
67
|
reason: err.message,
|
|
69
68
|
exception: err,
|
|
@@ -75,7 +74,7 @@ class MouseStepAction extends StepAction {
|
|
|
75
74
|
}
|
|
76
75
|
|
|
77
76
|
getEventSequenceOffset() {
|
|
78
|
-
const initialPosition =
|
|
77
|
+
const initialPosition = this.step.events[0]?.pointerPosition;
|
|
79
78
|
if (!initialPosition) {
|
|
80
79
|
return { xOffset: 0, yOffset: 0 };
|
|
81
80
|
}
|
|
@@ -91,7 +90,7 @@ class MouseStepAction extends StepAction {
|
|
|
91
90
|
|
|
92
91
|
addOffsetToEvents(offsetFromElement) {
|
|
93
92
|
this.step.events.forEach(event => {
|
|
94
|
-
if (event
|
|
93
|
+
if (event?.pointerPosition) {
|
|
95
94
|
event.pointerPosition.originX += offsetFromElement.xOffset;
|
|
96
95
|
event.pointerPosition.originY += offsetFromElement.yOffset;
|
|
97
96
|
}
|
|
@@ -113,7 +112,9 @@ class MouseStepAction extends StepAction {
|
|
|
113
112
|
|
|
114
113
|
const { recordPointerMoveEvents = false } = this.context.project.defaults || {};
|
|
115
114
|
const mouseUpEvent = this.step.events.find(event => event.event === 'mouseup') || (recordPointerMoveEvents && this.step.events.find(event => event.event === 'pointerup'));
|
|
116
|
-
const lastMouseMoveEventIndex =
|
|
115
|
+
const lastMouseMoveEventIndex =
|
|
116
|
+
_.findLastIndex(this.step.events, event => event.event === 'mousemove') ||
|
|
117
|
+
(recordPointerMoveEvents && _.findLastIndex(this.step.events, event => event.event === 'pointermove'));
|
|
117
118
|
if (mouseUpEvent && lastMouseMoveEventIndex > 0 && !this.step.allEventsOnSameElement) {
|
|
118
119
|
this.step.events.splice(lastMouseMoveEventIndex + 1, 0, this.generateEventOfType(mouseUpEvent, 'mouseover'));
|
|
119
120
|
}
|
|
@@ -159,12 +160,12 @@ class MouseStepAction extends StepAction {
|
|
|
159
160
|
|
|
160
161
|
return this.driver.executeCodeAsync(doDragPathCode, timeout, eventMessage)
|
|
161
162
|
.then(result => {
|
|
162
|
-
if (result.value
|
|
163
|
-
return
|
|
163
|
+
if (result.value?.success) {
|
|
164
|
+
return { success: true };
|
|
164
165
|
}
|
|
165
|
-
return
|
|
166
|
+
return { success: false };
|
|
166
167
|
})
|
|
167
|
-
.catch(err =>
|
|
168
|
+
.catch(err => ({
|
|
168
169
|
success: false,
|
|
169
170
|
reason: err.message,
|
|
170
171
|
exception: err,
|
|
@@ -173,9 +174,7 @@ class MouseStepAction extends StepAction {
|
|
|
173
174
|
|
|
174
175
|
chooseAndRunAction() {
|
|
175
176
|
const target = this.getTarget();
|
|
176
|
-
const {
|
|
177
|
-
locatedElement, seleniumElement, rectWithoutFrameOffset, rect,
|
|
178
|
-
} = target;
|
|
177
|
+
const { locatedElement, seleniumElement, rectWithoutFrameOffset, rect } = target;
|
|
179
178
|
const { xOffset, yOffset } = this.stepActionUtils.getClickOffset(this.step.element.clickOffset, rectWithoutFrameOffset);
|
|
180
179
|
|
|
181
180
|
// used for fallback native click
|
|
@@ -220,7 +219,7 @@ class MouseStepAction extends StepAction {
|
|
|
220
219
|
if (!isIE && featureFlagService.flags.usePortedHtml5DragDrop.isEnabled()) {
|
|
221
220
|
const events = this.generateHTML5DragEventSequence();
|
|
222
221
|
const timeout = this.context.data.timeToPlayStep + 3000;
|
|
223
|
-
const
|
|
222
|
+
const contextTarget = this.context.data[this.step.targetId || 'targetId'];
|
|
224
223
|
const eventMessage = {
|
|
225
224
|
transactionId: `${this.context.testResultId}:${this.step.id}`,
|
|
226
225
|
id: this.step.id,
|
|
@@ -235,10 +234,10 @@ class MouseStepAction extends StepAction {
|
|
|
235
234
|
isDrag: this.step.isDrag,
|
|
236
235
|
useRecordedMousedown: this.step.useRecordedMousedown,
|
|
237
236
|
allEventsOnSameElement: this.step.allEventsOnSameElement,
|
|
238
|
-
elementToFocusLocatedElement:
|
|
237
|
+
elementToFocusLocatedElement: contextTarget.elementToFocusLocatedElement,
|
|
239
238
|
trackActiveElement: this.step.trackActiveElement,
|
|
240
|
-
locatedElement:
|
|
241
|
-
isRoot:
|
|
239
|
+
locatedElement: contextTarget.locatedElement,
|
|
240
|
+
isRoot: contextTarget.isRoot,
|
|
242
241
|
};
|
|
243
242
|
// hack for Edge (17/18) which does not accept properties with negative (throws Unknown Error)
|
|
244
243
|
// values between 0 and -1 -_-.
|
|
@@ -311,7 +310,7 @@ class MouseStepAction extends StepAction {
|
|
|
311
310
|
}
|
|
312
311
|
|
|
313
312
|
addDragendIfNeeded(events) {
|
|
314
|
-
if (events.
|
|
313
|
+
if (events.some(event => event.event === 'dragend')) {
|
|
315
314
|
return events;
|
|
316
315
|
}
|
|
317
316
|
const dragendDefaultEvent = {
|
|
@@ -325,7 +324,7 @@ class MouseStepAction extends StepAction {
|
|
|
325
324
|
}
|
|
326
325
|
|
|
327
326
|
getToElementPosition() {
|
|
328
|
-
if (!(this.context.data
|
|
327
|
+
if (!(this.context.data?.toElement?.rect)) {
|
|
329
328
|
return undefined;
|
|
330
329
|
}
|
|
331
330
|
const { rect } = this.context.data.toElement;
|
|
@@ -1,47 +1,46 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
const StepAction = require('./stepAction');
|
|
4
|
-
const
|
|
5
|
-
const {NpmPackageError} = require('../../errors');
|
|
4
|
+
const Bluebird = require('bluebird');
|
|
5
|
+
const { NpmPackageError } = require('../../errors');
|
|
6
6
|
|
|
7
7
|
const service = require('../../agent/routers/cliJsCode/service');
|
|
8
8
|
|
|
9
9
|
class NodePackageStepAction extends StepAction {
|
|
10
|
+
async performAction() {
|
|
11
|
+
const { context } = this;
|
|
12
|
+
const { stepId, packageData, resultId, retryIndex, stepResultId, timeToPlayBeforeExec } = context;
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
.catch(NpmPackageError, err => {
|
|
25
|
-
return Promise.resolve({
|
|
26
|
-
success: false,
|
|
27
|
-
code: "invalid-node-package",
|
|
28
|
-
message: err.message
|
|
29
|
-
})
|
|
30
|
-
})
|
|
31
|
-
.catch(Promise.TimeoutError, () => {
|
|
32
|
-
return Promise.resolve({
|
|
14
|
+
try {
|
|
15
|
+
const data = await service.installPackage(
|
|
16
|
+
stepId,
|
|
17
|
+
resultId,
|
|
18
|
+
retryIndex,
|
|
19
|
+
packageData,
|
|
20
|
+
stepResultId,
|
|
21
|
+
timeToPlayBeforeExec,
|
|
22
|
+
);
|
|
23
|
+
return ({ data, success: true });
|
|
24
|
+
} catch (err) {
|
|
25
|
+
if (err instanceof NpmPackageError) {
|
|
26
|
+
return {
|
|
33
27
|
success: false,
|
|
34
|
-
code:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
28
|
+
code: 'invalid-node-package',
|
|
29
|
+
message: err.message,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if (err instanceof Bluebird.TimeoutError) {
|
|
33
|
+
return {
|
|
39
34
|
success: false,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
35
|
+
code: 'timeout',
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
success: false,
|
|
40
|
+
reason: err.message,
|
|
41
|
+
exception: err,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
45
44
|
}
|
|
46
45
|
}
|
|
47
46
|
|
|
@@ -22,6 +22,7 @@ class StepAction {
|
|
|
22
22
|
this.context = context;
|
|
23
23
|
this.frameHandler = frameHandler;
|
|
24
24
|
this.frameId = 0;
|
|
25
|
+
/** @type {import('../utils/stepActionUtils'))} */
|
|
25
26
|
this.stepActionUtils = stepActionUtils;
|
|
26
27
|
this.locateElementPlayer = locateElementPlayer;
|
|
27
28
|
this.exportsGlobal = exportsGlobal;
|