appium-android-driver 12.4.9 → 12.4.11
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 +12 -0
- package/build/lib/commands/app-management.d.ts.map +1 -1
- package/build/lib/commands/app-management.js.map +1 -1
- package/build/lib/commands/appearance.d.ts +9 -9
- package/build/lib/commands/appearance.d.ts.map +1 -1
- package/build/lib/commands/appearance.js +6 -7
- package/build/lib/commands/appearance.js.map +1 -1
- package/build/lib/commands/bluetooth.d.ts +13 -7
- package/build/lib/commands/bluetooth.d.ts.map +1 -1
- package/build/lib/commands/bluetooth.js +6 -10
- package/build/lib/commands/bluetooth.js.map +1 -1
- package/build/lib/commands/deviceidle.d.ts +9 -5
- package/build/lib/commands/deviceidle.d.ts.map +1 -1
- package/build/lib/commands/deviceidle.js +5 -9
- package/build/lib/commands/deviceidle.js.map +1 -1
- package/build/lib/commands/element.d.ts +90 -66
- package/build/lib/commands/element.d.ts.map +1 -1
- package/build/lib/commands/element.js +74 -53
- package/build/lib/commands/element.js.map +1 -1
- package/build/lib/commands/execute.d.ts +12 -8
- package/build/lib/commands/execute.d.ts.map +1 -1
- package/build/lib/commands/execute.js +13 -18
- package/build/lib/commands/execute.js.map +1 -1
- package/build/lib/commands/gestures.d.ts +8 -5
- package/build/lib/commands/gestures.d.ts.map +1 -1
- package/build/lib/commands/gestures.js +5 -6
- package/build/lib/commands/gestures.js.map +1 -1
- package/build/lib/commands/image-injection.d.ts +10 -11
- package/build/lib/commands/image-injection.d.ts.map +1 -1
- package/build/lib/commands/image-injection.js +7 -16
- package/build/lib/commands/image-injection.js.map +1 -1
- package/build/lib/commands/ime.d.ts +23 -17
- package/build/lib/commands/ime.d.ts.map +1 -1
- package/build/lib/commands/ime.js +20 -17
- package/build/lib/commands/ime.js.map +1 -1
- package/build/lib/commands/keyboard.d.ts +55 -39
- package/build/lib/commands/keyboard.d.ts.map +1 -1
- package/build/lib/commands/keyboard.js +47 -33
- package/build/lib/commands/keyboard.js.map +1 -1
- package/build/lib/commands/legacy.d.ts +16 -7
- package/build/lib/commands/legacy.d.ts.map +1 -1
- package/build/lib/commands/legacy.js +12 -6
- package/build/lib/commands/legacy.js.map +1 -1
- package/build/lib/commands/log.d.ts +7 -7
- package/build/lib/commands/log.d.ts.map +1 -1
- package/build/lib/commands/log.js +0 -1
- package/build/lib/commands/log.js.map +1 -1
- package/build/lib/commands/media-projection.d.ts +32 -36
- package/build/lib/commands/media-projection.d.ts.map +1 -1
- package/build/lib/commands/media-projection.js +27 -54
- package/build/lib/commands/media-projection.js.map +1 -1
- package/build/lib/commands/memory.d.ts +7 -7
- package/build/lib/commands/memory.d.ts.map +1 -1
- package/build/lib/commands/memory.js +4 -8
- package/build/lib/commands/memory.js.map +1 -1
- package/build/lib/commands/misc.d.ts +38 -26
- package/build/lib/commands/misc.d.ts.map +1 -1
- package/build/lib/commands/misc.js +31 -24
- package/build/lib/commands/misc.js.map +1 -1
- package/build/lib/commands/nfc.d.ts +7 -7
- package/build/lib/commands/nfc.d.ts.map +1 -1
- package/build/lib/commands/nfc.js +6 -10
- package/build/lib/commands/nfc.js.map +1 -1
- package/build/lib/commands/performance.d.ts.map +1 -1
- package/build/lib/commands/performance.js.map +1 -1
- package/build/lib/commands/permissions.d.ts +47 -19
- package/build/lib/commands/permissions.d.ts.map +1 -1
- package/build/lib/commands/permissions.js +21 -36
- package/build/lib/commands/permissions.js.map +1 -1
- package/build/lib/commands/resources.d.ts +16 -16
- package/build/lib/commands/resources.d.ts.map +1 -1
- package/build/lib/commands/resources.js +12 -38
- package/build/lib/commands/resources.js.map +1 -1
- package/build/lib/commands/shell.d.ts.map +1 -1
- package/build/lib/commands/shell.js +1 -1
- package/build/lib/commands/shell.js.map +1 -1
- package/build/lib/commands/system-bars.d.ts +27 -21
- package/build/lib/commands/system-bars.d.ts.map +1 -1
- package/build/lib/commands/system-bars.js +23 -40
- package/build/lib/commands/system-bars.js.map +1 -1
- package/build/lib/commands/time.d.ts +17 -14
- package/build/lib/commands/time.d.ts.map +1 -1
- package/build/lib/commands/time.js +13 -13
- package/build/lib/commands/time.js.map +1 -1
- package/build/lib/commands/types.d.ts +17 -0
- package/build/lib/commands/types.d.ts.map +1 -1
- package/lib/commands/app-management.ts +3 -3
- package/lib/commands/{appearance.js → appearance.ts} +17 -9
- package/lib/commands/{bluetooth.js → bluetooth.ts} +13 -11
- package/lib/commands/{deviceidle.js → deviceidle.ts} +13 -12
- package/lib/commands/element.ts +234 -0
- package/lib/commands/{execute.js → execute.ts} +24 -19
- package/lib/commands/gestures.ts +19 -0
- package/lib/commands/{image-injection.js → image-injection.ts} +17 -19
- package/lib/commands/ime.ts +79 -0
- package/lib/commands/keyboard.ts +163 -0
- package/lib/commands/legacy.ts +41 -0
- package/lib/commands/log.ts +9 -9
- package/lib/commands/{media-projection.js → media-projection.ts} +69 -68
- package/lib/commands/memory.ts +29 -0
- package/lib/commands/misc.ts +118 -0
- package/lib/commands/{nfc.js → nfc.ts} +12 -11
- package/lib/commands/performance.ts +2 -1
- package/lib/commands/{permissions.js → permissions.ts} +58 -50
- package/lib/commands/{resources.js → resources.ts} +44 -52
- package/lib/commands/shell.ts +2 -1
- package/lib/commands/{system-bars.js → system-bars.ts} +59 -50
- package/lib/commands/{time.js → time.ts} +26 -16
- package/lib/commands/types.ts +27 -0
- package/package.json +1 -1
- package/lib/commands/element.js +0 -158
- package/lib/commands/gestures.js +0 -15
- package/lib/commands/ime.js +0 -64
- package/lib/commands/keyboard.js +0 -119
- package/lib/commands/legacy.js +0 -28
- package/lib/commands/memory.js +0 -27
- package/lib/commands/misc.js +0 -92
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
+
|
|
3
|
+
import {errors} from 'appium/driver';
|
|
4
|
+
import type {Position, Size} from '@appium/types';
|
|
5
|
+
import type {AndroidDriver} from '../driver';
|
|
6
|
+
import type {DoSetElementValueOpts} from './types';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Gets an attribute value from an element.
|
|
10
|
+
*
|
|
11
|
+
* @param attribute The name of the attribute to retrieve.
|
|
12
|
+
* @param elementId The element identifier.
|
|
13
|
+
* @returns Promise that resolves to the attribute value, or `null` if not found.
|
|
14
|
+
* @throws {errors.NotImplementedError} This method is not implemented.
|
|
15
|
+
*/
|
|
16
|
+
export async function getAttribute(
|
|
17
|
+
this: AndroidDriver,
|
|
18
|
+
attribute: string,
|
|
19
|
+
elementId: string,
|
|
20
|
+
): Promise<string | null> {
|
|
21
|
+
throw new errors.NotImplementedError('Not implemented');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Clicks on an element.
|
|
26
|
+
*
|
|
27
|
+
* @param elementId The element identifier.
|
|
28
|
+
* @returns Promise that resolves when the click is performed.
|
|
29
|
+
* @throws {errors.NotImplementedError} This method is not implemented.
|
|
30
|
+
*/
|
|
31
|
+
export async function click(
|
|
32
|
+
this: AndroidDriver,
|
|
33
|
+
elementId: string,
|
|
34
|
+
): Promise<void> {
|
|
35
|
+
throw new errors.NotImplementedError('Not implemented');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Gets the text content of an element.
|
|
40
|
+
*
|
|
41
|
+
* @param elementId The element identifier.
|
|
42
|
+
* @returns Promise that resolves to the element's text content.
|
|
43
|
+
* @throws {errors.NotImplementedError} This method is not implemented.
|
|
44
|
+
*/
|
|
45
|
+
export async function getText(
|
|
46
|
+
this: AndroidDriver,
|
|
47
|
+
elementId: string,
|
|
48
|
+
): Promise<string> {
|
|
49
|
+
throw new errors.NotImplementedError('Not implemented');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Gets the location of an element on the screen.
|
|
54
|
+
*
|
|
55
|
+
* @param elementId The element identifier.
|
|
56
|
+
* @returns Promise that resolves to the element's position (x, y coordinates).
|
|
57
|
+
* @throws {errors.NotImplementedError} This method is not implemented.
|
|
58
|
+
*/
|
|
59
|
+
export async function getLocation(
|
|
60
|
+
this: AndroidDriver,
|
|
61
|
+
elementId: string,
|
|
62
|
+
): Promise<Position> {
|
|
63
|
+
throw new errors.NotImplementedError('Not implemented');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Gets the size of an element.
|
|
68
|
+
*
|
|
69
|
+
* @param elementId The element identifier.
|
|
70
|
+
* @returns Promise that resolves to the element's size (width, height).
|
|
71
|
+
* @throws {errors.NotImplementedError} This method is not implemented.
|
|
72
|
+
*/
|
|
73
|
+
export async function getSize(
|
|
74
|
+
this: AndroidDriver,
|
|
75
|
+
elementId: string,
|
|
76
|
+
): Promise<Size> {
|
|
77
|
+
throw new errors.NotImplementedError('Not implemented');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Gets the class name of an element.
|
|
82
|
+
*
|
|
83
|
+
* @param elementId The element identifier.
|
|
84
|
+
* @returns Promise that resolves to the element's class name.
|
|
85
|
+
*/
|
|
86
|
+
export async function getName(
|
|
87
|
+
this: AndroidDriver,
|
|
88
|
+
elementId: string,
|
|
89
|
+
): Promise<string> {
|
|
90
|
+
return await this.getAttribute('className', elementId) as string;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Checks if an element is displayed.
|
|
95
|
+
*
|
|
96
|
+
* @param elementId The element identifier.
|
|
97
|
+
* @returns Promise that resolves to `true` if the element is displayed, `false` otherwise.
|
|
98
|
+
*/
|
|
99
|
+
export async function elementDisplayed(
|
|
100
|
+
this: AndroidDriver,
|
|
101
|
+
elementId: string,
|
|
102
|
+
): Promise<boolean> {
|
|
103
|
+
return (await this.getAttribute('displayed', elementId)) === 'true';
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Checks if an element is enabled.
|
|
108
|
+
*
|
|
109
|
+
* @param elementId The element identifier.
|
|
110
|
+
* @returns Promise that resolves to `true` if the element is enabled, `false` otherwise.
|
|
111
|
+
*/
|
|
112
|
+
export async function elementEnabled(
|
|
113
|
+
this: AndroidDriver,
|
|
114
|
+
elementId: string,
|
|
115
|
+
): Promise<boolean> {
|
|
116
|
+
return (await this.getAttribute('enabled', elementId)) === 'true';
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Checks if an element is selected.
|
|
121
|
+
*
|
|
122
|
+
* @param elementId The element identifier.
|
|
123
|
+
* @returns Promise that resolves to `true` if the element is selected, `false` otherwise.
|
|
124
|
+
*/
|
|
125
|
+
export async function elementSelected(
|
|
126
|
+
this: AndroidDriver,
|
|
127
|
+
elementId: string,
|
|
128
|
+
): Promise<boolean> {
|
|
129
|
+
return (await this.getAttribute('selected', elementId)) === 'true';
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Sets the value of an element.
|
|
134
|
+
*
|
|
135
|
+
* @param keys The text to set, either as a string or an array of strings (which will be joined).
|
|
136
|
+
* @param elementId The element identifier.
|
|
137
|
+
* @param replace If `true`, replaces the existing value. If `false`, appends to it. Defaults to `false`.
|
|
138
|
+
* @returns Promise that resolves when the value is set.
|
|
139
|
+
*/
|
|
140
|
+
export async function setElementValue(
|
|
141
|
+
this: AndroidDriver,
|
|
142
|
+
keys: string | string[],
|
|
143
|
+
elementId: string,
|
|
144
|
+
replace = false,
|
|
145
|
+
): Promise<void> {
|
|
146
|
+
const text = keys instanceof Array ? keys.join('') : keys;
|
|
147
|
+
return await this.doSetElementValue({
|
|
148
|
+
elementId,
|
|
149
|
+
text: String(text),
|
|
150
|
+
replace,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Sets the value of an element.
|
|
156
|
+
*
|
|
157
|
+
* Reason for isolating doSetElementValue from setElementValue is for reusing setElementValue
|
|
158
|
+
* across android-drivers (like appium-uiautomator2-driver) and to avoid code duplication.
|
|
159
|
+
* Other android-drivers (like appium-uiautomator2-driver) need to override doSetElementValue
|
|
160
|
+
* to facilitate setElementValue.
|
|
161
|
+
*
|
|
162
|
+
* @param params The parameters for setting the element value.
|
|
163
|
+
* @returns Promise that resolves when the value is set.
|
|
164
|
+
* @throws {errors.NotImplementedError} This method is not implemented.
|
|
165
|
+
*/
|
|
166
|
+
export async function doSetElementValue(
|
|
167
|
+
this: AndroidDriver,
|
|
168
|
+
params: DoSetElementValueOpts,
|
|
169
|
+
): Promise<void> {
|
|
170
|
+
throw new errors.NotImplementedError('Not implemented');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Sets the value of an element (appends to existing value).
|
|
175
|
+
*
|
|
176
|
+
* @param keys The text to set, either as a string or an array of strings (which will be joined).
|
|
177
|
+
* @param elementId The element identifier.
|
|
178
|
+
* @returns Promise that resolves when the value is set.
|
|
179
|
+
*/
|
|
180
|
+
export async function setValue(
|
|
181
|
+
this: AndroidDriver,
|
|
182
|
+
keys: string | string[],
|
|
183
|
+
elementId: string,
|
|
184
|
+
): Promise<void> {
|
|
185
|
+
return await this.setElementValue(keys, elementId, false);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Replaces the value of an element.
|
|
190
|
+
*
|
|
191
|
+
* @param keys The text to set, either as a string or an array of strings (which will be joined).
|
|
192
|
+
* @param elementId The element identifier.
|
|
193
|
+
* @returns Promise that resolves when the value is replaced.
|
|
194
|
+
*/
|
|
195
|
+
export async function replaceValue(
|
|
196
|
+
this: AndroidDriver,
|
|
197
|
+
keys: string | string[],
|
|
198
|
+
elementId: string,
|
|
199
|
+
): Promise<void> {
|
|
200
|
+
return await this.setElementValue(keys, elementId, true);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Sets the value of an element immediately using ADB input.
|
|
205
|
+
*
|
|
206
|
+
* @param keys The text to set, either as a string or an array of strings (which will be joined).
|
|
207
|
+
* @param elementId The element identifier.
|
|
208
|
+
* @returns Promise that resolves when the value is set.
|
|
209
|
+
*/
|
|
210
|
+
export async function setValueImmediate(
|
|
211
|
+
this: AndroidDriver,
|
|
212
|
+
keys: string | string[],
|
|
213
|
+
elementId: string,
|
|
214
|
+
): Promise<void> {
|
|
215
|
+
const text = Array.isArray(keys) ? keys.join('') : keys;
|
|
216
|
+
// first, make sure we are focused on the element
|
|
217
|
+
await this.click(elementId);
|
|
218
|
+
// then send through adb
|
|
219
|
+
await this.adb.inputText(text);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Gets the location of an element relative to the view.
|
|
224
|
+
*
|
|
225
|
+
* @param elementId The element identifier.
|
|
226
|
+
* @returns Promise that resolves to the element's position (x, y coordinates).
|
|
227
|
+
*/
|
|
228
|
+
export async function getLocationInView(
|
|
229
|
+
this: AndroidDriver,
|
|
230
|
+
elementId: string,
|
|
231
|
+
): Promise<Position> {
|
|
232
|
+
return await this.getLocation(elementId);
|
|
233
|
+
}
|
|
234
|
+
|
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
2
|
import {errors, PROTOCOLS} from 'appium/driver';
|
|
3
3
|
import { util } from '@appium/support';
|
|
4
|
+
import type {StringRecord, Element} from '@appium/types';
|
|
5
|
+
import type {AndroidDriver} from '../driver';
|
|
6
|
+
import type {Chromedriver} from 'appium-chromedriver';
|
|
4
7
|
|
|
5
8
|
const EXECUTE_SCRIPT_PREFIX = 'mobile:';
|
|
6
9
|
|
|
7
10
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* @param
|
|
11
|
-
*
|
|
11
|
+
* Executes a script on the device or in a web context.
|
|
12
|
+
*
|
|
13
|
+
* @param script The script to execute. If it starts with 'mobile:', it will be treated
|
|
14
|
+
* as a mobile command. Otherwise, it will be executed in the web context (if available).
|
|
15
|
+
* @param args Optional arguments to pass to the script.
|
|
16
|
+
* @returns Promise that resolves to the script execution result.
|
|
17
|
+
* @throws {errors.NotImplementedError} If not in a web context and script doesn't start with 'mobile:'.
|
|
12
18
|
*/
|
|
13
|
-
export async function execute(
|
|
19
|
+
export async function execute(
|
|
20
|
+
this: AndroidDriver,
|
|
21
|
+
script: string,
|
|
22
|
+
args?: ExecuteMethodArgs,
|
|
23
|
+
): Promise<any> {
|
|
14
24
|
if (_.startsWith(script, EXECUTE_SCRIPT_PREFIX)) {
|
|
15
25
|
const formattedScript = script.trim().replace(/^mobile:\s*/, `${EXECUTE_SCRIPT_PREFIX} `);
|
|
16
26
|
const executeMethodArgs = preprocessExecuteMethodArgs(args);
|
|
@@ -20,13 +30,11 @@ export async function execute(script, args) {
|
|
|
20
30
|
throw new errors.NotImplementedError();
|
|
21
31
|
}
|
|
22
32
|
const endpoint =
|
|
23
|
-
|
|
33
|
+
(this.chromedriver as Chromedriver).jwproxy
|
|
24
34
|
.downstreamProtocol === PROTOCOLS.MJSONWP
|
|
25
35
|
? '/execute'
|
|
26
36
|
: '/execute/sync';
|
|
27
|
-
return await
|
|
28
|
-
this.chromedriver
|
|
29
|
-
).jwproxy.command(endpoint, 'POST', {
|
|
37
|
+
return await (this.chromedriver as Chromedriver).jwproxy.command(endpoint, 'POST', {
|
|
30
38
|
script,
|
|
31
39
|
args,
|
|
32
40
|
});
|
|
@@ -37,11 +45,11 @@ export async function execute(script, args) {
|
|
|
37
45
|
/**
|
|
38
46
|
* Massages the arguments going into an execute method.
|
|
39
47
|
*
|
|
40
|
-
* @param
|
|
41
|
-
* @returns
|
|
48
|
+
* @param args Optional arguments to preprocess.
|
|
49
|
+
* @returns Preprocessed arguments as a StringRecord.
|
|
42
50
|
*/
|
|
43
|
-
function preprocessExecuteMethodArgs(args) {
|
|
44
|
-
const executeMethodArgs =
|
|
51
|
+
function preprocessExecuteMethodArgs(args?: ExecuteMethodArgs): StringRecord {
|
|
52
|
+
const executeMethodArgs = (_.isArray(args) ? _.first(args) : args) ?? {} as StringRecord;
|
|
45
53
|
|
|
46
54
|
/**
|
|
47
55
|
* Renames the deprecated `element` key to `elementId`. Historically,
|
|
@@ -57,7 +65,7 @@ function preprocessExecuteMethodArgs(args) {
|
|
|
57
65
|
*/
|
|
58
66
|
if ('elementId' in executeMethodArgs) {
|
|
59
67
|
executeMethodArgs.elementId = util.unwrapElement(
|
|
60
|
-
|
|
68
|
+
executeMethodArgs.elementId as Element | string,
|
|
61
69
|
);
|
|
62
70
|
}
|
|
63
71
|
|
|
@@ -66,8 +74,5 @@ function preprocessExecuteMethodArgs(args) {
|
|
|
66
74
|
|
|
67
75
|
// #endregion
|
|
68
76
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
* @typedef {import('@appium/types').StringRecord} StringRecord
|
|
72
|
-
* @typedef {readonly any[] | readonly [StringRecord] | Readonly<StringRecord>} ExecuteMethodArgs
|
|
73
|
-
*/
|
|
77
|
+
type ExecuteMethodArgs = readonly any[] | readonly [StringRecord] | Readonly<StringRecord>;
|
|
78
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
+
import {errors} from 'appium/driver';
|
|
3
|
+
import type {StringRecord} from '@appium/types';
|
|
4
|
+
import type {AndroidDriver} from '../driver';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Performs a series of actions (gestures) on the device.
|
|
8
|
+
*
|
|
9
|
+
* @param actions An array of action objects to perform.
|
|
10
|
+
* @returns Promise that resolves when all actions are performed.
|
|
11
|
+
* @throws {errors.NotImplementedError} This method is not implemented.
|
|
12
|
+
*/
|
|
13
|
+
export async function performActions(
|
|
14
|
+
this: AndroidDriver,
|
|
15
|
+
actions: StringRecord[],
|
|
16
|
+
): Promise<void> {
|
|
17
|
+
throw new errors.NotImplementedError('Not implemented');
|
|
18
|
+
}
|
|
19
|
+
|
|
@@ -3,6 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
import {fs, tempDir} from '@appium/support';
|
|
4
4
|
import crypto from 'node:crypto';
|
|
5
5
|
import _ from 'lodash';
|
|
6
|
+
import type {AndroidDriver} from '../driver';
|
|
6
7
|
|
|
7
8
|
const EMULATOR_RESOURCES_ROOT = ['emulator', 'resources'];
|
|
8
9
|
const CONFIG_NAME = 'Toren1BD.posters';
|
|
@@ -25,13 +26,15 @@ const PNG_MAGIC_LENGTH = 4;
|
|
|
25
26
|
* Updates the emulator configuration to show the
|
|
26
27
|
* image using the given properties when one opens the Camera app.
|
|
27
28
|
*
|
|
28
|
-
* @
|
|
29
|
-
* @
|
|
30
|
-
*
|
|
31
|
-
* to load the updated config or false if the current config is already up to date
|
|
29
|
+
* @param sdkRoot ADB SDK root folder path
|
|
30
|
+
* @returns Promise that resolves to `true` if emulator services restart is needed
|
|
31
|
+
* to load the updated config or `false` if the current config is already up to date
|
|
32
32
|
* or does not need to be updated
|
|
33
33
|
*/
|
|
34
|
-
export async function prepareEmulatorForImageInjection(
|
|
34
|
+
export async function prepareEmulatorForImageInjection(
|
|
35
|
+
this: AndroidDriver,
|
|
36
|
+
sdkRoot: string,
|
|
37
|
+
): Promise<boolean> {
|
|
35
38
|
const { injectedImageProperties: props } = this.opts;
|
|
36
39
|
if (!props) {
|
|
37
40
|
return false;
|
|
@@ -74,11 +77,15 @@ export async function prepareEmulatorForImageInjection(sdkRoot) {
|
|
|
74
77
|
* already prepared and loaded either manually or using the
|
|
75
78
|
* `injectedImageProperties` capability.
|
|
76
79
|
*
|
|
77
|
-
* @
|
|
78
|
-
* @
|
|
79
|
-
* @
|
|
80
|
+
* @param payload Base64-encoded payload of a .png image to be injected
|
|
81
|
+
* @returns Promise that resolves when the image is injected.
|
|
82
|
+
* @throws {Error} If called on a non-emulator device.
|
|
83
|
+
* @throws {errors.InvalidArgumentError} If the payload is not a valid base64-encoded PNG.
|
|
80
84
|
*/
|
|
81
|
-
export async function mobileInjectEmulatorCameraImage(
|
|
85
|
+
export async function mobileInjectEmulatorCameraImage(
|
|
86
|
+
this: AndroidDriver,
|
|
87
|
+
payload: string,
|
|
88
|
+
): Promise<void> {
|
|
82
89
|
if (!this.isEmulator()) {
|
|
83
90
|
throw new Error('The image injection feature is only available on emulators');
|
|
84
91
|
}
|
|
@@ -110,12 +117,7 @@ export async function mobileInjectEmulatorCameraImage(payload) {
|
|
|
110
117
|
|
|
111
118
|
// #region Internal helpers
|
|
112
119
|
|
|
113
|
-
|
|
114
|
-
*
|
|
115
|
-
* @param {Buffer} buffer
|
|
116
|
-
* @returns {string}
|
|
117
|
-
*/
|
|
118
|
-
function calculateImageHash(buffer) {
|
|
120
|
+
function calculateImageHash(buffer: Buffer): string {
|
|
119
121
|
const hasher = crypto.createHash('sha1');
|
|
120
122
|
hasher.update(buffer);
|
|
121
123
|
return hasher.digest('hex');
|
|
@@ -123,7 +125,3 @@ function calculateImageHash(buffer) {
|
|
|
123
125
|
|
|
124
126
|
// #endregion
|
|
125
127
|
|
|
126
|
-
/**
|
|
127
|
-
* @typedef {import('appium-adb').ADB} ADB
|
|
128
|
-
* @typedef {import('../driver').AndroidDriver} AndroidDriver
|
|
129
|
-
*/
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import {errors} from 'appium/driver';
|
|
2
|
+
import type {AndroidDriver} from '../driver';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Checks if an IME (Input Method Editor) is activated.
|
|
6
|
+
*
|
|
7
|
+
* @returns Promise that resolves to `true` (IME is always activated on Android devices).
|
|
8
|
+
*/
|
|
9
|
+
export async function isIMEActivated(
|
|
10
|
+
this: AndroidDriver,
|
|
11
|
+
): Promise<boolean> {
|
|
12
|
+
// IME is always activated on Android devices
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Gets the list of available IME engines.
|
|
18
|
+
*
|
|
19
|
+
* @returns Promise that resolves to an array of IME engine identifiers.
|
|
20
|
+
*/
|
|
21
|
+
export async function availableIMEEngines(
|
|
22
|
+
this: AndroidDriver,
|
|
23
|
+
): Promise<string[]> {
|
|
24
|
+
this.log.debug('Retrieving available IMEs');
|
|
25
|
+
const engines = await this.adb.availableIMEs();
|
|
26
|
+
this.log.debug(`Engines: ${JSON.stringify(engines)}`);
|
|
27
|
+
return engines;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Gets the currently active IME engine.
|
|
32
|
+
*
|
|
33
|
+
* @returns Promise that resolves to the active IME engine identifier.
|
|
34
|
+
*/
|
|
35
|
+
export async function getActiveIMEEngine(
|
|
36
|
+
this: AndroidDriver,
|
|
37
|
+
): Promise<string> {
|
|
38
|
+
this.log.debug('Retrieving current default IME');
|
|
39
|
+
return String(await this.adb.defaultIME());
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Activates an IME engine.
|
|
44
|
+
*
|
|
45
|
+
* @param imeId The IME engine identifier to activate.
|
|
46
|
+
* @returns Promise that resolves when the IME is activated.
|
|
47
|
+
* @throws {errors.IMENotAvailableError} If the IME is not available.
|
|
48
|
+
*/
|
|
49
|
+
export async function activateIMEEngine(
|
|
50
|
+
this: AndroidDriver,
|
|
51
|
+
imeId: string,
|
|
52
|
+
): Promise<void> {
|
|
53
|
+
this.log.debug(`Attempting to activate IME ${imeId}`);
|
|
54
|
+
const availableEngines = await this.adb.availableIMEs();
|
|
55
|
+
if (availableEngines.indexOf(imeId) === -1) {
|
|
56
|
+
this.log.debug('IME not found, failing');
|
|
57
|
+
throw new errors.IMENotAvailableError();
|
|
58
|
+
}
|
|
59
|
+
this.log.debug('Found installed IME, attempting to activate');
|
|
60
|
+
await this.adb.enableIME(imeId);
|
|
61
|
+
await this.adb.setIME(imeId);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Deactivates the currently active IME engine.
|
|
66
|
+
*
|
|
67
|
+
* @returns Promise that resolves when the IME is deactivated.
|
|
68
|
+
*/
|
|
69
|
+
export async function deactivateIMEEngine(
|
|
70
|
+
this: AndroidDriver,
|
|
71
|
+
): Promise<void> {
|
|
72
|
+
const currentEngine = await this.getActiveIMEEngine();
|
|
73
|
+
// XXX: this allowed 'null' to be passed into `adb.shell`
|
|
74
|
+
if (currentEngine) {
|
|
75
|
+
this.log.debug(`Attempting to deactivate ${currentEngine}`);
|
|
76
|
+
await this.adb.disableIME(currentEngine);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
+
import _ from 'lodash';
|
|
3
|
+
import {errors} from 'appium/driver';
|
|
4
|
+
import {UNICODE_IME, EMPTY_IME} from 'io.appium.settings';
|
|
5
|
+
import type {AndroidDriver} from '../driver';
|
|
6
|
+
import type {SendKeysOpts} from './types';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Hides the on-screen keyboard.
|
|
10
|
+
*
|
|
11
|
+
* @returns Promise that resolves to `true` if the keyboard was hidden, `false` otherwise.
|
|
12
|
+
*/
|
|
13
|
+
export async function hideKeyboard(
|
|
14
|
+
this: AndroidDriver,
|
|
15
|
+
): Promise<boolean> {
|
|
16
|
+
return await this.adb.hideKeyboard();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Checks if the on-screen keyboard is currently shown.
|
|
21
|
+
*
|
|
22
|
+
* @returns Promise that resolves to `true` if the keyboard is shown, `false` otherwise.
|
|
23
|
+
*/
|
|
24
|
+
export async function isKeyboardShown(
|
|
25
|
+
this: AndroidDriver,
|
|
26
|
+
): Promise<boolean> {
|
|
27
|
+
const {isKeyboardShown} = await this.adb.isSoftKeyboardPresent();
|
|
28
|
+
return isKeyboardShown;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Sends keys to the active element.
|
|
33
|
+
*
|
|
34
|
+
* @param keys The keys to send, either as a string or an array of strings (which will be joined).
|
|
35
|
+
* @returns Promise that resolves when the keys are sent.
|
|
36
|
+
*/
|
|
37
|
+
export async function keys(
|
|
38
|
+
this: AndroidDriver,
|
|
39
|
+
keys: string | string[],
|
|
40
|
+
): Promise<void> {
|
|
41
|
+
// Protocol sends an array; rethink approach
|
|
42
|
+
const keysStr = _.isArray(keys) ? keys.join('') : keys;
|
|
43
|
+
await this.doSendKeys({
|
|
44
|
+
text: keysStr,
|
|
45
|
+
replace: false,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Sends keys to the active element.
|
|
51
|
+
*
|
|
52
|
+
* @param params The parameters for sending keys.
|
|
53
|
+
* @returns Promise that resolves when the keys are sent.
|
|
54
|
+
* @throws {errors.NotImplementedError} This method is not implemented.
|
|
55
|
+
*/
|
|
56
|
+
export async function doSendKeys(
|
|
57
|
+
this: AndroidDriver,
|
|
58
|
+
params: SendKeysOpts,
|
|
59
|
+
): Promise<void> {
|
|
60
|
+
throw new errors.NotImplementedError('Not implemented');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Sends a key event to the device.
|
|
65
|
+
*
|
|
66
|
+
* @deprecated Use {@link pressKeyCode} instead.
|
|
67
|
+
* @param keycode The key code to press.
|
|
68
|
+
* @param metastate Optional meta state flags.
|
|
69
|
+
* @returns Promise that resolves when the key event is sent.
|
|
70
|
+
*/
|
|
71
|
+
export async function keyevent(
|
|
72
|
+
this: AndroidDriver,
|
|
73
|
+
keycode: string | number,
|
|
74
|
+
metastate?: number,
|
|
75
|
+
): Promise<void> {
|
|
76
|
+
// TODO deprecate keyevent; currently wd only implements keyevent
|
|
77
|
+
this.log.warn('keyevent will be deprecated use pressKeyCode');
|
|
78
|
+
return await this.pressKeyCode(keycode, metastate);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Presses a key code on the device.
|
|
83
|
+
*
|
|
84
|
+
* @param keycode The key code to press.
|
|
85
|
+
* @param metastate Optional meta state flags.
|
|
86
|
+
* @returns Promise that resolves when the key code is pressed.
|
|
87
|
+
* @throws {errors.NotImplementedError} This method is not implemented.
|
|
88
|
+
*/
|
|
89
|
+
export async function pressKeyCode(
|
|
90
|
+
this: AndroidDriver,
|
|
91
|
+
keycode: string | number,
|
|
92
|
+
metastate?: number,
|
|
93
|
+
): Promise<void> {
|
|
94
|
+
throw new errors.NotImplementedError('Not implemented');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Long presses a key code on the device.
|
|
99
|
+
*
|
|
100
|
+
* @param keycode The key code to long press.
|
|
101
|
+
* @param metastate Optional meta state flags.
|
|
102
|
+
* @returns Promise that resolves when the key code is long pressed.
|
|
103
|
+
* @throws {errors.NotImplementedError} This method is not implemented.
|
|
104
|
+
*/
|
|
105
|
+
export async function longPressKeyCode(
|
|
106
|
+
this: AndroidDriver,
|
|
107
|
+
keycode: string | number,
|
|
108
|
+
metastate?: number,
|
|
109
|
+
): Promise<void> {
|
|
110
|
+
throw new errors.NotImplementedError('Not implemented');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Performs an editor action on the active input field.
|
|
115
|
+
*
|
|
116
|
+
* @param action The editor action to perform (e.g., 'done', 'go', 'next').
|
|
117
|
+
* @returns Promise that resolves when the editor action is performed.
|
|
118
|
+
*/
|
|
119
|
+
export async function mobilePerformEditorAction(
|
|
120
|
+
this: AndroidDriver,
|
|
121
|
+
action: string | number,
|
|
122
|
+
): Promise<void> {
|
|
123
|
+
await this.settingsApp.performEditorAction(action);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// #region Internal Helpers
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Initializes Unicode keyboard support.
|
|
130
|
+
*
|
|
131
|
+
* @deprecated
|
|
132
|
+
* @returns Promise that resolves to the default IME identifier that was active before.
|
|
133
|
+
*/
|
|
134
|
+
export async function initUnicodeKeyboard(
|
|
135
|
+
this: AndroidDriver,
|
|
136
|
+
): Promise<string | null> {
|
|
137
|
+
this.log.debug('Enabling Unicode keyboard support');
|
|
138
|
+
|
|
139
|
+
// get the default IME so we can return back to it later if we want
|
|
140
|
+
const defaultIME = await this.adb.defaultIME();
|
|
141
|
+
|
|
142
|
+
this.log.debug(`Unsetting previous IME ${defaultIME}`);
|
|
143
|
+
this.log.debug(`Setting IME to '${UNICODE_IME}'`);
|
|
144
|
+
await this.adb.enableIME(UNICODE_IME);
|
|
145
|
+
await this.adb.setIME(UNICODE_IME);
|
|
146
|
+
return defaultIME;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Hides the on-screen keyboard completely by setting IME to empty.
|
|
151
|
+
*
|
|
152
|
+
* @returns Promise that resolves when the keyboard is hidden.
|
|
153
|
+
*/
|
|
154
|
+
export async function hideKeyboardCompletely(
|
|
155
|
+
this: AndroidDriver,
|
|
156
|
+
): Promise<void> {
|
|
157
|
+
this.log.debug(`Hiding the on-screen keyboard by setting IME to '${EMPTY_IME}'`);
|
|
158
|
+
await this.adb.enableIME(EMPTY_IME);
|
|
159
|
+
await this.adb.setIME(EMPTY_IME);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// #endregion
|
|
163
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { errors } from 'appium/driver';
|
|
2
|
+
import type {AndroidDriver} from '../driver';
|
|
3
|
+
|
|
4
|
+
const ISSUE_URL = 'https://github.com/appium/appium/issues/15807';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Launches the application.
|
|
8
|
+
*
|
|
9
|
+
* @returns Promise that resolves when the app is launched.
|
|
10
|
+
* @throws {errors.UnsupportedOperationError} This API is not supported anymore.
|
|
11
|
+
*/
|
|
12
|
+
export async function launchApp(
|
|
13
|
+
this: AndroidDriver,
|
|
14
|
+
): Promise<void> {
|
|
15
|
+
throw new errors.UnsupportedOperationError(`This API is not supported anymore. See ${ISSUE_URL}`);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Closes the application.
|
|
20
|
+
*
|
|
21
|
+
* @returns Promise that resolves when the app is closed.
|
|
22
|
+
* @throws {errors.UnsupportedOperationError} This API is not supported anymore.
|
|
23
|
+
*/
|
|
24
|
+
export async function closeApp(
|
|
25
|
+
this: AndroidDriver,
|
|
26
|
+
): Promise<void> {
|
|
27
|
+
throw new errors.UnsupportedOperationError(`This API is not supported anymore. See ${ISSUE_URL}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Resets the application state.
|
|
32
|
+
*
|
|
33
|
+
* @returns Promise that resolves when the app is reset.
|
|
34
|
+
* @throws {errors.UnsupportedOperationError} This API is not supported anymore.
|
|
35
|
+
*/
|
|
36
|
+
export async function reset(
|
|
37
|
+
this: AndroidDriver,
|
|
38
|
+
): Promise<void> {
|
|
39
|
+
throw new errors.UnsupportedOperationError(`This API is not supported anymore. See ${ISSUE_URL}`);
|
|
40
|
+
}
|
|
41
|
+
|