appium-android-driver 9.15.0 → 10.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.
Files changed (135) hide show
  1. package/CHANGELOG.md +121 -0
  2. package/build/lib/commands/app-management.d.ts +39 -26
  3. package/build/lib/commands/app-management.d.ts.map +1 -1
  4. package/build/lib/commands/app-management.js +59 -42
  5. package/build/lib/commands/app-management.js.map +1 -1
  6. package/build/lib/commands/appearance.d.ts +10 -4
  7. package/build/lib/commands/appearance.d.ts.map +1 -1
  8. package/build/lib/commands/appearance.js +10 -7
  9. package/build/lib/commands/appearance.js.map +1 -1
  10. package/build/lib/commands/bluetooth.d.ts +2 -2
  11. package/build/lib/commands/bluetooth.d.ts.map +1 -1
  12. package/build/lib/commands/bluetooth.js +2 -3
  13. package/build/lib/commands/bluetooth.js.map +1 -1
  14. package/build/lib/commands/context/exports.d.ts +2 -2
  15. package/build/lib/commands/context/exports.d.ts.map +1 -1
  16. package/build/lib/commands/context/exports.js +3 -3
  17. package/build/lib/commands/context/exports.js.map +1 -1
  18. package/build/lib/commands/device/emulator-actions.d.ts +25 -18
  19. package/build/lib/commands/device/emulator-actions.d.ts.map +1 -1
  20. package/build/lib/commands/device/emulator-actions.js +38 -40
  21. package/build/lib/commands/device/emulator-actions.js.map +1 -1
  22. package/build/lib/commands/device/emulator-console.d.ts +9 -2
  23. package/build/lib/commands/device/emulator-console.d.ts.map +1 -1
  24. package/build/lib/commands/device/emulator-console.js +9 -3
  25. package/build/lib/commands/device/emulator-console.js.map +1 -1
  26. package/build/lib/commands/deviceidle.d.ts +3 -2
  27. package/build/lib/commands/deviceidle.d.ts.map +1 -1
  28. package/build/lib/commands/deviceidle.js +3 -3
  29. package/build/lib/commands/deviceidle.js.map +1 -1
  30. package/build/lib/commands/execute.d.ts +6 -15
  31. package/build/lib/commands/execute.d.ts.map +1 -1
  32. package/build/lib/commands/execute.js +36 -93
  33. package/build/lib/commands/execute.js.map +1 -1
  34. package/build/lib/commands/file-actions.d.ts +13 -24
  35. package/build/lib/commands/file-actions.d.ts.map +1 -1
  36. package/build/lib/commands/file-actions.js +13 -38
  37. package/build/lib/commands/file-actions.js.map +1 -1
  38. package/build/lib/commands/geolocation.d.ts +9 -4
  39. package/build/lib/commands/geolocation.d.ts.map +1 -1
  40. package/build/lib/commands/geolocation.js +14 -6
  41. package/build/lib/commands/geolocation.js.map +1 -1
  42. package/build/lib/commands/image-injection.d.ts +2 -2
  43. package/build/lib/commands/image-injection.d.ts.map +1 -1
  44. package/build/lib/commands/image-injection.js +2 -3
  45. package/build/lib/commands/image-injection.js.map +1 -1
  46. package/build/lib/commands/intent.d.ts +70 -8
  47. package/build/lib/commands/intent.d.ts.map +1 -1
  48. package/build/lib/commands/intent.js +118 -16
  49. package/build/lib/commands/intent.js.map +1 -1
  50. package/build/lib/commands/keyboard.d.ts +2 -2
  51. package/build/lib/commands/keyboard.d.ts.map +1 -1
  52. package/build/lib/commands/keyboard.js +2 -4
  53. package/build/lib/commands/keyboard.js.map +1 -1
  54. package/build/lib/commands/lock/exports.d.ts +12 -8
  55. package/build/lib/commands/lock/exports.d.ts.map +1 -1
  56. package/build/lib/commands/lock/exports.js +12 -13
  57. package/build/lib/commands/lock/exports.js.map +1 -1
  58. package/build/lib/commands/media-projection.d.ts +41 -4
  59. package/build/lib/commands/media-projection.d.ts.map +1 -1
  60. package/build/lib/commands/media-projection.js +52 -11
  61. package/build/lib/commands/media-projection.js.map +1 -1
  62. package/build/lib/commands/memory.d.ts +4 -2
  63. package/build/lib/commands/memory.d.ts.map +1 -1
  64. package/build/lib/commands/memory.js +4 -3
  65. package/build/lib/commands/memory.js.map +1 -1
  66. package/build/lib/commands/network.d.ts +10 -4
  67. package/build/lib/commands/network.d.ts.map +1 -1
  68. package/build/lib/commands/network.js +17 -14
  69. package/build/lib/commands/network.js.map +1 -1
  70. package/build/lib/commands/nfc.d.ts +2 -2
  71. package/build/lib/commands/nfc.d.ts.map +1 -1
  72. package/build/lib/commands/nfc.js +2 -3
  73. package/build/lib/commands/nfc.js.map +1 -1
  74. package/build/lib/commands/performance.d.ts +3 -2
  75. package/build/lib/commands/performance.d.ts.map +1 -1
  76. package/build/lib/commands/performance.js +3 -4
  77. package/build/lib/commands/performance.js.map +1 -1
  78. package/build/lib/commands/permissions.d.ts +23 -5
  79. package/build/lib/commands/permissions.d.ts.map +1 -1
  80. package/build/lib/commands/permissions.js +27 -8
  81. package/build/lib/commands/permissions.js.map +1 -1
  82. package/build/lib/commands/shell.d.ts +3 -9
  83. package/build/lib/commands/shell.d.ts.map +1 -1
  84. package/build/lib/commands/shell.js +3 -10
  85. package/build/lib/commands/shell.js.map +1 -1
  86. package/build/lib/commands/streamscreen.d.ts +56 -6
  87. package/build/lib/commands/streamscreen.d.ts.map +1 -1
  88. package/build/lib/commands/streamscreen.js +28 -4
  89. package/build/lib/commands/streamscreen.js.map +1 -1
  90. package/build/lib/commands/system-bars.d.ts +6 -2
  91. package/build/lib/commands/system-bars.d.ts.map +1 -1
  92. package/build/lib/commands/system-bars.js +7 -7
  93. package/build/lib/commands/system-bars.js.map +1 -1
  94. package/build/lib/commands/time.d.ts +2 -2
  95. package/build/lib/commands/time.d.ts.map +1 -1
  96. package/build/lib/commands/time.js +3 -3
  97. package/build/lib/commands/time.js.map +1 -1
  98. package/build/lib/commands/types.d.ts +0 -588
  99. package/build/lib/commands/types.d.ts.map +1 -1
  100. package/build/lib/driver.d.ts +364 -12
  101. package/build/lib/driver.d.ts.map +1 -1
  102. package/build/lib/driver.js +2 -8
  103. package/build/lib/driver.js.map +1 -1
  104. package/build/lib/execute-method-map.d.ts +361 -0
  105. package/build/lib/execute-method-map.d.ts.map +1 -0
  106. package/build/lib/execute-method-map.js +437 -0
  107. package/build/lib/execute-method-map.js.map +1 -0
  108. package/lib/commands/app-management.js +68 -42
  109. package/lib/commands/appearance.js +10 -8
  110. package/lib/commands/bluetooth.js +2 -3
  111. package/lib/commands/context/exports.js +3 -3
  112. package/lib/commands/device/emulator-actions.js +28 -30
  113. package/lib/commands/device/emulator-console.js +9 -4
  114. package/lib/commands/deviceidle.js +3 -4
  115. package/lib/commands/execute.js +42 -124
  116. package/lib/commands/file-actions.js +13 -38
  117. package/lib/commands/geolocation.js +14 -6
  118. package/lib/commands/image-injection.js +2 -3
  119. package/lib/commands/intent.js +174 -16
  120. package/lib/commands/keyboard.js +2 -4
  121. package/lib/commands/lock/exports.js +12 -13
  122. package/lib/commands/media-projection.js +62 -11
  123. package/lib/commands/memory.js +4 -4
  124. package/lib/commands/network.js +14 -10
  125. package/lib/commands/nfc.js +2 -3
  126. package/lib/commands/performance.js +3 -4
  127. package/lib/commands/permissions.js +33 -14
  128. package/lib/commands/{shell.js → shell.ts} +8 -11
  129. package/lib/commands/streamscreen.js +39 -15
  130. package/lib/commands/system-bars.js +7 -9
  131. package/lib/commands/time.js +3 -3
  132. package/lib/commands/types.ts +0 -646
  133. package/lib/driver.ts +4 -16
  134. package/lib/execute-method-map.ts +464 -0
  135. package/package.json +2 -2
