@applitools/driver 1.9.7 → 1.9.10

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.
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseCapabilities = void 0;
4
4
  function parseCapabilities(capabilities, customConfig) {
5
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
5
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
6
6
  if (capabilities.capabilities)
7
7
  capabilities = capabilities.capabilities;
8
8
  if (!(customConfig === null || customConfig === void 0 ? void 0 : customConfig.keepPlatformNameAsIs)) {
@@ -35,9 +35,9 @@ function parseCapabilities(capabilities, customConfig) {
35
35
  if (info.isNative) {
36
36
  info.displaySize = extractDisplaySize(capabilities);
37
37
  info.pixelRatio = capabilities.pixelRatio;
38
- info.statusBarHeight = capabilities.statBarHeight;
38
+ info.statusBarSize = (_o = capabilities.statBarHeight) !== null && _o !== void 0 ? _o : (_p = capabilities.viewportRect) === null || _p === void 0 ? void 0 : _p.top;
39
39
  if (info.displaySize && info.orientation && capabilities.viewportRect) {
40
- info.navigationBarHeight =
40
+ info.navigationBarSize =
41
41
  info.orientation === 'landscape'
42
42
  ? info.displaySize.width - (capabilities.viewportRect.left + capabilities.viewportRect.width)
43
43
  : info.displaySize.height - (capabilities.viewportRect.top + capabilities.viewportRect.height);
package/dist/context.js CHANGED
@@ -232,12 +232,11 @@ class Context {
232
232
  }
233
233
  return {
234
234
  context,
235
- shadow: root ? new element_1.Element({ spec: this._spec, context, element, logger: this._logger, root }) : null,
235
+ shadow: element && new element_1.Element({ spec: this._spec, context, element, logger: this._logger }),
236
236
  selector: currentSelector,
237
237
  };
238
238
  }
239
239
  async element(elementOrSelector) {
240
- var _a;
241
240
  if (this._spec.isElement(elementOrSelector)) {
242
241
  return new element_1.Element({ spec: this._spec, context: this, element: elementOrSelector, logger: this._logger });
243
242
  }
@@ -249,7 +248,7 @@ class Context {
249
248
  const root = await this.root(elementOrSelector);
250
249
  if (!root)
251
250
  return null;
252
- const element = await this._spec.findElement(root.context.target, specUtils.transformSelector(this._spec, root.selector, this.driver), (_a = root.shadow) === null || _a === void 0 ? void 0 : _a.target);
251
+ const element = await this._spec.findElement(root.context.target, specUtils.transformSelector(this._spec, root.selector, this.driver), root.shadow && (await root.shadow.getShadowRoot()));
253
252
  // TODO root.selector is not a full selector from context root to an element, but selector inside a shadow
254
253
  return element
255
254
  ? new element_1.Element({ spec: this._spec, context: root.context, element, selector: root.selector, logger: this._logger })
@@ -260,7 +259,6 @@ class Context {
260
259
  }
261
260
  }
262
261
  async elements(elementOrSelector) {
263
- var _a;
264
262
  if (this._spec.isElement(elementOrSelector)) {
265
263
  return [new element_1.Element({ spec: this._spec, context: this, element: elementOrSelector, logger: this._logger })];
266
264
  }
@@ -272,7 +270,7 @@ class Context {
272
270
  const root = await this.root(elementOrSelector);
273
271
  if (!root)
274
272
  return [];
275
- const elements = await this._spec.findElements(root.context.target, specUtils.transformSelector(this._spec, root.selector, this.driver), (_a = root.shadow) === null || _a === void 0 ? void 0 : _a.target);
273
+ const elements = await this._spec.findElements(root.context.target, specUtils.transformSelector(this._spec, root.selector, this.driver), root.shadow && (await root.shadow.getShadowRoot()));
276
274
  return elements.map((element, index) => {
277
275
  // TODO root.selector is not a full selector from context root to an element, but selector inside a shadow
278
276
  return new element_1.Element({
package/dist/driver.js CHANGED
@@ -107,13 +107,13 @@ class Driver {
107
107
  var _a;
108
108
  return (_a = this._driverInfo.viewportScale) !== null && _a !== void 0 ? _a : 1;
109
109
  }
110
- get statusBarHeight() {
110
+ get statusBarSize() {
111
111
  var _a;
112
- return (_a = this._driverInfo.statusBarHeight) !== null && _a !== void 0 ? _a : (this.isNative ? 0 : undefined);
112
+ return (_a = this._driverInfo.statusBarSize) !== null && _a !== void 0 ? _a : (this.isNative ? 0 : undefined);
113
113
  }
114
- get navigationBarHeight() {
114
+ get navigationBarSize() {
115
115
  var _a;
116
- return (_a = this._driverInfo.navigationBarHeight) !== null && _a !== void 0 ? _a : (this.isNative ? 0 : undefined);
116
+ return (_a = this._driverInfo.navigationBarSize) !== null && _a !== void 0 ? _a : (this.isNative ? 0 : undefined);
117
117
  }
118
118
  get isNative() {
119
119
  var _a, _b;
@@ -144,84 +144,92 @@ 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;
148
- var _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8;
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;
148
+ var _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12;
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;
152
152
  const driverInfo = await ((_d = (_c = this._spec).getDriverInfo) === null || _d === void 0 ? void 0 : _d.call(_c, this.target));
153
153
  this._driverInfo = { ...capabilitiesInfo, ...driverInfo };
154
+ if (this.isMobile) {
155
+ this._driverInfo.orientation =
156
+ (_e = (await this.getOrientation().catch(() => undefined))) !== null && _e !== void 0 ? _e : this._driverInfo.orientation;
157
+ }
154
158
  if (this.isWeb) {
155
- (_e = (_x = this._driverInfo).pixelRatio) !== null && _e !== void 0 ? _e : (_x.pixelRatio = await this.execute(snippets.getPixelRatio));
156
- (_f = (_y = this._driverInfo).viewportScale) !== null && _f !== void 0 ? _f : (_y.viewportScale = await this.execute(snippets.getViewportScale));
157
- (_g = (_z = this._driverInfo).userAgent) !== null && _g !== void 0 ? _g : (_z.userAgent = await this.execute(snippets.getUserAgent));
159
+ (_f = (_1 = this._driverInfo).pixelRatio) !== null && _f !== void 0 ? _f : (_1.pixelRatio = await this.execute(snippets.getPixelRatio));
160
+ (_g = (_2 = this._driverInfo).viewportScale) !== null && _g !== void 0 ? _g : (_2.viewportScale = await this.execute(snippets.getViewportScale));
161
+ (_h = (_3 = this._driverInfo).userAgent) !== null && _h !== void 0 ? _h : (_3.userAgent = await this.execute(snippets.getUserAgent));
158
162
  if (this._driverInfo.userAgent) {
159
163
  const userAgentInfo = (0, user_agent_1.parseUserAgent)(this._driverInfo.userAgent);
160
- this._driverInfo.browserName = (_h = userAgentInfo.browserName) !== null && _h !== void 0 ? _h : this._driverInfo.browserName;
161
- this._driverInfo.browserVersion = (_j = userAgentInfo.browserVersion) !== null && _j !== void 0 ? _j : this._driverInfo.browserVersion;
164
+ this._driverInfo.browserName = (_j = userAgentInfo.browserName) !== null && _j !== void 0 ? _j : this._driverInfo.browserName;
165
+ this._driverInfo.browserVersion = (_k = userAgentInfo.browserVersion) !== null && _k !== void 0 ? _k : this._driverInfo.browserVersion;
162
166
  if (this._driverInfo.isMobile) {
163
- (_k = (_0 = this._driverInfo).platformName) !== null && _k !== void 0 ? _k : (_0.platformName = userAgentInfo.platformName);
164
- (_l = (_1 = this._driverInfo).platformVersion) !== null && _l !== void 0 ? _l : (_1.platformVersion = userAgentInfo.platformVersion);
167
+ (_l = (_4 = this._driverInfo).platformName) !== null && _l !== void 0 ? _l : (_4.platformName = userAgentInfo.platformName);
168
+ (_m = (_5 = this._driverInfo).platformVersion) !== null && _m !== void 0 ? _m : (_5.platformVersion = userAgentInfo.platformVersion);
165
169
  }
166
170
  else {
167
- this._driverInfo.platformName = (_m = userAgentInfo.platformName) !== null && _m !== void 0 ? _m : this._driverInfo.platformName;
168
- this._driverInfo.platformVersion = (_o = userAgentInfo.platformVersion) !== null && _o !== void 0 ? _o : this._driverInfo.platformVersion;
171
+ this._driverInfo.platformName = (_o = userAgentInfo.platformName) !== null && _o !== void 0 ? _o : this._driverInfo.platformName;
172
+ this._driverInfo.platformVersion = (_p = userAgentInfo.platformVersion) !== null && _p !== void 0 ? _p : this._driverInfo.platformVersion;
169
173
  }
170
174
  }
171
- (_p = (_2 = this._driverInfo).features) !== null && _p !== void 0 ? _p : (_2.features = {});
172
- (_q = (_3 = this._driverInfo.features).allCookies) !== null && _q !== void 0 ? _q : (_3.allCookies = /chrome/i.test(this._driverInfo.browserName) && !this._driverInfo.isMobile);
175
+ (_q = (_6 = this._driverInfo).features) !== null && _q !== void 0 ? _q : (_6.features = {});
176
+ (_r = (_7 = this._driverInfo.features).allCookies) !== null && _r !== void 0 ? _r : (_7.allCookies = /chrome/i.test(this._driverInfo.browserName) && !this._driverInfo.isMobile);
173
177
  }
174
178
  else {
175
179
  // this value always excludes the height of the navigation bar, and sometimes it also excludes the height of the status bar
176
180
  let windowSize = await this._spec.getWindowSize(this.target);
177
- (_r = (_4 = this._driverInfo).displaySize) !== null && _r !== void 0 ? _r : (_4.displaySize = windowSize);
178
- const orientation = await this.getOrientation();
181
+ (_s = (_8 = this._driverInfo).displaySize) !== null && _s !== void 0 ? _s : (_8.displaySize = windowSize);
179
182
  if (this.isAndroid) {
180
183
  // bar sizes could be extracted only on android
181
- const barsSize = await ((_t = (_s = this._spec).getBarsSize) === null || _t === void 0 ? void 0 : _t.call(_s, this.target).catch(() => undefined));
182
- if (barsSize) {
183
- this._logger.log('Driver bars size', barsSize);
184
- // navigation bar height is replaced with the width in landscape orientation on android (due to the bug in appium)
185
- if (orientation === 'landscape')
186
- barsSize.navigationBarHeight = barsSize.navigationBarWidth;
184
+ const systemBars = await ((_u = (_t = this._spec).getSystemBars) === null || _u === void 0 ? void 0 : _u.call(_t, this.target).catch(() => null));
185
+ const { statusBar, navigationBar } = systemBars !== null && systemBars !== void 0 ? systemBars : {};
186
+ if (statusBar === null || statusBar === void 0 ? void 0 : statusBar.visible) {
187
+ this._logger.log('Driver status bar', statusBar);
188
+ const statusBarSize = statusBar.height;
187
189
  // when status bar is overlapping content on android it returns status bar height equal to display height
188
- if (barsSize.statusBarHeight < this._driverInfo.displaySize.height) {
189
- this._driverInfo.statusBarHeight = Math.max((_u = this._driverInfo.statusBarHeight) !== null && _u !== void 0 ? _u : 0, barsSize.statusBarHeight);
190
+ if (statusBarSize < this._driverInfo.displaySize.height) {
191
+ this._driverInfo.statusBarSize = Math.max((_v = this._driverInfo.statusBarSize) !== null && _v !== void 0 ? _v : 0, statusBarSize);
190
192
  }
191
- // when navigation bar is invisible on android it returns navigation bar height equal to display height
192
- if (barsSize.navigationBarHeight < this._driverInfo.displaySize.height) {
193
- this._driverInfo.navigationBarHeight = Math.max((_v = this._driverInfo.navigationBarHeight) !== null && _v !== void 0 ? _v : 0, barsSize.navigationBarHeight);
193
+ }
194
+ if (navigationBar === null || navigationBar === void 0 ? void 0 : navigationBar.visible) {
195
+ this._logger.log('Driver navigation size', navigationBar);
196
+ // if navigation bar is placed on the right side is screen the the orientation is landscape-secondary
197
+ if (navigationBar.x > 0)
198
+ this._driverInfo.orientation = 'landscape-secondary';
199
+ // navigation bar size could be its height or width depending on screen orientation
200
+ const navigationBarSize = navigationBar[((_w = this.orientation) === null || _w === void 0 ? void 0 : _w.startsWith('landscape')) ? 'width' : 'height'];
201
+ // when navigation bar is invisible on android it returns navigation bar size equal to display size
202
+ if (navigationBarSize <
203
+ this._driverInfo.displaySize[((_x = this.orientation) === null || _x === void 0 ? void 0 : _x.startsWith('landscape')) ? 'width' : 'height']) {
204
+ this._driverInfo.navigationBarSize = Math.max((_y = this._driverInfo.navigationBarSize) !== null && _y !== void 0 ? _y : 0, navigationBarSize);
194
205
  }
195
206
  else {
196
- this._driverInfo.navigationBarHeight = 0;
207
+ this._driverInfo.navigationBarSize = 0;
197
208
  }
198
- // bar heights have to be scaled on android
199
- (_5 = this._driverInfo).statusBarHeight && (_5.statusBarHeight = this._driverInfo.statusBarHeight / this.pixelRatio);
200
- (_6 = this._driverInfo).navigationBarHeight && (_6.navigationBarHeight = this._driverInfo.navigationBarHeight / this.pixelRatio);
201
209
  }
202
- windowSize = utils.geometry.scale(this._driverInfo.displaySize, 1 / this.pixelRatio);
203
- (_7 = this._driverInfo).displaySize && (_7.displaySize = utils.geometry.scale(this._driverInfo.displaySize, 1 / this.pixelRatio));
210
+ // bar sizes have to be scaled on android
211
+ (_9 = this._driverInfo).statusBarSize && (_9.statusBarSize = this._driverInfo.statusBarSize / this.pixelRatio);
212
+ (_10 = this._driverInfo).navigationBarSize && (_10.navigationBarSize = this._driverInfo.navigationBarSize / this.pixelRatio);
213
+ windowSize = utils.geometry.scale(windowSize, 1 / this.pixelRatio);
214
+ (_11 = this._driverInfo).displaySize && (_11.displaySize = utils.geometry.scale(this._driverInfo.displaySize, 1 / this.pixelRatio));
204
215
  }
216
+ // calculate viewport location
217
+ (_z = (_12 = this._driverInfo).viewportLocation) !== null && _z !== void 0 ? _z : (_12.viewportLocation = {
218
+ x: this.orientation === 'landscape' ? this.navigationBarSize : 0,
219
+ y: this.statusBarSize,
220
+ });
205
221
  // calculate viewport size
206
222
  if (!this._driverInfo.viewportSize) {
207
- if (this.navigationBarHeight > 1) {
208
- if (orientation === 'landscape') {
209
- this._driverInfo.viewportSize = {
210
- width: this._driverInfo.displaySize.height - this.navigationBarHeight,
211
- height: this._driverInfo.displaySize.width - this.statusBarHeight,
212
- };
213
- }
214
- else {
215
- this._driverInfo.viewportSize = {
216
- width: this._driverInfo.displaySize.width,
217
- height: this._driverInfo.displaySize.height - this.statusBarHeight - this.navigationBarHeight,
218
- };
219
- }
223
+ if ((_0 = this.orientation) === null || _0 === void 0 ? void 0 : _0.startsWith('landscape')) {
224
+ this._driverInfo.viewportSize = {
225
+ width: this._driverInfo.displaySize.height - this.navigationBarSize,
226
+ height: this._driverInfo.displaySize.width - this.statusBarSize,
227
+ };
220
228
  }
221
229
  else {
222
230
  this._driverInfo.viewportSize = {
223
- width: windowSize.width,
224
- height: windowSize.height - this.statusBarHeight,
231
+ width: this._driverInfo.displaySize.width,
232
+ height: this._driverInfo.displaySize.height - this.statusBarSize - this.navigationBarSize,
225
233
  };
226
234
  }
227
235
  }
@@ -247,9 +255,6 @@ class Driver {
247
255
  ? await helper_ios_1.HelperIOS.make({ spec: this._spec, driver: this, logger: this._logger })
248
256
  : await helper_android_1.HelperAndroid.make({ spec: this._spec, driver: this, logger: this._logger });
249
257
  }
250
- if (this.isMobile) {
251
- (_w = (_8 = this._driverInfo).orientation) !== null && _w !== void 0 ? _w : (_8.orientation = await this.getOrientation().catch(() => undefined));
252
- }
253
258
  this._logger.log('Combined driver info', this._driverInfo);
254
259
  return this;
255
260
  }
@@ -416,7 +421,7 @@ class Driver {
416
421
  return this.currentContext;
417
422
  }
418
423
  async normalizeRegion(region) {
419
- if (this.isWeb || !utils.types.has(this._driverInfo, ['viewportSize', 'statusBarHeight']))
424
+ if (this.isWeb)
420
425
  return region;
421
426
  let normalizedRegion = region;
422
427
  if (this.isAndroid) {
@@ -425,10 +430,7 @@ class Driver {
425
430
  if (this.isIOS && utils.geometry.isIntersected(normalizedRegion, this._driverInfo.safeArea)) {
426
431
  normalizedRegion = utils.geometry.intersect(normalizedRegion, this._driverInfo.safeArea);
427
432
  }
428
- normalizedRegion = utils.geometry.offsetNegative(normalizedRegion, {
429
- x: this.isAndroid && this.orientation === 'landscape' && this.platformVersion > 7 ? this.navigationBarHeight : 0,
430
- y: this.statusBarHeight,
431
- });
433
+ normalizedRegion = utils.geometry.offsetNegative(normalizedRegion, this._driverInfo.viewportLocation);
432
434
  if (normalizedRegion.y < 0) {
433
435
  normalizedRegion.height += normalizedRegion.y;
434
436
  normalizedRegion.y = 0;
@@ -455,6 +457,13 @@ class Driver {
455
457
  }
456
458
  return image;
457
459
  }
460
+ async getViewportRegion() {
461
+ var _a, _b;
462
+ return {
463
+ ...((_b = (_a = this._driverInfo) === null || _a === void 0 ? void 0 : _a.viewportLocation) !== null && _b !== void 0 ? _b : { x: 0, y: 0 }),
464
+ ...(await this.getViewportSize()),
465
+ };
466
+ }
458
467
  async getViewportSize() {
459
468
  var _a;
460
469
  let size;
@@ -466,7 +475,7 @@ class Driver {
466
475
  else {
467
476
  this._logger.log('Extracting viewport size from native driver');
468
477
  size = await this.getDisplaySize();
469
- size.height -= this.statusBarHeight;
478
+ size.height -= this.statusBarSize;
470
479
  }
471
480
  this._logger.log(`Rounding viewport size using`, this._customConfig.useCeilForViewportSize ? 'ceil' : 'round');
472
481
  if (this._customConfig.useCeilForViewportSize) {
@@ -523,7 +532,7 @@ class Driver {
523
532
  throw new Error('Failed to set viewport size!');
524
533
  }
525
534
  async getDisplaySize() {
526
- var _a;
535
+ var _a, _b;
527
536
  if (this.isWeb && !this.isMobile)
528
537
  return;
529
538
  if ((_a = this._driverInfo) === null || _a === void 0 ? void 0 : _a.displaySize) {
@@ -531,7 +540,7 @@ class Driver {
531
540
  return this._driverInfo.displaySize;
532
541
  }
533
542
  let size = await this._spec.getWindowSize(this.target);
534
- if ((await this.getOrientation()) === 'landscape' && size.height > size.width) {
543
+ if (((_b = (await this.getOrientation())) === null || _b === void 0 ? void 0 : _b.startsWith('landscape')) && size.height > size.width) {
535
544
  size = { width: size.height, height: size.width };
536
545
  }
537
546
  const normalizedSize = this.isAndroid ? utils.geometry.scale(size, 1 / this.pixelRatio) : size;
@@ -541,7 +550,27 @@ class Driver {
541
550
  async getOrientation() {
542
551
  if (this.isWeb && !this.isMobile)
543
552
  return;
544
- const orientation = await this._spec.getOrientation(this.target);
553
+ let orientation;
554
+ if (this.isAndroid) {
555
+ this._logger.log('Extracting device orientation using adb command on android');
556
+ const rotation = await this.execute('mobile:shell', {
557
+ command: "dumpsys window | grep 'mCurrentRotation' | cut -d = -f2",
558
+ })
559
+ .then(r => { var _a; return (_a = r === null || r === void 0 ? void 0 : r.trim) === null || _a === void 0 ? void 0 : _a.call(r); })
560
+ .catch(() => null);
561
+ if (rotation === 'ROTATION_0')
562
+ orientation = 'portrait';
563
+ else if (rotation === 'ROTATION_90')
564
+ orientation = 'landscape-secondary';
565
+ else if (rotation === 'ROTATION_180')
566
+ orientation = 'portrait-secondary';
567
+ else if (rotation === 'ROTATION_270')
568
+ orientation = 'landscape';
569
+ }
570
+ if (!orientation) {
571
+ this._logger.log('Extracting device orientation');
572
+ orientation = await this._spec.getOrientation(this.target);
573
+ }
545
574
  this._logger.log('Extracted device orientation:', orientation);
546
575
  return orientation;
547
576
  }
package/dist/element.js CHANGED
@@ -39,16 +39,9 @@ class Element {
39
39
  if (options.logger)
40
40
  this._logger = options.logger;
41
41
  if (this._spec.isElement(options.element)) {
42
- let elementToUse = options.element;
43
- if (options.root) {
44
- elementToUse = options.root;
45
- this._target = elementToUse;
46
- }
47
- else {
48
- this._target = (_c = (_b = (_a = this._spec).transformElement) === null || _b === void 0 ? void 0 : _b.call(_a, elementToUse)) !== null && _c !== void 0 ? _c : elementToUse;
49
- }
42
+ this._target = (_c = (_b = (_a = this._spec).transformElement) === null || _b === void 0 ? void 0 : _b.call(_a, options.element)) !== null && _c !== void 0 ? _c : options.element;
50
43
  // Some frameworks contains information about the selector inside an element
51
- this._selector = (_d = options.selector) !== null && _d !== void 0 ? _d : (_f = (_e = this._spec).extractSelector) === null || _f === void 0 ? void 0 : _f.call(_e, elementToUse);
44
+ this._selector = (_d = options.selector) !== null && _d !== void 0 ? _d : (_f = (_e = this._spec).extractSelector) === null || _f === void 0 ? void 0 : _f.call(_e, options.element);
52
45
  this._index = options.index;
53
46
  }
54
47
  else if (specUtils.isSelector(this._spec, options.selector)) {
@@ -57,6 +50,9 @@ class Element {
57
50
  else {
58
51
  throw new TypeError('Element constructor called with argument of unknown type!');
59
52
  }
53
+ if (this._selector && this._spec.untransformSelector) {
54
+ this._commonSelector = this._spec.untransformSelector(this._spec.transformSelector(this._selector));
55
+ }
60
56
  }
61
57
  get target() {
62
58
  return this._target;
@@ -64,6 +60,12 @@ class Element {
64
60
  get selector() {
65
61
  return this._selector;
66
62
  }
63
+ get commonSelector() {
64
+ return this._commonSelector;
65
+ }
66
+ get index() {
67
+ return this._index;
68
+ }
67
69
  get context() {
68
70
  return this._context;
69
71
  }
@@ -218,8 +220,8 @@ class Element {
218
220
  if (this.driver.isAndroid) {
219
221
  this._state.contentSize = utils.geometry.scale(this._state.contentSize, 1 / this.driver.pixelRatio);
220
222
  }
221
- if (contentRegion.y < this.driver.statusBarHeight) {
222
- this._state.contentSize.height -= this.driver.statusBarHeight - contentRegion.y;
223
+ if (contentRegion.y < this.driver.statusBarSize) {
224
+ this._state.contentSize.height -= this.driver.statusBarSize - contentRegion.y;
223
225
  }
224
226
  return this._state.contentSize;
225
227
  }
@@ -277,6 +279,11 @@ class Element {
277
279
  }
278
280
  });
279
281
  }
282
+ async getShadowRoot() {
283
+ if (!this.driver.isWeb)
284
+ return null;
285
+ return this._spec.executeScript(this.context.target, snippets.getShadowRoot, [this.target]);
286
+ }
280
287
  async getTouchPadding() {
281
288
  var _a, _b;
282
289
  if (this._state.touchPadding == null) {
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.visit = exports.getTitle = exports.getUrl = exports.getOrientation = exports.setWindowSize = exports.getWindowSize = exports.getDriverInfo = exports.takeScreenshot = exports.childContext = exports.parentContext = exports.mainContext = exports.findElements = exports.findElement = exports.executeScript = exports.isEqualElements = exports.isStaleElementError = exports.transformSelector = exports.isSelector = exports.isElement = exports.isDriver = void 0;
26
+ exports.visit = exports.getTitle = exports.getUrl = exports.getOrientation = exports.setWindowSize = exports.getWindowSize = exports.getDriverInfo = exports.takeScreenshot = exports.childContext = exports.parentContext = exports.mainContext = exports.findElements = exports.findElement = exports.executeScript = exports.isEqualElements = exports.isStaleElementError = exports.extractSelector = exports.untransformSelector = exports.transformSelector = exports.isSelector = exports.isElement = exports.isDriver = void 0;
27
27
  const utils = __importStar(require("@applitools/utils"));
28
28
  function isDriver(driver) {
29
29
  return driver && driver.constructor.name === 'MockDriver';
@@ -41,6 +41,24 @@ function transformSelector(selector) {
41
41
  return utils.types.has(selector, 'selector') ? selector.selector : selector;
42
42
  }
43
43
  exports.transformSelector = transformSelector;
44
+ function untransformSelector(selector) {
45
+ if (utils.types.isString(selector)) {
46
+ return { type: 'css', selector: selector };
47
+ }
48
+ else if (utils.types.has(selector, ['using', 'value'])) {
49
+ return { type: selector.using === 'css selector' ? 'css' : selector.using, selector: selector.value };
50
+ }
51
+ else if (utils.types.has(selector, ['selector'])) {
52
+ return selector;
53
+ }
54
+ }
55
+ exports.untransformSelector = untransformSelector;
56
+ function extractSelector(element) {
57
+ if (utils.types.has(element, ['selector'])) {
58
+ return element.selector;
59
+ }
60
+ }
61
+ exports.extractSelector = extractSelector;
44
62
  function isStaleElementError() {
45
63
  return false;
46
64
  }
@@ -28,7 +28,8 @@ const utils = __importStar(require("@applitools/utils"));
28
28
  class HelperAndroid {
29
29
  constructor(options) {
30
30
  this._spec = options.spec;
31
- this._element = options.element;
31
+ this._input = options.input;
32
+ this._action = options.action;
32
33
  this._legacy = options.legacy;
33
34
  this._logger = options.logger;
34
35
  this.name = this._legacy ? 'android-legacy' : 'android';
@@ -36,18 +37,17 @@ class HelperAndroid {
36
37
  static async make(options) {
37
38
  const { spec, driver, logger } = options;
38
39
  let legacy = false;
39
- let element = await driver.element({
40
- type: 'xpath',
41
- selector: '//*[@content-desc="EyesAppiumHelperEDT"]',
42
- });
43
- if (!element) {
40
+ let input = await driver.element({ type: 'xpath', selector: '//*[@content-desc="EyesAppiumHelperEDT"]' });
41
+ if (!input) {
44
42
  legacy = true;
45
- element = await driver.element({
46
- type: '-android uiautomator',
47
- selector: 'new UiSelector().description("EyesAppiumHelper")',
48
- });
43
+ input = await driver.element({ type: 'xpath', selector: '//*[@content-desc="EyesAppiumHelper"]' });
49
44
  }
50
- return element ? new HelperAndroid({ spec, element, legacy, logger }) : null;
45
+ const action = !legacy
46
+ ? await driver.element({ type: 'xpath', selector: '//*[@content-desc="EyesAppiumHelper_Action"]' })
47
+ : null;
48
+ return input
49
+ ? new HelperAndroid({ spec, input, action, legacy, logger })
50
+ : null;
51
51
  }
52
52
  async _getElementId(element) {
53
53
  const resourceId = await element.getAttribute('resource-id');
@@ -56,21 +56,25 @@ class HelperAndroid {
56
56
  return resourceId.split('/')[1];
57
57
  }
58
58
  async getContentSize(element) {
59
+ console.log('getContentSize', !!this._action);
59
60
  let contentHeightString;
60
61
  if (this._legacy) {
61
- await this._element.click();
62
- contentHeightString = await this._element.getText();
62
+ await this._input.click();
63
+ contentHeightString = await this._input.getText();
63
64
  }
64
65
  else {
65
66
  const elementId = await this._getElementId(element);
66
67
  if (!elementId)
67
68
  return null;
68
- await this._element.type(`offset;${elementId};0;0;0`);
69
- await this._element.click();
70
- contentHeightString = await this._element.getText();
71
- await this._element.type('');
69
+ await this._input.type(`offset;${elementId};0;0;0`);
70
+ if (this._action)
71
+ await this._action.type('1');
72
+ else
73
+ await this._input.click();
74
+ contentHeightString = await this._input.getText();
75
+ await this._input.type('');
72
76
  }
73
- const region = await this._spec.getElementRegion(this._element.driver.target, element.target);
77
+ const region = await this._spec.getElementRegion(this._input.driver.target, element.target);
74
78
  const contentHeight = Number(contentHeightString);
75
79
  if (Number.isNaN(contentHeight))
76
80
  return utils.geometry.size(region);
@@ -82,10 +86,13 @@ class HelperAndroid {
82
86
  const elementId = await this._getElementId(element);
83
87
  if (!elementId)
84
88
  return null;
85
- await this._element.type(`getRect;${elementId};0;0`);
86
- await this._element.click();
87
- const regionString = await this._element.getText();
88
- await this._element.type('');
89
+ await this._input.type(`getRect;${elementId};0;0`);
90
+ if (this._action)
91
+ await this._action.type('1');
92
+ else
93
+ await this._input.click();
94
+ const regionString = await this._input.getText();
95
+ await this._input.type('');
89
96
  const [, x, y, height, width] = regionString.match(/\[(-?\d+(?:\.\d+)?);(-?\d+(?:\.\d+)?);(-?\d+(?:\.\d+)?);(-?\d+(?:\.\d+)?)\]/);
90
97
  const region = { x: Number(x), y: Number(y), width: Number(width), height: Number(height) };
91
98
  if (Number.isNaN(region.x + region.y + region.width + region.height))
@@ -98,9 +105,12 @@ class HelperAndroid {
98
105
  const elementId = await this._getElementId(element);
99
106
  if (!elementId)
100
107
  return null;
101
- await this._element.type(`moveToTop;${elementId};0;-1`);
102
- await this._element.click();
103
- await this._element.type('');
108
+ await this._input.type(`moveToTop;${elementId};0;-1`);
109
+ if (this._action)
110
+ await this._action.type('1');
111
+ else
112
+ await this._input.click();
113
+ await this._input.type('');
104
114
  }
105
115
  async scrollBy(element, offset) {
106
116
  if (this._legacy)
@@ -108,17 +118,23 @@ class HelperAndroid {
108
118
  const elementId = await this._getElementId(element);
109
119
  if (!elementId)
110
120
  return null;
111
- await this._element.type(`scroll;${elementId};${offset.y};0;0`);
112
- await this._element.click();
113
- await this._element.type('');
121
+ await this._input.type(`scroll;${elementId};${offset.y};0;0`);
122
+ if (this._action)
123
+ await this._action.type('1');
124
+ else
125
+ await this._input.click();
126
+ await this._input.type('');
114
127
  }
115
128
  async getTouchPadding() {
116
129
  if (this._legacy)
117
130
  return null;
118
- await this._element.type(`getTouchPadding;0;0;0;0`);
119
- await this._element.click();
120
- const touchPaddingString = await this._element.getText();
121
- await this._element.type('');
131
+ await this._input.type(`getTouchPadding;0;0;0;0`);
132
+ if (this._action)
133
+ await this._action.type('1');
134
+ else
135
+ await this._input.click();
136
+ const touchPaddingString = await this._input.getText();
137
+ await this._input.type('');
122
138
  const touchPadding = Number(touchPaddingString);
123
139
  if (Number.isNaN(touchPadding))
124
140
  return null;
@@ -40,10 +40,12 @@ function transformSelector(spec, selector, environment) {
40
40
  if ((environment === null || environment === void 0 ? void 0 : environment.isWeb) && isCommonSelector(spec, selector)) {
41
41
  if (selector.type === 'id')
42
42
  selector = { type: 'css', selector: `#${selector.selector}` };
43
- if (selector.type === 'name')
43
+ else if (selector.type === 'name')
44
44
  selector = { type: 'css', selector: `[name="${selector.selector}"]` };
45
- if (selector.type === 'class name')
45
+ else if (selector.type === 'class name')
46
46
  selector = { type: 'css', selector: `.${selector.selector}` };
47
+ else if (selector.type === 'tag name')
48
+ selector = { type: 'css', selector: `${selector.selector}` };
47
49
  }
48
50
  return (_b = (_a = spec.transformSelector) === null || _a === void 0 ? void 0 : _a.call(spec, selector)) !== null && _b !== void 0 ? _b : selector;
49
51
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applitools/driver",
3
- "version": "1.9.7",
3
+ "version": "1.9.10",
4
4
  "description": "Applitools universal framework wrapper",
5
5
  "keywords": [
6
6
  "applitools",
@@ -17,7 +17,7 @@
17
17
  "repository": {
18
18
  "type": "git",
19
19
  "url": "git://github.com/applitools/eyes.sdk.javascript1.git",
20
- "directory": "packages/driver"
20
+ "directory": "js/packages/driver"
21
21
  },
22
22
  "license": "SEE LICENSE IN LICENSE",
23
23
  "author": {
@@ -64,7 +64,9 @@
64
64
  "scripts": {
65
65
  "lint": "eslint '**/*.ts'",
66
66
  "build": "tsc",
67
- "test": "mocha --no-timeouts -r ts-node/register ./test/**/*.spec.ts",
67
+ "test": "yarn test:unit",
68
+ "test:sanity": "yarn test:unit",
69
+ "test:unit": "mocha --no-timeouts -r ts-node/register ./test/unit/*.spec.ts",
68
70
  "deps": "bongo deps",
69
71
  "preversion": "bongo preversion",
70
72
  "version": "bongo version",
@@ -78,11 +80,11 @@
78
80
  "dependencies": {
79
81
  "@applitools/logger": "1.1.13",
80
82
  "@applitools/snippets": "2.4.3",
81
- "@applitools/types": "1.5.4",
83
+ "@applitools/types": "1.5.5",
82
84
  "@applitools/utils": "1.3.9"
83
85
  },
84
86
  "devDependencies": {
85
- "@applitools/bongo": "^2.1.5",
87
+ "@applitools/bongo": "^2.1.6",
86
88
  "@types/mocha": "^9.1.1",
87
89
  "@types/node": "^17.0.31",
88
90
  "@typescript-eslint/eslint-plugin": "^5.22.0",
package/types/driver.d.ts CHANGED
@@ -34,11 +34,11 @@ export declare class Driver<TDriver, TContext, TElement, TSelector> {
34
34
  get browserName(): string;
35
35
  get browserVersion(): string | number;
36
36
  get userAgent(): string;
37
- get orientation(): 'portrait' | 'landscape';
37
+ get orientation(): 'portrait' | 'landscape' | 'portrait-secondary' | 'landscape-secondary';
38
38
  get pixelRatio(): number;
39
39
  get viewportScale(): number;
40
- get statusBarHeight(): number;
41
- get navigationBarHeight(): number;
40
+ get statusBarSize(): number;
41
+ get navigationBarSize(): number;
42
42
  get isNative(): boolean;
43
43
  get isWeb(): boolean;
44
44
  get isMobile(): boolean;
@@ -59,10 +59,11 @@ export declare class Driver<TDriver, TContext, TElement, TSelector> {
59
59
  elements(selector: types.Selector<TSelector>): Promise<Element<TDriver, TContext, TElement, TSelector>[]>;
60
60
  execute(script: ((arg: any) => any) | string, arg?: any): Promise<any>;
61
61
  takeScreenshot(): Promise<Buffer>;
62
+ getViewportRegion(): Promise<types.Region>;
62
63
  getViewportSize(): Promise<types.Size>;
63
64
  setViewportSize(size: types.Size): Promise<void>;
64
65
  getDisplaySize(): Promise<types.Size>;
65
- getOrientation(): Promise<'portrait' | 'landscape'>;
66
+ getOrientation(): Promise<'portrait' | 'landscape' | 'portrait-secondary' | 'landscape-secondary'>;
66
67
  setOrientation(orientation: 'portrait' | 'landscape'): Promise<void>;
67
68
  getCookies(): Promise<types.Cookie[]>;
68
69
  getTitle(): Promise<string>;
@@ -13,6 +13,7 @@ export declare class Element<TDriver, TContext, TElement, TSelector> {
13
13
  private _target;
14
14
  private _context;
15
15
  private _selector;
16
+ private _commonSelector?;
16
17
  private _index;
17
18
  private _state;
18
19
  private _originalOverflow;
@@ -25,10 +26,11 @@ export declare class Element<TDriver, TContext, TElement, TSelector> {
25
26
  selector?: types.Selector<TSelector>;
26
27
  index?: number;
27
28
  logger?: Logger;
28
- root?: TElement;
29
29
  });
30
30
  get target(): TElement;
31
31
  get selector(): types.Selector<TSelector>;
32
+ get commonSelector(): types.Selector<never>;
33
+ get index(): number;
32
34
  get context(): Context<TDriver, TContext, TElement, TSelector>;
33
35
  get driver(): import("./driver").Driver<TDriver, TContext, TElement, TSelector>;
34
36
  get isRef(): boolean;
@@ -41,6 +43,7 @@ export declare class Element<TDriver, TContext, TElement, TSelector> {
41
43
  isPager(): Promise<boolean>;
42
44
  isScrollable(): Promise<boolean>;
43
45
  isRoot(): Promise<boolean>;
46
+ getShadowRoot(): Promise<TElement>;
44
47
  getTouchPadding(): Promise<number>;
45
48
  getText(): Promise<string>;
46
49
  getAttribute(name: string): Promise<string>;
@@ -6,12 +6,18 @@ export declare type Selector = string | {
6
6
  using: string;
7
7
  value: string;
8
8
  };
9
+ declare type CommonSelector = string | {
10
+ selector: Selector | string;
11
+ type?: string;
12
+ };
9
13
  export declare function isDriver(driver: any): driver is Driver;
10
14
  export declare function isElement(element: any): element is Element;
11
15
  export declare function isSelector(selector: any): selector is Selector;
12
16
  export declare function transformSelector(selector: Selector | {
13
17
  selector: Selector;
14
18
  }): Selector;
19
+ export declare function untransformSelector(selector: Selector): CommonSelector;
20
+ export declare function extractSelector(element: Element): any;
15
21
  export declare function isStaleElementError(): boolean;
16
22
  export declare function isEqualElements(_driver: Driver, element1: Element, element2: Element): Promise<boolean>;
17
23
  export declare function executeScript(driver: Driver, script: ((arg: any) => any) | string, arg: any): Promise<any>;
@@ -28,3 +34,4 @@ export declare function getOrientation(_driver: Driver): Promise<'portrait' | 'l
28
34
  export declare function getUrl(driver: Driver): Promise<string>;
29
35
  export declare function getTitle(driver: Driver): Promise<string>;
30
36
  export declare function visit(driver: Driver, url: string): Promise<void>;
37
+ export {};
@@ -9,13 +9,15 @@ export declare class HelperAndroid<TDriver, TContext, TElement, TSelector> {
9
9
  logger: Logger;
10
10
  }): Promise<HelperAndroid<TDriver, TContext, TElement, TSelector> | null>;
11
11
  private readonly _spec;
12
- private readonly _element;
12
+ private readonly _input;
13
+ private readonly _action?;
13
14
  private readonly _legacy;
14
15
  private _logger;
15
16
  readonly name: 'android' | 'android-legacy';
16
17
  constructor(options: {
17
18
  spec: types.SpecDriver<TDriver, TContext, TElement, TSelector>;
18
- element: Element<TDriver, TContext, TElement, TSelector>;
19
+ input: Element<TDriver, TContext, TElement, TSelector>;
20
+ action?: Element<TDriver, TContext, TElement, TSelector>;
19
21
  legacy: boolean;
20
22
  logger?: any;
21
23
  });