@testim/testim-cli 3.193.0 → 3.197.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 (70) hide show
  1. package/README.md +1 -1
  2. package/cli/onExit.js +12 -1
  3. package/cli.js +5 -1
  4. package/codim/codim-npm-package/index.ts +1 -0
  5. package/commons/constants.js +0 -25
  6. package/commons/featureFlags.js +2 -0
  7. package/commons/socket/testResultService.js +4 -14
  8. package/commons/testimAnalytics.js +0 -1
  9. package/commons/testimDesiredCapabilitiesBuilder.js +0 -95
  10. package/commons/testimServicesApi.js +10 -80
  11. package/executionQueue.js +7 -4
  12. package/npm-shrinkwrap.json +956 -520
  13. package/package.json +3 -1
  14. package/player/chromeLauncherTestPlayer.js +5 -2
  15. package/player/stepActions/apiStepAction.js +1 -0
  16. package/player/stepActions/baseJsStepAction.js +5 -1
  17. package/player/stepActions/pixelValidationStepAction.js +28 -0
  18. package/player/stepActions/salesforceAutoLoginStepAction.js +39 -0
  19. package/player/stepActions/scripts/focusElement.js +5 -3
  20. package/player/stepActions/stepActionRegistrar.js +5 -47
  21. package/player/utils/eyeSdkService.js +230 -0
  22. package/reports/consoleReporter.js +0 -20
  23. package/reports/reporter.js +0 -21
  24. package/runOptions.js +13 -89
  25. package/runner.js +9 -46
  26. package/runners/{strategies/LocalStrategy.js → ParallelWorkerManager.js} +60 -66
  27. package/runners/TestPlanRunner.js +286 -67
  28. package/runners/runnerUtils.js +73 -0
  29. package/{runners/strategies/BaseStrategy.js → services/analyticsService.js} +41 -28
  30. package/services/gridService.js +24 -16
  31. package/services/gridService.test.js +21 -21
  32. package/services/lambdatestService.js +1 -1
  33. package/testRunHandler.js +1 -1
  34. package/testRunStatus.js +30 -20
  35. package/utils.js +5 -5
  36. package/workers/BaseWorker.js +38 -39
  37. package/workers/BaseWorker.test.js +1 -1
  38. package/workers/WorkerExtensionSingleBrowser.js +6 -3
  39. package/commons/apkUploader/apkUploader.js +0 -46
  40. package/commons/apkUploader/apkUploaderFactory.js +0 -68
  41. package/commons/apkUploader/deviceFarmApkUploader.js +0 -41
  42. package/commons/apkUploader/saucelabsApkUploader.js +0 -36
  43. package/commons/apkUploader/testObjectApkUploader.js +0 -34
  44. package/player/mobile/mobileTestPlayer.js +0 -80
  45. package/player/mobile/mobileWebDriver.js +0 -155
  46. package/player/mobile/services/frameLocatorMock.js +0 -18
  47. package/player/mobile/services/mobilePortSelector.js +0 -22
  48. package/player/mobile/services/mobileTabService.js +0 -241
  49. package/player/mobile/utils/mobileScreenshotUtils.js +0 -46
  50. package/player/mobile/utils/mobileWindowUtils.js +0 -84
  51. package/player/stepActions/mobile/android/androidLocateStepAction.js +0 -122
  52. package/player/stepActions/mobile/android/androidLongClickStepAction.js +0 -12
  53. package/player/stepActions/mobile/android/androidScrollStepAction.js +0 -134
  54. package/player/stepActions/mobile/android/androidSpecialKeyStepAction.js +0 -22
  55. package/player/stepActions/mobile/android/androidSwipeStepAction.js +0 -32
  56. package/player/stepActions/mobile/androidGlobalActionStepAction.js +0 -12
  57. package/player/stepActions/mobile/androidTapStepAction.js +0 -19
  58. package/player/stepActions/mobile/androidTextChangeStepAction.js +0 -23
  59. package/player/stepActions/mobile/ios/iosLocateStepAction.js +0 -124
  60. package/player/stepActions/mobile/ios/iosScrollStepAction.js +0 -76
  61. package/runners/AnonymousTestPlanRunner.js +0 -106
  62. package/runners/BaseRunner.js +0 -42
  63. package/runners/BaseTestPlanRunner.js +0 -194
  64. package/runners/DeviceFarmRemoteRunner.js +0 -50
  65. package/runners/SchedulerRemoteRunner.js +0 -47
  66. package/runners/strategies/DeviceFarmStrategy.js +0 -195
  67. package/runners/strategies/LocalDeviceFarmStrategy.js +0 -12
  68. package/runners/strategies/LocalTestStrategy.js +0 -14
  69. package/runners/strategies/Strategy.js +0 -17
  70. package/workers/WorkerAppium.js +0 -70
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testim/testim-cli",
3
- "version": "3.193.0",
3
+ "version": "3.197.0",
4
4
  "description": "Command line interface for running Testing on your CI",
