@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.
Files changed (61) hide show
  1. package/agent/routers/cliJsCode/service.js +11 -8
  2. package/agent/routers/codim/router.test.js +9 -12
  3. package/agent/routers/codim/service.js +16 -16
  4. package/agent/routers/playground/service.js +5 -7
  5. package/cli.js +6 -6
  6. package/cliAgentMode.js +11 -10
  7. package/codim/codim-cli.js +14 -9
  8. package/commons/featureFlags.js +29 -7
  9. package/commons/httpRequest.js +5 -1
  10. package/commons/httpRequestCounters.js +21 -10
  11. package/commons/initializeUserWithAuth.js +7 -4
  12. package/commons/lazyRequire.js +4 -3
  13. package/commons/preloadTests.js +6 -3
  14. package/commons/prepareRunner.js +7 -5
  15. package/commons/prepareRunnerAndTestimStartUtils.js +51 -45
  16. package/commons/runnerFileCache.js +10 -2
  17. package/commons/testimServicesApi.js +36 -5
  18. package/commons/testimTunnel.test.js +2 -1
  19. package/coverage/SummaryToObjectReport.js +0 -1
  20. package/coverage/jsCoverage.js +12 -10
  21. package/inputFileUtils.js +11 -9
  22. package/npm-shrinkwrap.json +214 -471
  23. package/package.json +4 -3
  24. package/player/services/tabService.js +15 -1
  25. package/player/stepActions/apiStepAction.js +49 -43
  26. package/player/stepActions/baseCliJsStepAction.js +19 -14
  27. package/player/stepActions/baseJsStepAction.js +9 -8
  28. package/player/stepActions/dropFileStepAction.js +1 -3
  29. package/player/stepActions/inputFileStepAction.js +10 -8
  30. package/player/stepActions/locateStepAction.js +2 -0
  31. package/player/stepActions/mouseStepAction.js +21 -22
  32. package/player/stepActions/nodePackageStepAction.js +34 -35
  33. package/player/stepActions/stepAction.js +1 -0
  34. package/player/utils/imageCaptureUtils.js +133 -172
  35. package/player/utils/screenshotUtils.js +16 -13
  36. package/player/utils/windowUtils.js +20 -8
  37. package/player/webdriver.js +25 -22
  38. package/processHandler.js +4 -0
  39. package/reports/junitReporter.js +6 -7
  40. package/reports/reporter.js +34 -39
  41. package/runOptions.d.ts +286 -0
  42. package/runOptions.js +60 -45
  43. package/runner.js +64 -24
  44. package/runners/ParallelWorkerManager.js +12 -12
  45. package/runners/TestPlanRunner.js +14 -15
  46. package/runners/buildCodeTests.js +1 -0
  47. package/runners/runnerUtils.js +11 -2
  48. package/services/branchService.js +11 -5
  49. package/services/gridService.js +36 -40
  50. package/services/localRCASaver.js +4 -0
  51. package/testRunStatus.js +8 -5
  52. package/utils/argsUtils.js +86 -0
  53. package/utils/argsUtils.test.js +32 -0
  54. package/utils/fsUtils.js +154 -0
  55. package/utils/index.js +10 -161
  56. package/utils/promiseUtils.js +13 -2
  57. package/utils/stringUtils.js +4 -2
  58. package/utils/stringUtils.test.js +22 -0
  59. package/utils/timeUtils.js +25 -0
  60. package/utils/utils.test.js +0 -41
  61. 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.254.0",
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": "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",
115
- "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",
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, { tabCount: number; tabInfos: Record<string, TabInfo> }>} */
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
- return this.driver.executeCodeAsync(apiCall, timeout, eventData)
16
- .then(autRes => {
17
- const resp = autRes && autRes.value;
18
- return resp || {};
19
- }).catch(err => err && err.message && err.message.includes('Javascript execution context no longer exists'), err => {
20
- throw new Error('The page refreshed or changed while executing this step. Please consider unchecking "Send via web page" if this is expected.');
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
- return (step.sendViaWebApp ? this.runApiInAut(eventData) : this.runApiInBg(eventData))
45
- .then(resp => {
46
- const result = resp.result || {};
47
-
48
- const resultInfo = {
49
- method: step.method,
50
- status: result.status,
51
- url: step.url,
52
- };
53
-
54
- if (resp.success) {
55
- if (result.status === 0) {
56
- return {
57
- result,
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: result.error || sessionPlayer.commonConstants.error.REQUEST_TIMED_OUT,
79
- errorType: result.error ? constants.API_FAILURE : constants.API_REQUEST_NETWORK_ERROR,
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 Promise = require('bluebird');
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 Promise.resolve({
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
- return service.runCodeWithPackages(code, id, incomingParams, contextData, testResultId, retryIndex, stepResultId, runTimeout)
32
- .then(data => this.checkCodeResponse(data));
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
- return this.executeCliCode()
37
- .catch(Promise.TimeoutError, () => Promise.resolve({
38
- success: false,
39
- errorType: constants.ACTION_TIMEOUT,
40
- }))
41
- .catch(err => Promise.resolve({
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
- // eslint-disable-next-line prefer-arrow-callback
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
- ...['context', ...incomingParams.as.functionParameters],
72
- ...['exports', 'exportsTest', 'exportsGlobal'],
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 && x.locatedElement));
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 && resp.success ? this.codeExecDone(resp) : this.codeExecFailed(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 Promise.resolve();
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 && err.seleniumStack && err.seleniumStack.type === 'JavaScriptError' &&
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 (_.isEqual(errorMsg, invalidStateMsg) ||
61
- _.startsWith(errorMsg, mustBeVisibleMsg) ||
62
- _.startsWith(errorMsg, edgeErrorEditableMessage) ||
63
- _.startsWith(errorMsg, edgeErrorFocusableMessage) ||
64
- _.startsWith(errorMsg, safariErrorVisibleMessage) ||
65
- _.includes(errorMsg, notReachableByKeyboard) ||
66
- _.includes(errorMsg, elementNotInteractable) ||
67
- _.includes(errorMsg, elementNotPointerOrKeyboardInteractable)
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 || !events.length) {
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 && result.value.success) {
62
- return Promise.resolve({ success: true });
60
+ if (result.value?.success) {
61
+ return { success: true };
63
62
  }
64
- return Promise.resolve({ success: false });
63
+ return { success: false };
65
64
  })
66
- .catch(err => Promise.resolve({
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 = (this.step.events[0] || {}).pointerPosition;
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 && event.pointerPosition) {
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 = _.findLastIndex(this.step.events, event => event.event === 'mousemove') || (recordPointerMoveEvents && _.findLastIndex(this.step.events, event => event.event === 'pointermove'));
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 && result.value.success) {
163
- return Promise.resolve({ success: true });
163
+ if (result.value?.success) {
164
+ return { success: true };
164
165
  }
165
- return Promise.resolve({ success: false });
166
+ return { success: false };
166
167
  })
167
- .catch(err => Promise.resolve({
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 target = this.context.data[this.step.targetId || 'targetId'];
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: target.elementToFocusLocatedElement,
237
+ elementToFocusLocatedElement: contextTarget.elementToFocusLocatedElement,
239
238
  trackActiveElement: this.step.trackActiveElement,
240
- locatedElement: target.locatedElement,
241
- isRoot: target.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.find(event => event.event === 'dragend')) {
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 && this.context.data.toElement && this.context.data.toElement.rect)) {
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
- "use strict";
1
+ 'use strict';
2
2
 
3
3
  const StepAction = require('./stepAction');
4
- const Promise = require('bluebird');
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
- performAction() {
12
- const {context} = this;
13
- const {
14
- stepId,
15
- packageData,
16
- resultId,
17
- retryIndex,
18
- stepResultId,
19
- timeToPlayBeforeExec
20
- } = context;
21
-
22
- return service.installPackage(stepId, resultId, retryIndex, packageData, stepResultId, timeToPlayBeforeExec)
23
- .then(data => ({data, success: true}))
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: "timeout"
35
- });
36
- })
37
- .catch(err =>
38
- Promise.resolve({
28
+ code: 'invalid-node-package',
29
+ message: err.message,
30
+ };
31
+ }
32
+ if (err instanceof Bluebird.TimeoutError) {
33
+ return {
39
34
  success: false,
40
- reason: err.message,
41
- exception: err
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;