appium-android-driver 5.14.7 → 6.0.1
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/CHANGELOG.md +7 -0
- package/build/lib/commands/actions.d.ts +6 -224
- package/build/lib/commands/actions.d.ts.map +1 -1
- package/build/lib/commands/actions.js +306 -405
- package/build/lib/commands/actions.js.map +1 -1
- package/build/lib/commands/alert.d.ts +7 -9
- package/build/lib/commands/alert.d.ts.map +1 -1
- package/build/lib/commands/alert.js +24 -18
- package/build/lib/commands/alert.js.map +1 -1
- package/build/lib/commands/app-management.d.ts +7 -313
- package/build/lib/commands/app-management.d.ts.map +1 -1
- package/build/lib/commands/app-management.js +135 -293
- package/build/lib/commands/app-management.js.map +1 -1
- package/build/lib/commands/context.d.ts +8 -92
- package/build/lib/commands/context.d.ts.map +1 -1
- package/build/lib/commands/context.js +381 -439
- package/build/lib/commands/context.js.map +1 -1
- package/build/lib/commands/element.d.ts +8 -35
- package/build/lib/commands/element.d.ts.map +1 -1
- package/build/lib/commands/element.js +153 -136
- package/build/lib/commands/element.js.map +1 -1
- package/build/lib/commands/emu-console.d.ts +6 -48
- package/build/lib/commands/emu-console.d.ts.map +1 -1
- package/build/lib/commands/emu-console.js +19 -34
- package/build/lib/commands/emu-console.js.map +1 -1
- package/build/lib/commands/execute.d.ts +6 -5
- package/build/lib/commands/execute.d.ts.map +1 -1
- package/build/lib/commands/execute.js +77 -66
- package/build/lib/commands/execute.js.map +1 -1
- package/build/lib/commands/file-actions.d.ts +7 -128
- package/build/lib/commands/file-actions.d.ts.map +1 -1
- package/build/lib/commands/file-actions.js +183 -219
- package/build/lib/commands/file-actions.js.map +1 -1
- package/build/lib/commands/find.d.ts +8 -12
- package/build/lib/commands/find.d.ts.map +1 -1
- package/build/lib/commands/find.js +19 -23
- package/build/lib/commands/find.js.map +1 -1
- package/build/lib/commands/general.d.ts +9 -132
- package/build/lib/commands/general.d.ts.map +1 -1
- package/build/lib/commands/general.js +281 -312
- package/build/lib/commands/general.js.map +1 -1
- package/build/lib/commands/ime.d.ts +7 -10
- package/build/lib/commands/ime.d.ts.map +1 -1
- package/build/lib/commands/ime.js +47 -35
- package/build/lib/commands/ime.js.map +1 -1
- package/build/lib/commands/index.d.ts +27 -2
- package/build/lib/commands/index.d.ts.map +1 -1
- package/build/lib/commands/index.js +41 -19
- package/build/lib/commands/index.js.map +1 -1
- package/build/lib/commands/intent.d.ts +7 -417
- package/build/lib/commands/intent.d.ts.map +1 -1
- package/build/lib/commands/intent.js +104 -216
- package/build/lib/commands/intent.js.map +1 -1
- package/build/lib/commands/keyboard.d.ts +6 -5
- package/build/lib/commands/keyboard.d.ts.map +1 -1
- package/build/lib/commands/keyboard.js +16 -8
- package/build/lib/commands/keyboard.js.map +1 -1
- package/build/lib/commands/log.d.ts +7 -44
- package/build/lib/commands/log.d.ts.map +1 -1
- package/build/lib/commands/log.js +146 -108
- package/build/lib/commands/log.js.map +1 -1
- package/build/lib/commands/media-projection.d.ts +7 -143
- package/build/lib/commands/media-projection.d.ts.map +1 -1
- package/build/lib/commands/media-projection.js +113 -140
- package/build/lib/commands/media-projection.js.map +1 -1
- package/build/lib/commands/mixins.d.ts +740 -0
- package/build/lib/commands/mixins.d.ts.map +1 -0
- package/build/lib/commands/mixins.js +19 -0
- package/build/lib/commands/mixins.js.map +1 -0
- package/build/lib/commands/network.d.ts +7 -138
- package/build/lib/commands/network.d.ts.map +1 -1
- package/build/lib/commands/network.js +212 -254
- package/build/lib/commands/network.js.map +1 -1
- package/build/lib/commands/performance.d.ts +24 -70
- package/build/lib/commands/performance.d.ts.map +1 -1
- package/build/lib/commands/performance.js +144 -100
- package/build/lib/commands/performance.js.map +1 -1
- package/build/lib/commands/permissions.d.ts +8 -92
- package/build/lib/commands/permissions.d.ts.map +1 -1
- package/build/lib/commands/permissions.js +75 -87
- package/build/lib/commands/permissions.js.map +1 -1
- package/build/lib/commands/recordscreen.d.ts +7 -193
- package/build/lib/commands/recordscreen.d.ts.map +1 -1
- package/build/lib/commands/recordscreen.js +151 -182
- package/build/lib/commands/recordscreen.js.map +1 -1
- package/build/lib/commands/shell.d.ts +7 -7
- package/build/lib/commands/shell.d.ts.map +1 -1
- package/build/lib/commands/shell.js +40 -33
- package/build/lib/commands/shell.js.map +1 -1
- package/build/lib/commands/streamscreen.d.ts +9 -103
- package/build/lib/commands/streamscreen.d.ts.map +1 -1
- package/build/lib/commands/streamscreen.js +261 -218
- package/build/lib/commands/streamscreen.js.map +1 -1
- package/build/lib/commands/system-bars.d.ts +22 -90
- package/build/lib/commands/system-bars.d.ts.map +1 -1
- package/build/lib/commands/system-bars.js +76 -74
- package/build/lib/commands/system-bars.js.map +1 -1
- package/build/lib/commands/touch.d.ts +10 -29
- package/build/lib/commands/touch.d.ts.map +1 -1
- package/build/lib/commands/touch.js +301 -285
- package/build/lib/commands/touch.js.map +1 -1
- package/build/lib/commands/types.d.ts +978 -0
- package/build/lib/commands/types.d.ts.map +1 -0
- package/build/lib/commands/types.js +3 -0
- package/build/lib/commands/types.js.map +1 -0
- package/build/lib/constraints.d.ts +291 -0
- package/build/lib/constraints.d.ts.map +1 -0
- package/build/lib/{desired-caps.js → constraints.js} +103 -102
- package/build/lib/constraints.js.map +1 -0
- package/build/lib/driver.d.ts +68 -37
- package/build/lib/driver.d.ts.map +1 -1
- package/build/lib/driver.js +123 -80
- package/build/lib/driver.js.map +1 -1
- package/build/lib/helpers/android.d.ts +164 -0
- package/build/lib/helpers/android.d.ts.map +1 -0
- package/build/lib/helpers/android.js +819 -0
- package/build/lib/helpers/android.js.map +1 -0
- package/build/lib/helpers/index.d.ts +7 -0
- package/build/lib/helpers/index.d.ts.map +1 -0
- package/build/lib/helpers/index.js +29 -0
- package/build/lib/helpers/index.js.map +1 -0
- package/build/lib/helpers/types.d.ts +121 -0
- package/build/lib/helpers/types.d.ts.map +1 -0
- package/build/lib/helpers/types.js +3 -0
- package/build/lib/helpers/types.js.map +1 -0
- package/build/lib/helpers/unlock.d.ts +32 -0
- package/build/lib/helpers/unlock.d.ts.map +1 -0
- package/build/lib/helpers/unlock.js +273 -0
- package/build/lib/helpers/unlock.js.map +1 -0
- package/build/lib/helpers/webview.d.ts +74 -0
- package/build/lib/helpers/webview.d.ts.map +1 -0
- package/build/lib/helpers/webview.js +421 -0
- package/build/lib/helpers/webview.js.map +1 -0
- package/build/lib/index.d.ts +9 -0
- package/build/lib/index.d.ts.map +1 -0
- package/build/lib/index.js +37 -0
- package/build/lib/index.js.map +1 -0
- package/build/lib/method-map.d.ts +0 -8
- package/build/lib/method-map.d.ts.map +1 -1
- package/build/lib/method-map.js +63 -74
- package/build/lib/method-map.js.map +1 -1
- package/build/lib/stubs.d.ts +0 -1
- package/build/lib/stubs.d.ts.map +1 -1
- package/build/lib/stubs.js +1 -0
- package/build/lib/stubs.js.map +1 -1
- package/build/lib/utils.d.ts +1 -1
- package/build/lib/utils.d.ts.map +1 -1
- package/lib/commands/actions.js +351 -464
- package/lib/commands/alert.js +27 -17
- package/lib/commands/app-management.js +156 -314
- package/lib/commands/context.js +457 -441
- package/lib/commands/element.js +201 -157
- package/lib/commands/emu-console.js +25 -45
- package/lib/commands/execute.js +106 -90
- package/lib/commands/file-actions.js +222 -240
- package/lib/commands/find.ts +103 -0
- package/lib/commands/general.js +327 -339
- package/lib/commands/ime.js +50 -34
- package/lib/commands/{index.js → index.ts} +20 -24
- package/lib/commands/intent.js +108 -249
- package/lib/commands/keyboard.js +20 -8
- package/lib/commands/log.js +172 -116
- package/lib/commands/media-projection.js +134 -161
- package/lib/commands/mixins.ts +966 -0
- package/lib/commands/network.js +252 -281
- package/lib/commands/performance.js +203 -132
- package/lib/commands/permissions.js +108 -109
- package/lib/commands/recordscreen.js +212 -209
- package/lib/commands/shell.js +51 -40
- package/lib/commands/streamscreen.js +355 -289
- package/lib/commands/system-bars.js +92 -83
- package/lib/commands/touch.js +357 -294
- package/lib/commands/types.ts +1097 -0
- package/lib/{desired-caps.js → constraints.ts} +106 -103
- package/lib/{driver.js → driver.ts} +278 -132
- package/lib/helpers/android.ts +1143 -0
- package/lib/helpers/index.ts +6 -0
- package/lib/helpers/types.ts +134 -0
- package/lib/helpers/unlock.ts +329 -0
- package/lib/helpers/webview.ts +582 -0
- package/lib/index.ts +18 -0
- package/lib/method-map.js +87 -98
- package/lib/stubs.ts +0 -1
- package/package.json +26 -19
- package/build/index.js +0 -51
- package/build/lib/android-helpers.d.ts +0 -136
- package/build/lib/android-helpers.d.ts.map +0 -1
- package/build/lib/android-helpers.js +0 -855
- package/build/lib/android-helpers.js.map +0 -1
- package/build/lib/commands/coverage.d.ts +0 -5
- package/build/lib/commands/coverage.d.ts.map +0 -1
- package/build/lib/commands/coverage.js +0 -19
- package/build/lib/commands/coverage.js.map +0 -1
- package/build/lib/desired-caps.d.ts +0 -353
- package/build/lib/desired-caps.d.ts.map +0 -1
- package/build/lib/desired-caps.js.map +0 -1
- package/build/lib/unlock-helpers.d.ts +0 -38
- package/build/lib/unlock-helpers.d.ts.map +0 -1
- package/build/lib/unlock-helpers.js +0 -266
- package/build/lib/unlock-helpers.js.map +0 -1
- package/build/lib/webview-helpers.d.ts +0 -224
- package/build/lib/webview-helpers.d.ts.map +0 -1
- package/build/lib/webview-helpers.js +0 -528
- package/build/lib/webview-helpers.js.map +0 -1
- package/index.js +0 -24
- package/lib/android-helpers.js +0 -983
- package/lib/commands/coverage.js +0 -18
- package/lib/commands/find.js +0 -82
- package/lib/unlock-helpers.js +0 -278
- package/lib/webview-helpers.js +0 -602
|
@@ -1,24 +1,32 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
// @ts-check
|
|
2
3
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
4
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
5
|
};
|
|
5
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
|
|
7
|
-
const lodash_1 = __importDefault(require("lodash"));
|
|
8
|
-
const android_helpers_1 = __importDefault(require("../android-helpers"));
|
|
9
|
-
const bluebird_1 = __importDefault(require("bluebird"));
|
|
7
|
+
const support_1 = require("@appium/support");
|
|
10
8
|
const driver_1 = require("appium/driver");
|
|
11
9
|
const asyncbox_1 = require("asyncbox");
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
const bluebird_1 = __importDefault(require("bluebird"));
|
|
11
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
12
|
+
const android_1 = __importDefault(require("../helpers/android"));
|
|
13
|
+
const mixins_1 = require("./mixins");
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @param {number|null} [val]
|
|
17
|
+
* @returns {number}
|
|
18
|
+
*/
|
|
16
19
|
function getCoordDefault(val) {
|
|
17
20
|
// going the long way and checking for undefined and null since
|
|
18
21
|
// we can't be assured `elId` is a string and not an int. Same
|
|
19
22
|
// thing with destElement below.
|
|
20
23
|
return support_1.util.hasValue(val) ? val : 0.5;
|
|
21
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
*
|
|
27
|
+
* @param {NonReleaseTouchAction} waitGesture
|
|
28
|
+
* @returns {number}
|
|
29
|
+
*/
|
|
22
30
|
function getSwipeTouchDuration(waitGesture) {
|
|
23
31
|
// the touch action api uses ms, we want seconds
|
|
24
32
|
// 0.8 is the default time for the operation
|
|
@@ -33,314 +41,322 @@ function getSwipeTouchDuration(waitGesture) {
|
|
|
33
41
|
}
|
|
34
42
|
return duration;
|
|
35
43
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
let { x, y } = await this.getLocationInView(longPress.options.element);
|
|
69
|
-
startX += x || 0;
|
|
70
|
-
startY += y || 0;
|
|
71
|
-
}
|
|
72
|
-
if (moveTo.options.element) {
|
|
73
|
-
let { x, y } = await this.getLocationInView(moveTo.options.element);
|
|
74
|
-
endX += x || 0;
|
|
75
|
-
endY += y || 0;
|
|
76
|
-
}
|
|
77
|
-
let apiLevel = await this.adb.getApiLevel();
|
|
78
|
-
// lollipop takes a little longer to get things rolling
|
|
79
|
-
let duration = apiLevel >= 5 ? 2 : 1;
|
|
80
|
-
// make sure that if the long press has a duration, we use it.
|
|
81
|
-
if (longPress.options && longPress.options.duration) {
|
|
82
|
-
duration = Math.max(longPress.options.duration / 1000, duration);
|
|
83
|
-
}
|
|
84
|
-
// `drag` will take care of whether there is an element or not at that level
|
|
85
|
-
return await this.drag(startX, startY, endX, endY, duration, 1, longPress.options.element, moveTo.options.element);
|
|
86
|
-
};
|
|
87
|
-
// Release gesture needs element or co-ordinates to release it from that position
|
|
88
|
-
// or else release gesture is performed from center of the screen, so to fix it
|
|
89
|
-
// This method sets co-ordinates/element to release gesture if it has no options set already.
|
|
90
|
-
helpers.fixRelease = async function fixRelease(gestures) {
|
|
91
|
-
let release = lodash_1.default.last(gestures);
|
|
92
|
-
// sometimes there are no options
|
|
93
|
-
release.options = release.options || {};
|
|
94
|
-
// nothing to do if release options are already set
|
|
95
|
-
if (release.options.element || (release.options.x && release.options.y)) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
// without coordinates, `release` uses the center of the screen, which,
|
|
99
|
-
// generally speaking, is not what we want
|
|
100
|
-
// therefore: loop backwards and use the last command with an element and/or
|
|
101
|
-
// offset coordinates
|
|
102
|
-
gestures = lodash_1.default.clone(gestures);
|
|
103
|
-
let ref = null;
|
|
104
|
-
for (let gesture of gestures.reverse()) {
|
|
105
|
-
let opts = gesture.options;
|
|
106
|
-
if (opts.element || (opts.x && opts.y)) {
|
|
107
|
-
ref = gesture;
|
|
108
|
-
break;
|
|
44
|
+
/**
|
|
45
|
+
* @type {import('./mixins').TouchMixin & ThisType<import('../driver').AndroidDriver>}
|
|
46
|
+
* @satisfies {import('@appium/types').ExternalDriver}
|
|
47
|
+
*/
|
|
48
|
+
const TouchMixin = {
|
|
49
|
+
async doTouchAction(action, opts = {}) {
|
|
50
|
+
const { element, x, y, count, ms, duration } = opts;
|
|
51
|
+
// parseTouch precalculates absolute element positions
|
|
52
|
+
// so there is no need to pass `element` to the affected gestures
|
|
53
|
+
switch (action) {
|
|
54
|
+
case 'tap':
|
|
55
|
+
return await this.tap('', x, y, count);
|
|
56
|
+
case 'press':
|
|
57
|
+
return await this.touchDown('', /** @type {number} */ (x), /** @type {number} */ (y));
|
|
58
|
+
case 'release':
|
|
59
|
+
return await this.touchUp(String(element),
|
|
60
|
+
/** @type {number} */ (x),
|
|
61
|
+
/** @type {number} */ (y));
|
|
62
|
+
case 'moveTo':
|
|
63
|
+
return await this.touchMove('', /** @type {number} */ (x), /** @type {number} */ (y));
|
|
64
|
+
case 'wait':
|
|
65
|
+
return await bluebird_1.default.delay(/** @type {number} */ (ms));
|
|
66
|
+
case 'longPress':
|
|
67
|
+
return await this.touchLongClick('',
|
|
68
|
+
/** @type {number} */ (x),
|
|
69
|
+
/** @type {number} */ (y), duration ?? 1000);
|
|
70
|
+
case 'cancel':
|
|
71
|
+
// TODO: clarify behavior of 'cancel' action and fix this
|
|
72
|
+
this.log.warn('Cancel action currently has no effect');
|
|
73
|
+
break;
|
|
74
|
+
default:
|
|
75
|
+
this.log.errorAndThrow(`unknown action ${action}`);
|
|
109
76
|
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
let
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
77
|
+
},
|
|
78
|
+
async doTouchDrag(gestures) {
|
|
79
|
+
let longPress = gestures[0];
|
|
80
|
+
let moveTo = gestures[1];
|
|
81
|
+
let startX = longPress.options.x || 0, startY = longPress.options.y || 0, endX = moveTo.options.x || 0, endY = moveTo.options.y || 0;
|
|
82
|
+
if (longPress.options.element) {
|
|
83
|
+
let { x, y } = await this.getLocationInView(longPress.options.element);
|
|
84
|
+
startX += x || 0;
|
|
85
|
+
startY += y || 0;
|
|
86
|
+
}
|
|
87
|
+
if (moveTo.options.element) {
|
|
88
|
+
let { x, y } = await this.getLocationInView(moveTo.options.element);
|
|
89
|
+
endX += x || 0;
|
|
90
|
+
endY += y || 0;
|
|
91
|
+
}
|
|
92
|
+
let apiLevel = await /** @type {ADB} */ (this.adb).getApiLevel();
|
|
93
|
+
// lollipop takes a little longer to get things rolling
|
|
94
|
+
let duration = apiLevel >= 5 ? 2 : 1;
|
|
95
|
+
// make sure that if the long press has a duration, we use it.
|
|
96
|
+
if (longPress.options && longPress.options.duration) {
|
|
97
|
+
duration = Math.max(longPress.options.duration / 1000, duration);
|
|
98
|
+
}
|
|
99
|
+
// `drag` will take care of whether there is an element or not at that level
|
|
100
|
+
return await this.drag(startX, startY, endX, endY, duration, 1, longPress.options.element, moveTo.options.element);
|
|
101
|
+
},
|
|
102
|
+
async fixRelease(gestures) {
|
|
103
|
+
let release = /** @type {import('./types').ReleaseTouchAction} */ (lodash_1.default.last(gestures));
|
|
104
|
+
// sometimes there are no options
|
|
105
|
+
release.options = release.options || {};
|
|
106
|
+
// nothing to do if release options are already set
|
|
107
|
+
if (release.options.element || (release.options.x && release.options.y)) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// without coordinates, `release` uses the center of the screen, which,
|
|
111
|
+
// generally speaking, is not what we want
|
|
112
|
+
// therefore: loop backwards and use the last command with an element and/or
|
|
113
|
+
// offset coordinates
|
|
114
|
+
gestures = lodash_1.default.clone(gestures);
|
|
115
|
+
let ref = null;
|
|
116
|
+
for (let gesture of /** @type {NonReleaseTouchAction[]} */ (gestures.reverse())) {
|
|
117
|
+
let opts = gesture.options;
|
|
118
|
+
if (opts.element || (opts.x && opts.y)) {
|
|
119
|
+
ref = gesture;
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (ref) {
|
|
124
|
+
let opts = ref.options;
|
|
125
|
+
if (opts.element) {
|
|
126
|
+
let loc = await this.getLocationInView(opts.element);
|
|
127
|
+
if (opts.x && opts.y) {
|
|
128
|
+
// this is an offset from the element
|
|
129
|
+
release.options = {
|
|
130
|
+
x: loc.x + opts.x,
|
|
131
|
+
y: loc.y + opts.y,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
// this is the center of the element
|
|
136
|
+
let size = await this.getSize(opts.element);
|
|
137
|
+
release.options = {
|
|
138
|
+
x: loc.x + size.width / 2,
|
|
139
|
+
y: loc.y + size.height / 2,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
121
142
|
}
|
|
122
143
|
else {
|
|
123
|
-
|
|
124
|
-
let size = await this.getSize(opts.element);
|
|
125
|
-
release.options = {
|
|
126
|
-
x: loc.x + size.width / 2,
|
|
127
|
-
y: loc.y + size.height / 2
|
|
128
|
-
};
|
|
144
|
+
release.options = lodash_1.default.pick(opts, 'x', 'y');
|
|
129
145
|
}
|
|
130
146
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
return release;
|
|
136
|
-
};
|
|
137
|
-
// Perform one gesture
|
|
138
|
-
helpers.performGesture = async function performGesture(gesture) {
|
|
139
|
-
try {
|
|
140
|
-
return await this.doTouchAction(gesture.action, gesture.options || {});
|
|
141
|
-
}
|
|
142
|
-
catch (e) {
|
|
143
|
-
// sometime the element is not available when releasing, retry without it
|
|
144
|
-
if ((0, driver_1.isErrorType)(e, driver_1.errors.NoSuchElementError) && gesture.action === 'release' &&
|
|
145
|
-
gesture.options.element) {
|
|
146
|
-
delete gesture.options.element;
|
|
147
|
-
this.log.debug(`retrying release without element opts: ${gesture.options}.`);
|
|
147
|
+
return release;
|
|
148
|
+
},
|
|
149
|
+
async performGesture(gesture) {
|
|
150
|
+
try {
|
|
148
151
|
return await this.doTouchAction(gesture.action, gesture.options || {});
|
|
149
152
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
let sizeResult = await this.getSize(destElement);
|
|
159
|
-
let offsetX = (Math.abs(endX) < 1 && Math.abs(endX) > 0) ? sizeResult.width * endX : endX;
|
|
160
|
-
let offsetY = (Math.abs(endY) < 1 && Math.abs(endY) > 0) ? sizeResult.height * endY : endY;
|
|
161
|
-
endX = locResult.x + offsetX;
|
|
162
|
-
endY = locResult.y + offsetY;
|
|
163
|
-
// if the target element was provided, the coordinates for the destination need to be relative to it.
|
|
164
|
-
if (support_1.util.hasValue(element)) {
|
|
165
|
-
let firstElLocation = await this.getLocationInView(element);
|
|
166
|
-
endX -= firstElLocation.x;
|
|
167
|
-
endY -= firstElLocation.y;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
// clients are responsible to use these options correctly
|
|
171
|
-
return { startX, startY, endX, endY, duration, touchCount, element };
|
|
172
|
-
};
|
|
173
|
-
commands.performTouch = async function performTouch(gestures) {
|
|
174
|
-
// press-wait-moveTo-release is `swipe`, so use native method
|
|
175
|
-
if (gestures.length === 4 &&
|
|
176
|
-
gestures[0].action === 'press' &&
|
|
177
|
-
gestures[1].action === 'wait' &&
|
|
178
|
-
gestures[2].action === 'moveTo' &&
|
|
179
|
-
gestures[3].action === 'release') {
|
|
180
|
-
let swipeOpts = await this.getSwipeOptions(gestures);
|
|
181
|
-
return await this.swipe(swipeOpts.startX, swipeOpts.startY, swipeOpts.endX, swipeOpts.endY, swipeOpts.duration, swipeOpts.touchCount, swipeOpts.element);
|
|
182
|
-
}
|
|
183
|
-
let actions = lodash_1.default.map(gestures, 'action');
|
|
184
|
-
if (actions[0] === 'longPress' && actions[1] === 'moveTo' && actions[2] === 'release') {
|
|
185
|
-
// some things are special
|
|
186
|
-
return await this.doTouchDrag(gestures);
|
|
187
|
-
}
|
|
188
|
-
else {
|
|
189
|
-
if (actions.length === 2) {
|
|
190
|
-
// `press` without a wait is too slow and gets interpretted as a `longPress`
|
|
191
|
-
if (lodash_1.default.head(actions) === 'press' && lodash_1.default.last(actions) === 'release') {
|
|
192
|
-
actions[0] = 'tap';
|
|
193
|
-
gestures[0].action = 'tap';
|
|
153
|
+
catch (e) {
|
|
154
|
+
// sometime the element is not available when releasing, retry without it
|
|
155
|
+
if ((0, driver_1.isErrorType)(e, driver_1.errors.NoSuchElementError) &&
|
|
156
|
+
gesture.action === 'release' &&
|
|
157
|
+
gesture.options?.element) {
|
|
158
|
+
delete gesture.options.element;
|
|
159
|
+
this.log.debug(`retrying release without element opts: ${gesture.options}.`);
|
|
160
|
+
return await this.doTouchAction(gesture.action, gesture.options || {});
|
|
194
161
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
162
|
+
throw e;
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
async getSwipeOptions(gestures, touchCount = 1) {
|
|
166
|
+
let startX = getCoordDefault(gestures[0].options.x), startY = getCoordDefault(gestures[0].options.y), endX = getCoordDefault(gestures[2].options.x), endY = getCoordDefault(gestures[2].options.y), duration = getSwipeTouchDuration(gestures[1]), element = /** @type {string} */ (gestures[0].options.element), destElement = gestures[2].options.element || gestures[0].options.element;
|
|
167
|
+
// there's no destination element handling in bootstrap and since it applies to all platforms, we handle it here
|
|
168
|
+
if (support_1.util.hasValue(destElement)) {
|
|
169
|
+
let locResult = await this.getLocationInView(destElement);
|
|
170
|
+
let sizeResult = await this.getSize(destElement);
|
|
171
|
+
let offsetX = Math.abs(endX) < 1 && Math.abs(endX) > 0 ? sizeResult.width * endX : endX;
|
|
172
|
+
let offsetY = Math.abs(endY) < 1 && Math.abs(endY) > 0 ? sizeResult.height * endY : endY;
|
|
173
|
+
endX = locResult.x + offsetX;
|
|
174
|
+
endY = locResult.y + offsetY;
|
|
175
|
+
// if the target element was provided, the coordinates for the destination need to be relative to it.
|
|
176
|
+
if (support_1.util.hasValue(element)) {
|
|
177
|
+
let firstElLocation = await this.getLocationInView(element);
|
|
178
|
+
endX -= firstElLocation.x;
|
|
179
|
+
endY -= firstElLocation.y;
|
|
199
180
|
}
|
|
200
181
|
}
|
|
182
|
+
// clients are responsible to use these options correctly
|
|
183
|
+
return { startX, startY, endX, endY, duration, touchCount, element };
|
|
184
|
+
},
|
|
185
|
+
async performTouch(gestures) {
|
|
186
|
+
// press-wait-moveTo-release is `swipe`, so use native method
|
|
187
|
+
if (gestures.length === 4 &&
|
|
188
|
+
gestures[0].action === 'press' &&
|
|
189
|
+
gestures[1].action === 'wait' &&
|
|
190
|
+
gestures[2].action === 'moveTo' &&
|
|
191
|
+
gestures[3].action === 'release') {
|
|
192
|
+
let swipeOpts = await this.getSwipeOptions(
|
|
193
|
+
/** @type {import('./types').SwipeAction} */ (gestures));
|
|
194
|
+
return await this.swipe(swipeOpts.startX, swipeOpts.startY, swipeOpts.endX, swipeOpts.endY, swipeOpts.duration, swipeOpts.touchCount, swipeOpts.element);
|
|
195
|
+
}
|
|
196
|
+
let actions = /** @type {(import('./types').TouchActionKind|TouchAction)[]} */ (lodash_1.default.map(gestures, 'action'));
|
|
197
|
+
if (actions[0] === 'longPress' && actions[1] === 'moveTo' && actions[2] === 'release') {
|
|
198
|
+
// some things are special
|
|
199
|
+
return await this.doTouchDrag(/** @type {import('./types').TouchDragAction} */ (gestures));
|
|
200
|
+
}
|
|
201
201
|
else {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
actions
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
202
|
+
if (actions.length === 2) {
|
|
203
|
+
// `press` without a wait is too slow and gets interpretted as a `longPress`
|
|
204
|
+
if (lodash_1.default.head(actions) === 'press' && lodash_1.default.last(actions) === 'release') {
|
|
205
|
+
actions[0] = 'tap';
|
|
206
|
+
gestures[0].action = 'tap';
|
|
207
|
+
}
|
|
208
|
+
// the `longPress` and `tap` methods release on their own
|
|
209
|
+
if ((lodash_1.default.head(actions) === 'tap' || lodash_1.default.head(actions) === 'longPress') &&
|
|
210
|
+
lodash_1.default.last(actions) === 'release') {
|
|
211
|
+
gestures.pop();
|
|
212
|
+
actions.pop();
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
// longpress followed by anything other than release should become a press and wait
|
|
217
|
+
if (actions[0] === 'longPress') {
|
|
218
|
+
actions = ['press', 'wait', ...actions.slice(1)];
|
|
219
|
+
let press = /** @type {NonReleaseTouchAction} */ (gestures.shift());
|
|
220
|
+
press.action = 'press';
|
|
221
|
+
/** @type {NonReleaseTouchAction} */
|
|
222
|
+
let wait = {
|
|
223
|
+
action: 'wait',
|
|
224
|
+
options: { ms: press.options.duration || 1000 },
|
|
225
|
+
};
|
|
226
|
+
delete press.options.duration;
|
|
227
|
+
gestures = [press, wait, ...gestures];
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
let fixedGestures = await this.parseTouch(gestures, false);
|
|
231
|
+
// fix release action then perform all actions
|
|
232
|
+
if (actions[actions.length - 1] === 'release') {
|
|
233
|
+
actions[actions.length - 1] = /** @type {TouchAction} */ (await this.fixRelease(gestures));
|
|
234
|
+
}
|
|
235
|
+
for (let g of fixedGestures) {
|
|
236
|
+
await this.performGesture(g);
|
|
213
237
|
}
|
|
214
238
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
for (let g of fixedGestures) {
|
|
221
|
-
await this.performGesture(g);
|
|
239
|
+
},
|
|
240
|
+
async parseTouch(gestures, multi) {
|
|
241
|
+
// because multi-touch releases at the end by default
|
|
242
|
+
if (multi && /** @type {TouchAction} */ (lodash_1.default.last(gestures)).action === 'release') {
|
|
243
|
+
gestures.pop();
|
|
222
244
|
}
|
|
223
|
-
|
|
224
|
-
};
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
245
|
+
let touchStateObjects = await (0, asyncbox_1.asyncmap)(gestures, async (gesture) => {
|
|
246
|
+
let options = gesture.options || {};
|
|
247
|
+
if (lodash_1.default.includes(['press', 'moveTo', 'tap', 'longPress'], gesture.action)) {
|
|
248
|
+
options.offset = false;
|
|
249
|
+
let elementId = gesture.options.element;
|
|
250
|
+
if (elementId) {
|
|
251
|
+
let pos = await this.getLocationInView(elementId);
|
|
252
|
+
if (gesture.options.x || gesture.options.y) {
|
|
253
|
+
options.x = pos.x + (gesture.options.x || 0);
|
|
254
|
+
options.y = pos.y + (gesture.options.y || 0);
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
const { width, height } = await this.getSize(elementId);
|
|
258
|
+
options.x = pos.x + width / 2;
|
|
259
|
+
options.y = pos.y + height / 2;
|
|
260
|
+
}
|
|
261
|
+
let touchStateObject = {
|
|
262
|
+
action: gesture.action,
|
|
263
|
+
options,
|
|
264
|
+
timeOffset: 0.005,
|
|
265
|
+
};
|
|
266
|
+
return touchStateObject;
|
|
240
267
|
}
|
|
241
268
|
else {
|
|
242
|
-
|
|
243
|
-
options.
|
|
244
|
-
|
|
269
|
+
options.x = gesture.options.x || 0;
|
|
270
|
+
options.y = gesture.options.y || 0;
|
|
271
|
+
let touchStateObject = {
|
|
272
|
+
action: gesture.action,
|
|
273
|
+
options,
|
|
274
|
+
timeOffset: 0.005,
|
|
275
|
+
};
|
|
276
|
+
return touchStateObject;
|
|
245
277
|
}
|
|
246
|
-
let touchStateObject = {
|
|
247
|
-
action: gesture.action,
|
|
248
|
-
options,
|
|
249
|
-
timeOffset: 0.005,
|
|
250
|
-
};
|
|
251
|
-
return touchStateObject;
|
|
252
278
|
}
|
|
253
279
|
else {
|
|
254
|
-
|
|
255
|
-
|
|
280
|
+
let offset = 0.005;
|
|
281
|
+
if (gesture.action === 'wait') {
|
|
282
|
+
options = gesture.options;
|
|
283
|
+
offset = parseInt(gesture.options.ms, 10) / 1000;
|
|
284
|
+
}
|
|
256
285
|
let touchStateObject = {
|
|
257
286
|
action: gesture.action,
|
|
258
287
|
options,
|
|
259
|
-
timeOffset:
|
|
288
|
+
timeOffset: offset,
|
|
260
289
|
};
|
|
261
290
|
return touchStateObject;
|
|
262
291
|
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
292
|
+
}, false);
|
|
293
|
+
// we need to change the time (which is now an offset)
|
|
294
|
+
// and the position (which may be an offset)
|
|
295
|
+
let prevPos = null, time = 0;
|
|
296
|
+
for (let state of touchStateObjects) {
|
|
297
|
+
if (lodash_1.default.isUndefined(state.options.x) && lodash_1.default.isUndefined(state.options.y) && prevPos !== null) {
|
|
298
|
+
// this happens with wait
|
|
299
|
+
state.options.x = prevPos.x;
|
|
300
|
+
state.options.y = prevPos.y;
|
|
269
301
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
options
|
|
273
|
-
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
302
|
+
if (state.options.offset && prevPos) {
|
|
303
|
+
// the current position is an offset
|
|
304
|
+
state.options.x += prevPos.x;
|
|
305
|
+
state.options.y += prevPos.y;
|
|
306
|
+
}
|
|
307
|
+
delete state.options.offset;
|
|
308
|
+
if (!lodash_1.default.isUndefined(state.options.x) && !lodash_1.default.isUndefined(state.options.y)) {
|
|
309
|
+
prevPos = state.options;
|
|
310
|
+
}
|
|
311
|
+
if (multi) {
|
|
312
|
+
let timeOffset = state.timeOffset;
|
|
313
|
+
time += timeOffset;
|
|
314
|
+
state.time = android_1.default.truncateDecimals(time, 3);
|
|
315
|
+
// multi gestures require 'touch' rather than 'options'
|
|
316
|
+
if (!lodash_1.default.isUndefined(state.options.x) && !lodash_1.default.isUndefined(state.options.y)) {
|
|
317
|
+
state.touch = {
|
|
318
|
+
x: state.options.x,
|
|
319
|
+
y: state.options.y,
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
delete state.options;
|
|
323
|
+
}
|
|
324
|
+
delete state.timeOffset;
|
|
286
325
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
326
|
+
return touchStateObjects;
|
|
327
|
+
},
|
|
328
|
+
async performMultiAction(actions, elementId) {
|
|
329
|
+
// Android needs at least two actions to be able to perform a multi pointer gesture
|
|
330
|
+
if (actions.length === 1) {
|
|
331
|
+
throw new Error('Multi Pointer Gestures need at least two actions. ' +
|
|
332
|
+
'Use Touch Actions for a single action.');
|
|
291
333
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
334
|
+
const states = await (0, asyncbox_1.asyncmap)(actions, async (action) => await this.parseTouch(action, true), false);
|
|
335
|
+
return await this.doPerformMultiAction(elementId, states);
|
|
336
|
+
},
|
|
337
|
+
async doPerformMultiAction(elementId, states) {
|
|
338
|
+
let opts;
|
|
339
|
+
if (elementId) {
|
|
340
|
+
opts = {
|
|
341
|
+
elementId,
|
|
342
|
+
actions: states,
|
|
343
|
+
};
|
|
344
|
+
return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction('element:performMultiPointerGesture', opts);
|
|
295
345
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
if (!lodash_1.default.isUndefined(state.options.x) && !lodash_1.default.isUndefined(state.options.y)) {
|
|
302
|
-
state.touch = {
|
|
303
|
-
x: state.options.x,
|
|
304
|
-
y: state.options.y
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
delete state.options;
|
|
346
|
+
else {
|
|
347
|
+
opts = {
|
|
348
|
+
actions: states,
|
|
349
|
+
};
|
|
350
|
+
return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction('performMultiPointerGesture', opts);
|
|
308
351
|
}
|
|
309
|
-
|
|
310
|
-
}
|
|
311
|
-
return touchStateObjects;
|
|
312
|
-
};
|
|
313
|
-
commands.performMultiAction = async function performMultiAction(actions, elementId) {
|
|
314
|
-
// Android needs at least two actions to be able to perform a multi pointer gesture
|
|
315
|
-
if (actions.length === 1) {
|
|
316
|
-
throw new Error('Multi Pointer Gestures need at least two actions. ' +
|
|
317
|
-
'Use Touch Actions for a single action.');
|
|
318
|
-
}
|
|
319
|
-
const states = await (0, asyncbox_1.asyncmap)(actions, async (action) => await this.parseTouch(action, true), false);
|
|
320
|
-
return await this.doPerformMultiAction(elementId, states);
|
|
352
|
+
},
|
|
321
353
|
};
|
|
354
|
+
(0, mixins_1.mixin)(TouchMixin);
|
|
355
|
+
exports.default = TouchMixin;
|
|
322
356
|
/**
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
*
|
|
357
|
+
* @typedef {import('appium-adb').ADB} ADB
|
|
358
|
+
* @typedef {import('./types').TouchAction} TouchAction
|
|
359
|
+
* @typedef {import('./types').NonReleaseTouchAction} NonReleaseTouchAction
|
|
360
|
+
* @typedef {import('../bootstrap').AndroidBootstrap} AndroidBootstrap
|
|
327
361
|
*/
|
|
328
|
-
commands.doPerformMultiAction = async function doPerformMultiAction(elementId, states) {
|
|
329
|
-
let opts;
|
|
330
|
-
if (elementId) {
|
|
331
|
-
opts = {
|
|
332
|
-
elementId,
|
|
333
|
-
actions: states
|
|
334
|
-
};
|
|
335
|
-
return await this.bootstrap.sendAction('element:performMultiPointerGesture', opts);
|
|
336
|
-
}
|
|
337
|
-
else {
|
|
338
|
-
opts = {
|
|
339
|
-
actions: states
|
|
340
|
-
};
|
|
341
|
-
return await this.bootstrap.sendAction('performMultiPointerGesture', opts);
|
|
342
|
-
}
|
|
343
|
-
};
|
|
344
|
-
Object.assign(extensions, commands, helpers);
|
|
345
|
-
exports.default = extensions;
|
|
346
362
|
//# sourceMappingURL=touch.js.map
|