5
5
  "author": "Oren Rubin",
6
6
  "contributors": [{
@@ -48,6 +48,8 @@
48
48
  "multer": "1.4.2"
49
49
  },
50
50
  "dependencies": {
51
+ "@applitools/eyes-sdk-core": "12.23.12",
52
+ "@applitools/visual-grid-client": "15.8.31",
51
53
  "@testim/coralogix-logger": "1.1.27-beta",
52
54
  "@testim/webdriverio": "0.0.3",
53
55
  "abort-controller": "3.0.0",
@@ -4,9 +4,10 @@ const launcher = require('chrome-launcher');
4
4
  const desiredCapabilitiesBuilder = require('../commons/testimDesiredCapabilitiesBuilder');
5
5
  const utils = require('../utils');
6
6
  const httpRequest = require('../commons/httpRequest');
7
+ const { registerExitHook } = require('../processHandler');
7
8
  const CDPTestRunner = require('../cdpTestRunner');
8
9
 
9
- class LancherDriver {
10
+ class LauncherDriver {
10
11
  constructor(sessionId) {
11
12
  this.sessionId = sessionId;
12
13
  this.cdpTestRunner = new CDPTestRunner();
@@ -24,6 +25,8 @@ class LancherDriver {
24
25
  this._isAlive = true;
25
26
  const browserEndpoint = await httpRequest.get(`http://localhost:${this.chrome.port}/json/version`);
26
27
  await this.cdpTestRunner.initSession(browserEndpoint.webSocketDebuggerUrl);
28
+
29
+ registerExitHook(() => this.chrome.kill());
27
30
  }
28
31
 
29
32
  isAlive() {
@@ -49,7 +52,7 @@ class LancherDriver {
49
52
  class ChromeLauncherTestPlayer {
50
53
  constructor(id) {
51
54
  this.sessionId = utils.guid();
52
- this.driver = new LancherDriver(this.sessionId);
55
+ this.driver = new LauncherDriver(this.sessionId);
53
56
  this.id = id;
54
57
  }
55
58
 
@@ -36,6 +36,7 @@ class ApiStepAction extends StepAction {
36
36
  headers: context.apiHeaders,
37
37
  body: context.apiBody,
38
38
  timeout: context.data.maxTotalStepTime,
39
+ omitCookies: step.omitCookies,
39
40
  };
40
41
 
41
42
  return (step.sendViaWebApp ? this.runApiInAut(step, context) : this.runApiInBg(eventData))
@@ -44,6 +44,7 @@ class BaseJsStepAction extends StepAction {
44
44
  }
45
45
 
46
46
  executeGetStatus(transactionId) {
47
+ // eslint-disable-next-line prefer-arrow-callback
47
48
  return this.driver.executeJS(function (transactionId) {
48
49
  const sessionItem = 'data-testim-' + transactionId;
49
50
  try {
@@ -139,12 +140,15 @@ class BaseJsStepAction extends StepAction {
139
140
 
140
141
  executeInAut(eventMessage) {
141
142
  const useExperimentalPreCompilation = featureFlags.flags.experimentalPreCodeCompilation.isEnabled();
143
+ const experimentalAsyncCustomCode = featureFlags.flags.experimentalAsyncCustomCode.isEnabled();
142
144
  const rawParams = this.constructJSFunParams(eventMessage);
143
145
  const hasLocateParams = rawParams.function.args.some(x => Boolean(x && x.locatedElement));
144
146
  let funcToRunString = 'undefined';
145
147
  if (useExperimentalPreCompilation) {
146
148
  const paramNames = rawParams.function.params.slice(0, -1);
147
- funcToRunString = `function(${paramNames.join(',')}) {
149
+ funcToRunString = (experimentalAsyncCustomCode && !this.driver.isIE()) ? `async function(${paramNames.join(',')}) {
150
+ ${eventMessage.code}
151
+ };` : `function(${paramNames.join(',')}) {
148
152
  ${eventMessage.code}
149
153
  };`;
150
154
  // remove code from call.
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+
3
+ const StepAction = require('./stepAction');
4
+ const { eyeSdkService } = require('../utils/eyeSdkService');
5
+ const logger = require('../../commons/logger').getLogger('pixel-validation-step-action');
6
+
7
+
8
+ class PixelValidationStepAction extends StepAction {
9
+ async performAction() {
10
+ const { shouldUseVisualGrid, applitoolsSdkConfig: config } = this.context;
11
+ this.runContext = this.context.getRunContext(undefined);
12
+ const eyeManager = await eyeSdkService.getManager(shouldUseVisualGrid, this.context.config.applitoolsConcurrency || 5);
13
+ const targetElementData = this.getTarget() || {};
14
+ try {
15
+ const openedEye = await eyeManager.openEyes({ driver: this.driver.client, config });
16
+ const region = (this.step.action === 'element' && targetElementData.seleniumElement) || undefined;
17
+ await openedEye.check({ settings: { region, fully: this.step.action === 'stitched' } });
18
+ const eyesResults = await openedEye.close();
19
+
20
+ return { isApplitoolsSdkResult: true, success: true, eyesResults };
21
+ } catch (err) {
22
+ logger.error('Applitools SDK step failed', { err, info: err.info });
23
+ return { isApplitoolsSdkResult: true, success: false, err };
24
+ }
25
+ }
26
+ }
27
+
28
+ module.exports = PixelValidationStepAction;
@@ -0,0 +1,39 @@
1
+ const NavigationStepAction = require('./navigationStepAction');
2
+ const Promise = require('bluebird');
3
+
4
+ class SalesforceAutoLoginStepAction extends NavigationStepAction {
5
+ async performAction() {
6
+ let salesforceUrl = this.context.data.testimNavigationStepDestination || this.context.data.url;
7
+ try {
8
+ salesforceUrl = await this.updateBaseUrl(salesforceUrl);
9
+ await this.driver.url(salesforceUrl);
10
+ await Promise.delay(1000); // wait a little for the page to load (fixes screenshots and clicking on elements in username verification screen)
11
+ let newUrl = await this.driver.getUrl();
12
+ // Verify username screen
13
+ const isUsernameVerificationNeeded = newUrl.includes(this.step.USERNAME_VERIFICATION_PATH_ID);
14
+ const timeout = this.context.data.timeToPlayStep + 3000;
15
+ if (isUsernameVerificationNeeded) {
16
+ await this.driver.executeCodeAsync(`
17
+ function ${this.step.handleUsernameVerificationAUTFunc.toString()}
18
+ handleUsernameVerificationAUTFunc();
19
+ var done = arguments[1];
20
+ done();
21
+ `, timeout);
22
+ await Promise.delay(1500);
23
+ newUrl = await this.driver.getUrl(); // If we managed to continue correctly we want to get the new redirected url
24
+ }
25
+ await Promise.delay(700);
26
+ return {
27
+ success: true,
28
+ newUrl,
29
+ };
30
+ } catch (err) {
31
+ return {
32
+ success: false,
33
+ reason: err.message,
34
+ };
35
+ }
36
+ }
37
+ }
38
+
39
+ module.exports = SalesforceAutoLoginStepAction;
@@ -1,6 +1,6 @@
1
1
  module.exports = function dispatchFocus(targetElement, oldActiveElement) {
2
2
  function createFocusEvent(eventName) {
3
- var event = document.createEvent("FocusEvent");
3
+ var event = document.createEvent("HTMLEvents");
4
4
  // TODO we want to use new Event, but mootools (used by zuora which is used by jfrog)
5
5
  // overrides window.Event and throws an error
6
6
  event.initEvent(eventName, true, false);
@@ -16,10 +16,12 @@ module.exports = function dispatchFocus(targetElement, oldActiveElement) {
16
16
  }
17
17
 
18
18
  function setFocus(element, oldActiveElement) {
19
- element.dispatchEvent(createFocusEvent('focusin'));
20
19
  if (oldActiveElement) {
21
- oldActiveElement.dispatchEvent(createFocusEvent('focusout'));
20
+ oldActiveElement.dispatchEvent(createFocusEvent('focusout'));
21
+ oldActiveElement.dispatchEvent(createFocusEvent('blur'));
22
22
  }
23
+ element.dispatchEvent(createFocusEvent('focusin'));
24
+ element.dispatchEvent(createFocusEvent('focus'));
23
25
  if (typeof element.focus === 'function') {
24
26
  element.focus();
25
27
  }
@@ -21,25 +21,14 @@ const RefreshStepAction = require('./RefreshStepAction');
21
21
  const ApiStepAction = require('./apiStepAction');
22
22
  const ExtractTextStepAction = require('./extractTextStepAction');
23
23
  const TdkHybridStepAction = require('./tdkHybridStepAction');
24
+ const SalesforceAutoLoginStepAction = require('./salesforceAutoLoginStepAction');
25
+ const PixelValidationStepAction = require('./pixelValidationStepAction');
24
26
 
25
27
  const CliJsStepAction = require('./cliJsStepAction');
26
28
  const CliConditionStepAction = require('./cliConditionStepAction');
27
29
  const NodePackageStepAction = require('./nodePackageStepAction');
28
30
  const ExtensionOnlyStepAction = require('./extensionOnlyStepAction');
29
31
 
30
- const MobileTapStepAction = require('./mobile/androidTapStepAction');
31
- const MobileGlobalActionStepAction = require('./mobile/androidGlobalActionStepAction');
32
- const MobileTextChangeStepAction = require('./mobile/androidTextChangeStepAction');
33
-
34
- const AndroidLocateStepAction = require('./mobile/android/androidLocateStepAction');
35
- const AndroidLongClickStepAction = require('./mobile/android/androidLongClickStepAction');
36
- const AndroidScrollStepAction = require('./mobile/android/androidScrollStepAction');
37
- const AndroidSwipeStepAction = require('./mobile/android/androidSwipeStepAction');
38
- const AndroidSpecialKeyStepAction = require('./mobile/android/androidSpecialKeyStepAction');
39
-
40
- const IosLocateStepAction = require('./mobile/ios/iosLocateStepAction');
41
- const IosScrollStepAction = require('./mobile/ios/iosScrollStepAction');
42
-
43
32
  function register(stepActionByType, stepActionFactory) {
44
33
  Object.keys(stepActionByType).forEach(type => {
45
34
  stepActionFactory.registerStepAction(type, stepActionByType[type]);
@@ -76,6 +65,8 @@ module.exports = function (driver, stepActionFactory, runMode) {
76
65
  'api-action': ApiStepAction,
77
66
  'api-code-step': JsCodeStepAction,
78
67
  'extract-text': ExtractTextStepAction,
68
+ 'simple-ui-verification': PixelValidationStepAction,
69
+ 'wait-for-simple-ui-verification': PixelValidationStepAction,
79
70
 
80
71
  'cli-validation-download-file': ExtensionOnlyStepAction,
81
72
  'cli-wait-for-download-file': ExtensionOnlyStepAction,
@@ -92,46 +83,13 @@ module.exports = function (driver, stepActionFactory, runMode) {
92
83
  'email-code-step': JsCodeStepAction,
93
84
  'cli-email-code-step': CliJsStepAction,
94
85
  'tdk-hybrid': TdkHybridStepAction,
95
- };
96
-
97
- const ANDROID_STEP_ACTION_MAPPING = {
98
- locate: AndroidLocateStepAction,
99
- 'android-tap': MobileTapStepAction,
100
- 'android-long-click': AndroidLongClickStepAction,
101
- 'android-device-key': MobileGlobalActionStepAction,
102
- 'android-key-board-special-keys': AndroidSpecialKeyStepAction,
103
- text: MobileTextChangeStepAction,
104
- 'android-swipe': AndroidSwipeStepAction,
105
- 'android-scroll': AndroidScrollStepAction,
106
- };
107
86
 
108
- const IOS_STEP_ACTION_MAPPING = {
109
- locate: IosLocateStepAction,
110
- 'ios-tap': MobileTapStepAction,
111
- 'ios-device-key': MobileGlobalActionStepAction,
112
- text: MobileTextChangeStepAction,
113
- 'ios-scroll': IosScrollStepAction,
87
+ 'salesforce-autologin': SalesforceAutoLoginStepAction,
114
88
  };
115
89
 
116
90
  register(STEP_ACTION_MAPPING, stepActionFactory);
117
91
  if (stepActionFactory.registerLocateStepActionUtils) {
118
92
  stepActionFactory.registerLocateStepActionUtils(LocateStepAction.getUtils(driver));
119
93
  }
120
-
121
- // override android actions
122
- if (runMode === 'android') {
123
- register(ANDROID_STEP_ACTION_MAPPING, stepActionFactory);
124
- if (stepActionFactory.registerLocateStepActionUtils) {
125
- stepActionFactory.registerLocateStepActionUtils(AndroidLocateStepAction.getUtils(driver));
126
- }
127
- }
128
-
129
- // override ios actions
130
- if (runMode === 'ios') {
131
- register(IOS_STEP_ACTION_MAPPING, stepActionFactory);
132
- if (stepActionFactory.registerLocateStepActionUtils) {
133
- stepActionFactory.registerLocateStepActionUtils(IosLocateStepAction.getUtils(driver));
134
- }
135
- }
136
94
  };
137
95
 
@@ -0,0 +1,230 @@
1
+ // https://github.com/applitools/eyes.sdk.javascript1/blob/master/packages/eyes-webdriverio-4/src/spec-driver.ts
2
+
3
+ const { makeSDK } = require('@applitools/eyes-sdk-core');
4
+ const { W3C_ELEMENT_ID } = require('../constants');
5
+ const _ = require('lodash');
6
+
7
+ const LEGACY_ELEMENT_ID = 'ELEMENT';
8
+
9
+ function extractElementId(element) {
10
+ if (_.has(element, 'elementId')) {
11
+ return element.elementId;
12
+ }
13
+ if (_.has(element, W3C_ELEMENT_ID)) {
14
+ return element[W3C_ELEMENT_ID];
15
+ }
16
+ if (_.has(element, LEGACY_ELEMENT_ID)) {
17
+ return element[LEGACY_ELEMENT_ID];
18
+ }
19
+ return undefined;
20
+ }
21
+ /** implements the ?? capability for backward compatibility */
22
+ function getValueOrFallbackIfNullOrUndefined(value, fallback) {
23
+ if (value === null || value === undefined) {
24
+ return fallback;
25
+ }
26
+ return value;
27
+ }
28
+
29
+ /**
30
+ * @typedef {import('@applitools/types').SpecDriver} SpecDriver
31
+ * @implements {SpecDriver}
32
+ */
33
+ class EyesSpec {
34
+ // #region UTILITY
35
+ isDriver(driver) {
36
+ return Boolean(driver && driver.getPrototype && driver.desiredCapabilities && driver.requestHandler);
37
+ }
38
+
39
+ isElement(element) {
40
+ if (!element) {
41
+ return false;
42
+ }
43
+ const elementToCheck = element.value || element;
44
+ return Boolean(elementToCheck[W3C_ELEMENT_ID] || elementToCheck[LEGACY_ELEMENT_ID]);
45
+ }
46
+
47
+ isSelector(selector) {
48
+ return _.isString(selector);
49
+ }
50
+
51
+ transformDriver(driver) {
52
+ return new Proxy(driver, {
53
+ get: (target, key) => {
54
+ if (key === 'then') {
55
+ return undefined;
56
+ }
57
+ return Reflect.get(target, key);
58
+ },
59
+ });
60
+ }
61
+
62
+ transformElement(element) {
63
+ const elementId = extractElementId(element.value || element);
64
+ return { [W3C_ELEMENT_ID]: elementId, [LEGACY_ELEMENT_ID]: elementId };
65
+ }
66
+
67
+ transformSelector(selector) {
68
+ if (!_.has(selector, 'selector')) {
69
+ return selector;
70
+ }
71
+ if (!_.has(selector, 'type')) {
72
+ return selector.selector;
73
+ }
74
+ if (selector.type === 'css') {
75
+ return `css selector:${selector.selector}`;
76
+ }
77
+ return `${selector.type}:${selector.selector}`;
78
+ }
79
+
80
+ extractSelector(element) {
81
+ return _.has(element, 'selector') ? element.selector : undefined;
82
+ }
83
+
84
+ isStaleElementError(error, selector) {
85
+ if (!error) {
86
+ return false;
87
+ }
88
+ const errOrResult = error.originalError || error;
89
+ return errOrResult instanceof Error ?
90
+ errOrResult.seleniumStack && errOrResult.seleniumStack.type === 'StaleElementReference' :
91
+ errOrResult.value && errOrResult.selector && errOrResult.selector === selector;
92
+ }
93
+
94
+ isEqualElements(_browser, element1, element2) {
95
+ if (!element1 || !element2) {
96
+ return false;
97
+ }
98
+ const elementId1 = extractElementId(element1);
99
+ const elementId2 = extractElementId(element2);
100
+ return elementId1 === elementId2;
101
+ }
102
+ // #endregion
103
+
104
+ // #region COMMANDS
105
+ async executeScript(driver, script, arg) {
106
+ const { value } = await driver.execute(script, arg);
107
+ return value;
108
+ }
109
+
110
+ async mainContext(driver) {
111
+ await driver.frame(null);
112
+ return driver;
113
+ }
114
+
115
+ async parentContext(driver) {
116
+ await driver.frameParent();
117
+ return driver;
118
+ }
119
+
120
+ async childContext(driver, element) {
121
+ await driver.frame(element);
122
+ return driver;
123
+ }
124
+
125
+ async findElement(driver, selector, parent) {
126
+ const { value } = parent ? await driver.elementIdElement(extractElementId(parent), selector) : await driver.element(selector);
127
+ return value;
128
+ }
129
+
130
+ async findElements(driver, selector, parent) {
131
+ const { value } = parent ? await driver.elementIdElements(extractElementId(parent), selector) : await driver.elements(selector);
132
+ return value;
133
+ }
134
+
135
+ async getWindowSize(driver) {
136
+ const { value: size } = await driver.windowHandleSize();
137
+ return { width: size.width, height: size.height };
138
+ }
139
+
140
+ async setWindowSize(driver, size) {
141
+ await driver.windowHandlePosition({ x: 0, y: 0 });
142
+ await driver.windowHandleSize(size);
143
+ }
144
+
145
+ async getDriverInfo(driver) {
146
+ const desiredCapabilities = driver.desiredCapabilities;
147
+
148
+ return {
149
+ sessionId: driver.requestHandler.sessionID || driver.sessionId,
150
+ isMobile: driver.isMobile,
151
+ isNative: driver.isMobile && !desiredCapabilities.browserName,
152
+ deviceName: desiredCapabilities.deviceName,
153
+ platformName: desiredCapabilities.platformName || desiredCapabilities.platform,
154
+ platformVersion: desiredCapabilities.platformVersion,
155
+ browserName: getValueOrFallbackIfNullOrUndefined(desiredCapabilities.browserName, desiredCapabilities.name),
156
+ browserVersion: getValueOrFallbackIfNullOrUndefined(desiredCapabilities.browserVersion, desiredCapabilities.version),
157
+ pixelRatio: desiredCapabilities.pixelRatio,
158
+ };
159
+ }
160
+
161
+ async getTitle(driver) {
162
+ return driver.getTitle();
163
+ }
164
+
165
+ async getUrl(driver) {
166
+ return driver.getUrl();
167
+ }
168
+
169
+ async visit(driver, url) {
170
+ await driver.url(url);
171
+ }
172
+
173
+ async takeScreenshot(driver) {
174
+ return driver.saveScreenshot();
175
+ }
176
+
177
+ async click(driver, element) {
178
+ if (this.isSelector(element)) {
179
+ element = await this.findElement(driver, element);
180
+ }
181
+ await driver.elementIdClick(extractElementId(element));
182
+ }
183
+
184
+ async hover(driver, element, offset) {
185
+ if (this.isSelector(element)) {
186
+ element = await this.findElement(driver, element);
187
+ }
188
+ await driver.moveTo(extractElementId(element), offset && offset.x, offset && offset.y);
189
+ }
190
+
191
+ async type(driver, element, keys) {
192
+ if (this.isSelector(element)) {
193
+ element = await this.findElement(driver, element);
194
+ } else {
195
+ driver.elementIdValue(extractElementId(element), keys);
196
+ }
197
+ }
198
+
199
+ async scrollIntoView(driver, element, align = false) {
200
+ if (this.isSelector(element)) {
201
+ element = await this.findElement(driver, element);
202
+ }
203
+ await driver.execute('arguments[0].scrollIntoView(arguments[1])', element, align);
204
+ }
205
+
206
+ async waitUntilDisplayed(driver, selector, timeout) {
207
+ await driver.waitForVisible(selector, timeout);
208
+ }
209
+ // #endregion
210
+ }
211
+
212
+ class EyeSdkService {
213
+ constructor() {
214
+ /**
215
+ * @typedef {import('@applitools/types').Core} Core
216
+ * @type {Core}
217
+ */
218
+ this.sdk = makeSDK({
219
+ name: 'Testim.io',
220
+ version: '4.0.0',
221
+ spec: new EyesSpec(),
222
+ VisualGridClient: require('@applitools/visual-grid-client'),
223
+ });
224
+ }
225
+ getManager(useVisualGrid, concurrency) {
226
+ return this.sdk.makeManager({ type: useVisualGrid ? 'vg' : 'classic', concurrency });
227
+ }
228
+ }
229
+
230
+ exports.eyeSdkService = new EyeSdkService();
@@ -143,25 +143,9 @@ class ConsoleReporter {
143
143
  }
144
144
 
145
145
  onGetSession(workerId, testName, mode) {
146
- if ([constants.CLI_MODE.DEVICE_FARM_APPIUM, constants.CLI_MODE.APPIUM].includes(mode)) {
147
- this.printWorkerMessage(workerId, `Get device to run ${chalk.underline(testName)}`);
148
- return;
149
- }
150
146
  this.printWorkerMessage(workerId, `Get browser to run ${chalk.underline(testName)}`);
151
147
  }
152
148
 
153
- onUploadApk(apkLocation, vendorAppId) {
154
- if (vendorAppId) {
155
- console.log(`Use existing app id: ${vendorAppId}`);
156
- return;
157
- }
158
- console.log(`Upload apk file: ${apkLocation}`);
159
- }
160
-
161
- onUploadApkFinished(appId) {
162
- console.log(`Finished to upload apk file id: ${appId}`);
163
- }
164
-
165
149
  onWaitToTestStart(workerId) {
166
150
  this.printWorkerMessage(workerId, 'Wait for test start');
167
151
  }
@@ -175,10 +159,6 @@ class ConsoleReporter {
175
159
  }
176
160
  }
177
161
 
178
- onWaitForDevice(workerId, executionId) {
179
- this.printWorkerMessage(workerId, `Device is being prepared for execution ${executionId} (this may take a few minutes)`);
180
- }
181
-
182
162
  onGetBrowserFailure(workerId, projectId, attempt) {
183
163
  if (attempt !== 2) {
184
164
  return; // we want to try 2 times before showing the message once
@@ -58,14 +58,11 @@ addHook('onGetBrowserSuccess');
58
58
  addHook('onTestPlanStarted');
59
59
  addHook('onGetSlot');
60
60
  addHook('onGetSession');
61
- addHook('onUploadApkFinished');
62
- addHook('onUploadApk');
63
61
  addHook('onTestFinished');
64
62
  addHook('onTestFailed');
65
63
  addHook('onTestPassed');
66
64
  addHook('onTestStarted');
67
65
  addHook('onTestIgnored');
68
- addHook('onWaitForDevice');
69
66
  addHook('onWaitToTestStart');
70
67
  addHook('onWaitToTestComplete');
71
68
 
@@ -128,24 +125,6 @@ Reporter.prototype.onGetSession = function (workerId, testName, mode) {
128
125
  });
129
126
  };
130
127
 
131
- Reporter.prototype.onUploadApkFinished = function (appId) {
132
- return Promise.each(this.reporters, reporter => {
133
- if (reporter && reporter.onUploadApkFinished) {
134
- return reporter.onUploadApkFinished(appId);
135
- }
136
- return undefined;
137
- });
138
- };
139
-
140
- Reporter.prototype.onUploadApk = function (apkLocation, vendorAppId) {
141
- return Promise.each(this.reporters, reporter => {
142
- if (reporter && reporter.onUploadApk) {
143
- return reporter.onUploadApk(apkLocation, vendorAppId);
144
- }
145
- return undefined;
146
- });
147
- };
148
-
149
128
  Reporter.prototype.onWaitToTestComplete = function (workerId, isCodeMode, debuggerAddress) {
150
129
  return Promise.each(this.reporters, reporter => {
151
130
  if (reporter && reporter.onWaitToTestComplete) {