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
@@ -73,16 +73,16 @@ export async function setContext(name) {
73
73
 
74
74
  /**
75
75
  * @this {AndroidDriver}
76
- * @param {any} [opts={}]
76
+ * @param {number} [waitForWebviewMs]
77
77
  * @returns {Promise<import('../types').WebviewsMapping[]>}
78
78
  */
79
- export async function mobileGetContexts(opts = {}) {
79
+ export async function mobileGetContexts(waitForWebviewMs) {
80
80
  const _opts = {
81
81
  androidDeviceSocket: this.opts.androidDeviceSocket,
82
82
  ensureWebviewsHavePages: true,
83
83
  webviewDevtoolsPort: this.opts.webviewDevtoolsPort,
84
84
  enableWebviewDetailsCollection: true,
85
- waitForWebviewMs: opts.waitForWebviewMs || 0,
85
+ waitForWebviewMs: waitForWebviewMs || 0,
86
86
  };
87
87
  return await getWebViewsMapping.bind(this)(_opts);
88
88
  }
@@ -1,6 +1,6 @@
1
1
  import {util} from '@appium/support';
2
- import {requireArgs} from '../../utils';
3
2
  import {requireEmulator} from './utils';
3
+ import { errors } from 'appium/driver';
4
4
 
5
5
  /**
6
6
  * @deprecated Use mobile: extension
@@ -15,11 +15,14 @@ export async function fingerprint(fingerprintId) {
15
15
 
16
16
  /**
17
17
  * @this {import('../../driver').AndroidDriver}
18
- * @param {import('../types').FingerprintOpts} opts
18
+ * @param {string | number} fingerprintId The value is the `finger_id` for the finger that was "scanned". It is a
19
+ * unique integer that you assign for each virtual fingerprint. When the app
20
+ * is running you can run this same command each time the emulator prompts you
21
+ * for a fingerprint, you can run the adb command and pass it the `finger_id`
22
+ * to simulate the fingerprint scan.
19
23
  * @returns {Promise<void>}
20
24
  */
21
- export async function mobileFingerprint(opts) {
22
- const {fingerprintId} = requireArgs('fingerprintId', opts);
25
+ export async function mobileFingerprint(fingerprintId) {
23
26
  await this.fingerprint(fingerprintId);
24
27
  }
25
28
 
@@ -37,11 +40,11 @@ export async function sendSMS(phoneNumber, message) {
37
40
 
38
41
  /**
39
42
  * @this {import('../../driver').AndroidDriver}
40
- * @param {import('../types').SendSMSOpts} opts
43
+ * @param {string} phoneNumber The phone number to send SMS to
44
+ * @param {string} message The message payload
41
45
  * @returns {Promise<void>}
42
46
  */
43
- export async function mobileSendSms(opts) {
44
- const {phoneNumber, message} = requireArgs(['phoneNumber', 'message'], opts);
47
+ export async function mobileSendSms(phoneNumber, message) {
45
48
  await this.sendSMS(phoneNumber, message);
46
49
  }
47
50
 
@@ -59,11 +62,11 @@ export async function gsmCall(phoneNumber, action) {
59
62
 
60
63
  /**
61
64
  * @this {import('../../driver').AndroidDriver}
62
- * @param {import('../types').GsmCallOpts} opts
65
+ * @param {string} phoneNumber The phone number to call to
66
+ * @param {import('../types').GsmAction} action Action to take
63
67
  * @returns {Promise<void>}
64
68
  */
65
- export async function mobileGsmCall(opts) {
66
- const {phoneNumber, action} = requireArgs(['phoneNumber', 'action'], opts);
69
+ export async function mobileGsmCall(phoneNumber, action) {
67
70
  await this.gsmCall(phoneNumber, action);
68
71
  }
69
72
 
@@ -80,11 +83,10 @@ export async function gsmSignal(signalStrengh) {
80
83
 
81
84
  /**
82
85
  * @this {import('../../driver').AndroidDriver}
83
- * @param {import('../types').GsmSignalStrengthOpts} opts
86
+ * @param {import('../types').GsmSignalStrength} strength The signal strength value
84
87
  * @returns {Promise<void>}
85
88
  */
86
- export async function mobileGsmSignal(opts) {
87
- const {strength} = requireArgs('strength', opts);
89
+ export async function mobileGsmSignal(strength) {
88
90
  await this.gsmSignal(strength);
89
91
  }
90
92
 
@@ -101,11 +103,10 @@ export async function gsmVoice(state) {
101
103
 
102
104
  /**
103
105
  * @this {import('../../driver').AndroidDriver}
104
- * @param {import('../types').GsmVoiceOpts} opts
106
+ * @param {import('../types').GsmVoiceState} state
105
107
  * @returns {Promise<void>}
106
108
  */
107
- export async function mobileGsmVoice(opts) {
108
- const {state} = requireArgs('state', opts);
109
+ export async function mobileGsmVoice(state) {
109
110
  await this.gsmVoice(state);
110
111
  }
111
112
 
@@ -122,11 +123,10 @@ export async function powerAC(state) {
122
123
 
123
124
  /**
124
125
  * @this {import('../../driver').AndroidDriver}
125
- * @param {import('../types').PowerACOpts} opts
126
+ * @param {import('../types').PowerACState} state
126
127
  * @returns {Promise<void>}
127
128
  */
128
- export async function mobilePowerAc(opts) {
129
- const {state} = requireArgs('state', opts);
129
+ export async function mobilePowerAc(state) {
130
130
  await this.powerAC(state);
131
131
  }
132
132
 
@@ -143,11 +143,10 @@ export async function powerCapacity(batteryPercent) {
143
143
 
144
144
  /**
145
145
  * @this {import('../../driver').AndroidDriver}
146
- * @param {import('../types').PowerCapacityOpts} opts
146
+ * @param {number} percent Percentage value in range `[0, 100]`
147
147
  * @return {Promise<void>}
148
148
  */
149
- export async function mobilePowerCapacity(opts) {
150
- const {percent} = requireArgs('percent', opts);
149
+ export async function mobilePowerCapacity(percent) {
151
150
  await this.powerCapacity(percent);
152
151
  }
153
152
 
@@ -164,27 +163,26 @@ export async function networkSpeed(networkSpeed) {
164
163
 
165
164
  /**
166
165
  * @this {import('../../driver').AndroidDriver}
167
- * @param {import('../types').NetworkSpeedOpts} opts
166
+ * @param {import('../types').NetworkSpeed} speed
168
167
  * @returns {Promise<void>}
169
168
  */
170
- export async function mobileNetworkSpeed(opts) {
171
- const {speed} = requireArgs('speed', opts);
169
+ export async function mobileNetworkSpeed(speed) {
172
170
  await this.networkSpeed(speed);
173
171
  }
174
172
 
175
173
  /**
176
174
  * @this {import('../../driver').AndroidDriver}
177
- * @param {import('../types').SensorSetOpts} opts
175
+ * @param {string} sensorType Sensor type as declared in `adb.SENSORS`
176
+ * @param {string} value Value to set to the sensor
178
177
  * @returns {Promise<void>}
179
178
  */
180
- export async function sensorSet(opts) {
179
+ export async function sensorSet(sensorType, value) {
181
180
  requireEmulator.bind(this)('sensorSet is only available for emulators');
182
- const {sensorType, value} = opts;
183
181
  if (!util.hasValue(sensorType)) {
184
- throw this.log.errorWithException(`'sensorType' argument is required`);
182
+ throw new errors.InvalidArgumentError(`'sensorType' argument is required`);
185
183
  }
186
184
  if (!util.hasValue(value)) {
187
- throw this.log.errorWithException(`'value' argument is required`);
185
+ throw new errors.InvalidArgumentError(`'value' argument is required`);
188
186
  }
189
187
  await this.adb.sensorSet(sensorType, /** @type {any} */ (value));
190
188
  }
@@ -4,14 +4,19 @@ const EMU_CONSOLE_FEATURE = 'emulator_console';
4
4
 
5
5
  /**
6
6
  * @this {import('../../driver').AndroidDriver}
7
- * @param {import('../types').ExecOptions} opts
8
7
  * @returns {Promise<string>}
8
+ * @param {string | string[]} command The actual command to execute.
9
+ * @see {@link https://developer.android.com/studio/run/emulator-console}
10
+ * @param {number} [execTimeout] A timeout used to wait for a server reply to the given command in
11
+ * milliseconds. 60000ms by default
12
+ * @param {number} [connTimeout] Console connection timeout in milliseconds.
13
+ * 5000ms by default.
14
+ * @param {number} [initTimeout] Telnet console initialization timeout in milliseconds (the time between the
15
+ * connection happens and the command prompt is available)
9
16
  */
10
- export async function mobileExecEmuConsoleCommand(opts) {
17
+ export async function mobileExecEmuConsoleCommand(command, execTimeout, connTimeout, initTimeout) {
11
18
  this.assertFeatureEnabled(EMU_CONSOLE_FEATURE);
12
19
 
13
- const {command, execTimeout, connTimeout, initTimeout} = opts;
14
-
15
20
  if (!command) {
16
21
  throw new errors.InvalidArgumentError(`The 'command' argument is mandatory`);
17
22
  }
@@ -8,12 +8,11 @@ const SUPPORTED_ACTIONS = ['whitelistAdd', 'whitelistRemove'];
8
8
  * Read https://www.protechtraining.com/blog/post/diving-into-android-m-doze-875
9
9
  * for more details.
10
10
  *
11
- * @param {import('./types').DeviceidleOpts} opts
11
+ * @param {'whitelistAdd' | 'whitelistRemove'} action The action name to execute
12
+ * @param {string} [packages] Either a single package or multiple packages to add or remove from the idle whitelist
12
13
  * @returns {Promise<void>}
13
14
  */
14
- export async function mobileDeviceidle(opts) {
15
- const {action, packages} = opts;
16
-
15
+ export async function mobileDeviceidle(action, packages) {
17
16
  if (!(_.isString(packages) || _.isArray(packages))) {
18
17
  throw new errors.InvalidArgumentError(`packages argument must be a string or an array`);
19
18
  }
@@ -1,125 +1,20 @@
1
1
  import _ from 'lodash';
2
2
  import {errors, PROTOCOLS} from 'appium/driver';
3
+ import { util } from '@appium/support';
3
4
 
4
- /**
5
- * @this {import('../driver').AndroidDriver}
6
- * @returns {import('@appium/types').StringRecord<string>}
7
- */
8
- export function mobileCommandsMapping() {
9
- return {
10
- shell: 'mobileShell',
11
-
12
- execEmuConsoleCommand: 'mobileExecEmuConsoleCommand',
13
-
14
- startLogsBroadcast: 'mobileStartLogsBroadcast',
15
- stopLogsBroadcast: 'mobileStopLogsBroadcast',
16
-
17
- changePermissions: 'mobileChangePermissions',
18
- getPermissions: 'mobileGetPermissions',
19
-
20
- performEditorAction: 'mobilePerformEditorAction',
21
-
22
- getDeviceTime: 'mobileGetDeviceTime',
23
-
24
- startScreenStreaming: 'mobileStartScreenStreaming',
25
- stopScreenStreaming: 'mobileStopScreenStreaming',
26
-
27
- getNotifications: 'mobileGetNotifications',
28
-
29
- listSms: 'mobileListSms',
30
-
31
- pushFile: 'mobilePushFile',
32
- pullFile: 'mobilePullFile',
33
- pullFolder: 'mobilePullFolder',
34
- deleteFile: 'mobileDeleteFile',
35
-
36
- isAppInstalled: 'mobileIsAppInstalled',
37
- queryAppState: 'mobileQueryAppState',
38
- activateApp: 'mobileActivateApp',
39
- removeApp: 'mobileRemoveApp',
40
- terminateApp: 'mobileTerminateApp',
41
- installApp: 'mobileInstallApp',
42
- clearApp: 'mobileClearApp',
43
-
44
- startService: 'mobileStartService',
45
- stopService: 'mobileStopService',
46
- startActivity: 'mobileStartActivity',
47
- broadcast: 'mobileBroadcast',
48
-
49
- getContexts: 'mobileGetContexts',
50
-
51
- lock: 'mobileLock',
52
- unlock: 'mobileUnlock',
53
- isLocked: 'isLocked',
54
-
55
- refreshGpsCache: 'mobileRefreshGpsCache',
56
-
57
- startMediaProjectionRecording: 'mobileStartMediaProjectionRecording',
58
- isMediaProjectionRecordingRunning: 'mobileIsMediaProjectionRecordingRunning',
59
- stopMediaProjectionRecording: 'mobileStopMediaProjectionRecording',
60
-
61
- getConnectivity: 'mobileGetConnectivity',
62
- setConnectivity: 'mobileSetConnectivity',
63
-
64
- hideKeyboard: 'hideKeyboard',
65
- isKeyboardShown: 'isKeyboardShown',
66
-
67
- deviceidle: 'mobileDeviceidle',
68
-
69
- bluetooth: 'mobileBluetooth',
70
-
71
- nfc: 'mobileNfc',
72
-
73
- setUiMode: 'mobileSetUiMode',
74
- getUiMode: 'mobileGetUiMode',
75
-
76
- injectEmulatorCameraImage: 'mobileInjectEmulatorCameraImage',
77
-
78
- sendTrimMemory: 'mobileSendTrimMemory',
79
-
80
- getPerformanceData: 'mobileGetPerformanceData',
81
- getPerformanceDataTypes: 'getPerformanceDataTypes',
82
-
83
- toggleGps: 'toggleLocationServices',
84
- isGpsEnabled: 'isLocationServicesEnabled',
85
-
86
- getDisplayDensity: 'getDisplayDensity',
87
- getSystemBars: 'getSystemBars',
88
- statusBar: 'mobilePerformStatusBarCommand',
89
-
90
- fingerprint: 'mobileFingerprint',
91
- sendSms: 'mobileSendSms',
92
- gsmCall: 'mobileGsmCall',
93
- gsmSignal: 'mobileGsmSignal',
94
- gsmVoice: 'mobileGsmVoice',
95
- powerAc: 'mobilePowerAc',
96
- powerCapacity: 'mobilePowerCapacity',
97
- networkSpeed: 'mobileNetworkSpeed',
98
- sensorSet: 'sensorSet',
99
-
100
- getCurrentActivity: 'getCurrentActivity',
101
- getCurrentPackage: 'getCurrentPackage',
102
-
103
- setGeolocation: 'mobileSetGeolocation',
104
- getGeolocation: 'mobileGetGeolocation',
105
- resetGeolocation: 'mobileResetGeolocation',
106
- };
107
- }
5
+ const EXECUTE_SCRIPT_PREFIX = 'mobile:';
108
6
 
109
7
  /**
110
- * @this {import('../driver').AndroidDriver}
8
+ * @this {AndroidDriver}
111
9
  * @param {string} script
112
- * @param {import('@appium/types').StringRecord[]|import('@appium/types').StringRecord} [args]
10
+ * @param {ExecuteMethodArgs} [args]
113
11
  * @returns {Promise<any>}
114
12
  */
115
13
  export async function execute(script, args) {
116
- if (script.match(/^mobile:/)) {
117
- this.log.info(`Executing native command '${script}'`);
118
- script = script.replace(/^mobile:/, '').trim();
119
- return await this.executeMobile(
120
- script,
121
- Array.isArray(args) ? (args[0]) : args,
122
- );
14
+ if (_.startsWith(script, EXECUTE_SCRIPT_PREFIX)) {
15
+ const formattedScript = script.trim().replace(/^mobile:\s*/, `${EXECUTE_SCRIPT_PREFIX} `);
16
+ const executeMethodArgs = preprocessExecuteMethodArgs(args);
17
+ return await this.executeMethod(formattedScript, [executeMethodArgs]);
123
18
  }
124
19
  if (!this.isWebContext()) {
125
20
  throw new errors.NotImplementedError();
@@ -137,19 +32,42 @@ export async function execute(script, args) {
137
32
  });
138
33
  }
139
34
 
35
+ // #region Internal Helpers
36
+
140
37
  /**
141
- * @this {import('../driver').AndroidDriver}
142
- * @param {string} mobileCommand
143
- * @param {import('@appium/types').StringRecord} [opts={}]
144
- * @returns {Promise<any>}
38
+ * Massages the arguments going into an execute method.
39
+ *
40
+ * @param {ExecuteMethodArgs} [args]
41
+ * @returns {StringRecord}
145
42
  */
146
- export async function executeMobile(mobileCommand, opts = {}) {
147
- const mobileCommandsMapping = this.mobileCommandsMapping();
148
- if (!(mobileCommand in mobileCommandsMapping)) {
149
- throw new errors.UnknownCommandError(
150
- `Unknown mobile command "${mobileCommand}". ` +
151
- `Only ${_.keys(mobileCommandsMapping)} commands are supported.`,
43
+ function preprocessExecuteMethodArgs(args) {
44
+ const executeMethodArgs = /** @type {StringRecord} */ ((_.isArray(args) ? _.first(args) : args) ?? {});
45
+
46
+ /**
47
+ * Renames the deprecated `element` key to `elementId`. Historically,
48
+ * all of the pre-Execute-Method-Map execute methods accepted an `element` _or_ and `elementId` param.
49
+ * This assigns the `element` value to `elementId` if `elementId` is not already present.
50
+ */
51
+ if (!('elementId' in executeMethodArgs) && 'element' in executeMethodArgs) {
52
+ executeMethodArgs.elementId = executeMethodArgs.element;
53
+ }
54
+
55
+ /**
56
+ * Automatically unwraps the `elementId` prop _if and only if_ the execute method expects it.
57
+ */
58
+ if ('elementId' in executeMethodArgs) {
59
+ executeMethodArgs.elementId = util.unwrapElement(
60
+ /** @type {import('@appium/types').Element|string} */ (executeMethodArgs.elementId),
152
61
  );
153
62
  }
154
- return await this[mobileCommandsMapping[mobileCommand]](opts);
63
+
64
+ return executeMethodArgs;
155
65
  }
66
+
67
+ // #endregion
68
+
69
+ /**
70
+ * @typedef {import('../driver').AndroidDriver} AndroidDriver
71
+ * @typedef {import('@appium/types').StringRecord} StringRecord
72
+ * @typedef {readonly any[] | readonly [StringRecord] | Readonly<StringRecord>} ExecuteMethodArgs
73
+ */
@@ -2,7 +2,6 @@ import _ from 'lodash';
2
2
  import {fs, util, zip, tempDir} from '@appium/support';
3
3
  import path from 'path';
4
4
  import {errors} from 'appium/driver';
5
- import {requireArgs} from '../utils';
6
5
 
7
6
  const CONTAINER_PATH_MARKER = '@';
8
7
  // https://regex101.com/r/PLdB0G/2
@@ -11,7 +10,10 @@ const ANDROID_MEDIA_RESCAN_INTENT = 'android.intent.action.MEDIA_SCANNER_SCAN_FI
11
10
 
12
11
  /**
13
12
  * @this {import('../driver').AndroidDriver}
14
- * @param {string} remotePath
13
+ * @param {string} remotePath The full path to the remote file or a specially formatted path, which
14
+ * points to an item inside an app bundle, for example `@my.app.id/my/path`.
15
+ * It is mandatory for the app bundle to have debugging enabled in order to
16
+ * use the latter `remotePath` format.
15
17
  * @returns {Promise<string>}
16
18
  */
17
19
  export async function pullFile(remotePath) {
@@ -59,18 +61,11 @@ export async function pullFile(remotePath) {
59
61
 
60
62
  /**
61
63
  * @this {import('../driver').AndroidDriver}
62
- * @param {import('./types').PullFileOpts} opts
63
- * @returns {Promise<string>}
64
- */
65
- export async function mobilePullFile(opts) {
66
- const {remotePath} = requireArgs('remotePath', opts);
67
- return await this.pullFile(remotePath);
68
- }
69
-
70
- /**
71
- * @this {import('../driver').AndroidDriver}
72
- * @param {string} remotePath
73
- * @param {string} base64Data
64
+ * @param {string} remotePath The full path to the remote file or a specially formatted path, which
65
+ * points to an item inside an app bundle, for example `@my.app.id/my/path`.
66
+ * It is mandatory for the app bundle to have debugging enabled in order to
67
+ * use the latter `remotePath` format.
68
+ * @param {string} base64Data Base64-encoded content of the file to be pushed.
74
69
  * @returns {Promise<void>}
75
70
  */
76
71
  export async function pushFile(remotePath, base64Data) {
@@ -138,17 +133,7 @@ export async function pushFile(remotePath, base64Data) {
138
133
 
139
134
  /**
140
135
  * @this {import('../driver').AndroidDriver}
141
- * @param {import('./types').PushFileOpts} opts
142
- * @returns {Promise<void>}
143
- */
144
- export async function mobilePushFile(opts) {
145
- const {remotePath, payload} = requireArgs(['remotePath', 'payload'], opts);
146
- return await this.pushFile(remotePath, payload);
147
- }
148
-
149
- /**
150
- * @this {import('../driver').AndroidDriver}
151
- * @param {string} remotePath
136
+ * @param {string} remotePath The full path to the remote folder
152
137
  * @returns {Promise<string>}
153
138
  */
154
139
  export async function pullFolder(remotePath) {
@@ -167,21 +152,11 @@ export async function pullFolder(remotePath) {
167
152
 
168
153
  /**
169
154
  * @this {import('../driver').AndroidDriver}
170
- * @param {import('./types').PullFolderOpts} opts
171
- * @returns {Promise<string>}
172
- */
173
- export async function mobilePullFolder(opts) {
174
- const {remotePath} = requireArgs('remotePath', opts);
175
- return await this.pullFolder(remotePath);
176
- }
177
-
178
- /**
179
- * @this {import('../driver').AndroidDriver}
180
- * @param {import('./types').DeleteFileOpts} opts
155
+ * @param {string} remotePath The full path to the remote file or a file inside an application bundle
156
+ * (for example `@my.app.id/path/in/bundle`)
181
157
  * @returns {Promise<boolean>}
182
158
  */
183
- export async function mobileDeleteFile(opts) {
184
- const {remotePath} = requireArgs('remotePath', opts);
159
+ export async function mobileDeleteFile(remotePath) {
185
160
  if (remotePath.endsWith('/')) {
186
161
  throw new errors.InvalidArgumentError(
187
162
  `It is expected that remote path points to a folder and not to a file. ` +
@@ -37,10 +37,16 @@ export async function setGeoLocation(location) {
37
37
 
38
38
  /**
39
39
  * @this {import('../driver').AndroidDriver}
40
- * @param {import('@appium/types').Location} opts
40
+ * @param {number} latitude
41
+ * @param {number} longitude
42
+ * @param {number} [altitude]
41
43
  */
42
- export async function mobileSetGeolocation(opts) {
43
- await this.settingsApp.setGeoLocation(opts, this.isEmulator());
44
+ export async function mobileSetGeolocation(latitude, longitude, altitude) {
45
+ await this.settingsApp.setGeoLocation({
46
+ latitude,
47
+ longitude,
48
+ altitude,
49
+ }, this.isEmulator());
44
50
  }
45
51
 
46
52
  /**
@@ -51,11 +57,13 @@ export async function mobileSetGeolocation(opts) {
51
57
  * must be at version 30 (Android R) or higher.
52
58
  *
53
59
  * @this {import('../driver').AndroidDriver}
54
- * @param {import('./types').GpsCacheRefreshOpts} [opts={}]
60
+ * @param {number} [timeoutMs] The maximum number of milliseconds
61
+ * to block until GPS cache is refreshed. Providing zero or a negative
62
+ * value to it skips waiting completely.
63
+ * 20000ms by default.
55
64
  * @returns {Promise<void>}
56
65
  */
57
- export async function mobileRefreshGpsCache(opts = {}) {
58
- const {timeoutMs} = opts;
66
+ export async function mobileRefreshGpsCache(timeoutMs) {
59
67
  await this.settingsApp.refreshGeoLocationCache(timeoutMs);
60
68
  }
61
69
 
@@ -75,15 +75,14 @@ export async function prepareEmulatorForImageInjection(sdkRoot) {
75
75
  * `injectedImageProperties` capability.
76
76
  *
77
77
  * @this {AndroidDriver}
78
- * @param {import('./types').ImageInjectionOpts} opts
78
+ * @param {string} payload Base64-encoded payload of a .png image to be injected
79
79
  * @returns {Promise<void>}
80
80
  */
81
- export async function mobileInjectEmulatorCameraImage(opts) {
81
+ export async function mobileInjectEmulatorCameraImage(payload) {
82
82
  if (!this.isEmulator()) {
83
83
  throw new Error('The image injection feature is only available on emulators');
84
84
  }
85
85
 
86
- const {payload} = opts;
87
86
  if (!_.isString(payload) || _.size(payload) <= PNG_MAGIC_LENGTH) {
88
87
  throw new errors.InvalidArgumentError(
89
88
  `You must provide a valid base64-encoded .PNG data as the 'payload' argument`