@testim/testim-cli 3.252.0 → 3.254.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 (97) hide show
  1. package/OverrideTestDataBuilder.js +1 -1
  2. package/agent/routers/cliJsCode/index.js +4 -4
  3. package/agent/routers/cliJsCode/router.js +46 -42
  4. package/agent/routers/cliJsCode/service.js +18 -13
  5. package/agent/routers/codim/router.js +14 -17
  6. package/agent/routers/codim/router.test.js +15 -14
  7. package/agent/routers/codim/service.js +1 -1
  8. package/agent/routers/general/index.js +4 -8
  9. package/agent/routers/hybrid/registerRoutes.js +18 -18
  10. package/agent/routers/index.js +9 -8
  11. package/agent/routers/playground/router.js +12 -11
  12. package/agent/routers/playground/service.js +19 -18
  13. package/agent/routers/standalone-browser/registerRoutes.js +10 -10
  14. package/cdpTestRunner.js +4 -3
  15. package/chromiumInstaller.js +4 -5
  16. package/cli/onExit.js +2 -2
  17. package/cli.js +7 -6
  18. package/cliAgentMode.js +4 -5
  19. package/codim/codim-cli.js +11 -10
  20. package/codim/hybrid-utils.js +1 -1
  21. package/codim/measure-perf.js +9 -6
  22. package/codim/template.js/tests/examples/01-simple-text-validation.test.js +6 -6
  23. package/codim/template.js/tests/examples/02-using-locators.test.js +13 -15
  24. package/codim/template.js/tests/examples/03-using-hooks.test.js +17 -19
  25. package/codim/template.js/tests/examples/04-skip-and-only.test.js +16 -17
  26. package/codim/template.js/tests/examples/05-multiple-windows.test.js +16 -17
  27. package/codim/template.js/webpack.config.js +1 -1
  28. package/codim/template.ts/webpack.config.js +3 -3
  29. package/commons/AbortError.js +4 -4
  30. package/commons/chrome-launcher.js +6 -6
  31. package/commons/constants.js +2 -0
  32. package/commons/detectDebugger.js +4 -2
  33. package/commons/getSessionPlayerRequire.js +2 -20
  34. package/commons/initializeUserWithAuth.js +2 -2
  35. package/commons/lazyRequire.js +10 -9
  36. package/commons/logger.js +4 -4
  37. package/commons/performance-logger.js +14 -8
  38. package/commons/prepareRunnerAndTestimStartUtils.js +6 -7
  39. package/commons/socket/baseSocketServiceSocketIO.js +32 -34
  40. package/commons/socket/realDataService.js +6 -5
  41. package/commons/socket/realDataServiceSocketIO.js +4 -4
  42. package/commons/socket/remoteStepService.js +4 -3
  43. package/commons/socket/remoteStepServiceSocketIO.js +11 -12
  44. package/commons/socket/socketService.js +50 -52
  45. package/commons/socket/testResultServiceSocketIO.js +11 -11
  46. package/commons/testimDesiredCapabilitiesBuilder.js +44 -0
  47. package/commons/testimNgrok.js +2 -2
  48. package/commons/testimNgrok.test.js +1 -1
  49. package/commons/testimServicesApi.js +37 -21
  50. package/commons/xhr2.js +97 -100
  51. package/credentialsManager.js +17 -20
  52. package/errors.js +5 -0
  53. package/fixLocalBuild.js +2 -0
  54. package/npm-shrinkwrap.json +4455 -1576
  55. package/package.json +9 -7
  56. package/player/WebdriverioWebDriverApi.js +7 -2
  57. package/player/appiumTestPlayer.js +102 -0
  58. package/player/chromeLauncherTestPlayer.js +0 -1
  59. package/player/seleniumTestPlayer.js +3 -2
  60. package/player/services/frameLocator.js +2 -1
  61. package/player/services/mobileFrameLocatorMock.js +32 -0
  62. package/player/services/playbackTimeoutCalculator.js +1 -0
  63. package/player/services/portSelector.js +10 -8
  64. package/player/services/tabService.js +29 -0
  65. package/player/services/tabServiceMock.js +166 -0
  66. package/player/stepActions/navigationStepAction.js +11 -10
  67. package/player/stepActions/sleepStepAction.js +4 -5
  68. package/player/stepActions/stepAction.js +15 -1
  69. package/player/stepActions/textStepAction.js +4 -11
  70. package/player/utils/stepActionUtils.js +4 -2
  71. package/player/utils/windowUtils.js +139 -125
  72. package/player/webdriver.js +40 -26
  73. package/processHandler.js +3 -3
  74. package/processHandler.test.js +1 -1
  75. package/reports/consoleReporter.js +3 -2
  76. package/reports/debugReporter.js +41 -39
  77. package/reports/jsonReporter.js +53 -50
  78. package/reports/junitReporter.js +1 -2
  79. package/reports/reporter.js +135 -136
  80. package/runOptions.js +8 -7
  81. package/runner.js +13 -0
  82. package/runners/ParallelWorkerManager.js +2 -0
  83. package/runners/TestPlanRunner.js +142 -74
  84. package/runners/buildCodeTests.js +38 -37
  85. package/runners/runnerUtils.js +3 -3
  86. package/services/lambdatestService.js +3 -5
  87. package/stepPlayers/cliJsStepPlayback.js +22 -17
  88. package/testRunHandler.js +8 -0
  89. package/testRunStatus.js +458 -460
  90. package/{utils.js → utils/index.js} +25 -117
  91. package/utils/promiseUtils.js +78 -0
  92. package/utils/stringUtils.js +96 -0
  93. package/{utils.test.js → utils/utils.test.js} +2 -2
  94. package/workers/BaseWorker.js +29 -20
  95. package/workers/WorkerAppium.js +123 -0
  96. package/workers/WorkerExtensionSingleBrowser.js +4 -4
  97. package/workers/WorkerSelenium.js +5 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testim/testim-cli",
