@testim/testim-cli 3.213.0 → 3.217.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testim/testim-cli",
3
- "version": "3.213.0",
3
+ "version": "3.217.0",
4
4
  "description": "Command line interface for running Testing on your CI",
5
5
  "author": "Oren Rubin",
6
6
  "contributors": [{
@@ -17,23 +17,22 @@
17
17
  "@types/node": "10.17.24",
18
18
  "@types/selenium-webdriver": "4.0.9",
19
19
  "bundle-deps": "1.0.0",
20
- "chai": "4.2.0",
20
+ "chai": "4.3.4",
21
21
  "chai-as-promised": "7.1.1",
22
22
  "gulp": "4.0.2",
23
23
  "gulp-cli": "2.3.0",
24
24
  "gulp-json-editor": "2.5.4",
25
25
  "gulp-preprocess": "3.0.3",
26
- "husky": "4.3.8",
27
26
  "merge-stream": "2.0.0",
28
- "mocha": "7.2.0",
27
+ "mocha": "9.2.0",
29
28
  "nyc": "15.1.0",
30
29
  "proxyquire": "2.1.3",
31
- "request": "2.88.2",
30
+ "request": "2.88.0",
32
31
  "sinon": "9.0.2",
33
- "sinon-chai": "3.5.0",
34
- "ts-node": "8.10.1",
35
- "tsconfig-paths": "3.9.0",
36
- "typescript": "3.9.3"
32
+ "sinon-chai": "3.7.0",
33
+ "ts-node": "9.1.1",
34
+ "tsconfig-paths": "3.12.0",
35
+ "typescript": "4.5.5"
37
36
  },
38
37
  "lazyDependencies": {
39
38
  "ngrok": "3.4.0",
@@ -51,15 +50,15 @@
51
50
  "@applitools/eyes-sdk-core": "12.23.12",
52
51
  "@applitools/visual-grid-client": "15.8.31",
53
52
  "@testim/coralogix-logger": "1.1.27-beta",
54
- "@testim/webdriverio": "0.0.4",
53
+ "@testim/webdriverio": "0.0.5",
55
54
  "abort-controller": "3.0.0",
56
- "ajv": "6.12.2",
55
+ "ajv": "6.12.6",
57
56
  "analytics-node": "5.0.0",
58
57
  "appium-dom-utils": "1.0.6",
59
58
  "archiver": "3.1.1",
60
59
  "bluebird": "3.7.2",
61
60
  "bluebird-retry": "0.11.0",
62
- "body-parser": "1.19.0",
61
+ "body-parser": "1.19.1",
63
62
  "chalk": "4.1.0",
64
63
  "chrome-launcher": "0.13.4",
65
64
  "combine-source-map": "0.8.0",
@@ -86,7 +85,7 @@
86
85
  "mkdirp": "1.0.4",
87
86
  "moment": "2.25.3",
88
87
  "ms": "2.1.2",
89
- "npm": "6.14.11",
88
+ "npm": "8.3.0",
90
89
  "object-hash": "2.0.3",
91
90
  "ora": "4.0.4",
92
91
  "pako": "1.0.11",
@@ -97,7 +96,7 @@
97
96
  "rox-node": "4.9.18",
98
97
  "semver": "7.3.2",
99
98
  "serialize-error": "7.0.1",
100
- "socket.io-client": "2.4.0",
99
+ "socket.io-client": "4.4.1",
101
100
  "superagent": "3.8.3",
102
101
  "superagent-proxy": "3.0.0",
103
102
  "test-exclude": "6.0.0",
@@ -115,8 +114,8 @@
115
114
  "testim": "cli.js"
116
115
  },
117
116
  "scripts": {
118
- "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",
119
- "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",
117
+ "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",
118
+ "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",
120
119
  "test:cov": "nyc --reporter=lcov --reporter=text yarn test",
121
120
  "upload-bundle-s3": "scripts/upload.js",
122
121
  "prepare-version": "rm -rf ./deploy && mkdir -p deploy && gulp prepare-version-on-prem",
@@ -125,6 +124,6 @@
125
124
  "pack-serve": "yarn pack-onprem && http-server deploy/"
126
125
  },
127
126
  "engines": {
128
- "node": ">= 10.0.0"
127
+ "node": ">= 12.0.0"
129
128
  }
130
129
  }
