@applitools/driver 1.9.22 → 1.9.25

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/dist/driver.js CHANGED
@@ -144,8 +144,8 @@ class Driver {
144
144
  this._currentContext = context;
145
145
  }
146
146
  async init() {
147
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2;
148
- var _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14;
147
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3;
148
+ var _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
149
149
  const capabilities = await ((_b = (_a = this._spec).getCapabilities) === null || _b === void 0 ? void 0 : _b.call(_a, this.target));
150
150
  this._logger.log('Driver capabilities', capabilities);
151
151
  const capabilitiesInfo = capabilities ? (0, capabilities_1.parseCapabilities)(capabilities, this._customConfig) : undefined;
@@ -156,29 +156,29 @@ class Driver {
156
156
  (_e = (await this.getOrientation().catch(() => undefined))) !== null && _e !== void 0 ? _e : this._driverInfo.orientation;
157
157
  }
158
158
  if (this.isWeb) {
159
- (_f = (_3 = this._driverInfo).pixelRatio) !== null && _f !== void 0 ? _f : (_3.pixelRatio = await this.execute(snippets.getPixelRatio));
160
- (_g = (_4 = this._driverInfo).viewportScale) !== null && _g !== void 0 ? _g : (_4.viewportScale = await this.execute(snippets.getViewportScale));
161
- (_h = (_5 = this._driverInfo).userAgent) !== null && _h !== void 0 ? _h : (_5.userAgent = await this.execute(snippets.getUserAgent));
159
+ (_f = (_4 = this._driverInfo).pixelRatio) !== null && _f !== void 0 ? _f : (_4.pixelRatio = await this.execute(snippets.getPixelRatio));
160
+ (_g = (_5 = this._driverInfo).viewportScale) !== null && _g !== void 0 ? _g : (_5.viewportScale = await this.execute(snippets.getViewportScale));
161
+ (_h = (_6 = this._driverInfo).userAgent) !== null && _h !== void 0 ? _h : (_6.userAgent = await this.execute(snippets.getUserAgent));
162
162
  if (this._driverInfo.userAgent) {
163
163
  const userAgentInfo = (0, user_agent_1.parseUserAgent)(this._driverInfo.userAgent);
164
164
  this._driverInfo.browserName = (_j = userAgentInfo.browserName) !== null && _j !== void 0 ? _j : this._driverInfo.browserName;
165
165
  this._driverInfo.browserVersion = (_k = userAgentInfo.browserVersion) !== null && _k !== void 0 ? _k : this._driverInfo.browserVersion;
166
166
  if (this._driverInfo.isMobile) {
167
- (_l = (_6 = this._driverInfo).platformName) !== null && _l !== void 0 ? _l : (_6.platformName = userAgentInfo.platformName);
168
- (_m = (_7 = this._driverInfo).platformVersion) !== null && _m !== void 0 ? _m : (_7.platformVersion = userAgentInfo.platformVersion);
167
+ (_l = (_7 = this._driverInfo).platformName) !== null && _l !== void 0 ? _l : (_7.platformName = userAgentInfo.platformName);
168
+ (_m = (_8 = this._driverInfo).platformVersion) !== null && _m !== void 0 ? _m : (_8.platformVersion = userAgentInfo.platformVersion);
169
169
  }
170
170
  else {
171
171
  this._driverInfo.platformName = (_o = userAgentInfo.platformName) !== null && _o !== void 0 ? _o : this._driverInfo.platformName;
172
172
  this._driverInfo.platformVersion = (_p = userAgentInfo.platformVersion) !== null && _p !== void 0 ? _p : this._driverInfo.platformVersion;
173
173
  }
174
174
  }
175
- (_q = (_8 = this._driverInfo).features) !== null && _q !== void 0 ? _q : (_8.features = {});
176
- (_r = (_9 = this._driverInfo.features).allCookies) !== null && _r !== void 0 ? _r : (_9.allCookies = /chrome/i.test(this._driverInfo.browserName) && !this._driverInfo.isMobile);
175
+ (_q = (_9 = this._driverInfo).features) !== null && _q !== void 0 ? _q : (_9.features = {});
176
+ (_r = (_10 = this._driverInfo.features).allCookies) !== null && _r !== void 0 ? _r : (_10.allCookies = /chrome/i.test(this._driverInfo.browserName) && !this._driverInfo.isMobile);
177
177
  }
178
178
  else {
179
179
  // this value always excludes the height of the navigation bar, and sometimes it also excludes the height of the status bar
180
180
  let windowSize = await this._spec.getWindowSize(this.target);
181
- (_s = (_10 = this._driverInfo).displaySize) !== null && _s !== void 0 ? _s : (_10.displaySize = windowSize);
181
+ (_s = (_11 = this._driverInfo).displaySize) !== null && _s !== void 0 ? _s : (_11.displaySize = windowSize);
182
182
  if (((_t = this.orientation) === null || _t === void 0 ? void 0 : _t.startsWith('landscape')) &&
183
183
  this._driverInfo.displaySize.height > this._driverInfo.displaySize.width) {
184
184
  this._driverInfo.displaySize = {
@@ -215,17 +215,17 @@ class Driver {
215
215
  }
216
216
  }
217
217
  // bar sizes have to be scaled on android
218
- (_11 = this._driverInfo).statusBarSize && (_11.statusBarSize = this._driverInfo.statusBarSize / this.pixelRatio);
219
- (_12 = this._driverInfo).navigationBarSize && (_12.navigationBarSize = this._driverInfo.navigationBarSize / this.pixelRatio);
218
+ (_12 = this._driverInfo).statusBarSize && (_12.statusBarSize = this._driverInfo.statusBarSize / this.pixelRatio);
219
+ (_13 = this._driverInfo).navigationBarSize && (_13.navigationBarSize = this._driverInfo.navigationBarSize / this.pixelRatio);
220
220
  windowSize = utils.geometry.scale(windowSize, 1 / this.pixelRatio);
221
- (_13 = this._driverInfo).displaySize && (_13.displaySize = utils.geometry.scale(this._driverInfo.displaySize, 1 / this.pixelRatio));
221
+ (_14 = this._driverInfo).displaySize && (_14.displaySize = utils.geometry.scale(this._driverInfo.displaySize, 1 / this.pixelRatio));
222
222
  }
223
223
  if (this.isIOS) {
224
224
  if ((_0 = this.orientation) === null || _0 === void 0 ? void 0 : _0.startsWith('landscape'))
225
225
  this._driverInfo.statusBarSize = 0;
226
226
  }
227
227
  // calculate viewport location
228
- (_1 = (_14 = this._driverInfo).viewportLocation) !== null && _1 !== void 0 ? _1 : (_14.viewportLocation = {
228
+ (_1 = (_15 = this._driverInfo).viewportLocation) !== null && _1 !== void 0 ? _1 : (_15.viewportLocation = {
229
229
  x: this.orientation === 'landscape' ? this.navigationBarSize : 0,
230
230
  y: this.statusBarSize,
231
231
  });
@@ -255,10 +255,13 @@ class Driver {
255
255
  this._driverInfo.safeArea.height -= bottomOffset;
256
256
  }
257
257
  }
258
+ // TODO: if user opts into NML, skip initializing the helpers
258
259
  // init helper lib
259
- this._helper = this.isIOS
260
- ? await helper_ios_1.HelperIOS.make({ spec: this._spec, driver: this, logger: this._logger })
261
- : await helper_android_1.HelperAndroid.make({ spec: this._spec, driver: this, logger: this._logger });
260
+ if (!((_3 = this._customConfig) === null || _3 === void 0 ? void 0 : _3.disableHelper)) {
261
+ this._helper = this.isIOS
262
+ ? await helper_ios_1.HelperIOS.make({ spec: this._spec, driver: this, logger: this._logger })
263
+ : await helper_android_1.HelperAndroid.make({ spec: this._spec, driver: this, logger: this._logger });
264
+ }
262
265
  }
263
266
  this._logger.log('Combined driver info', this._driverInfo);
264
267
  return this;
package/dist/element.js CHANGED
@@ -190,7 +190,7 @@ class Element {
190
190
  this._logger.log('Extracted client region', region);
191
191
  return region;
192
192
  }
193
- async getContentSize() {
193
+ async getContentSize(options = {}) {
194
194
  if (this._state.contentSize)
195
195
  return this._state.contentSize;
196
196
  const size = await this.withRefresh(async () => {
@@ -202,7 +202,7 @@ class Element {
202
202
  else {
203
203
  this._logger.log('Extracting content size of native element with selector', this.selector);
204
204
  try {
205
- let contentRegion = await ((_a = this.driver.helper) === null || _a === void 0 ? void 0 : _a.getContentRegion(this));
205
+ let contentRegion = await ((_a = this.driver.helper) === null || _a === void 0 ? void 0 : _a.getContentRegion(this, options));
206
206
  this._logger.log('Extracted native content region using helper library', contentRegion);
207
207
  // on android extraction of this argument will perform non-deterministic touch action, so it is better to avoid it
208
208
  if (!contentRegion || !this.driver.isAndroid) {
@@ -398,6 +398,11 @@ class Element {
398
398
  const currentScrollOffset = await this.getScrollOffset();
399
399
  if (!(options === null || options === void 0 ? void 0 : options.force) && utils.geometry.equals(offset, currentScrollOffset))
400
400
  return currentScrollOffset;
401
+ if (((_a = this.driver.helper) === null || _a === void 0 ? void 0 : _a.name) === 'android' && utils.geometry.equals(offset, { x: 0, y: 0 })) {
402
+ await this.driver.helper.scrollToTop(this);
403
+ this._state.scrollOffset = offset;
404
+ return this._state.scrollOffset;
405
+ }
401
406
  const contentSize = await this.getContentSize();
402
407
  const scrollableRegion = await this.getClientRegion();
403
408
  const maxOffset = {
@@ -405,11 +410,6 @@ class Element {
405
410
  y: Math.round(scrollableRegion.height * (contentSize.height / scrollableRegion.height - 1)),
406
411
  };
407
412
  const requiredOffset = { x: Math.min(offset.x, maxOffset.x), y: Math.min(offset.y, maxOffset.y) };
408
- if (((_a = this.driver.helper) === null || _a === void 0 ? void 0 : _a.name) === 'android' && utils.geometry.equals(requiredOffset, { x: 0, y: 0 })) {
409
- await this.driver.helper.scrollToTop(this);
410
- this._state.scrollOffset = requiredOffset;
411
- return this._state.scrollOffset;
412
- }
413
413
  let effectiveRegion = scrollableRegion;
414
414
  let remainingOffset = utils.geometry.equals(requiredOffset, { x: 0, y: 0 })
415
415
  ? { x: -maxOffset.x, y: -maxOffset.y } // if it has to be scrolled to the very beginning, then scroll maximum amount of pixels
@@ -1,16 +1,47 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
2
28
  Object.defineProperty(exports, "__esModule", { value: true });
3
29
  exports.HelperAndroid = void 0;
30
+ const utils = __importStar(require("@applitools/utils"));
31
+ const gte_1 = __importDefault(require("semver/functions/gte"));
4
32
  class HelperAndroid {
5
33
  constructor(options) {
34
+ this._supportAsync = false;
6
35
  this._spec = options.spec;
7
36
  this._input = options.input;
8
37
  this._action = options.action;
9
38
  this._legacy = options.legacy;
10
39
  this._logger = options.logger;
11
40
  this.name = this._legacy ? 'android-legacy' : 'android';
41
+ this._supportAsync = options.supportAsync === true;
12
42
  }
13
43
  static async make(options) {
44
+ var _a;
14
45
  const { spec, driver, logger } = options;
15
46
  let legacy = false;
16
47
  let input = await driver.element({ type: 'xpath', selector: '//*[@content-desc="EyesAppiumHelperEDT"]' });
@@ -18,11 +49,23 @@ class HelperAndroid {
18
49
  legacy = true;
19
50
  input = await driver.element({ type: 'xpath', selector: '//*[@content-desc="EyesAppiumHelper"]' });
20
51
  }
52
+ const versionElement = await driver.element({
53
+ type: 'xpath',
54
+ selector: '//*[@content-desc="EyesAppiumHelper_Version"]',
55
+ });
56
+ const version = (_a = (await (versionElement === null || versionElement === void 0 ? void 0 : versionElement.getText()))) !== null && _a !== void 0 ? _a : '0.0.0';
21
57
  const action = !legacy
22
58
  ? await driver.element({ type: 'xpath', selector: '//*[@content-desc="EyesAppiumHelper_Action"]' })
23
59
  : null;
24
60
  return input
25
- ? new HelperAndroid({ spec, input, action, legacy, logger })
61
+ ? new HelperAndroid({
62
+ spec,
63
+ input,
64
+ action,
65
+ legacy,
66
+ logger,
67
+ supportAsync: (0, gte_1.default)(version, '1.8.0'),
68
+ })
26
69
  : null;
27
70
  }
28
71
  async _getElementId(element) {
@@ -39,31 +82,49 @@ class HelperAndroid {
39
82
  await this._action.type('1').catch(() => null);
40
83
  text = await this._input.getText();
41
84
  }
85
+ // wait until the JAVA complete the async operation
86
+ const timeout = 5 * 60 * 1000;
87
+ const finishAt = Date.now() + timeout;
88
+ while (text === 'WAIT' && finishAt > Date.now()) {
89
+ await utils.general.sleep(1000);
90
+ text = await this._input.getText();
91
+ }
92
+ if (text === 'WAIT') {
93
+ this._logger.warn(`Helper library didn't provide a response for async command (${command}) during ${timeout}ms`);
94
+ text = null;
95
+ }
42
96
  await this._input.type('');
43
97
  return text;
44
98
  }
45
- async getContentRegion(element) {
99
+ async getContentRegion(element, options) {
100
+ var _a, _b, _c;
101
+ const elementId = await this._getElementId(element);
102
+ if (!elementId)
103
+ return null;
46
104
  let contentHeightString;
47
105
  if (this._legacy) {
48
106
  await this._input.click();
49
107
  contentHeightString = await this._input.getText();
50
108
  }
109
+ else if (this._supportAsync && ((_a = options === null || options === void 0 ? void 0 : options.lazyLoad) === null || _a === void 0 ? void 0 : _a.waitingTime)) {
110
+ const result = await this._command(`offset_async;${elementId};0;0;0;${(_c = (_b = options === null || options === void 0 ? void 0 : options.lazyLoad) === null || _b === void 0 ? void 0 : _b.waitingTime) !== null && _c !== void 0 ? _c : 0}`);
111
+ contentHeightString = result.split(';')[0];
112
+ }
51
113
  else {
52
- const elementId = await this._getElementId(element);
53
- if (!elementId)
54
- return null;
55
- contentHeightString = await this._command(`offset;${elementId};0;0;0`);
114
+ contentHeightString = await this._command(`'offset';${elementId};0;0;0;0`);
56
115
  }
57
- const region = await this._spec.getElementRegion(this._input.driver.target, element.target);
58
116
  const contentHeight = Number(contentHeightString);
59
- return !Number.isNaN(contentHeight) && contentHeight >= region.height
60
- ? { x: region.x, y: region.y, width: region.width, height: contentHeight }
61
- : null;
117
+ if (Number.isNaN(contentHeight))
118
+ return null;
119
+ const region = await this._spec.getElementRegion(this._input.driver.target, element.target);
120
+ if (contentHeight < region.height)
121
+ return null;
122
+ return { x: region.x, y: region.y, width: region.width, height: contentHeight };
62
123
  }
63
124
  async getTouchPadding() {
64
125
  if (this._legacy)
65
126
  return null;
66
- const touchPaddingString = await this._command(`getTouchPadding;0;0;0;0`);
127
+ const touchPaddingString = await this._command(`getTouchPadding;0;0;0;0;0`);
67
128
  const touchPadding = Number(touchPaddingString);
68
129
  if (!touchPadding || Number.isNaN(touchPadding))
69
130
  return null;
@@ -75,7 +136,7 @@ class HelperAndroid {
75
136
  const elementId = await this._getElementId(element);
76
137
  if (!elementId)
77
138
  return null;
78
- const regionString = await this._command(`getRect;${elementId};0;0`);
139
+ const regionString = await this._command(`getRect;${elementId};0;0;0`);
79
140
  if (!regionString)
80
141
  return null;
81
142
  const [, x, y, height, width] = regionString.match(/\[(-?\d+(?:\.\d+)?);(-?\d+(?:\.\d+)?);(-?\d+(?:\.\d+)?);(-?\d+(?:\.\d+)?)\]/);
@@ -90,7 +151,7 @@ class HelperAndroid {
90
151
  const elementId = await this._getElementId(element);
91
152
  if (!elementId)
92
153
  return null;
93
- await this._command(`moveToTop;${elementId};0;-1`);
154
+ await this._command(`moveToTop;${elementId};0;-1;0`);
94
155
  }
95
156
  async scrollBy(element, offset) {
96
157
  if (this._legacy)
@@ -98,7 +159,7 @@ class HelperAndroid {
98
159
  const elementId = await this._getElementId(element);
99
160
  if (!elementId)
100
161
  return null;
101
- await this._command(`scroll;${elementId};${offset.y};0;0`);
162
+ await this._command(`scroll;${elementId};${offset.y};0;0;0`);
102
163
  }
103
164
  }
104
165
  exports.HelperAndroid = HelperAndroid;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applitools/driver",
3
- "version": "1.9.22",
3
+ "version": "1.9.25",
4
4
  "description": "Applitools universal framework wrapper",
5
5
  "keywords": [
6
6
  "applitools",
@@ -80,11 +80,12 @@
80
80
  "dependencies": {
81
81
  "@applitools/logger": "1.1.16",
82
82
  "@applitools/snippets": "2.4.5",
83
- "@applitools/types": "1.5.8",
84
- "@applitools/utils": "1.3.10"
83
+ "@applitools/types": "1.5.9",
84
+ "@applitools/utils": "1.3.10",
85
+ "semver": "7.3.7"
85
86
  },
86
87
  "devDependencies": {
87
- "@applitools/bongo": "^2.1.6",
88
+ "@applitools/bongo": "^2.2.0",
88
89
  "@applitools/scripts": "^1.1.0",
89
90
  "@types/mocha": "^9.1.1",
90
91
  "@types/node": "^17.0.31",
@@ -39,7 +39,9 @@ export declare class Element<TDriver, TContext, TElement, TSelector> {
39
39
  init(context: Context<TDriver, TContext, TElement, TSelector>): Promise<this>;
40
40
  getRegion(): Promise<types.Region>;
41
41
  getClientRegion(): Promise<types.Region>;
42
- getContentSize(): Promise<types.Size>;
42
+ getContentSize(options?: {
43
+ lazyLoad?: types.LazyLoadOptions;
44
+ }): Promise<types.Size>;
43
45
  isPager(): Promise<boolean>;
44
46
  isScrollable(): Promise<boolean>;
45
47
  isRoot(): Promise<boolean>;
@@ -12,6 +12,7 @@ export declare class HelperAndroid<TDriver, TContext, TElement, TSelector> {
12
12
  private readonly _input;
13
13
  private readonly _action?;
14
14
  private readonly _legacy;
15
+ private readonly _supportAsync;
15
16
  private _logger;
16
17
  readonly name: 'android' | 'android-legacy';
17
18
  constructor(options: {
@@ -20,10 +21,13 @@ export declare class HelperAndroid<TDriver, TContext, TElement, TSelector> {
20
21
  action?: Element<TDriver, TContext, TElement, TSelector>;
21
22
  legacy: boolean;
22
23
  logger?: any;
24
+ supportAsync?: boolean;
23
25
  });
24
26
  private _getElementId;
25
27
  private _command;
26
- getContentRegion(element: Element<TDriver, TContext, TElement, TSelector>): Promise<types.Region>;
28
+ getContentRegion(element: Element<TDriver, TContext, TElement, TSelector>, options?: {
29
+ lazyLoad?: types.LazyLoadOptions;
30
+ }): Promise<types.Region>;
27
31
  getTouchPadding(): Promise<number>;
28
32
  getRegion(element: Element<TDriver, TContext, TElement, TSelector>): Promise<types.Region>;
29
33
  scrollToTop(element: Element<TDriver, TContext, TElement, TSelector>): Promise<void>;