@testim/testim-cli 3.251.0 → 3.253.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 (34) hide show
  1. package/agent/routers/index.js +2 -1
  2. package/agent/routers/playground/router.js +1 -1
  3. package/commons/chrome-launcher.js +6 -6
  4. package/commons/constants.js +2 -0
  5. package/commons/getSessionPlayerRequire.js +2 -20
  6. package/commons/initializeUserWithAuth.js +2 -2
  7. package/commons/mockNetworkRuleFileSchema.json +40 -38
  8. package/commons/testimDesiredCapabilitiesBuilder.js +43 -0
  9. package/commons/testimServicesApi.js +11 -2
  10. package/credentialsManager.js +17 -20
  11. package/npm-shrinkwrap.json +2104 -444
  12. package/package.json +4 -2
  13. package/player/WebdriverioWebDriverApi.js +7 -2
  14. package/player/appiumTestPlayer.js +102 -0
  15. package/player/seleniumTestPlayer.js +3 -2
  16. package/player/services/frameLocator.js +2 -1
  17. package/player/services/mobileFrameLocatorMock.js +32 -0
  18. package/player/services/playbackTimeoutCalculator.js +1 -0
  19. package/player/services/portSelector.js +10 -8
  20. package/player/services/tabService.js +29 -0
  21. package/player/stepActions/sfdcRecordedStepAction.js +2 -2
  22. package/player/stepActions/sfdcStepAction.js +2 -2
  23. package/player/stepActions/stepAction.js +15 -1
  24. package/player/utils/stepActionUtils.js +4 -2
  25. package/player/utils/windowUtils.js +138 -125
  26. package/player/webdriver.js +39 -25
  27. package/reports/debugReporter.js +41 -39
  28. package/reports/jsonReporter.js +53 -50
  29. package/reports/reporter.js +135 -136
  30. package/runOptions.js +2 -1
  31. package/runners/ParallelWorkerManager.js +2 -0
  32. package/testRunStatus.js +457 -459
  33. package/workers/BaseWorker.js +13 -6
  34. package/workers/WorkerAppium.js +123 -0
@@ -5,159 +5,172 @@ const pRetry = require('p-retry');
5
5
  const { PageNotAvailableError } = require('../../errors');
6
6
  const logger = require('../../commons/logger').getLogger('window-utils');
7
7
 