@@ -4,7 +4,7 @@ const TabService = require('./services/tabService');
4
4
  const PortSelector = require('./services/portSelector');
5
5
  const windowCreationListener = require('./services/windowCreationListener');
6
6
  const CookieUtils = require('./utils/cookieUtils');
7
- const FrameLocator = require('./services/frameLocator');
7
+ const frameLocatorFactory = require('./services/frameLocator');
8
8
  const Promise = require('bluebird');
9
9
  const { isDebuggerConnected } = require('../commons/detectDebugger');
10
10
 
@@ -45,12 +45,14 @@ class SeleniumTestPlayer {
45
45
 
46
46
  this.tabService.createSesion(id);
47
47
 
48
+ const FrameLocator = frameLocatorFactory(this.driver);
49
+
48
50
  this.sessionPlayer = new player(
49
51
  id,
50
52
  this.tabService,
51
53
  CookieUtils(this.driver),
52
54
  windowCreationListener,
53
- FrameLocator(this.driver),
55
+ FrameLocator,
54
56
  PortSelector,
55
57
  null,
56
58
  null /* Not in use, placeholder for the order of arguments */,
@@ -8,123 +8,127 @@ const featureFlags = require('../../commons/featureFlags');
8
8
  const SELENIUM_ELEMENT_KEY = 'ELEMENT';
9
9
  const SELENIUM_GUID_KEY = 'element-6066-11e4-a52e-4f735466cecf';
10
10
 
11
- module.exports = function (driver) {
12
- const FrameLocator = function (frameManager, locateElementPlayer) {
13
- this.frameManager = frameManager;
14
- this.locateElementPlayer = locateElementPlayer;
15
- this._cache = {};
16
- };
11
+ const _getGuidFromSeleniumElement = (seleniumElement) => {
12
+ if (!seleniumElement) {
13
+ return null;
14
+ }
17
15
 
18
- const _getGuidFromSeleniumElement = (seleniumElement) => {
19
- if (!seleniumElement) {
20
- return null;
21
- }
16
+ return seleniumElement[SELENIUM_ELEMENT_KEY] || seleniumElement[SELENIUM_GUID_KEY];
17
+ };
22
18
 
23
- return seleniumElement[SELENIUM_ELEMENT_KEY] || seleniumElement[SELENIUM_GUID_KEY];
24
- };
19
+ /** @param {import('../webdriver')} driver*/
20
+ module.exports = function frameLocatorFactory(driver) {
21
+ class FrameLocator {
22
+ constructor(frameManager, locateElementPlayer) {
23
+ this.frameManager = frameManager;
24
+ this.locateElementPlayer = locateElementPlayer;
25
+ this._cache = {};
26
+ }
25
27
 
26
- FrameLocator.prototype.cacheResults = function (seleniumGuid, resultsUrl) {
27
- this._cache[seleniumGuid] = resultsUrl;
28
- };
28
+ cacheResults(seleniumGuid, resultsUrl) {
29
+ this._cache[seleniumGuid] = resultsUrl;
30
+ }
29
31
 
30
- FrameLocator.prototype.getResultsFromCache = function (seleniumGuid) {
31
- return this._cache[seleniumGuid];
32
- };
32
+ getResultsFromCache(seleniumGuid) {
33
+ return this._cache[seleniumGuid];
34
+ }
33
35
 
34
- FrameLocator.prototype.cacheFrameLocateResults = function (frameHandler) {
35
- if (frameHandler && frameHandler.seleniumFrameElement && frameHandler.frameLocateResultUrl) {
36
- const guid = _getGuidFromSeleniumElement(frameHandler.seleniumFrameElement);
37
- if (guid) {
38
- this.cacheResults(guid, frameHandler.frameLocateResultUrl);
36
+ cacheFrameLocateResults(frameHandler) {
37
+ if (frameHandler && frameHandler.seleniumFrameElement && frameHandler.frameLocateResultUrl) {
38
+ const guid = _getGuidFromSeleniumElement(frameHandler.seleniumFrameElement);
39
+ if (guid) {
40
+ this.cacheResults(guid, frameHandler.frameLocateResultUrl);
41
+ }
39
42
  }
40
43
  }
41
- };
42
44
 
43
- FrameLocator.prototype.foundFrameCallback = function (result, frameTree, testimFrameId) {
44
- const { frameOffset, locatedElement } = result;
45
- if (locatorBuilderUtils.isEmptyResult(locatedElement)) {
46
- logger.error('got empty result in frame result, not rejected from locate element player');
47
- return Promise.reject();
45
+ foundFrameCallback(result, frameTree, testimFrameId) {
46
+ const { frameOffset, locatedElement } = result;
47
+ if (locatorBuilderUtils.isEmptyResult(locatedElement)) {
48
+ logger.error('got empty result in frame result, not rejected from locate element player');
49
+ return Promise.reject();
50
+ }
51
+ return driver.switchToLocatedFrame(locatedElement)
52
+ .then(el => {
53
+ const guid = _getGuidFromSeleniumElement(el.value);
54
+ const frameLocateResultUrl = this.getResultsFromCache(guid);
55
+
56
+ return {
57
+ frameId: -1,
58
+ frameOffset,
59
+ tabInfo: frameTree.tabInfo,
60
+ tabId: frameTree.tabId,
61
+ testimFrameId,
62
+ testimFullFrameId: `${this.currentFrameHandler.testimFullFrameId}-${testimFrameId}`,
63
+ seleniumFrameElement: el.value,
64
+ frameLocateResultUrl,
65
+ };
66
+ });
48
67
  }
49
- return driver.switchToLocatedFrame(locatedElement)
50
- .then(el => {
51
- const guid = _getGuidFromSeleniumElement(el.value);
52
- const frameLocateResultUrl = this.getResultsFromCache(guid);
53
68
 
54
- return {
55
- frameId: -1,
56
- frameOffset,
57
- tabInfo: frameTree.tabInfo,
58
- tabId: frameTree.tabId,
59
- testimFrameId,
60
- testimFullFrameId: `${this.currentFrameHandler.testimFullFrameId}-${testimFrameId}`,
61
- seleniumFrameElement: el.value,
62
- frameLocateResultUrl,
63
- };
64
- });
65
- };
69
+ locate(frameLocator, frameDepth, currentFrame, context, frameTree, stepData) {
70
+ // eslint-disable-next-line new-cap
71
+ const locateElementPlayer = new this.locateElementPlayer(context);
72
+ frameLocator.targetId = `frameLocator_${frameDepth}`;
73
+ return locateElementPlayer.locate(frameLocator, currentFrame, frameLocator.targetId)
74
+ .then(result => {
75
+ result.isVisible = true; // frame visibility check is done on the target element
76
+ return locateElementPlayer.handleLocateResult(result, stepData, frameLocator)
77
+ .catch(() => { throw new Error(); }); // silence [object object] errors;
78
+ })
79
+ .then(result => {
80
+ const { locatedElement } = context.data[frameLocator.targetId];
81
+ return driver.getElementLocationWithPadding(locatedElement)
82
+ .then(location => {
83
+ const value = location.value || { top: 0, left: 0 };
84
+ result.frameOffset = {
85
+ top: currentFrame.frameOffset.top + value.top,
86
+ left: currentFrame.frameOffset.left + value.left,
87
+ };
88
+ return result;
89
+ });
90
+ })
91
+ .then(result => {
92
+ if (locateElementPlayer.addFrameDataToContext) {
93
+ locateElementPlayer.addFrameDataToContext(result.targetId, result.locateResult);
94
+ }
95
+ return this.foundFrameCallback(result, frameTree, frameLocator.testimFrameId);
96
+ })
97
+ .then(frameHandler => {
98
+ this.currentFrameHandler = frameHandler;
99
+ return frameHandler;
100
+ });
101
+ }
66
102
 
67
- FrameLocator.prototype.locate = function (frameLocator, frameDepth, currentFrame, context, frameTree, stepData) {
68
- // eslint-disable-next-line
69
- var locateElementPlayer = new this.locateElementPlayer(context);
70
- frameLocator.targetId = `frameLocator_${frameDepth}`;
71
- return locateElementPlayer.locate(frameLocator, currentFrame, frameLocator.targetId)
72
- .then(result => {
73
- result.isVisible = true; // frame visibility check is done on the target element
74
- return locateElementPlayer.handleLocateResult(result, stepData, frameLocator)
75
- .catch(() => { throw new Error(); }); // silence [object object] errors;
76
- })
77
- .then(result => {
78
- const { locatedElement } = context.data[frameLocator.targetId];
79
- return driver.getElementLocationWithPadding(locatedElement)
80
- .then(location => {
81
- const value = location.value || { top: 0, left: 0 };
82
- result.frameOffset = {
83
- top: currentFrame.frameOffset.top + value.top,
84
- left: currentFrame.frameOffset.left + value.left,
85
- };
86
- return result;
87
- });
88
- })
89
- .then(result => {
90
- if (locateElementPlayer.addFrameDataToContext) {
91
- locateElementPlayer.addFrameDataToContext(result.targetId, result.locateResult);
103
+ findFrame(stepData, frameLocators, context, frameTree) {
104
+ const allowNoFrameSwitch = featureFlags.flags.enableFrameSwitchOptimization.isEnabled();
105
+ const chronologicalResults = context.playback.resultsHandler.resultsByChronologicOrder;
106
+ const lastResult = chronologicalResults[chronologicalResults.length - 1];
107
+ const allowedRetries = 1;
108
+ const moreThanAllowedRetries = Boolean(lastResult) && lastResult.stepId === stepData.id && lastResult.results.length > allowedRetries;
109
+ if (allowNoFrameSwitch && !moreThanAllowedRetries && this.currentFrameHandler) {
110
+ const currentFramePos = frameLocators.findIndex(x => x.testimFrameId === this.currentFrameHandler.testimFrameId);
111
+ if (currentFramePos > -1) {
112
+ const shorterPath = frameLocators.slice(currentFramePos + 1);
113
+ return Promise.reduce(shorterPath, (currentFrame, frameLocator, index) => this.locate(frameLocator, index, currentFrame, context, frameTree, stepData), this.currentFrameHandler);
92
114
  }
93
- return this.foundFrameCallback(result, frameTree, frameLocator.testimFrameId);
94
- })
95
- .tap(frameHandler => {
96
- this.currentFrameHandler = frameHandler;
97
- });
98
- };
99
-
100
- FrameLocator.prototype.findFrame = function (stepData, frameLocators, context, frameTree) {
101
- const allowNoFrameSwitch = featureFlags.flags.enableFrameSwitchOptimization.isEnabled();
102
- const chronologicalResults = context.playback.resultsHandler.resultsByChronologicOrder;
103
- const lastResult = chronologicalResults[chronologicalResults.length - 1];
104
- const allowedRetries = 1;
105
- const moreThanAllowedRetries = Boolean(lastResult) && lastResult.stepId === stepData.id && lastResult.results.length > allowedRetries;
106
- if (allowNoFrameSwitch && !moreThanAllowedRetries && this.currentFrameHandler) {
107
- const currentFramePos = frameLocators.findIndex(x => x.testimFrameId === this.currentFrameHandler.testimFrameId);
108
- if (currentFramePos > -1) {
109
- const shorterPath = frameLocators.slice(currentFramePos + 1);
110
- return Promise.reduce(shorterPath, (currentFrame, frameLocator, index) => this.locate(frameLocator, index, currentFrame, context, frameTree, stepData), this.currentFrameHandler);
111
115
  }
112
- }
113
116
 
114
- return frameTree.getTopFrameHandler()
115
- .then(topFrameHandler => {
116
- topFrameHandler.frameOffset = { top: 0, left: 0 };
117
- const switchToTop = (allowNoFrameSwitch && this.currentFrameHandler === topFrameHandler) ?
118
- Promise.resolve(this.currentFrameHandler) :
119
- driver.switchToTopFrame();
120
- return switchToTop.then(() => {
121
- this.cacheFrameLocateResults(this.currentFrameHandler);
122
- this.currentFrameHandler = topFrameHandler;
123
- return Promise.reduce(frameLocators, (currentFrame, frameLocator, index) =>
124
- this.locate(frameLocator, index, currentFrame, context, frameTree, stepData), topFrameHandler);
117
+ return frameTree.getTopFrameHandler()
118
+ .then(topFrameHandler => {
119
+ topFrameHandler.frameOffset = { top: 0, left: 0 };
120
+ const switchToTop = (allowNoFrameSwitch && this.currentFrameHandler === topFrameHandler) ?
121
+ Promise.resolve(this.currentFrameHandler) :
122
+ driver.switchToTopFrame();
123
+ return switchToTop.then(() => {
124
+ this.cacheFrameLocateResults(this.currentFrameHandler);
125
+ this.currentFrameHandler = topFrameHandler;
126
+ return Promise.reduce(frameLocators, (currentFrame, frameLocator, index) =>
127
+ this.locate(frameLocator, index, currentFrame, context, frameTree, stepData), topFrameHandler);
128
+ });
125
129
  });
126
- });
127
- };
130
+ }
131
+ }
128
132
 
129
133
  return FrameLocator;
130
134
  };
@@ -72,9 +72,9 @@ class TabService {
72
72
  }
73
73
 
74
74
  getAllTabInfoStrings(sessionId) {
75
- var allIds = this.getAllTabIds(sessionId);
75
+ const allIds = this.getAllTabIds(sessionId);
76
76
  return allIds.map(tabId => {
77
- var tabInfo = this.getTabInfo(sessionId, tabId);
77
+ const tabInfo = this.getTabInfo(sessionId, tabId);
78
78
  return `tabId=${tabId}, url=${tabInfo.url}, order=${tabInfo.order}, isMain=${tabInfo.isMain}, openerStepId=${tabInfo.openerStepId}, isClosed=${tabInfo.isClosed}, currentUrl: ${tabInfo.currentUrl}, lastUpdatedUrl: ${tabInfo.lastUpdatedUrl}`;
79
79
  });
80
80
  }
@@ -116,7 +116,7 @@ class TabService {
116
116
  buildTabInfo(sessionId, tabId, order, openerStepId, options = {}) {
117
117
  return this.getTabDetails(tabId, sessionId, options)
118
118
  .then(tab => {
119
- var infoId = guid();
119
+ const infoId = guid();
120
120
 
121
121
  function isMainTab(tabService) {
122
122
  if (options.checkForMainTab) {
@@ -147,7 +147,7 @@ class TabService {
147
147
  addTab(sessionId, id, order, openerStepId, options = {}) {
148
148
  return this.buildTabInfo(sessionId, id, order, openerStepId, options)
149
149
  .then(infoId => {
150
- var _windowUtils = new WindowUtils(id, this.driver);
150
+ const _windowUtils = new WindowUtils(id, this.driver);
151
151
  this._utils[infoId] = {
152
152
  attachDebugger: () => Promise.resolve(),
153
153
  detachDebugger: () => Promise.resolve(),
@@ -191,15 +191,15 @@ class TabService {
191
191
  return this.getMainTabUtils(sessionId);
192
192
  }
193
193
 
194
- var infos = this.getAllTabInfos(sessionId);
195
- var nonMainTabs = Object.keys(infos)
194
+ const infos = this.getAllTabInfos(sessionId);
195
+ const nonMainTabs = Object.keys(infos)
196
196
  .map(tabId => infos[tabId])
197
197
  .filter(info => !info.isMain);
198
198
  if (nonMainTabs.length === 1) {
199
199
  return this._utils[nonMainTabs[0].infoId];
200
200
  }
201
201
 
202
- var sameTabs = Object.keys(sessionId)
202
+ const sameTabs = Object.keys(sessionId)
203
203
  .map(key => sessionId[key])
204
204
  .filter(info => this.isSameTab(sessionId, tabInfo, info));
205
205
  if (sameTabs.length > 0) {
@@ -211,7 +211,7 @@ class TabService {
211
211
  }
212
212
 
213
213
  exactUrlMatch(first, second, allUrls) {
214
- var exactUrlMatch = allUrls
214
+ const exactUrlMatch = allUrls
215
215
  .filter(url => url === second.url);
216
216
 
217
217
  if ((first.url === second.url || first.currentUrl === second.url || (first.currentUrl && (first.currentUrl === second.currentUrl))) && (exactUrlMatch.length === 1)) {
@@ -221,11 +221,11 @@ class TabService {
221
221
  }
222
222
 
223
223
  singleExactMatchForParts(first, second, allUrls, combinePartsFunction) {
224
- var firstUrlParts = UrlUtils.urlBreaker(first.url || first.currentUrl);
225
- var secondUrlParts = UrlUtils.urlBreaker(second.url || second.currentUrl);
226
- var firstPartsCombined = combinePartsFunction(firstUrlParts);
227
- var secondPartsCombined = combinePartsFunction(secondUrlParts);
228
- var allDomainAndPathMatches = allUrls.map(url => UrlUtils.urlBreaker(url))
224
+ const firstUrlParts = UrlUtils.urlBreaker(first.url || first.currentUrl);
225
+ const secondUrlParts = UrlUtils.urlBreaker(second.url || second.currentUrl);
226
+ const firstPartsCombined = combinePartsFunction(firstUrlParts);
227
+ const secondPartsCombined = combinePartsFunction(secondUrlParts);
228
+ const allDomainAndPathMatches = allUrls.map(url => UrlUtils.urlBreaker(url))
229
229
  .map(urlParts => combinePartsFunction(urlParts))
230
230
  .filter(combinedParts => combinedParts === firstPartsCombined);
231
231
  if ((firstPartsCombined === secondPartsCombined) && (allDomainAndPathMatches.length === 1)) {
@@ -251,20 +251,20 @@ class TabService {
251
251
  return true;
252
252
  }
253
253
 
254
- var infos = this.getAllTabInfos(sessionId);
255
- var alltopFrameUrls = Object.keys(infos)
254
+ const infos = this.getAllTabInfos(sessionId);
255
+ const alltopFrameUrls = Object.keys(infos)
256
256
  .map(tabId => infos[tabId].url);
257
257
 
258
258
  if (this.exactUrlMatch(first, second, alltopFrameUrls)) {
259
259
  return true;
260
260
  }
261
261
 
262
- var combineDomainAndPath = urlParts => (`${urlParts.domain}/${urlParts.path.join('/')}`);
262
+ const combineDomainAndPath = urlParts => (`${urlParts.domain}/${urlParts.path.join('/')}`);
263
263
  if (this.singleExactMatchForParts(first, second, alltopFrameUrls, combineDomainAndPath)) {
264
264
  return true;
265
265
  }
266
266
 
267
- var combineDomainPathAndHash = urlParts => (`${urlParts.domain}/${urlParts.path.join('/')}#${urlParts.hash}`);
267
+ const combineDomainPathAndHash = urlParts => (`${urlParts.domain}/${urlParts.path.join('/')}#${urlParts.hash}`);
268
268
  if (this.singleExactMatchForParts(first, second, alltopFrameUrls, combineDomainPathAndHash)) {
269
269
  return true;
270
270
  }
@@ -277,14 +277,14 @@ class TabService {
277
277
  }
278
278
 
279
279
  getMainTabInfo(sessionId) {
280
- var infos = this.getAllTabInfos(sessionId);
280
+ const infos = this.getAllTabInfos(sessionId);
281
281
  return Object.keys(infos)
282
282
  .map(id => infos[id])
283
283
  .find(tabInfo => tabInfo.isMain);
284
284
  }
285
285
 
286
286
  getMainTabUtils(sessionId) {
287
- var mainTabInfo = this.getMainTabInfo(sessionId);
287
+ const mainTabInfo = this.getMainTabInfo(sessionId);
288
288
  if (!mainTabInfo) {
289
289
  return {};
290
290
  }
@@ -292,20 +292,20 @@ class TabService {
292
292
  }
293
293
 
294
294
  removeTabInfo(sessionId, tabId) {
295
- var infos = this.getAllTabInfos(sessionId);
296
- var info = infos[tabId];
295
+ const infos = this.getAllTabInfos(sessionId);
296
+ const info = infos[tabId];
297
297
  delete this.sessionTabs[sessionId].tabInfos[tabId];
298
298
  delete this._utils[info.infoId];
299
299
  this.sessionTabs[sessionId].tabCount--;
300
300
  }
301
301
 
302
302
  getMainTabId(sessionId) {
303
- var infos = this.getAllTabInfos(sessionId);
303
+ const infos = this.getAllTabInfos(sessionId);
304
304
  return Object.keys(infos).find(id => infos[id].isMain);
305
305
  }
306
306
 
307
307
  isMainTabExists(sessionId) {
308
- var mainTabId = this.getMainTabId(sessionId);
308
+ const mainTabId = this.getMainTabId(sessionId);
309
309
  if (!mainTabId) {
310
310
  return Promise.resolve(false);
311
311
  }
@@ -313,7 +313,7 @@ class TabService {
313
313
  }
314
314
 
315
315
  clearAllTabs(sessionId) {
316
- var infos = this.getAllTabInfos(sessionId);
316
+ const infos = this.getAllTabInfos(sessionId);
317
317
 
318
318
  this.sessionTabs[sessionId].tabCount = 0;
319
319
  Object.keys(infos)
@@ -321,7 +321,7 @@ class TabService {
321
321
  }
322
322
 
323
323
  clearNonMainTabs(sessionId) {
324
- var infos = this.getAllTabInfos(sessionId);
324
+ const infos = this.getAllTabInfos(sessionId);
325
325
  Object.keys(infos)
326
326
  .filter(tabId => !infos[tabId].isMain)
327
327
  .forEach(tabId => this.removeTabInfo(sessionId, tabId));
@@ -414,9 +414,9 @@ class TabService {
414
414
  }
415
415
 
416
416
  waitToPendingTabs(id, openerStepId) {
417
- var retryInterval = 500;
418
- var timeToWait = 3000;
419
- var that = this;
417
+ const retryInterval = 500;
418
+ let timeToWait = 3000;
419
+ const that = this;
420
420
 
421
421
  if (!openerStepId) {
422
422
  return Promise.resolve();
@@ -186,18 +186,27 @@ ImageCaptureUtils.prototype = {
186
186
  },
187
187
 
188
188
  takeAreaDataUrl(areas, format) {
189
+ // Future changes in clickim will pass parameters to this function as a single object
190
+ if (areas.areas) {
191
+ areas = areas.areas;
192
+ }
193
+
189
194
  return this.screenshotUtils.takeScreenshot(format)
190
195
  .then((imageInfo) => cropImageFromImageData(areas, imageInfo).then((result) => {
191
196
  result.screenImage = imageInfo.image;
192
197
  result.absoluteScreenHighlight = getElementAbsoluteRectangle(
193
198
  areas.elementRect,
194
199
  imageInfo.devicePixelRatio);
195
-
196
200
  return Promise.resolve(result);
197
201
  }));
198
202
  },
199
203
 
200
204
  takeArea(areas) {
205
+ // Future changes in clickim will pass parameters to this function as a single object
206
+ if (areas.areas) {
207
+ areas = areas.areas;
208
+ }
209
+
201
210
  return this.screenshotUtils.takeScreenshot()
202
211
  .then((imageInfo) => {
203
212
  const result = {};
@@ -11,7 +11,7 @@ class ScreenshotUtils {
11
11
  }
12
12
 
13
13
  base64AddPadding(str) {
14
- return str + Array((4 - str.length % 4) % 4 + 1).join('=');
14
+ return str + Array(((4 - (str.length % 4)) % 4) + 1).join('=');
15
15
  }
16
16
 
17
17
  shouldTakeScreenshots() {
package/runOptions.js CHANGED
@@ -17,6 +17,7 @@ const utils = require('./utils');
17
17
  const runOptionsAgentFlow = require('./runOptionsAgentFlow');
18
18
  const runOptionsUtils = require('./runOptionsUtils');
19
19
  const localRunnerCache = require('./commons/runnerFileCache');
20
+ const chalk = require('chalk');
20
21
 
21
22
  const camelizeHyphenValues = (prop) => prop.replace(/-([a-z])/g, (m, w) => w.toUpperCase());
22
23
 
@@ -109,6 +110,10 @@ const printUsage = () => {
109
110
  return line.includes('--exit-code-ignore-failing-tests');
110
111
  }
111
112
 
113
+ function isDeprecatedHighSpeed(line) {
114
+ return line.includes('--high-speed'); // high speed mode was renamed to turbo mode
115
+ }
116
+
112
117
  program.help((txt) => {
113
118
  const lines = txt.split('\n');
114
119
  return lines
@@ -123,12 +128,18 @@ const printUsage = () => {
123
128
  !isUserId(ln) &&
124
129
  !isWebdriverTimeout(ln) &&
125
130
  !isSaveRCALocally(ln) &&
126
- !isExitCodeIgnoreFailingTests(ln)
131
+ !isExitCodeIgnoreFailingTests(ln) &&
132
+ !isDeprecatedHighSpeed(ln)
127
133
  )
128
134
  .join('\n');
129
135
  });
130
136
  };
131
137
 
138
+ const printDeprecationWarning = (deprecatedUsage, newUsage) => {
139
+ const newUsageString = newUsage ? `Please use ${newUsage} instead.` : '';
140
+ console.log(chalk.yellow(`\nWARNING: ${deprecatedUsage} is deprecated. ${newUsageString}\n`));
141
+ };
142
+
132
143
  const CODE_COVERAGE_REPORTER_OPTIONS = [
133
144
  'clover',
134
145
  'html',
@@ -323,7 +334,8 @@ program
323
334
  .option('--version [version]', 'print the current version of the Testim CLI and exit', false)
324
335
  .option('--monitor-performance', 'collect test playback performance data')
325
336
 
326
- .option('--high-speed', 'run in high speed mode')
337
+ .option('--high-speed', 'DEPRECATED: use --turbo-mode instead') // When removing, remove from the program.help output filter
338
+ .option('--turbo-mode', 'run in turbo mode')
327
339
  .option('--lightweight-mode [settings]', 'run lightweight mode')
328
340
  .option('--create-prefeched-data [location]', 'prefech data into local cache file')
329
341
  .option('--use-prefeched-data [location]', 'use prefeched data from local cache file, and force using only cached data')
@@ -958,6 +970,12 @@ module.exports = {
958
970
  }
959
971
  }
960
972
 
973
+ /** Handling deprecation of High speed mode (renamed to Turbo mode) */
974
+ if (program.highSpeed) {
975
+ printDeprecationWarning('--high-speed', ' --turbo-mode');
976
+ program.turboMode = true;
977
+ }
978
+
961
979
  if (program.lightweightMode) {
962
980
  try {
963
981
  const DEFAULTS = {
@@ -987,7 +1005,7 @@ module.exports = {
987
1005
  } catch (err) {
988
1006
  return Promise.reject(new ArgError(`failed to parse lightweightMode settings error: ${err.message}`));
989
1007
  }
990
- } else if (program.highSpeed && program.mode === CLI_MODE.EXTENSION) {
1008
+ } else if (program.turboMode && program.mode === CLI_MODE.EXTENSION) {
991
1009
  program.lightweightMode = {
992
1010
  general: true,
993
1011
  disableLabs: false,
@@ -1007,7 +1025,7 @@ module.exports = {
1007
1025
  uploadAssetsAndResultsOnFailure: true,
1008
1026
  preloadTests: false,
1009
1027
  disableProjectDefaults: false,
1010
- type: 'highSpeed',
1028
+ type: 'turboMode',
1011
1029
  };
1012
1030
  }
1013
1031