3
- "version": "3.252.0",
3
+ "version": "3.254.0",
4
4
  "description": "Command line interface for running Testing on your CI",
5
5
  "author": "Oren Rubin",
6
6
  "contributors": [{
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "lazyDependencies": {
34
34
  "ngrok": "3.4.0",
35
- "webpack": "4.43.0",
35
+ "webpack": "5.74.0",
36
36
  "playwright": "0.12.1",
37
37
  "puppeteer": "2.1.1",
38
38
  "selenium-webdriver": "3.6.0",
@@ -68,25 +68,26 @@
68
68
  "form-data": "3.0.0",
69
69
  "fs-extra": "10.0.1",
70
70
  "glob": "7.2.0",
71
+ "https-proxy-agent": "5.0.0",
71
72
  "istanbul-lib-report": "3.0.0",
72
73
  "istanbul-reports": "3.0.2",
73
- "jimp": "0.16.1",
74
+ "jimp": "0.16.2",
74
75
  "jsdom": "19.0.0",
75
76
  "jsonwebtoken": "8.5.1",
76
77
  "lodash": "4.17.21",
77
78
  "memory-fs": "0.5.0",
78
79
  "memorystream": "0.3.1",
79
80
  "mkdirp": "1.0.4",
80
- "moment": "2.25.3",
81
+ "moment": "2.29.4",
81
82
  "ms": "2.1.2",
82
- "npm": "8.3.0",
83
+ "npm": "8.19.2",
83
84
  "object-hash": "3.0.0",
84
85
  "ora": "5.4.1",
85
86
  "p-retry": "4.6.2",
86
87
  "pako": "1.0.11",
87
88
  "portfinder": "1.0.28",
88
89
  "promise-queue": "2.2.5",
89
- "prompts": "2.3.2",
90
+ "prompts": "2.4.2",
90
91
  "proxy-agent": "5.0.0",
91
92
  "rox-node": "4.9.18",
92
93
  "semver": "7.3.2",
@@ -98,6 +99,7 @@
98
99
  "threads": "0.12.0",
99
100
  "ua-parser-js": "0.7.28",
100
101
  "validate-npm-package-name": "3.0.0",
102
+ "webdriverio": "7.24.0",
101
103
  "winston": "3.6.0",
102
104
  "winston-transport": "4.5.0",
103
105
  "ws": "8.5.0",
@@ -119,6 +121,6 @@
119
121
  "pack-serve": "yarn pack-onprem && http-server deploy/"
120
122
  },
121
123
  "engines": {
122
- "node": ">= 12.0.0"
124
+ "node": ">= 14.0.0"
123
125
  }
124
126
  }
@@ -5,7 +5,7 @@ const Queue = require('promise-queue');
5
5
  const Promise = require('bluebird');
6
6
  const config = require('../commons/config');
7
7
  const {
8
- UNICODE_CHARACTERS, W3C_ELEMENT_ID, EDGE_LAST_VERSION, EDGE_CHROMIUM_MIN_VERSION,
8
+ UNICODE_CHARACTERS, W3C_ELEMENT_ID,
9
9
  } = require('./constants');
10
10
  const isElementDisplayed = require('./scripts/isElementDisplayed');
11
11
  const logger = require('../commons/logger').getLogger('WebDriverApi');
@@ -59,6 +59,7 @@ class WebdriverioWebDriverApi {
59
59
  this.queue = new Queue(maxConcurrent, maxQueue);
60
60
  }
61
61
 
62
+ /** @returns {Promise<any>} */
62
63
  addToQueue(func) {
63
64
  const perfId = this.seleniumPerfStats.markStart();
64
65
  return this.queue.add(func)
@@ -247,6 +248,10 @@ class WebdriverioWebDriverApi {
247
248
  .finally(() => this.seleniumPerfStats.markEnd(perfId, SELENIUM_PERF_MARKS.GET_SCREENSHOT));
248
249
  }
249
250
 
251
+ /**
252
+ * @param {string} selector
253
+ * @returns {Promise<{ value: HTMLElement }>}
254
+ */
250
255
  getElementBySelector(selector) {
251
256
  return this.addToQueue(() => this.client.element(selector));
252
257
  }
@@ -506,7 +511,7 @@ class WebdriverioWebDriverApi {
506
511
  return this.addToQueue(() => this.client.getTitle());
507
512
  }
508
513
 
509
-
514
+ // eslint-disable-next-line default-param-last
510
515
  windowHandleSize(windowHandle = 'current', size) {
511
516
  return this.addToQueue(() => {
512
517
  let data = {};
@@ -0,0 +1,102 @@
1
+ 'use strict';
2
+
3
+ const webdriverio = require('webdriverio');
4
+ const TabService = require('./services/tabServiceMock');
5
+ const PortSelector = require('./services/portSelector');
6
+ const windowCreationListener = require('./services/windowCreationListener');
7
+ const frameLocatorFactory = require('./services/mobileFrameLocatorMock');
8
+ const { isDebuggerConnected } = require('../commons/detectDebugger');
9
+ const logger = require('../commons/logger').getLogger('appium-test-player');
10
+
11
+ const sessionPlayer = require('../commons/getSessionPlayerRequire');
12
+
13
+ const Player = sessionPlayer.sessionPlayer;
14
+ // delete after https://github.com/testimio/clickim/pull/3430 release to the store
15
+ const assetService = sessionPlayer.assetService;
16
+ const commonConstants = sessionPlayer.commonConstants;
17
+ const StepActionFactory = sessionPlayer.stepActionFactory;
18
+ const mobileLocateElementPlayer = sessionPlayer.MobileLocateElementPlayer;
19
+ const PlaybackTimeoutCalculator = require('./services/playbackTimeoutCalculator');
20
+ const testResultService = require('../commons/socket/testResultService');
21
+
22
+ // delete after https://github.com/testimio/clickim/pull/3430 release to the store
23
+ const CryptoJS = require('crypto-js');
24
+ const StepActionUtils = require('./utils/stepActionUtils');
25
+
26
+ class AppiumTestPlayer {
27
+ //eslint-disable-next-line default-param-last
28
+ constructor(id, userParamsData, shouldMonitorPerformance, automationMode = 'code', driver = webdriverio, testRetryCount, previousTestResultId) {
29
+ this.driver = driver;
30
+ this.id = id;
31
+
32
+ const stepActionUtils = new StepActionUtils(this.driver);
33
+ this.stepActionFactory = new StepActionFactory(stepActionUtils);
34
+ require('./stepActions/stepActionRegistrar')(this.driver, this.stepActionFactory, 'selenium');
35
+
36
+ if (assetService.setMd5) {
37
+ // delete after https://github.com/testimio/clickim/pull/3430 release to the store
38
+ assetService.setMd5(CryptoJS);
39
+ }
40
+ this.tabService = new TabService(this.driver);
41
+ this.windowCreationListener = windowCreationListener;
42
+ this.playbackTimeoutCalculator = new PlaybackTimeoutCalculator(isDebuggerConnected());
43
+
44
+ this.tabService.createSesion(id);
45
+
46
+ const FrameLocator = frameLocatorFactory(this.driver);
47
+
48
+ this.sessionPlayer = new Player(
49
+ id,
50
+ this.tabService,
51
+ null,
52
+ null,
53
+ FrameLocator,
54
+ PortSelector,
55
+ mobileLocateElementPlayer,
56
+ null /* Not in use, placeholder for the order of arguments */,
57
+ stepActionUtils,
58
+ this.stepActionFactory,
59
+ this.playbackTimeoutCalculator,
60
+ testResultService.getSocket(),
61
+ automationMode,
62
+ );
63
+
64
+ if (this.sessionPlayer.setShouldMonitorPerformance) {
65
+ this.sessionPlayer.setShouldMonitorPerformance(shouldMonitorPerformance);
66
+ }
67
+ this.sessionPlayer.playbackManager.isRemoteSession = true;
68
+ this.sessionPlayer.playbackManager.isLocalRun = false;
69
+ this.sessionPlayer.playbackManager.testRetryCount = testRetryCount;
70
+ this.sessionPlayer.playbackManager.previousTestResultId = previousTestResultId;
71
+
72
+ this.sessionPlayer.playbackManager.userParamsData = userParamsData || {};
73
+ this.onStepCompleted = this.onStepCompleted.bind(this);
74
+
75
+ this.sessionPlayer.playbackManager.on(commonConstants.playback.RESULT, this.onStepCompleted);
76
+ }
77
+
78
+ onStepCompleted(result, testId, resultId, step) {
79
+ //do nothing for now ...
80
+ }
81
+
82
+
83
+ async onDone() {
84
+ try {
85
+ await this.driver.activeSession.deleteSession();
86
+ } catch (error) {
87
+ logger.error('error while deleting appium session', { error });
88
+ } finally {
89
+ this.sessionPlayer.playbackManager.off(commonConstants.playback.RESULT);
90
+ this.sessionPlayer = null;
91
+ this.tabService = null;
92
+ this.stepActionFactory = null;
93
+ this.driver = null;
94
+ }
95
+ }
96
+
97
+ getSessionId() {
98
+ return this.driver.activeSession.sessionId;
99
+ }
100
+ }
101
+
102
+ module.exports = AppiumTestPlayer;
@@ -3,7 +3,6 @@
3
3
  const launcher = require('chrome-launcher');
4
4
  const desiredCapabilitiesBuilder = require('../commons/testimDesiredCapabilitiesBuilder');
5
5
  const utils = require('../utils');
6
- const httpRequest = require('../commons/httpRequest');
7
6
  const { registerExitHook } = require('../processHandler');
8
7
  const CDPTestRunner = require('../cdpTestRunner');
9
8
 
@@ -10,7 +10,7 @@ const { isDebuggerConnected } = require('../commons/detectDebugger');
10
10
 
11
11
  const sessionPlayer = require('../commons/getSessionPlayerRequire');
12
12
 
13
- const player = sessionPlayer.sessionPlayer;
13
+ const Player = sessionPlayer.sessionPlayer;
14
14
  // delete after https://github.com/testimio/clickim/pull/3430 release to the store
15
15
  const assetService = sessionPlayer.assetService;
16
16
  const commonConstants = sessionPlayer.commonConstants;
@@ -24,6 +24,7 @@ const CryptoJS = require('crypto-js');
24
24
  const StepActionUtils = require('./utils/stepActionUtils');
25
25
 
26
26
  class SeleniumTestPlayer {
27
+ //eslint-disable-next-line default-param-last
27
28
  constructor(id, userParamsData, shouldMonitorPerformance, automationMode = 'code', driver = new WebDriver(), testRetryCount, previousTestResultId) {
28
29
  this.driver = driver;
29
30
  this.id = id;
@@ -47,7 +48,7 @@ class SeleniumTestPlayer {
47
48
 
48
49
  const FrameLocator = frameLocatorFactory(this.driver);
49
50
 
50
- this.sessionPlayer = new player(
51
+ this.sessionPlayer = new Player(
51
52
  id,
52
53
  this.tabService,
53
54
  CookieUtils(this.driver),
@@ -19,6 +19,7 @@ const _getGuidFromSeleniumElement = (seleniumElement) => {
19
19
  /** @param {import('../webdriver')} driver*/
20
20
  module.exports = function frameLocatorFactory(driver) {
21
21
  class FrameLocator {
22
+ /** @type {(...args: ConstructorParameters<typeof import('clickim/src/background/frameLocator').FrameLocator>) => this} */
22
23
  constructor(frameManager, locateElementPlayer) {
23
24
  this.frameManager = frameManager;
24
25
  this.locateElementPlayer = locateElementPlayer;
@@ -34,7 +35,7 @@ module.exports = function frameLocatorFactory(driver) {
34
35
  }
35
36
 
36
37
  cacheFrameLocateResults(frameHandler) {
37
- if (frameHandler && frameHandler.seleniumFrameElement && frameHandler.frameLocateResultUrl) {
38
+ if (frameHandler?.seleniumFrameElement && frameHandler.frameLocateResultUrl) {
38
39
  const guid = _getGuidFromSeleniumElement(frameHandler.seleniumFrameElement);
39
40
  if (guid) {
40
41
  this.cacheResults(guid, frameHandler.frameLocateResultUrl);
@@ -0,0 +1,32 @@
1
+ 'use strict';
2
+
3
+ const logger = require('../../commons/logger').getLogger('mobile-frame-locator-mock');
4
+
5
+ /** @param {import('../webdriver')} driver*/
6
+ module.exports = function frameLocatorFactory(driver) {
7
+ class FrameLocator {
8
+ /** @type {(...args: ConstructorParameters<typeof import('clickim/src/background/frameLocator').FrameLocator>) => this} */
9
+ constructor(frameManager, locateElementPlayer) {
10
+ this.frameManager = frameManager;
11
+ this.locateElementPlayer = locateElementPlayer;
12
+ }
13
+
14
+ foundFrameCallback(result, frameTree, testimFrameId) {
15
+ logger.info('foundFrameCallback-mock invoked');
16
+ return {};
17
+ }
18
+
19
+
20
+ locate(frameLocator, frameDepth, currentFrame, context, frameTree, stepData) {
21
+ logger.info('locate-mock invoked');
22
+ return {};
23
+ }
24
+
25
+ findFrame(stepData, frameLocators, context, frameTree) {
26
+ logger.info('findFrame-mock invoked');
27
+ return {};
28
+ }
29
+ }
30
+
31
+ return FrameLocator;
32
+ };
@@ -18,6 +18,7 @@ const FULL_TIMEOUT_STEP_TYPES = [
18
18
  'sfdc-step-launchapp',
19
19
  'sfdc-step-closeconsoletabs',
20
20
  'sfdc-step-sobjectedit',
21
+ 'sfdc-step-relatedlistaction',
21
22
  ];
22
23
 
23
24
  class PlaybackTimeoutCalculator {
@@ -1,16 +1,18 @@
1
- "use strict";
1
+ 'use strict';
2
+
2
3
  const Promise = require('bluebird');
3
4
 
4
5
  // Legacy code not supported in selenium mode
5
6
  class PortSelector {
6
- constructor(){}
7
- select(){
8
- console.log("\n\t\t\tinternal error - cant use port selector in selenium!!!!\n");
9
- return Promise.reject({
10
- reason: "cant use port selector in selenium!"
11
- });
7
+ // eslint-disable-next-line no-useless-constructor, no-empty-function
8
+ constructor() { }
9
+ select() {
10
+ // eslint-disable-next-line no-console
11
+ console.log('\n\t\t\tinternal error - cant use port selector in selenium!!!!\n');
12
+ // eslint-disable-next-line prefer-promise-reject-errors
13
+ return Promise.reject({ reason: 'cant use port selector in selenium!' });
12
14
  }
13
- prepare(){}
15
+ prepare() {}
14
16
  handleLegacyDataCaching() {}
15
17
  }
16
18
 
@@ -15,12 +15,41 @@ const constants = sessionPlayer.commonConstants.stepResult;
15
15
  const tabMatcher = sessionPlayer.tabMatcher;
16
16
  const logger = require('../../commons/logger').getLogger('tab-service');
17
17
 
18
+ /**
19
+ * @typedef {{
20
+ * attachDebugger(): Promise<any>,
21
+ * detachDebugger(): Promise<any>,
22
+ * onDebuggerDetached(): {},
23
+ * tabId: string,
24
+ * domUtils: { getDOM(): Promise<any> },
25
+ * windowUtils: WindowUtils,
26
+ * imageCaptureUtils: ImageCaptureUtils
27
+ * }} TabUtil
28
+ * */
29
+ /**
30
+ * @typedef {{
31
+ * infoId: any;
32
+ * url: any;
33
+ * title: any;
34
+ * favIconUrl: any;
35
+ * order: any;
36
+ * from: any;
37
+ * isMain: any;
38
+ * openerStepId: any;
39
+ * }} TabInfo
40
+ */
41
+
18
42
  class TabService {
43
+ /** @param {import('../webdriver')} driver */
19
44
  constructor(driver) {
20
45
  this.driver = driver;
46
+ /** @type {Record<string, TabUtil>} */
21
47
  this._utils = {};
48
+ /** @type {Record<string, { tabCount: number; tabInfos: Record<string, TabInfo> }>} */
22
49
  this.sessionTabs = {};
50
+ /** @type {Record<string, string>} */
23
51
  this.pendingTabs = {};
52
+ /** @type {Record<string, Set<any>>} */
24
53
  this.addedTabs = {};
25
54
  }
26
55
 
@@ -0,0 +1,166 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @typedef {{
5
+ * attachDebugger(): Promise<any>,
6
+ * detachDebugger(): Promise<any>,
7
+ * onDebuggerDetached(): {},
8
+ * tabId: string,
9
+ * domUtils: { getDOM(): Promise<any> },
10
+ * windowUtils: WindowUtils,
11
+ * imageCaptureUtils: ImageCaptureUtils
12
+ * }} TabUtil
13
+ * */
14
+ /**
15
+ * @typedef {{
16
+ * infoId: any;
17
+ * url: any;
18
+ * title: any;
19
+ * favIconUrl: any;
20
+ * order: any;
21
+ * from: any;
22
+ * isMain: any;
23
+ * openerStepId: any;
24
+ * }} TabInfo
25
+ */
26
+
27
+ class TabService {
28
+ /** @param {import('../webdriver')} driver */
29
+ constructor(driver) {
30
+ this.driver = driver;
31
+ /** @type {Record<string, TabUtil>} */
32
+ this._utils = {};
33
+ /** @type {Record<string, { tabCount: number; tabInfos: Record<string, TabInfo> }>} */
34
+ this.sessionTabs = {};
35
+ /** @type {Record<string, string>} */
36
+ this.pendingTabs = {};
37
+ /** @type {Record<string, Set<any>>} */
38
+ this.addedTabs = {};
39
+ }
40
+
41
+ on() {}
42
+
43
+ tabCount(sessionId) {
44
+ }
45
+
46
+ getAllOpenTabIds(sessionId) {
47
+ }
48
+
49
+ /**
50
+ * Get last tab info for pixel validation
51
+ *
52
+ * @returns last tab info
53
+ */
54
+ getActiveTabInfo(sessionId) {
55
+ }
56
+
57
+ getAllTabIds(sessionId) {
58
+ }
59
+
60
+ isSessionTab(sessionId, tabId) {
61
+ }
62
+
63
+ createSesion(sessionId) {
64
+ }
65
+
66
+ setAddFrameHandlerCallBack(addFrameHandlerCb) {
67
+ }
68
+
69
+ getAllTabInfoStrings(sessionId) {
70
+ }
71
+
72
+ getAllTabInfos(sessionId) {
73
+ }
74
+
75
+ addNewTab(sessionId, tabId, openerStepId, options = {}) {
76
+ }
77
+
78
+ addOpenerStepId(sessionId, tabId, openerStepId) {
79
+ }
80
+ addOpenerStep(sessionId, tabId, openerStep) {
81
+ }
82
+
83
+ fixMissingMainTab(sessionId) {
84
+ }
85
+
86
+ buildTabInfo(sessionId, tabId, order, openerStepId, options = {}) {
87
+ }
88
+
89
+ addTab(sessionId, id, order, openerStepId, options = {}) {
90
+ }
91
+
92
+ getTabUtilsByTabIdAndSessionId(sessionId, tabId) {
93
+ }
94
+
95
+ getTabUtilsByTabId(tabId) {
96
+ }
97
+
98
+ getTabInfo(sessionId, id) {
99
+ }
100
+
101
+ getTabUtils(sessionId, tabInfo) {
102
+ }
103
+
104
+ exactUrlMatch(first, second, allUrls) {
105
+ }
106
+
107
+ singleExactMatchForParts(first, second, allUrls, combinePartsFunction) {
108
+ }
109
+
110
+ isSameTab(sessionId, first, second) {
111
+ }
112
+
113
+ getMainTabInfo(sessionId) {
114
+ }
115
+
116
+ getMainTabUtils(sessionId) {
117
+ }
118
+
119
+ removeTabInfo(sessionId, tabId) {
120
+ }
121
+
122
+ getMainTabId(sessionId) {
123
+ }
124
+
125
+ isMainTabExists(sessionId) {
126
+ }
127
+
128
+ clearAllTabs(sessionId) {
129
+ }
130
+
131
+ clearNonMainTabs(sessionId) {
132
+ }
133
+
134
+ switchTab(tabId, sessionId, { forceSwitch } = { forceSwitch: false }) {
135
+ }
136
+
137
+ getTabDetails(tabId, sessionId, options = {}) {
138
+ }
139
+
140
+ getUnregisteredTabId(sessionId) {
141
+ }
142
+
143
+ waitForTabToOpen(sessionId) {
144
+ }
145
+
146
+ tryToAddTab(sessionId, openerStepId) {
147
+
148
+ }
149
+
150
+ addNewPopup(id, openerStepId) {
151
+ }
152
+
153
+ waitToPendingTabs(id, openerStepId) {
154
+ }
155
+
156
+ isMainTabIncognito() {
157
+ }
158
+
159
+ isInvalidStepVersion(step) {
160
+ }
161
+
162
+ getTabIdByTabInfo(sessionId, step) {
163
+ }
164
+ }
165
+
166
+ module.exports = TabService;
@@ -1,15 +1,14 @@
1
- "use strict";
1
+ 'use strict';
2
2
 
3
3
  const StepAction = require('./stepAction');
4
- const url = require('url');
4
+ const requiredUrl = require('url');
5
5
  const Promise = require('bluebird');
6
6
 
7
7
  class NavigationStepAction extends StepAction {
8
-
9
8
  updateBaseUrl(location) {
10
- let orgUrl = url.parse(location);
11
- const baseLocation = url.parse(this.context.recordedBaseUrl);
12
- const newBaseLocation = url.parse(this.context.baseUrl);
9
+ const orgUrl = requiredUrl.parse(location);
10
+ const baseLocation = requiredUrl.parse(this.context.recordedBaseUrl);
11
+ const newBaseLocation = requiredUrl.parse(this.context.baseUrl);
13
12
  if (orgUrl.host === baseLocation.host && baseLocation.host !== newBaseLocation.host) {
14
13
  orgUrl.host = newBaseLocation.host;
15
14
  }
@@ -18,12 +17,14 @@ class NavigationStepAction extends StepAction {
18
17
 
19
18
  performAction() {
20
19
  const url = this.context.data.testimNavigationStepDestination || this.context.data.url;
21
-
20
+ // Opens a new tab and switches to new tab
21
+ if (this.step.openInNewTab) {
22
+ return this.driver.client.newWindow(url).then(() => {});
23
+ }
22
24
  return this.updateBaseUrl(url)
23
- .then(url => this.driver.url(url))
24
- .then(() => Promise.resolve());
25
+ .then(updatedUrl => this.driver.url(updatedUrl))
26
+ .then(() => {});
25
27
  }
26
-
27
28
  }
28
29
 
29
30
  module.exports = NavigationStepAction;
@@ -1,12 +1,11 @@
1
- "use strict";
1
+ 'use strict';
2
2
 
3
3
  const StepAction = require('./stepAction');
4
- const Promise = require("bluebird");
4
+ const { delay } = require('../../utils');
5
5
 
6
6
  class SleepStepAction extends StepAction {
7
-
8
- performAction() {
9
- return Promise.delay(this.step.durationMS).then(() => Promise.resolve());
7
+ async performAction() {
8
+ await delay(this.step.durationMS);
10
9
  }
11
10
  }
12
11
 
@@ -3,8 +3,21 @@
3
3
  const { commonConstants } = require('../../commons/getSessionPlayerRequire');
4
4
  const Promise = require('bluebird');
5
5
 
6
+ /** @typedef {typeof import('clickim/src/background/stepActions/stepAction').StepAction} ClickimStepActionCtor */
7
+ /** @typedef {ConstructorParameters<ClickimStepActionCtor>} ClickimStepActionCtorParams */
8
+ /** @typedef {InstanceType<ClickimStepActionCtor>} ClickimStepAction */
9
+
6
10
  class StepAction {
7
- constructor(step, context, frameHandler, exportsGlobal = {}, stepActionUtils, locateElementPlayer, exportsTest = {}) {
11
+ /** @type {(...args: ClickimStepActionCtorParams) => this} */
12
+ constructor(
13
+ step,
14
+ context,
15
+ frameHandler,
16
+ exportsGlobal = {},
17
+ stepActionUtils = undefined,
18
+ locateElementPlayer = undefined,
19
+ exportsTest = {},
20
+ ) {
8
21
  this.step = step;
9
22
  this.context = context;
10
23
  this.frameHandler = frameHandler;
@@ -28,6 +41,7 @@ class StepAction {
28
41
  return this.context.data[targetId];
29
42
  }
30
43
 
44
+ /** @type {ClickimStepAction['execute']} */
31
45
  execute(stepActionFactory, step) {
32
46
  return Promise.resolve(this.performAction(stepActionFactory, step))
33
47
  .then(res => Promise.resolve(Object.assign({}, { success: true }, res)))
@@ -6,12 +6,10 @@ const Promise = require('bluebird');
6
6
  const { codeSnippets } = require('../../commons/getSessionPlayerRequire');
7
7
  const dispatchFocus = require('./scripts/focusElement');
8
8
  const sessionPlayer = require('../../commons/getSessionPlayerRequire');
9
- const { extractElementId } = require('../../utils');
10
- const util = require('util');
9
+ const { extractElementId, delay } = require('../../utils');
11
10
 
12
11
  const constants = sessionPlayer.commonConstants.stepResult;
13
- const setTextDraftJs = codeSnippets && codeSnippets.setTextDraftJs;
14
- const delay = util.promisify(setTimeout);
12
+ const setTextDraftJs = codeSnippets?.setTextDraftJs;
15
13
  class TextStepAction extends StepAction {
16
14
  setValueNative() {
17
15
  const context = this.context;
@@ -61,12 +59,7 @@ class TextStepAction extends StepAction {
61
59
  const eventParam = this.driver.isEdge() ? JSON.stringify(eventMessage) : eventMessage;
62
60
 
63
61
  return this.driver.executeCodeAsync(setTextCode, timeout, eventParam)
64
- .then(result => {
65
- if (result.value && result.value.success) {
66
- return Promise.resolve({ success: true });
67
- }
68
- return Promise.resolve({ success: false });
69
- });
62
+ .then(result => ({ success: Boolean(result.value?.success) }));
70
63
  }
71
64
 
72
65
  async setTextDelayed() {
@@ -86,7 +79,7 @@ class TextStepAction extends StepAction {
86
79
  const context = this.context;
87
80
  const target = this.getTarget();
88
81
 
89
- if (target && target.seleniumElement) {
82
+ if (target?.seleniumElement) {
90
83
  if (!this.step.delayBetweenChars) {
91
84
  keys.push(Array.from(context.stepText));
92
85
  return this.driver.elementIdValue(extractElementId(target.seleniumElement), keys);
@@ -4,6 +4,7 @@ const { locatorBuilderUtils, utils, codeSnippets } = sessionPlayer;
4
4
  const CookieUtils = require('./cookieUtils');
5
5
 
6
6
  class StepActionUtils {
7
+ /** @param {import('../webdriver')} driver */
7
8
  constructor(driver, cookieUtils) {
8
9
  this.driver = driver;
9
10
  this._abortedSteps = [];
@@ -63,8 +64,9 @@ class StepActionUtils {
63
64
  return this.driver.getElementTextJS(locatedElement);
64
65
  }
65
66
 
66
- markDynamicParent(target, id) {
67
- return this.driver.markDynamicParent(target, id);
67
+ /** @type {import('clickim/src/background/stepActions/stepActionUtils').StepActionUtils['markDynamicParent']} */
68
+ async markDynamicParent(target, id, frameHandler) {
69
+ return this.driver.markDynamicParent(target, id, frameHandler);
68
70
  }
69
71
 
70
72
  getCookie(name) {