@applitools/driver 1.9.3 → 1.9.6
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/capabilities.js +5 -1
- package/dist/driver.js +5 -2
- package/dist/element.js +68 -24
- package/dist/helper-android.js +64 -4
- package/dist/helper-ios.js +1 -0
- package/package.json +5 -5
- package/types/helper-android.d.ts +4 -0
- package/types/helper-ios.d.ts +1 -0
package/dist/capabilities.js
CHANGED
|
@@ -33,9 +33,13 @@ function parseCapabilities(capabilities, customConfig) {
|
|
|
33
33
|
info.orientation = (_m = ((_l = capabilities.deviceOrientation) !== null && _l !== void 0 ? _l : capabilities.orientation)) === null || _m === void 0 ? void 0 : _m.toLowerCase();
|
|
34
34
|
}
|
|
35
35
|
if (info.isNative) {
|
|
36
|
+
info.displaySize = extractDisplaySize(capabilities);
|
|
36
37
|
info.pixelRatio = capabilities.pixelRatio;
|
|
37
38
|
info.statusBarHeight = capabilities.statBarHeight;
|
|
38
|
-
info.displaySize
|
|
39
|
+
if (info.displaySize && capabilities.viewportRect) {
|
|
40
|
+
info.navigationBarHeight =
|
|
41
|
+
info.displaySize.height - (capabilities.viewportRect.top + capabilities.viewportRect.height);
|
|
42
|
+
}
|
|
39
43
|
}
|
|
40
44
|
return info;
|
|
41
45
|
}
|
package/dist/driver.js
CHANGED
|
@@ -184,14 +184,17 @@ class Driver {
|
|
|
184
184
|
// navigation bar height is replaced with the width in landscape orientation on android (due to the bug in appium)
|
|
185
185
|
if (orientation === 'landscape')
|
|
186
186
|
barsSize.navigationBarHeight = barsSize.navigationBarWidth;
|
|
187
|
-
// when status bar is overlapping content on android it returns status bar height equal to
|
|
187
|
+
// when status bar is overlapping content on android it returns status bar height equal to display height
|
|
188
188
|
if (barsSize.statusBarHeight < this._driverInfo.displaySize.height) {
|
|
189
189
|
this._driverInfo.statusBarHeight = Math.max((_u = this._driverInfo.statusBarHeight) !== null && _u !== void 0 ? _u : 0, barsSize.statusBarHeight);
|
|
190
190
|
}
|
|
191
|
-
// when navigation bar is invisible on android it returns navigation bar height equal to
|
|
191
|
+
// when navigation bar is invisible on android it returns navigation bar height equal to display height
|
|
192
192
|
if (barsSize.navigationBarHeight < this._driverInfo.displaySize.height) {
|
|
193
193
|
this._driverInfo.navigationBarHeight = Math.max((_v = this._driverInfo.navigationBarHeight) !== null && _v !== void 0 ? _v : 0, barsSize.navigationBarHeight);
|
|
194
194
|
}
|
|
195
|
+
else {
|
|
196
|
+
this._driverInfo.navigationBarHeight = 0;
|
|
197
|
+
}
|
|
195
198
|
// bar heights have to be scaled on android
|
|
196
199
|
(_5 = this._driverInfo).statusBarHeight && (_5.statusBarHeight = this._driverInfo.statusBarHeight / this.pixelRatio);
|
|
197
200
|
(_6 = this._driverInfo).navigationBarHeight && (_6.navigationBarHeight = this._driverInfo.navigationBarHeight / this.pixelRatio);
|
package/dist/element.js
CHANGED
|
@@ -278,18 +278,24 @@ class Element {
|
|
|
278
278
|
});
|
|
279
279
|
}
|
|
280
280
|
async getTouchPadding() {
|
|
281
|
+
var _a, _b;
|
|
281
282
|
if (this._state.touchPadding == null) {
|
|
282
283
|
if (this.driver.isWeb)
|
|
283
284
|
this._state.touchPadding = 0;
|
|
284
285
|
else if (this.driver.isIOS)
|
|
285
286
|
this._state.touchPadding = 10;
|
|
286
287
|
else if (this.driver.isAndroid) {
|
|
287
|
-
|
|
288
|
-
.
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
288
|
+
if (((_a = this.driver.helper) === null || _a === void 0 ? void 0 : _a.name) === 'android') {
|
|
289
|
+
this._state.touchPadding = await ((_b = this.driver.helper) === null || _b === void 0 ? void 0 : _b.getTouchPadding());
|
|
290
|
+
}
|
|
291
|
+
if (!this._state.touchPadding) {
|
|
292
|
+
const touchPadding = await this.getAttribute('contentSize')
|
|
293
|
+
.then(data => JSON.parse(data).touchPadding)
|
|
294
|
+
.catch(err => {
|
|
295
|
+
this._logger.warn(`Unable to get the attribute 'contentSize' when looking up 'touchPadding' due to the following error: '${err.message}'`);
|
|
296
|
+
});
|
|
297
|
+
this._state.touchPadding = touchPadding !== null && touchPadding !== void 0 ? touchPadding : 20;
|
|
298
|
+
}
|
|
293
299
|
this._logger.log('Touch padding set:', this._state.touchPadding);
|
|
294
300
|
}
|
|
295
301
|
}
|
|
@@ -355,6 +361,7 @@ class Element {
|
|
|
355
361
|
}
|
|
356
362
|
async scrollTo(offset, options) {
|
|
357
363
|
return this.withRefresh(async () => {
|
|
364
|
+
var _a;
|
|
358
365
|
offset = utils.geometry.round({ x: Math.max(offset.x, 0), y: Math.max(offset.y, 0) });
|
|
359
366
|
if (this.driver.isWeb) {
|
|
360
367
|
let actualOffset = await this.context.execute(snippets.scrollTo, [this, offset]);
|
|
@@ -374,22 +381,29 @@ class Element {
|
|
|
374
381
|
y: Math.round(scrollableRegion.height * (contentSize.height / scrollableRegion.height - 1)),
|
|
375
382
|
};
|
|
376
383
|
const requiredOffset = { x: Math.min(offset.x, maxOffset.x), y: Math.min(offset.y, maxOffset.y) };
|
|
384
|
+
if (((_a = this.driver.helper) === null || _a === void 0 ? void 0 : _a.name) === 'android' && utils.geometry.equals(requiredOffset, { x: 0, y: 0 })) {
|
|
385
|
+
await this.driver.helper.scrollToTop(this);
|
|
386
|
+
this._state.scrollOffset = requiredOffset;
|
|
387
|
+
return this._state.scrollOffset;
|
|
388
|
+
}
|
|
377
389
|
let effectiveRegion = scrollableRegion;
|
|
378
390
|
let remainingOffset = utils.geometry.equals(requiredOffset, { x: 0, y: 0 })
|
|
379
391
|
? { x: -maxOffset.x, y: -maxOffset.y } // if it has to be scrolled to the very beginning, then scroll maximum amount of pixels
|
|
380
392
|
: utils.geometry.offsetNegative(requiredOffset, currentScrollOffset);
|
|
381
393
|
if (this.driver.isAndroid) {
|
|
382
|
-
remainingOffset = utils.geometry.scale(remainingOffset, this.driver.pixelRatio);
|
|
383
|
-
effectiveRegion = utils.geometry.scale(effectiveRegion, this.driver.pixelRatio);
|
|
394
|
+
remainingOffset = utils.geometry.round(utils.geometry.scale(remainingOffset, this.driver.pixelRatio));
|
|
395
|
+
effectiveRegion = utils.geometry.round(utils.geometry.scale(effectiveRegion, this.driver.pixelRatio));
|
|
384
396
|
}
|
|
385
|
-
const actions = [];
|
|
386
|
-
const touchPadding = await this.getTouchPadding();
|
|
387
397
|
const isPager = await this.isPager();
|
|
388
|
-
const
|
|
398
|
+
const touchPadding = await this.getTouchPadding();
|
|
399
|
+
const actions = [];
|
|
400
|
+
// horizontal scrolling
|
|
401
|
+
const xPadding = touchPadding + 3;
|
|
389
402
|
const yTrack = Math.floor(effectiveRegion.y + effectiveRegion.height / 2); // center
|
|
390
403
|
const xLeft = effectiveRegion.y + xPadding;
|
|
391
404
|
const xDirection = remainingOffset.x > 0 ? 'right' : 'left';
|
|
392
405
|
const xGap = xDirection === 'right' ? -touchPadding : touchPadding;
|
|
406
|
+
const xCompensation = xDirection === 'right' ? -1 : 1;
|
|
393
407
|
let xRemaining = Math.abs(remainingOffset.x);
|
|
394
408
|
if (isPager) {
|
|
395
409
|
const xPages = Math.floor(xRemaining / effectiveRegion.width);
|
|
@@ -407,28 +421,44 @@ class Element {
|
|
|
407
421
|
{ action: 'release' },
|
|
408
422
|
]);
|
|
409
423
|
}
|
|
410
|
-
else {
|
|
424
|
+
else if (this.driver.isAndroid) {
|
|
425
|
+
actions.push([
|
|
426
|
+
// move through scrolling gap (actual scrolling will be triggered only after that)
|
|
427
|
+
{ action: 'press', y: yTrack, x: xStart - xGap },
|
|
428
|
+
{ action: 'wait', ms: 100 },
|
|
429
|
+
{ action: 'moveTo', y: yTrack, x: xStart + xCompensation },
|
|
430
|
+
{ action: 'wait', ms: 100 },
|
|
431
|
+
{ action: 'moveTo', y: yTrack, x: xStart },
|
|
432
|
+
// perform actual scrolling
|
|
433
|
+
{ action: 'wait', ms: 100 },
|
|
434
|
+
{ action: 'moveTo', y: yTrack, x: xEnd },
|
|
435
|
+
{ action: 'release' },
|
|
436
|
+
]);
|
|
437
|
+
}
|
|
438
|
+
else if (this.driver.isIOS) {
|
|
411
439
|
actions.push([
|
|
412
|
-
{ action: 'press', y: yTrack, x: xStart },
|
|
413
440
|
// move through scrolling gap (actual scrolling will be triggered only after that)
|
|
441
|
+
{ action: 'press', y: yTrack, x: xStart - xGap },
|
|
414
442
|
{ action: 'wait', ms: 100 },
|
|
415
|
-
{ action: 'moveTo', y: yTrack, x: xStart
|
|
443
|
+
{ action: 'moveTo', y: yTrack, x: xStart },
|
|
416
444
|
// perform actual scrolling
|
|
417
445
|
{ action: 'wait', ms: 100 },
|
|
418
|
-
{ action: 'moveTo', y: yTrack, x: xEnd
|
|
446
|
+
{ action: 'moveTo', y: yTrack, x: xEnd },
|
|
419
447
|
// prevent inertial scrolling after release
|
|
420
448
|
{ action: 'wait', ms: 100 },
|
|
421
|
-
{ action: 'moveTo', y: yTrack + 1, x: xEnd
|
|
449
|
+
{ action: 'moveTo', y: yTrack + 1, x: xEnd },
|
|
422
450
|
{ action: 'release' },
|
|
423
451
|
]);
|
|
424
452
|
}
|
|
425
453
|
xRemaining -= xRight - xLeft;
|
|
426
454
|
}
|
|
427
|
-
|
|
455
|
+
// vertical scrolling
|
|
456
|
+
const yPadding = Math.max(Math.floor(effectiveRegion.height * 0.05), touchPadding + 3);
|
|
428
457
|
const xTrack = Math.floor(effectiveRegion.x + 5); // a little bit off left border
|
|
429
458
|
const yBottom = effectiveRegion.y + effectiveRegion.height - yPadding;
|
|
430
459
|
const yDirection = remainingOffset.y > 0 ? 'down' : 'up';
|
|
431
460
|
const yGap = yDirection === 'down' ? -touchPadding : touchPadding;
|
|
461
|
+
const yCompensation = yDirection === 'down' ? -1 : 1;
|
|
432
462
|
let yRemaining = Math.abs(remainingOffset.y);
|
|
433
463
|
if (isPager) {
|
|
434
464
|
const yPages = Math.floor(yRemaining / effectiveRegion.height);
|
|
@@ -446,18 +476,32 @@ class Element {
|
|
|
446
476
|
{ action: 'release' },
|
|
447
477
|
]);
|
|
448
478
|
}
|
|
449
|
-
else {
|
|
479
|
+
else if (this.driver.isAndroid) {
|
|
480
|
+
actions.push([
|
|
481
|
+
// move through scrolling gap (actual scrolling will be triggered only after that)
|
|
482
|
+
{ action: 'press', x: xTrack, y: yStart - yGap },
|
|
483
|
+
{ action: 'wait', ms: 100 },
|
|
484
|
+
{ action: 'moveTo', x: xTrack, y: yStart + yCompensation },
|
|
485
|
+
{ action: 'wait', ms: 100 },
|
|
486
|
+
{ action: 'moveTo', x: xTrack, y: yStart },
|
|
487
|
+
// perform actual scrolling
|
|
488
|
+
{ action: 'wait', ms: 100 },
|
|
489
|
+
{ action: 'moveTo', x: xTrack, y: yEnd },
|
|
490
|
+
{ action: 'release' },
|
|
491
|
+
]);
|
|
492
|
+
}
|
|
493
|
+
else if (this.driver.isIOS) {
|
|
450
494
|
actions.push([
|
|
451
|
-
{ action: 'press', x: xTrack, y: yStart },
|
|
452
495
|
// move through scrolling gap (actual scrolling will be triggered only after that)
|
|
496
|
+
{ action: 'press', x: xTrack, y: yStart - yGap },
|
|
453
497
|
{ action: 'wait', ms: 100 },
|
|
454
|
-
{ action: 'moveTo', x: xTrack, y: yStart
|
|
498
|
+
{ action: 'moveTo', x: xTrack, y: yStart },
|
|
455
499
|
// perform actual scrolling
|
|
456
500
|
{ action: 'wait', ms: 100 },
|
|
457
|
-
{ action: 'moveTo', x: xTrack, y: yEnd
|
|
501
|
+
{ action: 'moveTo', x: xTrack, y: yEnd },
|
|
458
502
|
// prevent inertial scrolling after release
|
|
459
503
|
{ action: 'wait', ms: 100 },
|
|
460
|
-
{ action: 'moveTo', x: xTrack + 1, y: yEnd
|
|
504
|
+
{ action: 'moveTo', x: xTrack + 1, y: yEnd },
|
|
461
505
|
{ action: 'release' },
|
|
462
506
|
]);
|
|
463
507
|
}
|
|
@@ -474,10 +518,10 @@ class Element {
|
|
|
474
518
|
await this._spec.performAction(this.driver.target, [].concat(...actions));
|
|
475
519
|
}
|
|
476
520
|
const actualScrollableRegion = await this.getClientRegion();
|
|
477
|
-
this._state.scrollOffset = utils.geometry.
|
|
521
|
+
this._state.scrollOffset = utils.geometry.offsetNegative(requiredOffset, {
|
|
478
522
|
x: scrollableRegion.x - actualScrollableRegion.x,
|
|
479
523
|
y: scrollableRegion.y - actualScrollableRegion.y,
|
|
480
|
-
})
|
|
524
|
+
});
|
|
481
525
|
return this._state.scrollOffset;
|
|
482
526
|
}
|
|
483
527
|
});
|
package/dist/helper-android.js
CHANGED
|
@@ -1,12 +1,37 @@
|
|
|
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
|
+
};
|
|
2
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
26
|
exports.HelperAndroid = void 0;
|
|
27
|
+
const utils = __importStar(require("@applitools/utils"));
|
|
4
28
|
class HelperAndroid {
|
|
5
29
|
constructor(options) {
|
|
6
30
|
this._spec = options.spec;
|
|
7
31
|
this._element = options.element;
|
|
8
32
|
this._legacy = options.legacy;
|
|
9
33
|
this._logger = options.logger;
|
|
34
|
+
this.name = this._legacy ? 'android-legacy' : 'android';
|
|
10
35
|
}
|
|
11
36
|
static async make(options) {
|
|
12
37
|
const { spec, driver, logger } = options;
|
|
@@ -31,10 +56,10 @@ class HelperAndroid {
|
|
|
31
56
|
return resourceId.split('/')[1];
|
|
32
57
|
}
|
|
33
58
|
async getContentSize(element) {
|
|
34
|
-
let
|
|
59
|
+
let contentHeightString;
|
|
35
60
|
if (this._legacy) {
|
|
36
61
|
await this._element.click();
|
|
37
|
-
|
|
62
|
+
contentHeightString = await this._element.getText();
|
|
38
63
|
}
|
|
39
64
|
else {
|
|
40
65
|
const elementId = await this._getElementId(element);
|
|
@@ -42,11 +67,14 @@ class HelperAndroid {
|
|
|
42
67
|
return null;
|
|
43
68
|
await this._element.type(`offset;${elementId};0;0;0`);
|
|
44
69
|
await this._element.click();
|
|
45
|
-
|
|
70
|
+
contentHeightString = await this._element.getText();
|
|
46
71
|
await this._element.type('');
|
|
47
72
|
}
|
|
48
73
|
const region = await this._spec.getElementRegion(this._element.driver.target, element.target);
|
|
49
|
-
|
|
74
|
+
const contentHeight = Number(contentHeightString);
|
|
75
|
+
if (Number.isNaN(contentHeight))
|
|
76
|
+
return utils.geometry.size(region);
|
|
77
|
+
return { width: region.width, height: contentHeight };
|
|
50
78
|
}
|
|
51
79
|
async getRegion(element) {
|
|
52
80
|
if (this._legacy)
|
|
@@ -64,5 +92,37 @@ class HelperAndroid {
|
|
|
64
92
|
return null;
|
|
65
93
|
return region;
|
|
66
94
|
}
|
|
95
|
+
async scrollToTop(element) {
|
|
96
|
+
if (this._legacy)
|
|
97
|
+
return null;
|
|
98
|
+
const elementId = await this._getElementId(element);
|
|
99
|
+
if (!elementId)
|
|
100
|
+
return null;
|
|
101
|
+
await this._element.type(`moveToTop;${elementId};0;-1`);
|
|
102
|
+
await this._element.click();
|
|
103
|
+
await this._element.type('');
|
|
104
|
+
}
|
|
105
|
+
async scrollBy(element, offset) {
|
|
106
|
+
if (this._legacy)
|
|
107
|
+
return null;
|
|
108
|
+
const elementId = await this._getElementId(element);
|
|
109
|
+
if (!elementId)
|
|
110
|
+
return null;
|
|
111
|
+
await this._element.type(`scroll;${elementId};${offset.y};0;0`);
|
|
112
|
+
await this._element.click();
|
|
113
|
+
await this._element.type('');
|
|
114
|
+
}
|
|
115
|
+
async getTouchPadding() {
|
|
116
|
+
if (this._legacy)
|
|
117
|
+
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('');
|
|
122
|
+
const touchPadding = Number(touchPaddingString);
|
|
123
|
+
if (Number.isNaN(touchPadding))
|
|
124
|
+
return null;
|
|
125
|
+
return touchPadding;
|
|
126
|
+
}
|
|
67
127
|
}
|
|
68
128
|
exports.HelperAndroid = HelperAndroid;
|
package/dist/helper-ios.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applitools/driver",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.6",
|
|
4
4
|
"description": "Applitools universal framework wrapper",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"applitools",
|
|
@@ -76,10 +76,10 @@
|
|
|
76
76
|
}
|
|
77
77
|
},
|
|
78
78
|
"dependencies": {
|
|
79
|
-
"@applitools/logger": "1.1.
|
|
80
|
-
"@applitools/snippets": "2.4.
|
|
81
|
-
"@applitools/types": "1.5.
|
|
82
|
-
"@applitools/utils": "1.3.
|
|
79
|
+
"@applitools/logger": "1.1.13",
|
|
80
|
+
"@applitools/snippets": "2.4.3",
|
|
81
|
+
"@applitools/types": "1.5.4",
|
|
82
|
+
"@applitools/utils": "1.3.9"
|
|
83
83
|
},
|
|
84
84
|
"devDependencies": {
|
|
85
85
|
"@applitools/bongo": "^2.1.5",
|
|
@@ -12,6 +12,7 @@ export declare class HelperAndroid<TDriver, TContext, TElement, TSelector> {
|
|
|
12
12
|
private readonly _element;
|
|
13
13
|
private readonly _legacy;
|
|
14
14
|
private _logger;
|
|
15
|
+
readonly name: 'android' | 'android-legacy';
|
|
15
16
|
constructor(options: {
|
|
16
17
|
spec: types.SpecDriver<TDriver, TContext, TElement, TSelector>;
|
|
17
18
|
element: Element<TDriver, TContext, TElement, TSelector>;
|
|
@@ -21,4 +22,7 @@ export declare class HelperAndroid<TDriver, TContext, TElement, TSelector> {
|
|
|
21
22
|
_getElementId(element: Element<TDriver, TContext, TElement, TSelector>): Promise<string>;
|
|
22
23
|
getContentSize(element: Element<TDriver, TContext, TElement, TSelector>): Promise<types.Size>;
|
|
23
24
|
getRegion(element: Element<TDriver, TContext, TElement, TSelector>): Promise<types.Region>;
|
|
25
|
+
scrollToTop(element: Element<TDriver, TContext, TElement, TSelector>): Promise<void>;
|
|
26
|
+
scrollBy(element: Element<TDriver, TContext, TElement, TSelector>, offset: types.Location): Promise<void>;
|
|
27
|
+
getTouchPadding(): Promise<number>;
|
|
24
28
|
}
|
package/types/helper-ios.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export declare class HelperIOS<TDriver, TContext, TElement, TSelector> {
|
|
|
12
12
|
private readonly _element;
|
|
13
13
|
private readonly _spec;
|
|
14
14
|
private _logger;
|
|
15
|
+
readonly name: 'ios';
|
|
15
16
|
constructor(options: {
|
|
16
17
|
driver: Driver<TDriver, TContext, TElement, TSelector>;
|
|
17
18
|
element: Element<TDriver, TContext, TElement, TSelector>;
|