@@ -75,11 +75,52 @@ export async function startActivity(
75
75
 
76
76
  /**
77
77
  * @this {import('../driver').AndroidDriver}
78
- * @param {import('./types').StartActivityOpts} [opts={}]
78
+ * @param {boolean} [wait] Set it to `true` if you want to block the method call
79
+ * until the activity manager's process returns the control to the system.
80
+ * false by default.
81
+ * @param {boolean} [stop] Set it to `true` to force stop the target
82
+ * app before starting the activity
83
+ * false by default.
84
+ * @param {string | number} [windowingMode] The windowing mode to launch the activity into.
85
+ * Check
86
+ * https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/WindowConfiguration.java
87
+ * for more details on possible windowing modes (constants starting with
88
+ * `WINDOWING_MODE_`).
89
+ * @param {string | number} [activityType] The activity type to launch the activity as.
90
+ * Check https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/WindowConfiguration.java
91
+ * for more details on possible activity types (constants starting with `ACTIVITY_TYPE_`).
92
+ * @param {number | string} [display] The display identifier to launch the activity into.
93
+ * @param {string} [user]
94
+ * @param {string} [intent]
95
+ * @param {string} [action]
96
+ * @param {string} [pkg]
97
+ * @param {string} [uri]
98
+ * @param {string} [mimeType]
99
+ * @param {string} [identifier]
100
+ * @param {string} [component]
101
+ * @param {string | string[]} [categories]
102
+ * @param {string[][]} [extras]
103
+ * @param {string} [flags]
79
104
  * @returns {Promise<string>}
80
105
  */
81
- export async function mobileStartActivity(opts = {}) {
82
- const {user, wait, stop, windowingMode, activityType, display} = opts;
106
+ export async function mobileStartActivity(
107
+ wait,
108
+ stop,
109
+ windowingMode,
110
+ activityType,
111
+ display,
112
+ user,
113
+ intent,
114
+ action,
115
+ pkg,
116
+ uri,
117
+ mimeType,
118
+ identifier,
119
+ component,
120
+ categories,
121
+ extras,
122
+ flags,
123
+ ) {
83
124
  const cmd = [
84
125
  'am',
85
126
  (await this.adb.getApiLevel()) < API_LEVEL_ANDROID_8 ? 'start' : 'start-activity',
@@ -102,17 +143,55 @@ export async function mobileStartActivity(opts = {}) {
102
143
  if (!_.isNil(display)) {
103
144
  cmd.push('--display', String(display));
104
145
  }
105
- cmd.push(...parseIntentSpec(opts));
146
+ cmd.push(...parseIntentSpec({
147
+ intent,
148
+ action,
149
+ package: pkg,
150
+ uri,
151
+ mimeType,
152
+ identifier,
153
+ component,
154
+ categories,
155
+ extras,
156
+ flags,
157
+ }));
106
158
  return await this.adb.shell(cmd);
107
159
  }
108
160
 
109
161
  /**
110
162
  * @this {import('../driver').AndroidDriver}
111
- * @param {import('./types').BroadcastOpts} [opts={}]
163
+ * @param {string | number} [user] The user ID for which the broadcast is sent.
164
+ * The `current` alias assumes the current user ID.
165
+ * `all` by default.
166
+ * @param {string} [receiverPermission] Require receiver to hold the given permission.
167
+ * @param {boolean} [allowBackgroundActivityStarts] Whether the receiver may start activities even if in the background.
168
+ * @param {string} [intent]
169
+ * @param {string} [action]
170
+ * @param {string} [pkg]
171
+ * @param {string} [uri]
172
+ * @param {string} [mimeType]
173
+ * @param {string} [identifier]
174
+ * @param {string} [component]
175
+ * @param {string | string[]} [categories]
176
+ * @param {string[][]} [extras]
177
+ * @param {string} [flags]
112
178
  * @returns {Promise<string>}
113
179
  */
114
- export async function mobileBroadcast(opts = {}) {
115
- const {user, receiverPermission, allowBackgroundActivityStarts} = opts;
180
+ export async function mobileBroadcast(
181
+ receiverPermission,
182
+ allowBackgroundActivityStarts,
183
+ user,
184
+ intent,
185
+ action,
186
+ pkg,
187
+ uri,
188
+ mimeType,
189
+ identifier,
190
+ component,
191
+ categories,
192
+ extras,
193
+ flags,
194
+ ) {
116
195
  const cmd = ['am', 'broadcast'];
117
196
  if (!_.isNil(user)) {
118
197
  cmd.push('--user', String(user));
@@ -123,17 +202,53 @@ export async function mobileBroadcast(opts = {}) {
123
202
  if (allowBackgroundActivityStarts) {
124
203
  cmd.push('--allow-background-activity-starts');
125
204
  }
126
- cmd.push(...parseIntentSpec(opts));
205
+ cmd.push(...parseIntentSpec({
206
+ intent,
207
+ action,
208
+ package: pkg,
209
+ uri,
210
+ mimeType,
211
+ identifier,
212
+ component,
213
+ categories,
214
+ extras,
215
+ flags,
216
+ }));
127
217
  return await this.adb.shell(cmd);
128
218
  }
129
219
 
130
220
  /**
131
221
  * @this {import('../driver').AndroidDriver}
132
- * @param {import('./types').StartServiceOpts} [opts={}]
222
+ * @param {boolean} [foreground] Set it to `true` if your service must be started as foreground service.
223
+ * This option is ignored if the API level of the device under test is below
224
+ * 26 (Android 8).
225
+ * @param {string} [user]
226
+ * @param {string} [intent]
227
+ * @param {string} [action]
228
+ * @param {string} [pkg]
229
+ * @param {string} [uri]
230
+ * @param {string} [mimeType]
231
+ * @param {string} [identifier]
232
+ * @param {string} [component]
233
+ * @param {string | string[]} [categories]
234
+ * @param {string[][]} [extras]
235
+ * @param {string} [flags]
133
236
  * @returns {Promise<string>}
134
237
  */
135
- export async function mobileStartService(opts = {}) {
136
- const {user, foreground} = opts;
238
+ export async function mobileStartService(
239
+ foreground,
240
+ user,
241
+ intent,
242
+ action,
243
+ pkg,
244
+ uri,
245
+ mimeType,
246
+ identifier,
247
+ component,
248
+ categories,
249
+ extras,
250
+ flags,
251
+ ) {
137
252
  const cmd = ['am'];
138
253
  if ((await this.adb.getApiLevel()) < API_LEVEL_ANDROID_8) {
139
254
  cmd.push('startservice');
@@ -143,17 +258,49 @@ export async function mobileStartService(opts = {}) {
143
258
  if (!_.isNil(user)) {
144
259
  cmd.push('--user', String(user));
145
260
  }
146
- cmd.push(...parseIntentSpec(opts));
261
+ cmd.push(...parseIntentSpec({
262
+ intent,
263
+ action,
264
+ package: pkg,
265
+ uri,
266
+ mimeType,
267
+ identifier,
268
+ component,
269
+ categories,
270
+ extras,
271
+ flags,
272
+ }));
147
273
  return await this.adb.shell(cmd);
148
274
  }
149
275
 
150
276
  /**
151
277
  * @this {import('../driver').AndroidDriver}
152
- * @param {import('./types').StopServiceOpts} [opts={}]
278
+ * @param {string} [user]
279
+ * @param {string} [intent]
280
+ * @param {string} [action]
281
+ * @param {string} [pkg]
282
+ * @param {string} [uri]
283
+ * @param {string} [mimeType]
284
+ * @param {string} [identifier]
285
+ * @param {string} [component]
286
+ * @param {string | string[]} [categories]
287
+ * @param {string[][]} [extras]
288
+ * @param {string} [flags]
153
289
  * @returns {Promise<string>}
154
290
  */
155
- export async function mobileStopService(opts = {}) {
156
- const {user} = opts;
291
+ export async function mobileStopService(
292
+ user,
293
+ intent,
294
+ action,
295
+ pkg,
296
+ uri,
297
+ mimeType,
298
+ identifier,
299
+ component,
300
+ categories,
301
+ extras,
302
+ flags,
303
+ ) {
157
304
  const cmd = [
158
305
  'am',
159
306
  (await this.adb.getApiLevel()) < API_LEVEL_ANDROID_8 ? 'stopservice' : 'stop-service',
@@ -161,7 +308,18 @@ export async function mobileStopService(opts = {}) {
161
308
  if (!_.isNil(user)) {
162
309
  cmd.push('--user', String(user));
163
310
  }
164
- cmd.push(...parseIntentSpec(opts));
311
+ cmd.push(...parseIntentSpec({
312
+ intent,
313
+ action,
314
+ package: pkg,
315
+ uri,
316
+ mimeType,
317
+ identifier,
318
+ component,
319
+ categories,
320
+ extras,
321
+ flags,
322
+ }));
165
323
  try {
166
324
  return await this.adb.shell(cmd);
167
325
  } catch (e) {
@@ -1,7 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-vars */
2
2
  import _ from 'lodash';
3
3
  import {errors} from 'appium/driver';
4
- import {requireArgs} from '../utils';
5
4
  import {UNICODE_IME, EMPTY_IME} from 'io.appium.settings';
6
5
 
7
6
  /**
@@ -80,11 +79,10 @@ export async function longPressKeyCode(keycode, metastate) {
80
79
 
81
80
  /**
82
81
  * @this {import('../driver').AndroidDriver}
83
- * @param {import('./types').PerformEditorActionOpts} opts
82
+ * @param {string | number} action
84
83
  * @returns {Promise<void>}
85
84
  */
86
- export async function mobilePerformEditorAction(opts) {
87
- const {action} = requireArgs('action', opts);
85
+ export async function mobilePerformEditorAction(action) {
88
86
  await this.settingsApp.performEditorAction(action);
89
87
  }
90
88
 
@@ -17,16 +17,6 @@ import {
17
17
  } from './helpers';
18
18
  import _ from 'lodash';
19
19
 
20
- /**
21
- * @this {AndroidDriver}
22
- * @param {import('../types').LockOpts} opts
23
- * @returns {Promise<void>}
24
- */
25
- export async function mobileLock(opts = {}) {
26
- const {seconds} = opts;
27
- return await this.lock(seconds);
28
- }
29
-
30
20
  /**
31
21
  * @this {AndroidDriver}
32
22
  * @param {number} [seconds]
@@ -64,11 +54,20 @@ export async function unlock() {
64
54
 
65
55
  /**
66
56
  * @this {AndroidDriver}
67
- * @param {import('../types').UnlockOptions} [opts={}]
57
+ * @param {string} [key] The unlock key. The value of this key depends on the actual unlock type and
58
+ * could be a pin/password/pattern value or a biometric finger id.
59
+ * If not provided then the corresponding value from session capabilities is
60
+ * used.
61
+ * @param {import('../types').UnlockType} [type] The unlock type.
62
+ * If not provided then the corresponding value from session capabilities is used.
63
+ * @param {string} [strategy] Setting it to 'uiautomator' will enforce the driver to avoid using special
64
+ * ADB shortcuts in order to speed up the unlock procedure.
65
+ * 'uiautomator' by default.
66
+ * @param {number} [timeoutMs] The maximum time in milliseconds to wait until the screen gets unlocked
67
+ * 2000ms byde fault.
68
68
  * @returns {Promise<void>}
69
69
  */
70
- export async function mobileUnlock(opts = {}) {
71
- const {key, type, strategy, timeoutMs} = opts;
70
+ export async function mobileUnlock(key, type, strategy, timeoutMs) {
72
71
  if (!key && !type) {
73
72
  await this.unlock();
74
73
  } else {
@@ -10,13 +10,25 @@ const DEFAULT_FILENAME_FORMAT = 'YYYY-MM-DDTHH-mm-ss';
10
10
 
11
11
  /**
12
12
  * @this {import('../driver').AndroidDriver}
13
- * @param {import('./types').StartMediaProjectionRecordingOpts} [options={}]
13
+ * @param {string} [resolution] Maximum supported resolution on-device (Detected automatically by the app
14
+ * itself), which usually equals to Full HD 1920x1080 on most phones however
15
+ * you can change it to following supported resolutions as well: "1920x1080",
16
+ * "1280x720", "720x480", "320x240", "176x144".
17
+ * @param {'high' | 'normal' | 'low'} [priority] Recording thread priority.
18
+ * If you face performance drops during testing with recording enabled, you
19
+ * can reduce recording priority
20
+ * 'high' by default
21
+ * @param {number} [maxDurationSec] Maximum allowed duration is 15 minutes; you can increase it if your test
22
+ * takes longer than that. 900s by default.
23
+ * @param {string} [filename] You can type recording video file name as you want, but recording currently
24
+ * supports only "mp4" format so your filename must end with ".mp4". An
25
+ * invalid file name will fail to start the recording. If not provided then
26
+ * the current timestamp will be used as file name.
14
27
  * @returns {Promise<boolean>}
15
28
  */
16
- export async function mobileStartMediaProjectionRecording(options = {}) {
29
+ export async function mobileStartMediaProjectionRecording(resolution, priority, maxDurationSec, filename) {
17
30
  await verifyMediaProjectionRecordingIsSupported(this.adb);
18
31
 
19
- const {resolution, priority, maxDurationSec, filename} = options;
20
32
  const recorder = this.settingsApp.makeMediaProjectionRecorder();
21
33
  const fname = adjustMediaExtension(filename || moment().format(DEFAULT_FILENAME_FORMAT));
22
34
  const didStart = await recorder.start({
@@ -48,10 +60,34 @@ export async function mobileIsMediaProjectionRecordingRunning() {
48
60
 
49
61
  /**
50
62
  * @this {import('../driver').AndroidDriver}
51
- * @param {import('./types').StopMediaProjectionRecordingOpts} [options={}]
63
+ * @param {string} [remotePath] The path to the remote location, where the resulting video should be
64
+ * uploaded. The following protocols are supported: http/https, ftp. Null or
65
+ * empty string value (the default setting) means the content of resulting
66
+ * file should be encoded as Base64 and passed as the endpoont response value.
67
+ * An exception will be thrown if the generated media file is too big to fit
68
+ * into the available process memory.
69
+ * @param {string} [user] The name of the user for the remote authentication.
70
+ * @param {string} [pass] The password for the remote authentication.
71
+ * @param {import('@appium/types').HTTPMethod} [method] The http multipart upload method name.
72
+ * 'PUT' by default.
73
+ * @param {import('@appium/types').StringRecord} [headers] Additional headers mapping for multipart http(s) uploads
74
+ * @param {string} [fileFieldName] The name of the form field, where the file content BLOB should be stored
75
+ * for http(s) uploads. 'file' by default.
76
+ * @param {import('./types').FormFields} [formFields] Additional form fields for multipart http(s) uploads
77
+ * @param {number} [uploadTimeout] The actual media upload request timeout in milliseconds.
78
+ * Defaults to `@appium/support.net.DEFAULT_TIMEOUT_MS`
52
79
  * @returns {Promise<string>}
53
80
  */
54
- export async function mobileStopMediaProjectionRecording(options = {}) {
81
+ export async function mobileStopMediaProjectionRecording(
82
+ remotePath,
83
+ user,
84
+ pass,
85
+ method,
86
+ headers,
87
+ fileFieldName,
88
+ formFields,
89
+ uploadTimeout,
90
+ ) {
55
91
  await verifyMediaProjectionRecordingIsSupported(this.adb);
56
92
 
57
93
  const recorder = this.settingsApp.makeMediaProjectionRecorder();
@@ -65,7 +101,6 @@ export async function mobileStopMediaProjectionRecording(options = {}) {
65
101
  throw new Error(`No recent media projection recording have been found. Did you start any?`);
66
102
  }
67
103
 
68
- const {remotePath} = options;
69
104
  if (_.isEmpty(remotePath)) {
70
105
  const {size} = await fs.stat(recentRecordingPath);
71
106
  this.log.debug(
@@ -73,7 +108,15 @@ export async function mobileStopMediaProjectionRecording(options = {}) {
73
108
  );
74
109
  }
75
110
  try {
76
- return await uploadRecordedMedia(recentRecordingPath, remotePath, options);
111
+ return await uploadRecordedMedia(recentRecordingPath, remotePath, {
112
+ user,
113
+ pass,
114
+ method,
115
+ headers,
116
+ fileFieldName,
117
+ formFields,
118
+ uploadTimeout,
119
+ });
77
120
  } finally {
78
121
  await fs.rimraf(path.dirname(recentRecordingPath));
79
122
  }
@@ -85,7 +128,7 @@ export async function mobileStopMediaProjectionRecording(options = {}) {
85
128
  *
86
129
  * @param {string} localFile
87
130
  * @param {string} [remotePath]
88
- * @param {import('./types').StopMediaProjectionRecordingOpts} uploadOptions
131
+ * @param {UploadOptions} uploadOptions
89
132
  * @returns
90
133
  */
91
134
  async function uploadRecordedMedia(localFile, remotePath, uploadOptions = {}) {
@@ -102,9 +145,6 @@ async function uploadRecordedMedia(localFile, remotePath, uploadOptions = {}) {
102
145
  formFields,
103
146
  uploadTimeout: timeout,
104
147
  } = uploadOptions;
105
- /**
106
- * @type {Omit<import('./types').StopMediaProjectionRecordingOpts, 'uploadTimeout'> & {auth?: {user: string, pass: string}, timeout?: number}}
107
- */
108
148
  const options = {
109
149
  method: method || 'PUT',
110
150
  headers,
@@ -144,6 +184,17 @@ async function verifyMediaProjectionRecordingIsSupported(adb) {
144
184
 
145
185
  // #endregion
146
186
 
187
+ /**
188
+ * @typedef {Object} UploadOptions
189
+ * @property {string} [user]
190
+ * @property {string} [pass]
191
+ * @property {import('@appium/types').HTTPMethod} [method]
192
+ * @property {import('@appium/types').StringRecord} [headers]
193
+ * @property {string} [fileFieldName]
194
+ * @property {import('./types').FormFields} [formFields]
195
+ * @property {number} [uploadTimeout]
196
+ */
197
+
147
198
  /**
148
199
  * @typedef {import('appium-adb').ADB} ADB
149
200
  */
@@ -6,12 +6,12 @@ import {errors} from 'appium/driver';
6
6
  * for more details.
7
7
  *
8
8
  * @this {import('../driver').AndroidDriver}
9
- * @param {import('./types').SendTrimMemoryOpts} opts
9
+ * @param {string} pkg The package name to send the `trimMemory` event to
10
+ * @param {'COMPLETE' | 'MODERATE' | 'BACKGROUND' | 'UI_HIDDEN' | 'RUNNING_CRITICAL' | 'RUNNING_LOW' | 'RUNNING_MODERATE'} level The
11
+ * actual memory trim level to be sent
10
12
  * @returns {Promise<void>}
11
13
  */
12
- export async function mobileSendTrimMemory(opts) {
13
- const {pkg, level} = opts;
14
-
14
+ export async function mobileSendTrimMemory(pkg, level) {
15
15
  if (!pkg) {
16
16
  throw new errors.InvalidArgumentError(`The 'pkg' argument must be provided`);
17
17
  }
@@ -9,7 +9,7 @@ const DATA_MASK = 0b100;
9
9
  const WIFI_KEY_NAME = 'wifi';
10
10
  const DATA_KEY_NAME = 'data';
11
11
  const AIRPLANE_MODE_KEY_NAME = 'airplaneMode';
12
- const SUPPORTED_SERVICE_NAMES = /** @type {const} */ ([
12
+ const SUPPORTED_SERVICE_NAMES = /** @type {import('./types').ServiceType[]} */ ([
13
13
  WIFI_KEY_NAME,
14
14
  DATA_KEY_NAME,
15
15
  AIRPLANE_MODE_KEY_NAME,
@@ -46,24 +46,28 @@ export async function isWifiOn() {
46
46
  /**
47
47
  * @since Android 12 (only real devices, emulators work in all APIs)
48
48
  * @this {import('../driver').AndroidDriver}
49
- * @param {import('./types').SetConnectivityOpts} [opts={}]
49
+ * @param {boolean} [wifi] Either to enable or disable Wi-Fi.
50
+ * An unset value means to not change the state for the given service.
51
+ * @param {boolean} [data] Either to enable or disable mobile data connection.
52
+ * An unset value means to not change the state for the given service.
53
+ * @param {boolean} [airplaneMode] Either to enable to disable the Airplane Mode
54
+ * An unset value means to not change the state for the given service.
50
55
  * @returns {Promise<void>}
51
56
  */
52
- export async function mobileSetConnectivity(opts = {}) {
53
- const {wifi, data, airplaneMode} = opts;
57
+ export async function mobileSetConnectivity(wifi, data, airplaneMode) {
54
58
  if (_.every([wifi, data, airplaneMode], _.isUndefined)) {
55
59
  throw new errors.InvalidArgumentError(
56
60
  `Either one of ${JSON.stringify(SUPPORTED_SERVICE_NAMES)} options must be provided`,
57
61
  );
58
62
  }
59
63
 
60
- const currentState = await this.mobileGetConnectivity({
61
- services: /** @type {import('./types').ServiceType[]} */ ([
64
+ const currentState = await this.mobileGetConnectivity(
65
+ /** @type {import('./types').ServiceType[]} */ ([
62
66
  ...(_.isUndefined(wifi) ? [] : [WIFI_KEY_NAME]),
63
67
  ...(_.isUndefined(data) ? [] : [DATA_KEY_NAME]),
64
68
  ...(_.isUndefined(airplaneMode) ? [] : [AIRPLANE_MODE_KEY_NAME]),
65
69
  ]),
66
- });
70
+ );
67
71
  /** @type {(Promise<any>|(() => Promise<any>))[]} */
68
72
  const setters = [];
69
73
  if (!_.isUndefined(wifi) && currentState.wifi !== Boolean(wifi)) {
@@ -87,11 +91,11 @@ export async function mobileSetConnectivity(opts = {}) {
87
91
 
88
92
  /**
89
93
  * @this {import('../driver').AndroidDriver}
90
- * @param {import('./types').GetConnectivityOpts} [opts={}]
94
+ * @param {import('./types').ServiceType[] | import('./types').ServiceType} [services] one or more
95
+ * services to get the connectivity for.
91
96
  * @returns {Promise<import('./types').GetConnectivityResult>}
92
97
  */
93
- export async function mobileGetConnectivity(opts = {}) {
94
- let {services = SUPPORTED_SERVICE_NAMES} = opts;
98
+ export async function mobileGetConnectivity(services = SUPPORTED_SERVICE_NAMES) {
95
99
  const svcs = _.castArray(services);
96
100
  const unsupportedServices = _.difference(services, SUPPORTED_SERVICE_NAMES);
97
101
  if (!_.isEmpty(unsupportedServices)) {
@@ -10,13 +10,12 @@ const SUPPORTED_ACTIONS = /** @type {const} */ ({
10
10
  * Performs the requested action on the default NFC adapter
11
11
  *
12
12
  * @this {AndroidDriver}
13
- * @param {import('./types').NfcOptions} opts
13
+ * @param { 'enable' | 'disable'} action
14
14
  * @returns {Promise<void>}
15
15
  * @throws {Error} if the device under test has no default NFC adapter
16
16
  * or there was a failure while performing the action.
17
17
  */
18
- export async function mobileNfc(opts) {
19
- const {action} = opts;
18
+ export async function mobileNfc(action) {
20
19
  switch (action) {
21
20
  case SUPPORTED_ACTIONS.ENABLE:
22
21
  await this.adb.setNfcOn(true);
@@ -1,7 +1,6 @@
1
1
  // @ts-check
2
2
  import {retryInterval} from 'asyncbox';
3
3
  import _ from 'lodash';
4
- import {requireArgs} from '../utils';
5
4
 
6
5
  export const NETWORK_KEYS = [
7
6
  [
@@ -121,11 +120,11 @@ export async function getPerformanceData(packageName, dataType, retries = 2) {
121
120
  * - cpuinfo: [[user, kernel], [0.9, 1.3]]
122
121
  *
123
122
  * @this {AndroidDriver}
124
- * @param {import('./types').PerformanceDataOpts} opts
123
+ * @param {string} packageName The name of the package identifier to fetch the data for
124
+ * @param {import('./types').PerformanceDataType} dataType One of supported subsystem to fetch the data for.
125
125
  * @returns {Promise<any[][]>}
126
126
  */
127
- export async function mobileGetPerformanceData(opts) {
128
- const {packageName, dataType} = requireArgs(['packageName', 'dataType'], opts);
127
+ export async function mobileGetPerformanceData(packageName, dataType) {
129
128
  return await this.getPerformanceData(packageName, dataType);
130
129
  }
131
130
 
@@ -26,18 +26,35 @@ const PERMISSIONS_TYPE = Object.freeze({
26
26
 
27
27
  /**
28
28
  * @this {import('../driver').AndroidDriver}
29
- * @param {import('./types').ChangePermissionsOpts} opts
30
- * @returns {Promise<void>}
29
+ * @param {string | string[]} permissions If `target` is set to 'pm':
30
+ * The full name of the permission to be changed
31
+ * or a list of permissions. Check https://developer.android.com/reference/android/Manifest.permission
32
+ * to get the full list of standard Android permssion names. Mandatory argument.
33
+ * If 'all' magic string is passed then the chosen action is going to be applied to all
34
+ * permisisons requested/granted by 'appPackage'.
35
+ * If `target` is set to 'appops':
36
+ * The full name of the appops permission to be changed
37
+ * or a list of permissions. Check AppOpsManager.java sources to get the full list of
38
+ * available appops permission names. Mandatory argument.
39
+ * Examples: 'ACTIVITY_RECOGNITION', 'SMS_FINANCIAL_TRANSACTIONS', 'READ_SMS', 'ACCESS_NOTIFICATIONS'.
40
+ * The 'all' magic string is unsupported.
41
+ * @param {string} [appPackage] The application package to set change permissions on. Defaults to the
42
+ * package name under test
43
+ * @param {string} [action] One of `PM_ACTION` values if `target` is set to 'pm', otherwise
44
+ * one of `APPOPS_ACTION` values
45
+ * @param {'pm' | 'appops'} [target='pm'] Either 'pm' or 'appops'. The 'appops' one requires
46
+ * 'adb_shell' server security option to be enabled.
31
47
  */
32
- export async function mobileChangePermissions(opts) {
33
- const {
34
- permissions,
35
- appPackage = this.opts.appPackage,
36
- action = _.toLower(opts.target) === PERMISSION_TARGET.APPOPS
37
- ? APPOPS_ACTION.ALLOW
38
- : PM_ACTION.GRANT,
39
- target = PERMISSION_TARGET.PM,
40
- } = opts;
48
+ export async function mobileChangePermissions(
49
+ permissions,
50
+ appPackage,
51
+ action,
52
+ target = PERMISSION_TARGET.PM
53
+ ) {
54
+ appPackage ??= this.opts.appPackage;
55
+ action ??= _.toLower(target) === PERMISSION_TARGET.APPOPS
56
+ ? APPOPS_ACTION.ALLOW
57
+ : PM_ACTION.GRANT;
41
58
  if (_.isNil(permissions)) {
42
59
  throw new errors.InvalidArgumentError(`'permissions' argument is required`);
43
60
  }
@@ -64,11 +81,13 @@ export async function mobileChangePermissions(opts) {
64
81
 
65
82
  /**
66
83
  * @this {import('../driver').AndroidDriver}
67
- * @param {import('./types').GetPermissionsOpts} [opts={}]
84
+ * @param {string} [type='requested'] One of possible permission types to get.
85
+ * @param {string} [appPackage] The application package to set change permissions on.
86
+ * Defaults to the package name under test
68
87
  * @returns {Promise<string[]>}
69
88
  */
70
- export async function mobileGetPermissions(opts = {}) {
71
- const {type = PERMISSIONS_TYPE.REQUESTED, appPackage = this.opts.appPackage} = opts;
89
+ export async function mobileGetPermissions(type = PERMISSIONS_TYPE.REQUESTED, appPackage) {
90
+ appPackage ??= this.opts.appPackage;
72
91
  /**
73
92
  * @type {(pkg: string) => Promise<string[]>}
74
93
  */
@@ -4,14 +4,13 @@ import _ from 'lodash';
4
4
  import {exec} from 'teen_process';
5
5
  import {ADB_SHELL_FEATURE} from '../utils';
6
6
 
7
- /**
8
- * @this {import('../driver').AndroidDriver}
9
- * @param {import('./types').ShellOpts} [opts={}]
10
- * @returns {Promise<string | {stderr: string; stdout: string}>};
11
- */
12
- export async function mobileShell(opts) {
7
+ export async function mobileShell<T extends boolean>(
8
+ command: string,
9
+ args: string[] = [],
10
+ timeout: number = 20000,
11
+ includeStderr?: T,
12
+ ): Promise<T extends true ? { stdout: string; stderr: string; } : string> {
13
13
  this.assertFeatureEnabled(ADB_SHELL_FEATURE);
14
- const {command, args = /** @type {string[]} */ ([]), timeout = 20000, includeStderr} = opts ?? {};
15
14
 
16
15
  if (!_.isString(command)) {
17
16
  throw new errors.InvalidArgumentError(`The 'command' argument is mandatory`);
@@ -22,11 +21,13 @@ export async function mobileShell(opts) {
22
21
  try {
23
22
  const {stdout, stderr} = await exec(this.adb.executable.path, adbArgs, {timeout});
24
23
  if (includeStderr) {
24
+ // @ts-ignore We know what we are doing here
25
25
  return {
26
26
  stdout,
27
27
  stderr,
28
28
  };
29
29
  }
30
+ // @ts-ignore We know what we are doing here
30
31
  return stdout;
31
32
  } catch (e) {
32
33
  const err = /** @type {import('teen_process').ExecError} */ (e);
@@ -37,7 +38,3 @@ export async function mobileShell(opts) {
37
38
  );
38
39
  }
39
40
  }
40
-
41
- /**
42
- * @typedef {import('appium-adb').ADB} ADB
43
- */