8
- function WindowUtils(id, driver) {
9
- this.id = id;
10
- this.driver = driver;
11
- }
12
-
13
- WindowUtils.prototype.getElementFromPoint = function (x, y) {
14
- function elementFromPoint(x, y) {
15
- var el = document.elementFromPoint(x, y);
16
- return { testimId: el ? el.getAttribute('testim_dom_element_id') : null, tagName: el ? el.tagName : null };
8
+ class WindowUtils {
9
+ constructor(id, driver) {
10
+ this.id = id;
11
+ this.driver = driver;
17
12
  }
18
13
 
19
- return this.driver.executeJS(elementFromPoint, x, y).then(result => Promise.resolve(result.value));
20
- };
14
+ getElementFromPoint(x, y) {
15
+ /* eslint-disable */
16
+ function elementFromPoint(x, y) {
17
+ var el = document.elementFromPoint(x, y);
18
+ return { testimId: el ? el.getAttribute('testim_dom_element_id') : null, tagName: el ? el.tagName : null };
19
+ }
20
+ /* eslint-enable */
21
21
 
22
- WindowUtils.prototype.getLocation = function () {
23
- return this.driver.getUrl();
24
- };
22
+ return this.driver.executeJS(elementFromPoint, x, y).then(result => result.value);
23
+ }
25
24
 
26
- WindowUtils.prototype.stopListeningToScroll = function () {
27
- return Promise.resolve();
28
- };
25
+ getLocation() {
26
+ return this.driver.getUrl();
27
+ }
29
28
 
30
- WindowUtils.prototype.resumeListeningToScroll = function () {
31
- return Promise.resolve();
32
- };
29
+ stopListeningToScroll() {
30
+ return Promise.resolve();
31
+ }
33
32
 
34
- WindowUtils.prototype.scrollToPosition = function (pos) {
35
- return this.driver.scroll(pos.x, pos.y);
36
- };
33
+ resumeListeningToScroll() {
34
+ return Promise.resolve();
35
+ }
37
36
 
38
- WindowUtils.prototype.scrollToPositionWithoutAnimation = function (pos) {
39
- //if scroll behaviour is not supported, then the scrolling is not animated anyway
40
- function scrollWithoutAnimation(position) {
41
- var scrollBehaviorSupported = 'scrollBehavior' in document.documentElement.style;
42
- if (scrollBehaviorSupported) {
43
- return window.scrollTo({ left: position.x, top: position.y, behavior: 'instant' });
44
- }
45
- return window.scrollTo(position.x, position.y);
37
+ scrollToPosition(pos) {
38
+ return this.driver.scroll(pos.x, pos.y);
46
39
  }
47
- return this.driver.executeJS(scrollWithoutAnimation, pos);
48
- };
49
40
 
50
- WindowUtils.prototype.getCurrentScrollPosition = function () {
51
- function scrollPosition() {
52
- return { x: window.scrollX, y: window.scrollY };
41
+ scrollToPositionWithoutAnimation(pos) {
42
+ /* eslint-disable */
43
+ // if scroll behaviour is not supported, then the scrolling is not animated anyway
44
+ function scrollWithoutAnimation(position) {
45
+ var scrollBehaviorSupported = 'scrollBehavior' in document.documentElement.style;
46
+ if (scrollBehaviorSupported) {
47
+ return window.scrollTo({ left: position.x, top: position.y, behavior: 'instant' });
48
+ }
49
+ return window.scrollTo(position.x, position.y);
50
+ }
51
+ /* eslint-enable */
52
+ return this.driver.executeJS(scrollWithoutAnimation, pos);
53
53
  }
54
54
 
55
- return this.driver.executeJS(scrollPosition).then(result => Promise.resolve(result.value));
56
- };
55
+ getCurrentScrollPosition() {
56
+ /* eslint-disable */
57
+ function scrollPosition() {
58
+ return { x: window.scrollX, y: window.scrollY };
59
+ }
60
+ /* eslint-enable */
57
61
 
58
- WindowUtils.prototype.navigate = function (location, NAVIGATION_MAX_TIME = 15000) {
59
- const that = this;
62
+ return this.driver.executeJS(scrollPosition).then(result => result.value);
63
+ }
60
64
 
61
- async function navigate(retries = 3) {
62
- try {
63
- await that.driver.url(location);
64
- } catch (err) {
65
- const shouldRetryNavigation = err.seleniumStack && err.message.includes('method IWebBrowser2::Navigate2() failed');
66
- if (shouldRetryNavigation && retries > 0) {
67
- logger.warn('selenium navigation failed. retrying to navigate', { err });
68
- await Promise.delay(1500);
69
- return navigate(retries - 1);
65
+ navigate(location, NAVIGATION_MAX_TIME = 15000) {
66
+ const that = this;
67
+
68
+ async function navigate(retries = 3) {
69
+ try {
70
+ await that.driver.url(location);
71
+ } catch (err) {
72
+ const shouldRetryNavigation = err.seleniumStack && err.message.includes('method IWebBrowser2::Navigate2() failed');
73
+ if (shouldRetryNavigation && retries > 0) {
74
+ logger.warn('selenium navigation failed. retrying to navigate', { err });
75
+ await Promise.delay(1500);
76
+ return navigate(retries - 1);
77
+ }
78
+ throw err;
70
79
  }
71
- throw err;
80
+ return undefined;
72
81
  }
73
- return undefined;
82
+
83
+ return Promise.race([navigate(), Promise.delay(NAVIGATION_MAX_TIME)]);
74
84
  }
75
85
 
76
- return Promise.race([navigate(), Promise.delay(NAVIGATION_MAX_TIME)]);
77
- };
86
+ reloadTab(timeoutMSec = 15000) {
87
+ return Promise.race([
88
+ this.driver.reloadTab(),
89
+ Promise.delay(timeoutMSec),
90
+ ]);
91
+ }
78
92
 
79
- WindowUtils.prototype.reloadTab = (timeoutMSec = 15000) => {
80
- return Promise.race([
81
- this.driver.reloadTab(),
82
- Promise.delay(timeoutMSec),
83
- ]);
84
- };
93
+ getViewportSize() {
94
+ return this.driver.getViewportSize();
95
+ }
85
96
 
86
- WindowUtils.prototype.getViewportSize = function () {
87
- return this.driver.getViewportSize();
88
- };
97
+ maximizeWithoutValidation() {
98
+ return this.driver.maximizeWithoutValidation();
99
+ }
89
100
 
90
- WindowUtils.prototype.maximizeWithoutValidation = function () {
91
- return this.driver.maximizeWithoutValidation();
92
- }
101
+ getFullPageSize() {
102
+ /* eslint-disable */
103
+ function fullPageSize() {
104
+ var body = document.body;
105
+ var html = document.documentElement;
106
+ var height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
107
+ var width = Math.max(body.scrollWidth, body.offsetWidth, html.clientWidth, html.scrollWidth, html.offsetWidth);
108
+ return {
109
+ height: height,
110
+ width: width
111
+ };
112
+ }
113
+ /* eslint-enable */
114
+
115
+ return this.driver.executeJS(fullPageSize).then(result => result.value);
116
+ }
117
+
118
+ extractToNewWindow() {
119
+ return Promise.resolve();
120
+ }
121
+
122
+ checkSize(size) {
123
+ return Promise.delay(1000)
124
+ .then(() => this.getViewportSize())
125
+ .then(actualSize => {
126
+ if (actualSize.width !== size.width || actualSize.height !== size.height) {
127
+ return Promise.reject({ actualSize, expectedSize: size });
128
+ }
129
+ return { actualSize, expectedSize: size };
130
+ });
131
+ }
132
+
133
+ setViewportSize(size) {
134
+ return this.driver.setViewportSize(size.width, size.height)
135
+ .then(() => this.checkSize(size));
136
+ }
93
137
 
94
- WindowUtils.prototype.getFullPageSize = function () {
95
- function fullPageSize() {
96
- var body = document.body, html = document.documentElement;
97
- var height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
98
- var width = Math.max(body.scrollWidth, body.offsetWidth, html.clientWidth, html.scrollWidth, html.offsetWidth);
99
- return {
100
- height: height,
101
- width: width
102
- };
103
- }
104
-
105
- return this.driver.executeJS(fullPageSize).then(result => Promise.resolve(result.value));
106
- };
107
-
108
- WindowUtils.prototype.extractToNewWindow = function () {
109
- return Promise.resolve();
110
- };
111
-
112
- WindowUtils.prototype.checkSize = function (size) {
113
- return Promise.delay(1000)
114
- .then(() => this.getViewportSize())
115
- .then(actualSize => {
116
- if (actualSize.width !== size.width || actualSize.height !== size.height) {
117
- return Promise.reject({ actualSize: actualSize, expectedSize: size });
138
+ validatePageIsAvailable() {
139
+ /* eslint-disable */
140
+ function pageIsAvailable() {
141
+ var locationObj;
142
+ // this sometimes happens on IE
143
+ if (typeof location !== 'undefined') {
144
+ locationObj = location;
145
+ } else if (typeof window !== 'undefined' && typeof window.location !== 'undefined') {
146
+ locationObj = window.location;
147
+ } else {
148
+ return false;
118
149
  }
119
- return Promise.resolve({ actualSize: actualSize, expectedSize: size });
120
- });
121
- };
122
-
123
- WindowUtils.prototype.setViewportSize = function (size) {
124
- return this.driver.setViewportSize(size.width, size.height)
125
- .then(() => this.checkSize(size));
126
- };
127
-
128
- WindowUtils.prototype.validatePageIsAvailable = function () {
129
- function pageIsAvailable() {
130
- var locationObj;
131
- // this sometimes happens on IE
132
- if (typeof location !== 'undefined') {
133
- locationObj = location;
134
- } else if (typeof window !== 'undefined' && typeof window.location !== 'undefined') {
135
- locationObj = window.location;
136
- } else {
137
- return false;
150
+
151
+ return locationObj.href !== 'chrome-error://chromewebdata/' && locationObj.href !== 'safari-resource:/ErrorPage.html' && locationObj.href.indexOf('res://ieframe.dll/http_404.htm') !== 0 && locationObj.href.indexOf('ms-appx-web://microsoft.microsoftedge/assets/errorpages/') !== 0;
138
152
  }
153
+ /* eslint-enable */
139
154
 
140
- return locationObj.href !== 'chrome-error://chromewebdata/' && locationObj.href !== 'safari-resource:/ErrorPage.html' && locationObj.href.indexOf('res://ieframe.dll/http_404.htm') !== 0 && locationObj.href.indexOf('ms-appx-web://microsoft.microsoftedge/assets/errorpages/') !== 0;
155
+ return this.driver.executeJS(pageIsAvailable).then(result => (result.value ? Promise.resolve() : Promise.reject(new PageNotAvailableError())));
141
156
  }
142
157
 
143
- return this.driver.executeJS(pageIsAvailable).then(result => result.value ? Promise.resolve() : Promise.reject(new PageNotAvailableError()));
144
- };
145
-
146
- WindowUtils.prototype.focusTab = function () {
147
- return this.driver.switchTab(this.id);
148
- };
158
+ focusTab() {
159
+ return this.driver.switchTab(this.id);
160
+ }
149
161
 
150
- WindowUtils.prototype.quit = function () {
151
- return undefined;
152
- };
162
+ quit() {
163
+ return undefined;
164
+ }
153
165
 
154
- WindowUtils.prototype.getOsAndBrowser = function () {
155
- return pRetry(() => this.driver.getBrowserAndOS(), { retries: 3 })
156
- .then(osAndBrowser => ({ uaBrowserName: osAndBrowser.browser, uaOs: osAndBrowser.os, userAgent: osAndBrowser.userAgent, browserVersion: osAndBrowser.browserVersion }));
157
- };
166
+ getOsAndBrowser() {
167
+ return pRetry(() => this.driver.getBrowserAndOS(), { retries: 3 })
168
+ .then(osAndBrowser => ({ uaBrowserName: osAndBrowser.browser, uaOs: osAndBrowser.os, userAgent: osAndBrowser.userAgent, browserVersion: osAndBrowser.browserVersion }));
169
+ }
158
170
 
159
- WindowUtils.prototype.getUserAgentInfo = function () {
160
- return pRetry(() => this.driver.getUserAgentInfo(), { retries: 3 });
161
- };
171
+ getUserAgentInfo() {
172
+ return pRetry(() => this.driver.getUserAgentInfo(), { retries: 3 });
173
+ }
174
+ }
162
175
 
163
176
  module.exports = WindowUtils;
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable no-var */
2
+
2
3
  'use strict';
3
4
 
4
5
  const logger = require('../commons/logger').getLogger('webdriver');
@@ -34,7 +35,7 @@ const playerUtils = () => {
34
35
 
35
36
  async function getCdpAddress(initResult) {
36
37
  try {
37
- const debuggerHost = initResult && initResult.value && initResult.value['goog:chromeOptions'] && initResult.value['goog:chromeOptions'].debuggerAddress;
38
+ const debuggerHost = initResult?.value?.['goog:chromeOptions']?.debuggerAddress;
38
39
  if (!debuggerHost) {
39
40
  return undefined;
40
41
  }
@@ -66,10 +67,12 @@ class WebDriver extends WebDriverApi {
66
67
  this.browserClosedCallbacks = this.browserClosedCallbacks.filter(cb => cb !== callback);
67
68
  }
68
69
 
70
+ // eslint-disable-next-line max-len, default-param-last
69
71
  async init(browserOptions, testName, testRunConfig, gridInfo, customExtensionLocalLocation, executionId, testResultId, seleniumPerfStats = new SeleniumPerfStats(), fastInit = false, lambdatestService) {
70
72
  this.browserClosedFailedKeepAlives = 0;
71
73
  this.ignoreHiddenTagsText = _(browserOptions).get('company.activePlan.premiumFeatures.ignoreHiddenTagsText');
72
74
  this.browserClosedCallbacks = [];
75
+ // eslint-disable-next-line max-len
73
76
  const capabilities = desiredCapabilitiesBuilder.buildSeleniumOptions(browserOptions, testName, testRunConfig, gridInfo, customExtensionLocalLocation, executionId, testResultId, lambdatestService);
74
77
  if (capabilities.desiredCapabilities) {
75
78
  delete capabilities.desiredCapabilities.marionette;
@@ -77,8 +80,8 @@ class WebDriver extends WebDriverApi {
77
80
  if (capabilities.capabilities) {
78
81
  delete capabilities.capabilities.alwaysMatch.marionette;
79
82
  }
80
- const browser = browserOptions.browser || (testRunConfig && testRunConfig.browserValue);
81
- this.initUnsupportedActions(browser, lambdatestService && lambdatestService.isLambdatestRun());
83
+ const browser = browserOptions.browser || (testRunConfig?.browserValue);
84
+ this.initUnsupportedActions(browser, lambdatestService?.isLambdatestRun());
82
85
  this.browserAndOS = null;
83
86
  this.seleniumPerfStats = seleniumPerfStats;
84
87
  const driverDelay = fastInit ? 0 : 1500;
@@ -217,6 +220,9 @@ class WebDriver extends WebDriverApi {
217
220
  });
218
221
  }
219
222
 
223
+ /**
224
+ * @returns {Promise<{ value: HTMLElement }>}
225
+ */
220
226
  getElement(locatedElement) {
221
227
  const perfId = this.seleniumPerfStats.markStart(SELENIUM_PERF_MARKS.GET_ELEMENT);
222
228
  if (typeof locatedElement === 'string' || typeof locatedElement === 'number') { // support testimId in the meanwhile for backwards compatability
@@ -252,7 +258,8 @@ class WebDriver extends WebDriverApi {
252
258
  .then(() => this.executeAsync(fn, args));
253
259
  }
254
260
 
255
- markDynamicParent(target, dynamicParentId) {
261
+ /** @type {import('clickim/src/background/stepActions/stepActionUtils').StepActionUtils['markDynamicParent']} */
262
+ async markDynamicParent(target, dynamicParentId, frameHandler) {
256
263
  function setDynamicParentAttribute(data) {
257
264
  var attributeName = data.attributeName;
258
265
  var attributeValue = data.attributeValue;
@@ -274,6 +281,7 @@ class WebDriver extends WebDriverApi {
274
281
  });
275
282
  }
276
283
 
284
+ /** @return {Promise<{ value: { top: number; left: number } | null }>} */
277
285
  getLocatedElementRectWithPadding(locatedElement) {
278
286
  // this is here to conform with clickim's logic in frame offset calculations
279
287
  function getLocationCode(locatedElement) {
@@ -281,8 +289,8 @@ class WebDriver extends WebDriverApi {
281
289
  if (!element) {
282
290
  return null;
283
291
  }
284
- var paddingTop = parseInt(window.getComputedStyle(element).paddingTop.replace('px', '')) || 0;
285
- var paddingLeft = parseInt(window.getComputedStyle(element).paddingLeft.replace('px', '')) || 0;
292
+ var paddingTop = parseInt(window.getComputedStyle(element).paddingTop.replace('px', ''), 10) || 0;
293
+ var paddingLeft = parseInt(window.getComputedStyle(element).paddingLeft.replace('px', ''), 10) || 0;
286
294
  var rect = element.getBoundingClientRect();
287
295
  return { top: Math.round(rect.top + paddingTop), left: Math.round(rect.left + paddingLeft) };
288
296
  }
@@ -298,6 +306,7 @@ class WebDriver extends WebDriverApi {
298
306
  return this.getLocatedElementRectWithPadding(locatedElement);
299
307
  }
300
308
 
309
+ /** @returns {Promise<{ value: null | Record<'bottom' | 'height' | 'x' | 'right' | 'y' | 'width', number> }>} */
301
310
  getLocatedElementRect(locatedElement) {
302
311
  function getLocationCode(locatedElement) {
303
312
  var element = getLocatedElement(locatedElement);
@@ -311,7 +320,7 @@ class WebDriver extends WebDriverApi {
311
320
  x: Math.round(rect.left),
312
321
  right: Math.round(rect.right),
313
322
  y: Math.round(rect.top),
314
- width: Math.round(rect.width)
323
+ width: Math.round(rect.width),
315
324
  };
316
325
  }
317
326
 
@@ -340,6 +349,7 @@ class WebDriver extends WebDriverApi {
340
349
  }
341
350
 
342
351
  var children = Array.apply(null, node.childNodes).filter(function (x) { return x.nodeType === Node.ELEMENT_NODE; });
352
+ // eslint-disable-next-line prefer-arrow-callback
343
353
  children.forEach(function (child) {
344
354
  if (typeof child.tagName === 'string' && child.tagName.toLowerCase() === 'title') {
345
355
  node.removeChild(child);
@@ -360,10 +370,14 @@ class WebDriver extends WebDriverApi {
360
370
  if (element.shadowRoot && Object.getOwnPropertyDescriptor(element.ownerDocument.defaultView.Node.prototype,'textContent').get.toString().indexOf('[native code]') === -1) {
361
371
  return element.shadowRoot.textContent.replace(/(\r\n|\n|\r)/gm, '');
362
372
  }
373
+ // eslint-disable-next-line no-empty
363
374
  } catch (err) { }
375
+ // eslint-disable-next-line prefer-arrow-callback
364
376
  if (ignoreHiddenTagsText && Array.prototype.some.call(element.children, function (elem) { return elem.hidden; })) {
365
377
  var dupElement = element.cloneNode(true);
378
+ // eslint-disable-next-line prefer-arrow-callback
366
379
  var hiddenChildren = Array.prototype.filter.call(dupElement.children, function (elem) { return elem.hidden; });
380
+ // eslint-disable-next-line prefer-arrow-callback
367
381
  hiddenChildren.forEach(function (child) {
368
382
  dupElement.removeChild(child);
369
383
  });
@@ -509,7 +523,7 @@ class WebDriver extends WebDriverApi {
509
523
  throw new Error('number or type of arguments don\'t agree with setViewportSize command');
510
524
  }
511
525
 
512
- let shouldIndent = (typeof type === 'undefined') ? true : type;
526
+ const shouldIndent = (typeof type === 'undefined') ? true : type;
513
527
 
514
528
  return shouldIndent ? _setViewportSize.call(this, size) : this.windowHandleSize(size);
515
529
  }
@@ -524,7 +538,7 @@ class WebDriver extends WebDriverApi {
524
538
 
525
539
  getBrowserMajorVersion(parse) {
526
540
  try {
527
- return parseInt(parse.browser.major);
541
+ return parseInt(parse.browser.major, 10);
528
542
  } catch (err) {
529
543
  logger.error('failed to get browser version', { err: err });
530
544
  return 0;
@@ -555,6 +569,7 @@ class WebDriver extends WebDriverApi {
555
569
  return Promise.resolve(this.browserAndOS);
556
570
  }
557
571
 
572
+ // eslint-disable-next-line prefer-arrow-callback
558
573
  return this.executeJS(function () {
559
574
  if (typeof window === 'undefined' || !window.navigator || !window.navigator.userAgent) {
560
575
  return 'unknown';
@@ -644,15 +659,16 @@ class WebDriver extends WebDriverApi {
644
659
  `, eventData.timeout, eventParam);
645
660
  }
646
661
 
662
+ // eslint-disable-next-line default-param-last
647
663
  getClickActions(types = [], button) {
648
664
  return types.map(type => ({ type: type, button }));
649
665
  }
650
-
666
+ // eslint-disable-next-line default-param-last
651
667
  getClickActionList(types = [], button) {
652
668
  return [{
653
669
  type: 'pointer',
654
670
  id: 'mouse',
655
- actions: this.getClickActions(types, button)
671
+ actions: this.getClickActions(types, button),
656
672
  }];
657
673
  }
658
674
 
@@ -747,7 +763,7 @@ class WebDriver extends WebDriverApi {
747
763
  return this.actions([{
748
764
  type: 'pointer',
749
765
  id: 'mouse',
750
- actions: actions
766
+ actions,
751
767
  }]);
752
768
  }
753
769
 
@@ -790,7 +806,7 @@ class WebDriver extends WebDriverApi {
790
806
  return this.actions([{
791
807
  type: 'pointer',
792
808
  id: 'mouse',
793
- actions: goToDrag.concat(startDrag).concat(doDrag).concat(endDrag)
809
+ actions: goToDrag.concat(startDrag).concat(doDrag).concat(endDrag),
794
810
  }]);
795
811
  }
796
812
 
@@ -826,12 +842,10 @@ class WebDriver extends WebDriverApi {
826
842
 
827
843
  /* generate move events array */
828
844
  const moves = Array.apply([], new Array(eventCount))
829
- .map(() => {
830
- return {
831
- x: Math.round((to.x - from.x) / eventCount),
832
- y: Math.round((to.y - from.y) / eventCount)
833
- };
834
- });
845
+ .map(() => ({
846
+ x: Math.round((to.x - from.x) / eventCount),
847
+ y: Math.round((to.y - from.y) / eventCount)
848
+ }));
835
849
  return [{ x: 1, y: 1 }].concat(moves);
836
850
  }
837
851
 
@@ -871,7 +885,7 @@ class WebDriver extends WebDriverApi {
871
885
  return this.actions([{
872
886
  type: 'pointer',
873
887
  id: 'mouse',
874
- actions: actions
888
+ actions,
875
889
  }]);
876
890
  }
877
891
 
@@ -888,7 +902,8 @@ class WebDriver extends WebDriverApi {
888
902
  }
889
903
  return Promise.reject(err);
890
904
  });
891
- } else if (this.unsupportedActions.move) {
905
+ }
906
+ if (this.unsupportedActions.move) {
892
907
  return this.dragAndDropWithActionsAPI(rectsAndOffsets);
893
908
  }
894
909
  return this.dragAndDropOldAPI(sourceSeleniumElement, destinationSeleniumElement)
@@ -943,7 +958,6 @@ class WebDriver extends WebDriverApi {
943
958
 
944
959
  getTabIds() {
945
960
  return this.windowHandles().get('value');
946
-
947
961
  }
948
962
 
949
963
  isVisible(el) {
@@ -955,10 +969,10 @@ class WebDriver extends WebDriverApi {
955
969
  }
956
970
 
957
971
  getElementRect(target) {
958
- let defaultLocation = { width: 0, height: 0, top: 0, left: 0 };
972
+ const defaultLocation = { width: 0, height: 0, top: 0, left: 0 };
959
973
  return this.getElementLocation(target).catch((err) => logger.error('error getting element location', { err }))
960
974
  .then(loc => {
961
- if (loc && loc.value) {
975
+ if (loc?.value) {
962
976
  return {
963
977
  top: loc.value.y,
964
978
  left: loc.value.x,
@@ -986,7 +1000,7 @@ class WebDriver extends WebDriverApi {
986
1000
  return {
987
1001
  x: rectangle.width / 2,
988
1002
  y: rectangle.height / 2,
989
- }
1003
+ };
990
1004
  }
991
1005
  }
992
1006
 
@@ -16,33 +16,48 @@ const MASK_OPTIONS = {
16
16
  testobjectSauce: undefined,
17
17
  };
18
18
 
19
- const DebugReporter = function (options) {
20
- this.options = options;
21
- };
19
+ class DebugReporter {
20
+ constructor(options) {
21
+ this.options = options;
22
+ }
22
23
 
23
- DebugReporter.prototype.onTestStarted = function (test, workerId) {
24
- logger.info('Test Started', { testId: test.testId, testName: test.name, resultId: test.resultId, workerId });
25
- };
24
+ onTestStarted(test, workerId) {
25
+ logger.info('Test Started', { testId: test.testId, testName: test.name, resultId: test.resultId, workerId });
26
+ }
26
27
 
27
- DebugReporter.prototype.onTestFinished = function (test, workerId) {
28
- const gridData = this.options.gridData || {};
29
- const provider = gridData.provider;
30
- const host = gridData.host;
31
- const gridId = gridData.gridId;
32
- const gridType = gridData.type;
33
- const failedGetBrowserAttempts = gridData.failedGetBrowserAttempts;
34
- logger.info('Test Finished', {
35
- testId: test.testId,
36
- testName: test.name,
37
- resultId: test.resultId,
38
- success: test.success,
39
- duration: test.duration,
40
- browser: this.options.browser,
41
- companyId: this.options.company.companyId,
42
- grid: { provider, host, failedGetBrowserAttempts, id: gridId, type: gridType },
43
- workerId,
44
- });
45
- };
28
+ onTestFinished(test, workerId) {
29
+ const gridData = this.options.gridData || {};
30
+ const provider = gridData.provider;
31
+ const host = gridData.host;
32
+ const gridId = gridData.gridId;
33
+ const gridType = gridData.type;
34
+ const failedGetBrowserAttempts = gridData.failedGetBrowserAttempts;
35
+ logger.info('Test Finished', {
36
+ testId: test.testId,
37
+ testName: test.name,
38
+ resultId: test.resultId,
39
+ success: test.success,
40
+ duration: test.duration,
41
+ browser: this.options.browser,
42
+ companyId: this.options.company.companyId,
43
+ grid: { provider, host, failedGetBrowserAttempts, id: gridId, type: gridType },
44
+ workerId,
45
+ });
46
+ }
47
+
48
+ onTestPlanStarted(beforeTests, tests, afterTests, testPlanName, executionId, isAnonymous, configName) {
49
+ const args = stripTokenFromConsoleArguments(process.argv);
50
+
51
+ logger.info('Test Plan Started', { executionId, testPlanName, isAnonymous, configName, options: Object.assign({}, this.options, MASK_OPTIONS), args });
52
+ }
53
+
54
+ onTestPlanFinished(testResults, testPlanName, duration, executionId, isAnonymous) {
55
+ const passed = Object.keys(testResults).filter(resultId => testResults[resultId].status === constants.runnerTestStatus.PASSED).length;
56
+ const failed = Object.keys(testResults).length - passed;
57
+
58
+ logger.info('Test Plan Finished', { isAnonymous, passed, failed, testPlanName, options: Object.assign({}, this.options, MASK_OPTIONS), duration, executionId });
59
+ }
60
+ }
46
61
 
47
62
  function stripTokenFromConsoleArguments(args) {
48
63
  let indexOfTokenFlag = args.indexOf('--token');
@@ -57,24 +72,11 @@ function stripTokenFromConsoleArguments(args) {
57
72
 
58
73
  return newArgs;
59
74
  } catch (e) {
60
-
75
+ /* empty */
61
76
  }
62
77
  }
63
78
 
64
79
  return args;
65
80
  }
66
81
 
67
- DebugReporter.prototype.onTestPlanStarted = function (beforeTests, tests, afterTests, testPlanName, executionId, isAnonymous, configName) {
68
- const args = stripTokenFromConsoleArguments(process.argv);
69
-
70
- logger.info('Test Plan Started', { executionId, testPlanName, isAnonymous, configName, options: Object.assign({}, this.options, MASK_OPTIONS), args });
71
- };
72
-
73
- DebugReporter.prototype.onTestPlanFinished = function (testResults, testPlanName, duration, executionId, isAnonymous) {
74
- const passed = Object.keys(testResults).filter(resultId => testResults[resultId].status === constants.runnerTestStatus.PASSED).length;
75
- const failed = Object.keys(testResults).length - passed;
76
-
77
- logger.info('Test Plan Finished', { isAnonymous, passed, failed, testPlanName, options: Object.assign({}, this.options, MASK_OPTIONS), duration, executionId });
78
- };
79
-
80
82
  module.exports = DebugReporter;