appium-android-driver 7.8.3 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/build/lib/commands/app-management.d.ts +129 -5
- package/build/lib/commands/app-management.d.ts.map +1 -1
- package/build/lib/commands/app-management.js +433 -128
- package/build/lib/commands/app-management.js.map +1 -1
- package/build/lib/commands/appearance.d.ts +17 -4
- package/build/lib/commands/appearance.d.ts.map +1 -1
- package/build/lib/commands/appearance.js +32 -33
- package/build/lib/commands/appearance.js.map +1 -1
- package/build/lib/commands/context/cache.d.ts +19 -0
- package/build/lib/commands/context/cache.d.ts.map +1 -0
- package/build/lib/commands/context/cache.js +32 -0
- package/build/lib/commands/context/cache.js.map +1 -0
- package/build/lib/commands/context/exports.d.ts +141 -0
- package/build/lib/commands/context/exports.d.ts.map +1 -0
- package/build/lib/commands/context/exports.js +351 -0
- package/build/lib/commands/context/exports.js.map +1 -0
- package/build/lib/commands/context/helpers.d.ts +98 -0
- package/build/lib/commands/context/helpers.d.ts.map +1 -0
- package/build/lib/commands/context/helpers.js +715 -0
- package/build/lib/commands/context/helpers.js.map +1 -0
- package/build/lib/commands/device/common.d.ts +23 -0
- package/build/lib/commands/device/common.d.ts.map +1 -0
- package/build/lib/commands/device/common.js +230 -0
- package/build/lib/commands/device/common.js.map +1 -0
- package/build/lib/commands/device/emulator-actions.d.ts +114 -0
- package/build/lib/commands/device/emulator-actions.d.ts.map +1 -0
- package/build/lib/commands/device/emulator-actions.js +197 -0
- package/build/lib/commands/device/emulator-actions.js.map +1 -0
- package/build/lib/commands/device/emulator-console.d.ts +7 -0
- package/build/lib/commands/device/emulator-console.d.ts.map +1 -0
- package/build/lib/commands/device/emulator-console.js +24 -0
- package/build/lib/commands/device/emulator-console.js.map +1 -0
- package/build/lib/commands/device/utils.d.ts +50 -0
- package/build/lib/commands/device/utils.d.ts.map +1 -0
- package/build/lib/commands/device/utils.js +238 -0
- package/build/lib/commands/device/utils.js.map +1 -0
- package/build/lib/commands/deviceidle.d.ts +8 -5
- package/build/lib/commands/deviceidle.d.ts.map +1 -1
- package/build/lib/commands/deviceidle.js +31 -37
- package/build/lib/commands/deviceidle.js.map +1 -1
- package/build/lib/commands/element.d.ts +99 -5
- package/build/lib/commands/element.d.ts.map +1 -1
- package/build/lib/commands/element.js +152 -116
- package/build/lib/commands/element.js.map +1 -1
- package/build/lib/commands/execute.d.ts +12 -4
- package/build/lib/commands/execute.d.ts.map +1 -1
- package/build/lib/commands/execute.js +83 -78
- package/build/lib/commands/execute.js.map +1 -1
- package/build/lib/commands/file-actions.d.ts +42 -5
- package/build/lib/commands/file-actions.d.ts.map +1 -1
- package/build/lib/commands/file-actions.js +230 -194
- package/build/lib/commands/file-actions.js.map +1 -1
- package/build/lib/commands/find.d.ts +5 -4
- package/build/lib/commands/find.d.ts.map +1 -1
- package/build/lib/commands/find.js +7 -10
- package/build/lib/commands/find.js.map +1 -1
- package/build/lib/commands/geolocation.d.ts +45 -0
- package/build/lib/commands/geolocation.d.ts.map +1 -0
- package/build/lib/commands/geolocation.js +182 -0
- package/build/lib/commands/geolocation.js.map +1 -0
- package/build/lib/commands/ime.d.ts +25 -5
- package/build/lib/commands/ime.d.ts.map +1 -1
- package/build/lib/commands/ime.js +59 -42
- package/build/lib/commands/ime.js.map +1 -1
- package/build/lib/commands/intent.d.ts +56 -5
- package/build/lib/commands/intent.d.ts.map +1 -1
- package/build/lib/commands/intent.js +135 -83
- package/build/lib/commands/intent.js.map +1 -1
- package/build/lib/commands/keyboard.d.ts +58 -4
- package/build/lib/commands/keyboard.d.ts.map +1 -1
- package/build/lib/commands/keyboard.js +119 -17
- package/build/lib/commands/keyboard.js.map +1 -1
- package/build/lib/commands/lock/exports.d.ts +301 -0
- package/build/lib/commands/lock/exports.d.ts.map +1 -0
- package/build/lib/commands/lock/exports.js +121 -0
- package/build/lib/commands/lock/exports.js.map +1 -0
- package/build/lib/commands/lock/helpers.d.ts +349 -0
- package/build/lib/commands/lock/helpers.d.ts.map +1 -0
- package/build/lib/commands/lock/helpers.js +375 -0
- package/build/lib/commands/lock/helpers.js.map +1 -0
- package/build/lib/commands/log.d.ts +59 -5
- package/build/lib/commands/log.d.ts.map +1 -1
- package/build/lib/commands/log.js +150 -140
- package/build/lib/commands/log.js.map +1 -1
- package/build/lib/commands/media-projection.d.ts +16 -5
- package/build/lib/commands/media-projection.d.ts.map +1 -1
- package/build/lib/commands/media-projection.js +69 -58
- package/build/lib/commands/media-projection.js.map +1 -1
- package/build/lib/commands/memory.d.ts +9 -5
- package/build/lib/commands/memory.d.ts.map +1 -1
- package/build/lib/commands/memory.js +19 -24
- package/build/lib/commands/memory.js.map +1 -1
- package/build/lib/commands/misc.d.ts +42 -0
- package/build/lib/commands/misc.d.ts.map +1 -0
- package/build/lib/commands/misc.js +100 -0
- package/build/lib/commands/misc.js.map +1 -0
- package/build/lib/commands/network.d.ts +61 -5
- package/build/lib/commands/network.d.ts.map +1 -1
- package/build/lib/commands/network.js +196 -189
- package/build/lib/commands/network.js.map +1 -1
- package/build/lib/commands/performance.d.ts +67 -27
- package/build/lib/commands/performance.d.ts.map +1 -1
- package/build/lib/commands/performance.js +105 -80
- package/build/lib/commands/performance.js.map +1 -1
- package/build/lib/commands/permissions.d.ts +12 -6
- package/build/lib/commands/permissions.d.ts.map +1 -1
- package/build/lib/commands/permissions.js +65 -62
- package/build/lib/commands/permissions.js.map +1 -1
- package/build/lib/commands/recordscreen.d.ts +44 -5
- package/build/lib/commands/recordscreen.d.ts.map +1 -1
- package/build/lib/commands/recordscreen.js +131 -126
- package/build/lib/commands/recordscreen.js.map +1 -1
- package/build/lib/commands/resources.d.ts +16 -0
- package/build/lib/commands/resources.d.ts.map +1 -0
- package/build/lib/commands/resources.js +91 -0
- package/build/lib/commands/resources.js.map +1 -0
- package/build/lib/commands/shell.d.ts +8 -5
- package/build/lib/commands/shell.d.ts.map +1 -1
- package/build/lib/commands/shell.js +29 -33
- package/build/lib/commands/shell.js.map +1 -1
- package/build/lib/commands/streamscreen.d.ts +34 -6
- package/build/lib/commands/streamscreen.d.ts.map +1 -1
- package/build/lib/commands/streamscreen.js +166 -162
- package/build/lib/commands/streamscreen.js.map +1 -1
- package/build/lib/commands/system-bars.d.ts +18 -13
- package/build/lib/commands/system-bars.d.ts.map +1 -1
- package/build/lib/commands/system-bars.js +68 -64
- package/build/lib/commands/system-bars.js.map +1 -1
- package/build/lib/commands/time.d.ts +14 -0
- package/build/lib/commands/time.d.ts.map +1 -0
- package/build/lib/commands/time.js +39 -0
- package/build/lib/commands/time.js.map +1 -0
- package/build/lib/commands/touch.d.ts +99 -6
- package/build/lib/commands/touch.d.ts.map +1 -1
- package/build/lib/commands/touch.js +399 -280
- package/build/lib/commands/touch.js.map +1 -1
- package/build/lib/commands/types.d.ts +110 -2
- package/build/lib/commands/types.d.ts.map +1 -1
- package/build/lib/doctor/checks.d.ts.map +1 -1
- package/build/lib/doctor/checks.js +4 -4
- package/build/lib/doctor/checks.js.map +1 -1
- package/build/lib/driver.d.ts +224 -27
- package/build/lib/driver.d.ts.map +1 -1
- package/build/lib/driver.js +232 -7
- package/build/lib/driver.js.map +1 -1
- package/build/lib/index.d.ts +1 -4
- package/build/lib/index.d.ts.map +1 -1
- package/build/lib/index.js +1 -13
- package/build/lib/index.js.map +1 -1
- package/build/lib/logger.js.map +1 -1
- package/build/lib/method-map.d.ts +0 -23
- package/build/lib/method-map.d.ts.map +1 -1
- package/build/lib/method-map.js +0 -11
- package/build/lib/method-map.js.map +1 -1
- package/build/lib/utils.d.ts +12 -0
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js +38 -2
- package/build/lib/utils.js.map +1 -1
- package/lib/commands/app-management.js +470 -145
- package/lib/commands/appearance.js +29 -36
- package/lib/commands/context/cache.js +29 -0
- package/lib/commands/context/exports.js +379 -0
- package/lib/commands/context/helpers.js +802 -0
- package/lib/commands/device/common.js +264 -0
- package/lib/commands/device/emulator-actions.js +194 -0
- package/lib/commands/device/emulator-console.js +24 -0
- package/lib/commands/device/utils.js +285 -0
- package/lib/commands/deviceidle.js +31 -44
- package/lib/commands/element.js +149 -142
- package/lib/commands/execute.js +86 -87
- package/lib/commands/file-actions.js +249 -222
- package/lib/commands/find.ts +13 -19
- package/lib/commands/geolocation.js +179 -0
- package/lib/commands/ime.js +53 -45
- package/lib/commands/intent.js +149 -91
- package/lib/commands/keyboard.js +114 -17
- package/lib/commands/lock/exports.js +139 -0
- package/lib/commands/lock/helpers.js +379 -0
- package/lib/commands/log.js +170 -166
- package/lib/commands/media-projection.js +75 -70
- package/lib/commands/memory.js +17 -29
- package/lib/commands/misc.js +94 -0
- package/lib/commands/network.js +209 -223
- package/lib/commands/performance.js +88 -73
- package/lib/commands/permissions.js +83 -84
- package/lib/commands/recordscreen.js +171 -170
- package/lib/commands/resources.js +96 -0
- package/lib/commands/shell.js +28 -42
- package/lib/commands/streamscreen.js +207 -206
- package/lib/commands/system-bars.js +76 -77
- package/lib/commands/time.js +36 -0
- package/lib/commands/touch.js +442 -346
- package/lib/commands/types.ts +123 -2
- package/lib/doctor/checks.js +24 -16
- package/lib/driver.ts +454 -12
- package/lib/index.ts +1 -13
- package/lib/logger.js +1 -1
- package/lib/method-map.js +0 -11
- package/lib/utils.js +40 -3
- package/package.json +1 -1
- package/build/lib/commands/actions.d.ts +0 -8
- package/build/lib/commands/actions.d.ts.map +0 -1
- package/build/lib/commands/actions.js +0 -207
- package/build/lib/commands/actions.js.map +0 -1
- package/build/lib/commands/alert.d.ts +0 -8
- package/build/lib/commands/alert.d.ts.map +0 -1
- package/build/lib/commands/alert.js +0 -29
- package/build/lib/commands/alert.js.map +0 -1
- package/build/lib/commands/context.d.ts +0 -10
- package/build/lib/commands/context.d.ts.map +0 -1
- package/build/lib/commands/context.js +0 -431
- package/build/lib/commands/context.js.map +0 -1
- package/build/lib/commands/emu-console.d.ts +0 -7
- package/build/lib/commands/emu-console.d.ts.map +0 -1
- package/build/lib/commands/emu-console.js +0 -27
- package/build/lib/commands/emu-console.js.map +0 -1
- package/build/lib/commands/general.d.ts +0 -9
- package/build/lib/commands/general.d.ts.map +0 -1
- package/build/lib/commands/general.js +0 -293
- package/build/lib/commands/general.js.map +0 -1
- package/build/lib/commands/index.d.ts +0 -28
- package/build/lib/commands/index.d.ts.map +0 -1
- package/build/lib/commands/index.js +0 -57
- package/build/lib/commands/index.js.map +0 -1
- package/build/lib/commands/mixins.d.ts +0 -747
- package/build/lib/commands/mixins.d.ts.map +0 -1
- package/build/lib/commands/mixins.js +0 -19
- package/build/lib/commands/mixins.js.map +0 -1
- package/build/lib/helpers/android.d.ts +0 -163
- package/build/lib/helpers/android.d.ts.map +0 -1
- package/build/lib/helpers/android.js +0 -818
- package/build/lib/helpers/android.js.map +0 -1
- package/build/lib/helpers/index.d.ts +0 -7
- package/build/lib/helpers/index.d.ts.map +0 -1
- package/build/lib/helpers/index.js +0 -29
- package/build/lib/helpers/index.js.map +0 -1
- package/build/lib/helpers/types.d.ts +0 -122
- package/build/lib/helpers/types.d.ts.map +0 -1
- package/build/lib/helpers/types.js +0 -3
- package/build/lib/helpers/types.js.map +0 -1
- package/build/lib/helpers/unlock.d.ts +0 -32
- package/build/lib/helpers/unlock.d.ts.map +0 -1
- package/build/lib/helpers/unlock.js +0 -273
- package/build/lib/helpers/unlock.js.map +0 -1
- package/build/lib/helpers/webview.d.ts +0 -74
- package/build/lib/helpers/webview.d.ts.map +0 -1
- package/build/lib/helpers/webview.js +0 -448
- package/build/lib/helpers/webview.js.map +0 -1
- package/lib/commands/actions.js +0 -244
- package/lib/commands/alert.js +0 -34
- package/lib/commands/context.js +0 -507
- package/lib/commands/emu-console.js +0 -31
- package/lib/commands/general.js +0 -343
- package/lib/commands/index.ts +0 -54
- package/lib/commands/mixins.ts +0 -976
- package/lib/helpers/android.ts +0 -1153
- package/lib/helpers/index.ts +0 -6
- package/lib/helpers/types.ts +0 -136
- package/lib/helpers/unlock.ts +0 -329
- package/lib/helpers/webview.ts +0 -610
package/lib/commands/keyboard.js
CHANGED
|
@@ -1,24 +1,121 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
+
import _ from 'lodash';
|
|
3
|
+
import {errors} from 'appium/driver';
|
|
4
|
+
import {requireArgs} from '../utils';
|
|
5
|
+
import {UNICODE_IME, EMPTY_IME} from 'io.appium.settings';
|
|
2
6
|
|
|
3
|
-
|
|
7
|
+
/**
|
|
8
|
+
* @this {import('../driver').AndroidDriver}
|
|
9
|
+
* @returns {Promise<boolean>}
|
|
10
|
+
*/
|
|
11
|
+
export async function hideKeyboard() {
|
|
12
|
+
return await /** @type {import('appium-adb').ADB} */ (this.adb).hideKeyboard();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @this {import('../driver').AndroidDriver}
|
|
17
|
+
* @returns {Promise<boolean>}
|
|
18
|
+
*/
|
|
19
|
+
export async function isKeyboardShown() {
|
|
20
|
+
const {isKeyboardShown} = await /** @type {import('appium-adb').ADB} */ (
|
|
21
|
+
this.adb
|
|
22
|
+
).isSoftKeyboardPresent();
|
|
23
|
+
return isKeyboardShown;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @this {import('../driver').AndroidDriver}
|
|
28
|
+
* @param {string|string[]} keys
|
|
29
|
+
* @returns {Promise<void>}
|
|
30
|
+
*/
|
|
31
|
+
export async function keys(keys) {
|
|
32
|
+
// Protocol sends an array; rethink approach
|
|
33
|
+
keys = _.isArray(keys) ? keys.join('') : keys;
|
|
34
|
+
await this.doSendKeys({
|
|
35
|
+
text: keys,
|
|
36
|
+
replace: false,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
4
39
|
|
|
5
40
|
/**
|
|
6
|
-
* @
|
|
7
|
-
* @
|
|
41
|
+
* @this {import('../driver').AndroidDriver}
|
|
42
|
+
* @param {import('./types').SendKeysOpts} params
|
|
43
|
+
* @returns {Promise<void>}
|
|
8
44
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
},
|
|
45
|
+
export async function doSendKeys(params) {
|
|
46
|
+
throw new errors.NotImplementedError('Not implemented');
|
|
47
|
+
}
|
|
13
48
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
49
|
+
/**
|
|
50
|
+
* @this {import('../driver').AndroidDriver}
|
|
51
|
+
* @param {string|number} keycode
|
|
52
|
+
* @param {number} [metastate]
|
|
53
|
+
* @returns {Promise<void>}
|
|
54
|
+
*/
|
|
55
|
+
export async function keyevent(keycode, metastate) {
|
|
56
|
+
// TODO deprecate keyevent; currently wd only implements keyevent
|
|
57
|
+
this.log.warn('keyevent will be deprecated use pressKeyCode');
|
|
58
|
+
return await this.pressKeyCode(keycode, metastate);
|
|
59
|
+
}
|
|
21
60
|
|
|
22
|
-
|
|
61
|
+
/**
|
|
62
|
+
* @this {import('../driver').AndroidDriver}
|
|
63
|
+
* @param {string|number} keycode
|
|
64
|
+
* @param {number} [metastate]
|
|
65
|
+
* @returns {Promise<void>}
|
|
66
|
+
*/
|
|
67
|
+
export async function pressKeyCode(keycode, metastate) {
|
|
68
|
+
throw new errors.NotImplementedError('Not implemented');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @this {import('../driver').AndroidDriver}
|
|
73
|
+
* @param {string|number} keycode
|
|
74
|
+
* @param {number} [metastate]
|
|
75
|
+
* @returns {Promise<void>}
|
|
76
|
+
*/
|
|
77
|
+
export async function longPressKeyCode(keycode, metastate) {
|
|
78
|
+
throw new errors.NotImplementedError('Not implemented');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @this {import('../driver').AndroidDriver}
|
|
83
|
+
* @param {import('./types').PerformEditorActionOpts} opts
|
|
84
|
+
* @returns {Promise<void>}
|
|
85
|
+
*/
|
|
86
|
+
export async function mobilePerformEditorAction(opts) {
|
|
87
|
+
const {action} = requireArgs('action', opts);
|
|
88
|
+
await this.settingsApp.performEditorAction(action);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// #region Internal Helpers
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @deprecated
|
|
95
|
+
* @this {import('../driver').AndroidDriver}
|
|
96
|
+
* @returns {Promise<string?>}
|
|
97
|
+
*/
|
|
98
|
+
export async function initUnicodeKeyboard() {
|
|
99
|
+
this.log.debug('Enabling Unicode keyboard support');
|
|
100
|
+
|
|
101
|
+
// get the default IME so we can return back to it later if we want
|
|
102
|
+
const defaultIME = await this.adb.defaultIME();
|
|
103
|
+
|
|
104
|
+
this.log.debug(`Unsetting previous IME ${defaultIME}`);
|
|
105
|
+
this.log.debug(`Setting IME to '${UNICODE_IME}'`);
|
|
106
|
+
await this.adb.enableIME(UNICODE_IME);
|
|
107
|
+
await this.adb.setIME(UNICODE_IME);
|
|
108
|
+
return defaultIME;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* @this {import('../driver').AndroidDriver}
|
|
113
|
+
* @returns {Promise<void>}
|
|
114
|
+
*/
|
|
115
|
+
export async function hideKeyboardCompletely() {
|
|
116
|
+
this.log.debug(`Hiding the on-screen keyboard by setting IME to '${EMPTY_IME}'`);
|
|
117
|
+
await this.adb.enableIME(EMPTY_IME);
|
|
118
|
+
await this.adb.setIME(EMPTY_IME);
|
|
119
|
+
}
|
|
23
120
|
|
|
24
|
-
|
|
121
|
+
// #endregion
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import B from 'bluebird';
|
|
2
|
+
import {
|
|
3
|
+
validateUnlockCapabilities,
|
|
4
|
+
FINGERPRINT_UNLOCK,
|
|
5
|
+
fastUnlock,
|
|
6
|
+
PIN_UNLOCK,
|
|
7
|
+
pinUnlock,
|
|
8
|
+
PIN_UNLOCK_KEY_EVENT,
|
|
9
|
+
pinUnlockWithKeyEvent,
|
|
10
|
+
PASSWORD_UNLOCK,
|
|
11
|
+
passwordUnlock,
|
|
12
|
+
PATTERN_UNLOCK,
|
|
13
|
+
patternUnlock,
|
|
14
|
+
fingerprintUnlock,
|
|
15
|
+
toCredentialType,
|
|
16
|
+
verifyUnlock,
|
|
17
|
+
} from './helpers';
|
|
18
|
+
import _ from 'lodash';
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @this {AndroidDriver}
|
|
23
|
+
* @param {import('../types').LockOpts} opts
|
|
24
|
+
* @returns {Promise<void>}
|
|
25
|
+
*/
|
|
26
|
+
export async function mobileLock(opts = {}) {
|
|
27
|
+
const {seconds} = opts;
|
|
28
|
+
return await this.lock(seconds);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @this {AndroidDriver}
|
|
33
|
+
* @param {number} [seconds]
|
|
34
|
+
* @returns {Promise<void>}
|
|
35
|
+
*/
|
|
36
|
+
export async function lock(seconds) {
|
|
37
|
+
await this.adb.lock();
|
|
38
|
+
if (Number.isNaN(seconds)) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const floatSeconds = parseFloat(String(seconds));
|
|
43
|
+
if (floatSeconds <= 0) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
await B.delay(1000 * floatSeconds);
|
|
47
|
+
await this.unlock();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @this {AndroidDriver}
|
|
52
|
+
* @returns {Promise<boolean>}
|
|
53
|
+
*/
|
|
54
|
+
export async function isLocked() {
|
|
55
|
+
return await this.adb.isScreenLocked();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @this {AndroidDriver}
|
|
60
|
+
* @returns {Promise<void>}
|
|
61
|
+
*/
|
|
62
|
+
export async function unlock() {
|
|
63
|
+
await unlockWithOptions.bind(this)();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @this {AndroidDriver}
|
|
68
|
+
* @param {import('../types').UnlockOptions} [opts={}]
|
|
69
|
+
* @returns {Promise<void>}
|
|
70
|
+
*/
|
|
71
|
+
export async function mobileUnlock(opts = {}) {
|
|
72
|
+
const {key, type, strategy, timeoutMs} = opts;
|
|
73
|
+
if (!key && !type) {
|
|
74
|
+
await this.unlock();
|
|
75
|
+
} else {
|
|
76
|
+
await unlockWithOptions.bind(this)({
|
|
77
|
+
unlockKey: key,
|
|
78
|
+
unlockType: type,
|
|
79
|
+
unlockStrategy: strategy,
|
|
80
|
+
unlockSuccessTimeout: timeoutMs,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// #region Internal Helpers
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @this {AndroidDriver}
|
|
89
|
+
* @param {AndroidDriverCaps?} [caps=null]
|
|
90
|
+
* @returns {Promise<void>}
|
|
91
|
+
*/
|
|
92
|
+
export async function unlockWithOptions(caps = null) {
|
|
93
|
+
if (!(await this.adb.isScreenLocked())) {
|
|
94
|
+
this.log.info('Screen already unlocked, doing nothing');
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const capabilities = caps ?? this.opts;
|
|
99
|
+
this.log.debug('Screen is locked, trying to unlock');
|
|
100
|
+
if (!capabilities.unlockType && !capabilities.unlockKey) {
|
|
101
|
+
this.log.info(
|
|
102
|
+
`Neither 'unlockType' nor 'unlockKey' capability is provided. ` +
|
|
103
|
+
`Assuming the device is locked with a simple lock screen.`,
|
|
104
|
+
);
|
|
105
|
+
await this.adb.dismissKeyguard();
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const {unlockType, unlockKey, unlockStrategy, unlockSuccessTimeout} =
|
|
110
|
+
validateUnlockCapabilities(capabilities);
|
|
111
|
+
if (
|
|
112
|
+
unlockKey &&
|
|
113
|
+
unlockType !== FINGERPRINT_UNLOCK &&
|
|
114
|
+
(_.isNil(unlockStrategy) || _.toLower(unlockStrategy) === 'locksettings') &&
|
|
115
|
+
(await this.adb.isLockManagementSupported())
|
|
116
|
+
) {
|
|
117
|
+
await fastUnlock.bind(this)({
|
|
118
|
+
credential: unlockKey,
|
|
119
|
+
credentialType: toCredentialType(/** @type {import('../types').UnlockType} */ (unlockType)),
|
|
120
|
+
});
|
|
121
|
+
} else {
|
|
122
|
+
const unlockMethod = {
|
|
123
|
+
[PIN_UNLOCK]: pinUnlock,
|
|
124
|
+
[PIN_UNLOCK_KEY_EVENT]: pinUnlockWithKeyEvent,
|
|
125
|
+
[PASSWORD_UNLOCK]: passwordUnlock,
|
|
126
|
+
[PATTERN_UNLOCK]: patternUnlock,
|
|
127
|
+
[FINGERPRINT_UNLOCK]: fingerprintUnlock,
|
|
128
|
+
}[unlockType];
|
|
129
|
+
await unlockMethod.bind(this)(capabilities);
|
|
130
|
+
}
|
|
131
|
+
await verifyUnlock.bind(this)(unlockSuccessTimeout);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// #endregion
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* @typedef {import('@appium/types').Capabilities<import('../../constraints').AndroidDriverConstraints>} AndroidDriverCaps
|
|
138
|
+
* @typedef {import('../../driver').AndroidDriver} AndroidDriver
|
|
139
|
+
*/
|
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
import {util} from '@appium/support';
|
|
2
|
+
import {sleep, waitForCondition} from 'asyncbox';
|
|
3
|
+
import _ from 'lodash';
|
|
4
|
+
|
|
5
|
+
export const PIN_UNLOCK = 'pin';
|
|
6
|
+
export const PIN_UNLOCK_KEY_EVENT = 'pinWithKeyEvent';
|
|
7
|
+
export const PASSWORD_UNLOCK = 'password';
|
|
8
|
+
export const PATTERN_UNLOCK = 'pattern';
|
|
9
|
+
export const FINGERPRINT_UNLOCK = 'fingerprint';
|
|
10
|
+
const UNLOCK_TYPES = /** @type {const} */ ([
|
|
11
|
+
PIN_UNLOCK,
|
|
12
|
+
PIN_UNLOCK_KEY_EVENT,
|
|
13
|
+
PASSWORD_UNLOCK,
|
|
14
|
+
PATTERN_UNLOCK,
|
|
15
|
+
FINGERPRINT_UNLOCK,
|
|
16
|
+
]);
|
|
17
|
+
export const KEYCODE_NUMPAD_ENTER = 66;
|
|
18
|
+
export const UNLOCK_WAIT_TIME = 100;
|
|
19
|
+
export const INPUT_KEYS_WAIT_TIME = 100;
|
|
20
|
+
const NUMBER_ZERO_KEYCODE = 7;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
*
|
|
24
|
+
* @param {any} value
|
|
25
|
+
* @returns {value is string}
|
|
26
|
+
*/
|
|
27
|
+
function isNonEmptyString(value) {
|
|
28
|
+
return typeof value === 'string' && value !== '';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Wait for the display to be unlocked.
|
|
33
|
+
* Some devices automatically accept typed 'pin' and 'password' code
|
|
34
|
+
* without pressing the Enter key. But some devices need it.
|
|
35
|
+
* This method waits a few seconds first for such automatic acceptance case.
|
|
36
|
+
* If the device is still locked, then this method will try to send
|
|
37
|
+
* the enter key code.
|
|
38
|
+
*
|
|
39
|
+
* @param {import('appium-adb').ADB} adb The instance of ADB
|
|
40
|
+
*/
|
|
41
|
+
async function waitForUnlock(adb) {
|
|
42
|
+
await sleep(UNLOCK_WAIT_TIME);
|
|
43
|
+
if (!(await adb.isScreenLocked())) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
await adb.keyevent(KEYCODE_NUMPAD_ENTER);
|
|
48
|
+
await sleep(UNLOCK_WAIT_TIME);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
*
|
|
53
|
+
* @param {import('../types').UnlockType} unlockType
|
|
54
|
+
* @returns {string}
|
|
55
|
+
*/
|
|
56
|
+
export function toCredentialType(unlockType) {
|
|
57
|
+
const result = {
|
|
58
|
+
[PIN_UNLOCK]: 'pin',
|
|
59
|
+
[PIN_UNLOCK_KEY_EVENT]: 'pin',
|
|
60
|
+
[PASSWORD_UNLOCK]: 'password',
|
|
61
|
+
[PATTERN_UNLOCK]: 'pattern',
|
|
62
|
+
}[unlockType];
|
|
63
|
+
if (result) {
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
throw new Error(`Unlock type '${unlockType}' is not known`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @template {AndroidDriverCaps} T
|
|
71
|
+
* @param {T} caps
|
|
72
|
+
* @returns {T}
|
|
73
|
+
*/
|
|
74
|
+
export function validateUnlockCapabilities(caps) {
|
|
75
|
+
const {unlockKey, unlockType} = caps ?? {};
|
|
76
|
+
if (!isNonEmptyString(unlockType)) {
|
|
77
|
+
throw new Error('A non-empty unlock key value must be provided');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if ([PIN_UNLOCK, PIN_UNLOCK_KEY_EVENT, FINGERPRINT_UNLOCK].includes(unlockType)) {
|
|
81
|
+
if (!/^[0-9]+$/.test(_.trim(unlockKey))) {
|
|
82
|
+
throw new Error(`Unlock key value '${unlockKey}' must only consist of digits`);
|
|
83
|
+
}
|
|
84
|
+
} else if (unlockType === PATTERN_UNLOCK) {
|
|
85
|
+
if (!/^[1-9]{2,9}$/.test(_.trim(unlockKey))) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
`Unlock key value '${unlockKey}' must only include from two to nine digits in range 1..9`,
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
if (/([1-9]).*?\1/.test(_.trim(unlockKey))) {
|
|
91
|
+
throw new Error(
|
|
92
|
+
`Unlock key value '${unlockKey}' must define a valid pattern where repeats are not allowed`,
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
} else if (unlockType === PASSWORD_UNLOCK) {
|
|
96
|
+
// Dont trim password key, you can use blank spaces in your android password
|
|
97
|
+
// ¯\_(ツ)_/¯
|
|
98
|
+
if (!/.{4,}/g.test(String(unlockKey))) {
|
|
99
|
+
throw new Error(
|
|
100
|
+
`The minimum allowed length of unlock key value '${unlockKey}' is 4 characters`,
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
throw new Error(
|
|
105
|
+
`Invalid unlock type '${unlockType}'. ` +
|
|
106
|
+
`Only the following unlock types are supported: ${UNLOCK_TYPES}`,
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
return caps;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* @this {AndroidDriver}
|
|
114
|
+
* @param {import('../types').FastUnlockOptions} opts
|
|
115
|
+
*/
|
|
116
|
+
export async function fastUnlock(opts) {
|
|
117
|
+
const {credential, credentialType} = opts;
|
|
118
|
+
this.log.info(`Unlocking the device via ADB using ${credentialType} credential '${credential}'`);
|
|
119
|
+
const wasLockEnabled = await this.adb.isLockEnabled();
|
|
120
|
+
if (wasLockEnabled) {
|
|
121
|
+
await this.adb.clearLockCredential(credential);
|
|
122
|
+
// not sure why, but the device's screen still remains locked
|
|
123
|
+
// if a preliminary wake up cycle has not been performed
|
|
124
|
+
await this.adb.cycleWakeUp();
|
|
125
|
+
} else {
|
|
126
|
+
this.log.info('No active lock has been detected. Proceeding to the keyguard dismissal');
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
await this.adb.dismissKeyguard();
|
|
130
|
+
} finally {
|
|
131
|
+
if (wasLockEnabled) {
|
|
132
|
+
await this.adb.setLockCredential(credentialType, credential);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
*
|
|
139
|
+
* @param {string} key
|
|
140
|
+
* @returns {string}
|
|
141
|
+
*/
|
|
142
|
+
export function encodePassword(key) {
|
|
143
|
+
return `${key}`.replace(/\s/gi, '%s');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
*
|
|
148
|
+
* @param {string} key
|
|
149
|
+
* @returns {string[]}
|
|
150
|
+
*/
|
|
151
|
+
export function stringKeyToArr(key) {
|
|
152
|
+
return `${key}`.trim().replace(/\s+/g, '').split(/\s*/);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @this {AndroidDriver}
|
|
157
|
+
* @param {AndroidDriverCaps} capabilities
|
|
158
|
+
* @returns {Promise<void>}
|
|
159
|
+
*/
|
|
160
|
+
export async function fingerprintUnlock(capabilities) {
|
|
161
|
+
if ((await this.adb.getApiLevel()) < 23) {
|
|
162
|
+
throw new Error('Fingerprint unlock only works for Android 6+ emulators');
|
|
163
|
+
}
|
|
164
|
+
await this.adb.fingerprint(String(capabilities.unlockKey));
|
|
165
|
+
await sleep(UNLOCK_WAIT_TIME);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* @this {AndroidDriver}
|
|
170
|
+
* @param {AndroidDriverCaps} capabilities
|
|
171
|
+
* @returns {Promise<void>}
|
|
172
|
+
*/
|
|
173
|
+
export async function pinUnlock(capabilities) {
|
|
174
|
+
this.log.info(`Trying to unlock device using pin ${capabilities.unlockKey}`);
|
|
175
|
+
await this.adb.dismissKeyguard();
|
|
176
|
+
const keys = stringKeyToArr(String(capabilities.unlockKey));
|
|
177
|
+
if ((await this.adb.getApiLevel()) >= 21) {
|
|
178
|
+
const els = await this.findElOrEls('id', 'com.android.systemui:id/digit_text', true);
|
|
179
|
+
if (_.isEmpty(els)) {
|
|
180
|
+
// fallback to pin with key event
|
|
181
|
+
return await pinUnlockWithKeyEvent.bind(this)(capabilities);
|
|
182
|
+
}
|
|
183
|
+
const pins = {};
|
|
184
|
+
for (const el of els) {
|
|
185
|
+
const text = await this.getAttribute('text', util.unwrapElement(el));
|
|
186
|
+
pins[text] = el;
|
|
187
|
+
}
|
|
188
|
+
for (const pin of keys) {
|
|
189
|
+
const el = pins[pin];
|
|
190
|
+
await this.click(util.unwrapElement(el));
|
|
191
|
+
}
|
|
192
|
+
} else {
|
|
193
|
+
for (const pin of keys) {
|
|
194
|
+
const el = await this.findElOrEls('id', `com.android.keyguard:id/key${pin}`, false);
|
|
195
|
+
if (el === null) {
|
|
196
|
+
// fallback to pin with key event
|
|
197
|
+
return await pinUnlockWithKeyEvent.bind(this)(capabilities);
|
|
198
|
+
}
|
|
199
|
+
await this.click(util.unwrapElement(el));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
await waitForUnlock(this.adb);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* @this {AndroidDriver}
|
|
207
|
+
* @param {AndroidDriverCaps} capabilities
|
|
208
|
+
* @returns {Promise<void>}
|
|
209
|
+
*/
|
|
210
|
+
export async function pinUnlockWithKeyEvent(capabilities) {
|
|
211
|
+
this.log.info(`Trying to unlock device using pin with keycode ${capabilities.unlockKey}`);
|
|
212
|
+
await this.adb.dismissKeyguard();
|
|
213
|
+
const keys = stringKeyToArr(String(capabilities.unlockKey));
|
|
214
|
+
|
|
215
|
+
// Some device does not have system key ids like 'com.android.keyguard:id/key'
|
|
216
|
+
// Then, sending keyevents are more reliable to unlock the screen.
|
|
217
|
+
for (const pin of keys) {
|
|
218
|
+
// 'pin' is number (0-9) in string.
|
|
219
|
+
// Number '0' is keycode '7'. number '9' is keycode '16'.
|
|
220
|
+
await this.adb.shell(['input', 'keyevent', String(parseInt(pin, 10) + NUMBER_ZERO_KEYCODE)]);
|
|
221
|
+
}
|
|
222
|
+
await waitForUnlock(this.adb);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* @this {AndroidDriver}
|
|
227
|
+
* @param {AndroidDriverCaps} capabilities
|
|
228
|
+
* @returns {Promise<void>}
|
|
229
|
+
*/
|
|
230
|
+
export async function passwordUnlock(capabilities) {
|
|
231
|
+
const {unlockKey} = capabilities;
|
|
232
|
+
this.log.info(`Trying to unlock device using password ${unlockKey}`);
|
|
233
|
+
await this.adb.dismissKeyguard();
|
|
234
|
+
// Replace blank spaces with %s
|
|
235
|
+
const key = encodePassword(String(unlockKey));
|
|
236
|
+
// Why adb ? It was less flaky
|
|
237
|
+
await this.adb.shell(['input', 'text', key]);
|
|
238
|
+
// Why sleeps ? Avoid some flakyness waiting for the input to receive the keys
|
|
239
|
+
await sleep(INPUT_KEYS_WAIT_TIME);
|
|
240
|
+
await this.adb.shell(['input', 'keyevent', String(KEYCODE_NUMPAD_ENTER)]);
|
|
241
|
+
// Waits a bit for the device to be unlocked
|
|
242
|
+
await waitForUnlock(this.adb);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
*
|
|
247
|
+
* @param {number} key
|
|
248
|
+
* @param {import('@appium/types').Position} initPos
|
|
249
|
+
* @param {number} piece
|
|
250
|
+
* @returns {import('@appium/types').Position}
|
|
251
|
+
*/
|
|
252
|
+
export function getPatternKeyPosition(key, initPos, piece) {
|
|
253
|
+
/*
|
|
254
|
+
How the math works:
|
|
255
|
+
We have 9 buttons divided in 3 columns and 3 rows inside the lockPatternView,
|
|
256
|
+
every button has a position on the screen corresponding to the lockPatternView since
|
|
257
|
+
it is the parent view right at the middle of each column or row.
|
|
258
|
+
*/
|
|
259
|
+
const cols = 3;
|
|
260
|
+
const pins = 9;
|
|
261
|
+
const xPos = (key, x, piece) => Math.round(x + (key % cols || cols) * piece - piece / 2);
|
|
262
|
+
const yPos = (key, y, piece) =>
|
|
263
|
+
Math.round(y + (Math.ceil((key % pins || pins) / cols) * piece - piece / 2));
|
|
264
|
+
return {
|
|
265
|
+
x: xPos(key, initPos.x, piece),
|
|
266
|
+
y: yPos(key, initPos.y, piece),
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* @param {string[]|number[]} keys
|
|
272
|
+
* @param {import('@appium/types').Position} initPos
|
|
273
|
+
* @param {number} piece
|
|
274
|
+
* @returns {import('../types').TouchAction[]}
|
|
275
|
+
*/
|
|
276
|
+
export function getPatternActions(keys, initPos, piece) {
|
|
277
|
+
/** @type {import('../types').TouchAction[]} */
|
|
278
|
+
const actions = [];
|
|
279
|
+
/** @type {number[]} */
|
|
280
|
+
const intKeys = keys.map((key) => (_.isString(key) ? _.parseInt(key) : key));
|
|
281
|
+
/** @type {import('@appium/types').Position|undefined} */
|
|
282
|
+
let lastPos;
|
|
283
|
+
for (const key of intKeys) {
|
|
284
|
+
const keyPos = getPatternKeyPosition(key, initPos, piece);
|
|
285
|
+
if (!lastPos) {
|
|
286
|
+
actions.push({action: 'press', options: {element: undefined, x: keyPos.x, y: keyPos.y}});
|
|
287
|
+
lastPos = keyPos;
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
const moveTo = {x: 0, y: 0};
|
|
291
|
+
const diffX = keyPos.x - lastPos.x;
|
|
292
|
+
if (diffX > 0) {
|
|
293
|
+
moveTo.x = piece;
|
|
294
|
+
if (Math.abs(diffX) > piece) {
|
|
295
|
+
moveTo.x += piece;
|
|
296
|
+
}
|
|
297
|
+
} else if (diffX < 0) {
|
|
298
|
+
moveTo.x = -1 * piece;
|
|
299
|
+
if (Math.abs(diffX) > piece) {
|
|
300
|
+
moveTo.x -= piece;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
const diffY = keyPos.y - lastPos.y;
|
|
304
|
+
if (diffY > 0) {
|
|
305
|
+
moveTo.y = piece;
|
|
306
|
+
if (Math.abs(diffY) > piece) {
|
|
307
|
+
moveTo.y += piece;
|
|
308
|
+
}
|
|
309
|
+
} else if (diffY < 0) {
|
|
310
|
+
moveTo.y = -1 * piece;
|
|
311
|
+
if (Math.abs(diffY) > piece) {
|
|
312
|
+
moveTo.y -= piece;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
actions.push({
|
|
316
|
+
action: 'moveTo',
|
|
317
|
+
// @ts-ignore lastPos should be defined
|
|
318
|
+
options: {element: undefined, x: moveTo.x + lastPos.x, y: moveTo.y + lastPos.y},
|
|
319
|
+
});
|
|
320
|
+
lastPos = keyPos;
|
|
321
|
+
}
|
|
322
|
+
actions.push({action: 'release'});
|
|
323
|
+
return actions;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* @this {AndroidDriver}
|
|
328
|
+
* @param {number?} [timeoutMs=null]
|
|
329
|
+
*/
|
|
330
|
+
export async function verifyUnlock(timeoutMs = null) {
|
|
331
|
+
try {
|
|
332
|
+
await waitForCondition(async () => !(await this.adb.isScreenLocked()), {
|
|
333
|
+
waitMs: timeoutMs ?? 2000,
|
|
334
|
+
intervalMs: 500,
|
|
335
|
+
});
|
|
336
|
+
} catch (ign) {
|
|
337
|
+
throw new Error('The device has failed to be unlocked');
|
|
338
|
+
}
|
|
339
|
+
this.log.info('The device has been successfully unlocked');
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* @this {AndroidDriver}
|
|
344
|
+
* @param {AndroidDriverCaps} capabilities
|
|
345
|
+
*/
|
|
346
|
+
export async function patternUnlock(capabilities) {
|
|
347
|
+
const {unlockKey} = capabilities;
|
|
348
|
+
this.log.info(`Trying to unlock device using pattern ${unlockKey}`);
|
|
349
|
+
await this.adb.dismissKeyguard();
|
|
350
|
+
const keys = stringKeyToArr(String(unlockKey));
|
|
351
|
+
/* We set the device pattern buttons as number of a regular phone
|
|
352
|
+
* | • • • | | 1 2 3 |
|
|
353
|
+
* | • • • | --> | 4 5 6 |
|
|
354
|
+
* | • • • | | 7 8 9 |
|
|
355
|
+
|
|
356
|
+
The pattern view buttons are not seeing by the uiautomator since they are
|
|
357
|
+
included inside a FrameLayout, so we are going to try clicking on the buttons
|
|
358
|
+
using the parent view bounds and math.
|
|
359
|
+
*/
|
|
360
|
+
const apiLevel = await this.adb.getApiLevel();
|
|
361
|
+
const el = await this.findElOrEls(
|
|
362
|
+
'id',
|
|
363
|
+
`com.android.${apiLevel >= 21 ? 'systemui' : 'keyguard'}:id/lockPatternView`,
|
|
364
|
+
false,
|
|
365
|
+
);
|
|
366
|
+
const initPos = await this.getLocation(util.unwrapElement(el));
|
|
367
|
+
const size = await this.getSize(util.unwrapElement(el));
|
|
368
|
+
// Get actions to perform
|
|
369
|
+
const actions = getPatternActions(keys, initPos, size.width / 3);
|
|
370
|
+
// Perform gesture
|
|
371
|
+
await this.performTouch(actions);
|
|
372
|
+
// Waits a bit for the device to be unlocked
|
|
373
|
+
await sleep(UNLOCK_WAIT_TIME);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* @typedef {import('@appium/types').Capabilities<import('../../constraints').AndroidDriverConstraints>} AndroidDriverCaps
|
|
378
|
+
* @typedef {import('../../driver').AndroidDriver} AndroidDriver
|
|
379
|
+
*/
|