appium-adb 14.0.6 → 14.0.7

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.
@@ -5,16 +5,29 @@ import { util, fs } from '@appium/support';
5
5
  import B from 'bluebird';
6
6
  import path from 'path';
7
7
  import * as ini from 'ini';
8
+ import type { ADB } from '../adb.js';
9
+ import type {
10
+ EmuInfo,
11
+ EmuVersionInfo,
12
+ StringRecord,
13
+ PowerAcStates,
14
+ Sensors,
15
+ GsmCallActions,
16
+ GsmSignalStrength,
17
+ GsmVoiceStates,
18
+ NetworkSpeed,
19
+ ExecTelnetOptions
20
+ } from './types.js';
8
21
 
9
22
  /**
10
23
  * Retrieves the list of available Android emulators
11
24
  *
12
- * @returns {Promise<import('./types').EmuInfo[]>}
25
+ * @returns
13
26
  */
14
- async function listEmulators () {
27
+ async function listEmulators (): Promise<EmuInfo[]> {
15
28
  let avdsRoot = process.env.ANDROID_AVD_HOME;
16
29
  if (await dirExists(avdsRoot ?? '')) {
17
- return await getAvdConfigPaths(/** @type {string} */ (avdsRoot));
30
+ return await getAvdConfigPaths(avdsRoot as string);
18
31
  }
19
32
 
20
33
  if (avdsRoot) {
@@ -38,10 +51,10 @@ async function listEmulators () {
38
51
  /**
39
52
  * Get configuration paths of all virtual devices
40
53
  *
41
- * @param {string} avdsRoot Path to the directory that contains the AVD .ini files
42
- * @returns {Promise<import('./types').EmuInfo[]>}
54
+ * @param avdsRoot Path to the directory that contains the AVD .ini files
55
+ * @returns
43
56
  */
44
- async function getAvdConfigPaths (avdsRoot) {
57
+ async function getAvdConfigPaths (avdsRoot: string): Promise<EmuInfo[]> {
45
58
  const configs = await fs.glob('*.ini', {
46
59
  cwd: avdsRoot,
47
60
  absolute: true,
@@ -55,21 +68,19 @@ async function getAvdConfigPaths (avdsRoot) {
55
68
  /**
56
69
  * Check the emulator state.
57
70
  *
58
- * @this {import('../adb.js').ADB}
59
- * @return {Promise<boolean>} True if Emulator is visible to adb.
71
+ * @returns True if Emulator is visible to adb.
60
72
  */
61
- export async function isEmulatorConnected () {
62
- let emulators = await this.getConnectedEmulators();
73
+ export async function isEmulatorConnected (this: ADB): Promise<boolean> {
74
+ const emulators = await this.getConnectedEmulators();
63
75
  return !!_.find(emulators, (x) => x && x.udid === this.curDeviceId);
64
76
  }
65
77
 
66
78
  /**
67
79
  * Verify the emulator is connected.
68
80
  *
69
- * @this {import('../adb.js').ADB}
70
- * @throws {Error} If Emulator is not visible to adb.
81
+ * @throws If Emulator is not visible to adb.
71
82
  */
72
- export async function verifyEmulatorConnected () {
83
+ export async function verifyEmulatorConnected (this: ADB): Promise<void> {
73
84
  if (!(await this.isEmulatorConnected())) {
74
85
  throw new Error(`The emulator "${this.curDeviceId}" was unexpectedly disconnected`);
75
86
  }
@@ -78,15 +89,14 @@ export async function verifyEmulatorConnected () {
78
89
  /**
79
90
  * Emulate fingerprint touch event on the connected emulator.
80
91
  *
81
- * @this {import('../adb.js').ADB}
82
- * @param {string} fingerprintId - The ID of the fingerprint.
92
+ * @param fingerprintId - The ID of the fingerprint.
83
93
  */
84
- export async function fingerprint (fingerprintId) {
94
+ export async function fingerprint (this: ADB, fingerprintId: string): Promise<void> {
85
95
  if (!fingerprintId) {
86
96
  throw new Error('Fingerprint id parameter must be defined');
87
97
  }
88
98
  // the method used only works for API level 23 and above
89
- let level = await this.getApiLevel();
99
+ const level = await this.getApiLevel();
90
100
  if (level < 23) {
91
101
  throw new Error(`Device API Level must be >= 23. Current Api level '${level}'`);
92
102
  }
@@ -97,19 +107,17 @@ export async function fingerprint (fingerprintId) {
97
107
  * Change the display orientation on the connected emulator.
98
108
  * The orientation is changed (PI/2 is added) every time
99
109
  * this method is called.
100
- * @this {import('../adb.js').ADB}
101
110
  */
102
- export async function rotate () {
111
+ export async function rotate (this: ADB): Promise<void> {
103
112
  await this.adbExecEmu(['rotate']);
104
113
  }
105
114
 
106
115
  /**
107
116
  * Emulate power state change on the connected emulator.
108
117
  *
109
- * @this {import('../adb.js').ADB}
110
- * @param {import('./types').PowerAcStates} [state='on'] - Either 'on' or 'off'.
118
+ * @param state - Either 'on' or 'off'.
111
119
  */
112
- export async function powerAC (state = 'on') {
120
+ export async function powerAC (this: ADB, state: PowerAcStates = 'on'): Promise<void> {
113
121
  if (_.values(this.POWER_AC_STATES).indexOf(state) === -1) {
114
122
  throw new TypeError(`Wrong power AC state sent '${state}'. `
115
123
  + `Supported values: ${_.values(this.POWER_AC_STATES)}]`);
@@ -120,12 +128,11 @@ export async function powerAC (state = 'on') {
120
128
  /**
121
129
  * Emulate sensors values on the connected emulator.
122
130
  *
123
- * @this {import('../adb.js').ADB}
124
- * @param {string} sensor - Sensor type declared in SENSORS items.
125
- * @param {import('./types').Sensors} value - Number to set as the sensor value.
126
- * @throws {TypeError} - If sensor type or sensor value is not defined
131
+ * @param sensor - Sensor type declared in SENSORS items.
132
+ * @param value - Number to set as the sensor value.
133
+ * @throws - If sensor type or sensor value is not defined
127
134
  */
128
- export async function sensorSet (sensor, value) {
135
+ export async function sensorSet (this: ADB, sensor: string, value: Sensors): Promise<void> {
129
136
  if (!_.includes(this.SENSORS, sensor)) {
130
137
  throw new TypeError(`Unsupported sensor sent '${sensor}'. `
131
138
  + `Supported values: ${_.values(this.SENSORS)}]`);
@@ -141,22 +148,20 @@ export async function sensorSet (sensor, value) {
141
148
  /**
142
149
  * Emulate power capacity change on the connected emulator.
143
150
  *
144
- * @this {import('../adb.js').ADB}
145
- * @param {string|number} [percent=100] - Percentage value in range [0, 100].
151
+ * @param percent - Percentage value in range [0, 100].
146
152
  */
147
- export async function powerCapacity (percent = 100) {
148
- percent = parseInt(`${percent}`, 10);
149
- if (isNaN(percent) || percent < 0 || percent > 100) {
153
+ export async function powerCapacity (this: ADB, percent: string | number = 100): Promise<void> {
154
+ const percentInt = parseInt(`${percent}`, 10);
155
+ if (isNaN(percentInt) || percentInt < 0 || percentInt > 100) {
150
156
  throw new TypeError(`The percentage value should be valid integer between 0 and 100`);
151
157
  }
152
- await this.adbExecEmu(['power', 'capacity', `${percent}`]);
158
+ await this.adbExecEmu(['power', 'capacity', `${percentInt}`]);
153
159
  }
154
160
 
155
161
  /**
156
162
  * Emulate power off event on the connected emulator.
157
- * @this {import('../adb.js').ADB}
158
163
  */
159
- export async function powerOFF () {
164
+ export async function powerOFF (this: ADB): Promise<void> {
160
165
  await this.powerAC(this.POWER_AC_STATES.POWER_AC_OFF);
161
166
  await this.powerCapacity(0);
162
167
  }
@@ -164,12 +169,11 @@ export async function powerOFF () {
164
169
  /**
165
170
  * Emulate send SMS event on the connected emulator.
166
171
  *
167
- * @this {import('../adb.js').ADB}
168
- * @param {string|number} phoneNumber - The phone number of message sender.
169
- * @param {string} [message=''] - The message content.
170
- * @throws {TypeError} If phone number has invalid format.
172
+ * @param phoneNumber - The phone number of message sender.
173
+ * @param message - The message content.
174
+ * @throws If phone number has invalid format.
171
175
  */
172
- export async function sendSMS (phoneNumber, message = '') {
176
+ export async function sendSMS (this: ADB, phoneNumber: string | number, message = ''): Promise<void> {
173
177
  if (_.isEmpty(message)) {
174
178
  throw new TypeError('SMS message must not be empty');
175
179
  }
@@ -182,13 +186,12 @@ export async function sendSMS (phoneNumber, message = '') {
182
186
  /**
183
187
  * Emulate GSM call event on the connected emulator.
184
188
  *
185
- * @this {import('../adb.js').ADB}
186
- * @param {string|number} phoneNumber - The phone number of the caller.
187
- * @param {import('./types').GsmCallActions} action - One of available GSM call actions.
188
- * @throws {TypeError} If phone number has invalid format.
189
- * @throws {TypeError} If _action_ value is invalid.
189
+ * @param phoneNumber - The phone number of the caller.
190
+ * @param action - One of available GSM call actions.
191
+ * @throws If phone number has invalid format.
192
+ * @throws If _action_ value is invalid.
190
193
  */
191
- export async function gsmCall (phoneNumber, action) {
194
+ export async function gsmCall (this: ADB, phoneNumber: string | number, action: GsmCallActions): Promise<void> {
192
195
  if (!_.values(this.GSM_CALL_ACTIONS).includes(action)) {
193
196
  throw new TypeError(
194
197
  `Invalid gsm action param ${action}. Supported values: ${_.values(this.GSM_CALL_ACTIONS)}`
@@ -203,11 +206,10 @@ export async function gsmCall (phoneNumber, action) {
203
206
  /**
204
207
  * Emulate GSM signal strength change event on the connected emulator.
205
208
  *
206
- * @this {import('../adb.js').ADB}
207
- * @param {import('./types').GsmSignalStrength} [strength=4] - A number in range [0, 4];
208
- * @throws {TypeError} If _strength_ value is invalid.
209
+ * @param strength - A number in range [0, 4];
210
+ * @throws If _strength_ value is invalid.
209
211
  */
210
- export async function gsmSignal (strength = 4) {
212
+ export async function gsmSignal (this: ADB, strength: GsmSignalStrength = 4): Promise<void> {
211
213
  const strengthInt = parseInt(`${strength}`, 10);
212
214
  if (!_.includes(this.GSM_SIGNAL_STRENGTHS, strengthInt)) {
213
215
  throw new TypeError(
@@ -221,11 +223,10 @@ export async function gsmSignal (strength = 4) {
221
223
  /**
222
224
  * Emulate GSM voice event on the connected emulator.
223
225
  *
224
- * @this {import('../adb.js').ADB}
225
- * @param {import('./types').GsmVoiceStates} [state='on'] - Either 'on' or 'off'.
226
- * @throws {TypeError} If _state_ value is invalid.
226
+ * @param state - Either 'on' or 'off'.
227
+ * @throws If _state_ value is invalid.
227
228
  */
228
- export async function gsmVoice (state = 'on') {
229
+ export async function gsmVoice (this: ADB, state: GsmVoiceStates = 'on'): Promise<void> {
229
230
  // gsm voice <state> allows you to change the state of your GPRS connection
230
231
  if (!_.values(this.GSM_VOICE_STATES).includes(state)) {
231
232
  throw new TypeError(
@@ -238,12 +239,11 @@ export async function gsmVoice (state = 'on') {
238
239
  /**
239
240
  * Emulate network speed change event on the connected emulator.
240
241
  *
241
- * @this {import('../adb.js').ADB}
242
- * @param {import('./types').NetworkSpeed} [speed='full']
242
+ * @param speed
243
243
  * One of possible NETWORK_SPEED values.
244
- * @throws {TypeError} If _speed_ value is invalid.
244
+ * @throws If _speed_ value is invalid.
245
245
  */
246
- export async function networkSpeed (speed = 'full') {
246
+ export async function networkSpeed (this: ADB, speed: NetworkSpeed = 'full'): Promise<void> {
247
247
  // network speed <speed> allows you to set the network speed emulation.
248
248
  if (!_.values(this.NETWORK_SPEED).includes(speed)) {
249
249
  throw new Error(
@@ -256,19 +256,18 @@ export async function networkSpeed (speed = 'full') {
256
256
  /**
257
257
  * Executes a command through emulator telnet console interface and returns its output
258
258
  *
259
- * @this {import('../adb.js').ADB}
260
- * @param {string[]|string} cmd - The actual command to execute. See
259
+ * @param cmd - The actual command to execute. See
261
260
  * https://developer.android.com/studio/run/emulator-console for more details
262
261
  * on available commands
263
- * @param {import('./types').ExecTelnetOptions} [opts={}]
264
- * @returns {Promise<string>} The command output
265
- * @throws {Error} If there was an error while connecting to the Telnet console
262
+ * @param opts
263
+ * @returns The command output
264
+ * @throws If there was an error while connecting to the Telnet console
266
265
  * or if the given command returned non-OK response
267
266
  */
268
- export async function execEmuConsoleCommand (cmd, opts = {}) {
267
+ export async function execEmuConsoleCommand (this: ADB, cmd: string[] | string, opts: ExecTelnetOptions = {}): Promise<string> {
269
268
  let port = parseInt(`${opts.port}`, 10);
270
269
  if (!port) {
271
- const portMatch = /emulator-(\d+)/i.exec(/** @type {string} */(this.curDeviceId));
270
+ const portMatch = /emulator-(\d+)/i.exec(this.curDeviceId as string);
272
271
  if (!portMatch) {
273
272
  throw new Error(`Cannot parse the console port number from the device identifier '${this.curDeviceId}'. ` +
274
273
  `Is it an emulator?`);
@@ -295,10 +294,10 @@ export async function execEmuConsoleCommand (cmd, opts = {}) {
295
294
  const connTimeoutObj = setTimeout(
296
295
  () => reject(new Error(`Cannot connect to the Emulator console at ${host}:${port} ` +
297
296
  `after ${connTimeout}ms`)), connTimeout);
298
- let execTimeoutObj;
299
- let initTimeoutObj;
297
+ let execTimeoutObj: NodeJS.Timeout;
298
+ let initTimeoutObj: NodeJS.Timeout;
300
299
  let isCommandSent = false;
301
- let serverResponse = [];
300
+ let serverResponse: Buffer[] = [];
302
301
 
303
302
  client.once('error', (e) => {
304
303
  clearTimeout(connTimeoutObj);
@@ -341,7 +340,7 @@ export async function execEmuConsoleCommand (cmd, opts = {}) {
341
340
  clearTimeout(execTimeoutObj);
342
341
  client.end();
343
342
  const outputArr = output.split(eol);
344
- return reject(_.trim(_.last(outputArr)));
343
+ return reject(_.trim(_.last(outputArr) || ''));
345
344
  }
346
345
  });
347
346
  });
@@ -350,19 +349,18 @@ export async function execEmuConsoleCommand (cmd, opts = {}) {
350
349
  /**
351
350
  * Retrieves emulator version from the file system
352
351
  *
353
- * @this {import('../adb.js').ADB}
354
- * @returns {Promise<import('./types').EmuVersionInfo>} If no version info could be parsed then an empty
352
+ * @returns If no version info could be parsed then an empty
355
353
  * object is returned
356
354
  */
357
- export async function getEmuVersionInfo () {
358
- const propsPath = path.join(/** @type {string} */ (this.sdkRoot), 'emulator', 'source.properties');
355
+ export async function getEmuVersionInfo (this: ADB): Promise<EmuVersionInfo> {
356
+ const propsPath = path.join(this.sdkRoot as string, 'emulator', 'source.properties');
359
357
  if (!await fs.exists(propsPath)) {
360
358
  return {};
361
359
  }
362
360
 
363
361
  const content = await fs.readFile(propsPath, 'utf8');
364
362
  const revisionMatch = /^Pkg\.Revision=([\d.]+)$/m.exec(content);
365
- const result = {};
363
+ const result: EmuVersionInfo = {};
366
364
  if (revisionMatch) {
367
365
  result.revision = revisionMatch[1];
368
366
  }
@@ -376,17 +374,16 @@ export async function getEmuVersionInfo () {
376
374
  /**
377
375
  * Retrieves emulator image properties from the local file system
378
376
  *
379
- * @this {import('../adb.js').ADB}
380
- * @param {string} avdName Emulator name. Should NOT start with '@' character
381
- * @throws {Error} if there was a failure while extracting the properties
382
- * @returns {Promise<import('./types').StringRecord>} The content of emulator image properties file.
377
+ * @param avdName Emulator name. Should NOT start with '@' character
378
+ * @throws if there was a failure while extracting the properties
379
+ * @returns The content of emulator image properties file.
383
380
  * Usually this configuration .ini file has the following content:
384
381
  * avd.ini.encoding=UTF-8
385
382
  * path=/Users/username/.android/avd/Pixel_XL_API_30.avd
386
383
  * path.rel=avd/Pixel_XL_API_30.avd
387
384
  * target=android-30
388
385
  */
389
- export async function getEmuImageProperties (avdName) {
386
+ export async function getEmuImageProperties (this: ADB, avdName: string): Promise<StringRecord> {
390
387
  const avds = await listEmulators();
391
388
  const avd = avds.find(({name}) => name === avdName);
392
389
  if (!avd) {
@@ -404,12 +401,11 @@ export async function getEmuImageProperties (avdName) {
404
401
  /**
405
402
  * Check if given emulator exists in the list of available avds.
406
403
  *
407
- * @this {import('../adb.js').ADB}
408
- * @param {string} avdName - The name of emulator to verify for existence.
404
+ * @param avdName - The name of emulator to verify for existence.
409
405
  * Should NOT start with '@' character
410
- * @throws {Error} If the emulator with given name does not exist.
406
+ * @throws If the emulator with given name does not exist.
411
407
  */
412
- export async function checkAvdExist (avdName) {
408
+ export async function checkAvdExist (this: ADB, avdName: string): Promise<boolean> {
413
409
  const avds = await listEmulators();
414
410
  if (!avds.some(({name}) => name === avdName)) {
415
411
  let msg = `Avd '${avdName}' is not available. `;
@@ -426,11 +422,10 @@ export async function checkAvdExist (avdName) {
426
422
  /**
427
423
  * Send an arbitrary Telnet command to the device under test.
428
424
  *
429
- * @this {import('../adb.js').ADB}
430
- * @param {string} command - The command to be sent.
431
- * @return {Promise<string>} The actual output of the given command.
425
+ * @param command - The command to be sent.
426
+ * @returns The actual output of the given command.
432
427
  */
433
- export async function sendTelnetCommand (command) {
428
+ export async function sendTelnetCommand (this: ADB, command: string): Promise<string> {
434
429
  return await this.execEmuConsoleCommand(command, {port: await this.getEmulatorPort()});
435
430
  }
436
431
 
@@ -440,9 +435,9 @@ export async function sendTelnetCommand (command) {
440
435
  /**
441
436
  * Retrieves the full path to the Android preferences root
442
437
  *
443
- * @returns {Promise<string?>} The full path to the folder or `null` if the folder cannot be found
438
+ * @returns The full path to the folder or `null` if the folder cannot be found
444
439
  */
445
- async function getAndroidPrefsRoot () {
440
+ async function getAndroidPrefsRoot (): Promise<string | null> {
446
441
  let location = process.env.ANDROID_EMULATOR_HOME;
447
442
  if (await dirExists(location ?? '')) {
448
443
  return location ?? null;
@@ -468,11 +463,12 @@ async function getAndroidPrefsRoot () {
468
463
  /**
469
464
  * Check if a path exists on the filesystem and is a directory
470
465
  *
471
- * @param {string} location The full path to the directory
472
- * @returns {Promise<boolean>}
466
+ * @param location The full path to the directory
467
+ * @returns
473
468
  */
474
- async function dirExists (location) {
469
+ async function dirExists (location: string): Promise<boolean> {
475
470
  return await fs.exists(location) && (await fs.stat(location)).isDirectory();
476
471
  }
477
472
 
478
473
  // #endregion
474
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appium-adb",
3
- "version": "14.0.6",
3
+ "version": "14.0.7",
4
4
  "description": "Android Debug Bridge interface",
5
5
  "main": "./build/index.js",
6
6
  "scripts": {