appium-android-driver 14.0.2 → 14.0.4
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 +1 -1
- package/build/lib/commands/app-management.d.ts.map +1 -1
- package/build/lib/commands/app-management.js +2 -4
- package/build/lib/commands/app-management.js.map +1 -1
- package/build/lib/commands/appearance.d.ts.map +1 -1
- package/build/lib/commands/appearance.js.map +1 -1
- package/build/lib/commands/bidi/models.d.ts +1 -1
- package/build/lib/commands/bidi/models.d.ts.map +1 -1
- package/build/lib/commands/bidi/models.js +1 -1
- package/build/lib/commands/bidi/models.js.map +1 -1
- package/build/lib/commands/bluetooth.d.ts.map +1 -1
- package/build/lib/commands/bluetooth.js.map +1 -1
- package/build/lib/commands/context/cache.d.ts +1 -1
- package/build/lib/commands/context/cache.d.ts.map +1 -1
- package/build/lib/commands/context/cache.js.map +1 -1
- package/build/lib/commands/context/exports.d.ts.map +1 -1
- package/build/lib/commands/context/exports.js +3 -4
- package/build/lib/commands/context/exports.js.map +1 -1
- package/build/lib/commands/context/helpers.d.ts.map +1 -1
- package/build/lib/commands/context/helpers.js +21 -26
- package/build/lib/commands/context/helpers.js.map +1 -1
- package/build/lib/commands/device/common.d.ts +1 -1
- package/build/lib/commands/device/common.d.ts.map +1 -1
- package/build/lib/commands/device/common.js +8 -16
- package/build/lib/commands/device/common.js.map +1 -1
- package/build/lib/commands/device/emulator-actions.d.ts.map +1 -1
- package/build/lib/commands/device/emulator-actions.js +1 -1
- package/build/lib/commands/device/emulator-actions.js.map +1 -1
- package/build/lib/commands/device/emulator-console.d.ts.map +1 -1
- package/build/lib/commands/device/emulator-console.js.map +1 -1
- package/build/lib/commands/device/utils.d.ts.map +1 -1
- package/build/lib/commands/device/utils.js +5 -6
- package/build/lib/commands/device/utils.js.map +1 -1
- package/build/lib/commands/deviceidle.d.ts.map +1 -1
- package/build/lib/commands/deviceidle.js.map +1 -1
- package/build/lib/commands/element.d.ts.map +1 -1
- package/build/lib/commands/element.js.map +1 -1
- package/build/lib/commands/execute.d.ts.map +1 -1
- package/build/lib/commands/execute.js +2 -4
- package/build/lib/commands/execute.js.map +1 -1
- package/build/lib/commands/file-actions.d.ts.map +1 -1
- package/build/lib/commands/file-actions.js +6 -20
- package/build/lib/commands/file-actions.js.map +1 -1
- package/build/lib/commands/find.d.ts +1 -1
- package/build/lib/commands/find.d.ts.map +1 -1
- package/build/lib/commands/find.js +1 -1
- package/build/lib/commands/find.js.map +1 -1
- package/build/lib/commands/geolocation.d.ts.map +1 -1
- package/build/lib/commands/geolocation.js +5 -12
- package/build/lib/commands/geolocation.js.map +1 -1
- package/build/lib/commands/gestures.d.ts.map +1 -1
- package/build/lib/commands/gestures.js.map +1 -1
- package/build/lib/commands/image-injection.d.ts.map +1 -1
- package/build/lib/commands/image-injection.js +2 -2
- package/build/lib/commands/image-injection.js.map +1 -1
- package/build/lib/commands/ime.d.ts.map +1 -1
- package/build/lib/commands/ime.js +1 -7
- package/build/lib/commands/ime.js.map +1 -1
- package/build/lib/commands/intent.d.ts.map +1 -1
- package/build/lib/commands/intent.js +2 -3
- package/build/lib/commands/intent.js.map +1 -1
- package/build/lib/commands/keyboard.d.ts.map +1 -1
- package/build/lib/commands/keyboard.js.map +1 -1
- package/build/lib/commands/legacy.d.ts.map +1 -1
- package/build/lib/commands/legacy.js.map +1 -1
- package/build/lib/commands/lock/exports.d.ts.map +1 -1
- package/build/lib/commands/lock/exports.js.map +1 -1
- package/build/lib/commands/lock/helpers.d.ts.map +1 -1
- package/build/lib/commands/lock/helpers.js +3 -10
- package/build/lib/commands/lock/helpers.js.map +1 -1
- package/build/lib/commands/log.d.ts +1 -1
- package/build/lib/commands/log.d.ts.map +1 -1
- package/build/lib/commands/log.js +6 -8
- package/build/lib/commands/log.js.map +1 -1
- package/build/lib/commands/media-projection.d.ts.map +1 -1
- package/build/lib/commands/media-projection.js +2 -2
- package/build/lib/commands/media-projection.js.map +1 -1
- package/build/lib/commands/memory.d.ts.map +1 -1
- package/build/lib/commands/memory.js.map +1 -1
- package/build/lib/commands/misc.d.ts.map +1 -1
- package/build/lib/commands/misc.js.map +1 -1
- package/build/lib/commands/network.d.ts.map +1 -1
- package/build/lib/commands/network.js +4 -11
- package/build/lib/commands/network.js.map +1 -1
- package/build/lib/commands/nfc.d.ts.map +1 -1
- 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 +4 -21
- package/build/lib/commands/performance.js.map +1 -1
- package/build/lib/commands/permissions.d.ts.map +1 -1
- package/build/lib/commands/permissions.js +4 -7
- package/build/lib/commands/permissions.js.map +1 -1
- package/build/lib/commands/recordscreen.d.ts.map +1 -1
- package/build/lib/commands/recordscreen.js +2 -2
- package/build/lib/commands/recordscreen.js.map +1 -1
- package/build/lib/commands/resources.d.ts.map +1 -1
- 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 -6
- package/build/lib/commands/shell.js.map +1 -1
- package/build/lib/commands/streamscreen.d.ts.map +1 -1
- package/build/lib/commands/streamscreen.js +6 -9
- package/build/lib/commands/streamscreen.js.map +1 -1
- package/build/lib/commands/system-bars.d.ts.map +1 -1
- package/build/lib/commands/system-bars.js +1 -1
- package/build/lib/commands/system-bars.js.map +1 -1
- package/build/lib/commands/time.d.ts.map +1 -1
- package/build/lib/commands/time.js +1 -1
- package/build/lib/commands/time.js.map +1 -1
- package/build/lib/commands/types.d.ts +4 -4
- package/build/lib/commands/types.d.ts.map +1 -1
- package/build/lib/doctor/checks.d.ts.map +1 -1
- package/build/lib/doctor/checks.js +2 -2
- package/build/lib/doctor/checks.js.map +1 -1
- package/build/lib/driver.d.ts +8 -8
- package/build/lib/driver.d.ts.map +1 -1
- package/build/lib/driver.js +14 -20
- package/build/lib/driver.js.map +1 -1
- package/build/lib/execute-method-map.d.ts.map +1 -1
- package/build/lib/execute-method-map.js +1 -10
- package/build/lib/execute-method-map.js.map +1 -1
- package/build/lib/index.d.ts +1 -1
- package/build/lib/index.d.ts.map +1 -1
- package/build/lib/index.js +1 -1
- package/build/lib/index.js.map +1 -1
- package/build/lib/method-map.d.ts.map +1 -1
- package/build/lib/method-map.js.map +1 -1
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js +1 -1
- package/build/lib/utils.js.map +1 -1
- package/lib/commands/app-management.ts +15 -43
- package/lib/commands/appearance.ts +1 -5
- package/lib/commands/bidi/models.ts +5 -12
- package/lib/commands/bluetooth.ts +1 -0
- package/lib/commands/context/cache.ts +2 -1
- package/lib/commands/context/exports.ts +17 -40
- package/lib/commands/context/helpers.ts +37 -88
- package/lib/commands/device/common.ts +16 -29
- package/lib/commands/device/emulator-actions.ts +12 -49
- package/lib/commands/device/emulator-console.ts +1 -0
- package/lib/commands/device/utils.ts +7 -16
- package/lib/commands/deviceidle.ts +1 -0
- package/lib/commands/element.ts +6 -20
- package/lib/commands/execute.ts +6 -13
- package/lib/commands/file-actions.ts +17 -50
- package/lib/commands/find.ts +4 -6
- package/lib/commands/geolocation.ts +9 -17
- package/lib/commands/gestures.ts +2 -1
- package/lib/commands/image-injection.ts +9 -19
- package/lib/commands/ime.ts +2 -7
- package/lib/commands/intent.ts +3 -3
- package/lib/commands/keyboard.ts +4 -14
- package/lib/commands/legacy.ts +1 -0
- package/lib/commands/lock/exports.ts +5 -10
- package/lib/commands/lock/helpers.ts +17 -52
- package/lib/commands/log.ts +12 -22
- package/lib/commands/media-projection.ts +9 -21
- package/lib/commands/memory.ts +2 -5
- package/lib/commands/misc.ts +3 -5
- package/lib/commands/network.ts +9 -27
- package/lib/commands/nfc.ts +1 -0
- package/lib/commands/performance.ts +12 -48
- package/lib/commands/permissions.ts +10 -22
- package/lib/commands/recordscreen.ts +16 -41
- package/lib/commands/resources.ts +3 -9
- package/lib/commands/shell.ts +3 -7
- package/lib/commands/streamscreen.ts +17 -37
- package/lib/commands/system-bars.ts +7 -13
- package/lib/commands/time.ts +4 -8
- package/lib/commands/types.ts +9 -10
- package/lib/doctor/checks.ts +11 -18
- package/lib/driver.ts +43 -65
- package/lib/execute-method-map.ts +1 -10
- package/lib/index.ts +1 -1
- package/lib/method-map.ts +1 -0
- package/lib/utils.ts +4 -6
- package/package.json +24 -38
|
@@ -1,15 +1,13 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
|
|
1
3
|
import {fs, net, system, tempDir, timing, util} from '@appium/support';
|
|
2
4
|
import type {NetOptions, HttpUploadOptions} from '@appium/support';
|
|
5
|
+
import type {ADB} from 'appium-adb';
|
|
3
6
|
import {waitForCondition} from 'asyncbox';
|
|
4
|
-
import path from 'node:path';
|
|
5
7
|
import {exec} from 'teen_process';
|
|
8
|
+
|
|
6
9
|
import type {AndroidDriver} from '../driver.js';
|
|
7
|
-
import type {
|
|
8
|
-
import type {
|
|
9
|
-
StartScreenRecordingOpts,
|
|
10
|
-
StopScreenRecordingOpts,
|
|
11
|
-
ScreenRecordingProperties,
|
|
12
|
-
} from './types.js';
|
|
10
|
+
import type {StartScreenRecordingOpts, StopScreenRecordingOpts, ScreenRecordingProperties} from './types.js';
|
|
13
11
|
|
|
14
12
|
const RETRY_PAUSE = 300;
|
|
15
13
|
const RETRY_TIMEOUT = 5000;
|
|
@@ -43,13 +41,7 @@ export async function startRecordingScreen(
|
|
|
43
41
|
await verifyScreenRecordIsSupported(this.adb, this.isEmulator());
|
|
44
42
|
|
|
45
43
|
let result = '';
|
|
46
|
-
const {
|
|
47
|
-
videoSize,
|
|
48
|
-
timeLimit = DEFAULT_RECORDING_TIME_SEC,
|
|
49
|
-
bugReport,
|
|
50
|
-
bitRate,
|
|
51
|
-
forceRestart,
|
|
52
|
-
} = options;
|
|
44
|
+
const {videoSize, timeLimit = DEFAULT_RECORDING_TIME_SEC, bugReport, bitRate, forceRestart} = options;
|
|
53
45
|
if (!forceRestart) {
|
|
54
46
|
result = await this.stopRecordingScreen(options);
|
|
55
47
|
}
|
|
@@ -109,10 +101,7 @@ export async function startRecordingScreen(
|
|
|
109
101
|
* @throws {Error} If screen recording is not supported, no recording was active,
|
|
110
102
|
* or if the recording process cannot be stopped.
|
|
111
103
|
*/
|
|
112
|
-
export async function stopRecordingScreen(
|
|
113
|
-
this: AndroidDriver,
|
|
114
|
-
options: StopScreenRecordingOpts = {},
|
|
115
|
-
): Promise<string> {
|
|
104
|
+
export async function stopRecordingScreen(this: AndroidDriver, options: StopScreenRecordingOpts = {}): Promise<string> {
|
|
116
105
|
await verifyScreenRecordIsSupported(this.adb, this.isEmulator());
|
|
117
106
|
|
|
118
107
|
const props = this._screenRecordingProperties;
|
|
@@ -130,9 +119,7 @@ export async function stopRecordingScreen(
|
|
|
130
119
|
}
|
|
131
120
|
|
|
132
121
|
if (!props) {
|
|
133
|
-
this.log.info(
|
|
134
|
-
`Screen recording has not been previously started by Appium. There is nothing to stop`,
|
|
135
|
-
);
|
|
122
|
+
this.log.info(`Screen recording has not been previously started by Appium. There is nothing to stop`);
|
|
136
123
|
return '';
|
|
137
124
|
}
|
|
138
125
|
|
|
@@ -140,9 +127,7 @@ export async function stopRecordingScreen(
|
|
|
140
127
|
try {
|
|
141
128
|
await props.recordingProcess.stop('SIGINT', PROCESS_SHUTDOWN_TIMEOUT);
|
|
142
129
|
} catch {
|
|
143
|
-
throw this.log.errorWithException(
|
|
144
|
-
`Unable to stop screen recording within ${PROCESS_SHUTDOWN_TIMEOUT}ms`,
|
|
145
|
-
);
|
|
130
|
+
throw this.log.errorWithException(`Unable to stop screen recording within ${PROCESS_SHUTDOWN_TIMEOUT}ms`);
|
|
146
131
|
}
|
|
147
132
|
props.recordingProcess = null;
|
|
148
133
|
}
|
|
@@ -177,9 +162,7 @@ export async function stopRecordingScreen(
|
|
|
177
162
|
}
|
|
178
163
|
if (util.isEmpty(options.remotePath)) {
|
|
179
164
|
const {size} = await fs.stat(resultFilePath);
|
|
180
|
-
this.log.debug(
|
|
181
|
-
`The size of the resulting screen recording is ${util.toReadableSizeString(size)}`,
|
|
182
|
-
);
|
|
165
|
+
this.log.debug(`The size of the resulting screen recording is ${util.toReadableSizeString(size)}`);
|
|
183
166
|
}
|
|
184
167
|
return await uploadRecordedMedia(resultFilePath, options.remotePath, options);
|
|
185
168
|
} finally {
|
|
@@ -307,14 +290,9 @@ async function mergeScreenRecords(this: AndroidDriver, mediaFiles: string[]): Pr
|
|
|
307
290
|
const configFile = path.resolve(path.dirname(mediaFiles[0]), 'config.txt');
|
|
308
291
|
await fs.writeFile(configFile, configContent, 'utf8');
|
|
309
292
|
this.log.debug(`Generated ffmpeg merging config '${configFile}' with items:\n${configContent}`);
|
|
310
|
-
const result = path.resolve(
|
|
311
|
-
path.dirname(mediaFiles[0]),
|
|
312
|
-
`merge_${Math.floor(+new Date())}${DEFAULT_EXT}`,
|
|
313
|
-
);
|
|
293
|
+
const result = path.resolve(path.dirname(mediaFiles[0]), `merge_${Math.floor(+new Date())}${DEFAULT_EXT}`);
|
|
314
294
|
const args = ['-safe', '0', '-f', 'concat', '-i', configFile, '-c', 'copy', result];
|
|
315
|
-
this.log.info(
|
|
316
|
-
`Initiating screen records merging using the command '${FFMPEG_BINARY} ${args.join(' ')}'`,
|
|
317
|
-
);
|
|
295
|
+
this.log.info(`Initiating screen records merging using the command '${FFMPEG_BINARY} ${args.join(' ')}'`);
|
|
318
296
|
await exec(FFMPEG_BINARY, args);
|
|
319
297
|
return result;
|
|
320
298
|
}
|
|
@@ -327,13 +305,10 @@ async function terminateBackgroundScreenRecording(adb: ADB, force = true): Promi
|
|
|
327
305
|
|
|
328
306
|
try {
|
|
329
307
|
await adb.shell(['kill', force ? '-15' : '-2', ...screenrecordPids.map(String)]);
|
|
330
|
-
await waitForCondition(
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
intervalMs: 500,
|
|
335
|
-
},
|
|
336
|
-
);
|
|
308
|
+
await waitForCondition(async () => util.isEmpty(await adb.getProcessIdsByName(SCREENRECORD_BINARY)), {
|
|
309
|
+
waitMs: PROCESS_SHUTDOWN_TIMEOUT,
|
|
310
|
+
intervalMs: 500,
|
|
311
|
+
});
|
|
337
312
|
return true;
|
|
338
313
|
} catch (err) {
|
|
339
314
|
throw new Error(`Unable to stop the background screen recording: ${(err as Error).message}`, {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {fs, tempDir, util} from '@appium/support';
|
|
2
2
|
import type {StringRecord} from '@appium/types';
|
|
3
|
+
|
|
3
4
|
import type {AndroidDriver, AndroidDriverOpts} from '../driver.js';
|
|
4
5
|
import type {Locale} from './types.js';
|
|
5
6
|
|
|
@@ -10,10 +11,7 @@ import type {Locale} from './types.js';
|
|
|
10
11
|
* the device's current language will be used.
|
|
11
12
|
* @returns Promise that resolves to a mapping of string keys to their localized values.
|
|
12
13
|
*/
|
|
13
|
-
export async function getStrings(
|
|
14
|
-
this: AndroidDriver,
|
|
15
|
-
language: string | null = null,
|
|
16
|
-
): Promise<StringRecord> {
|
|
14
|
+
export async function getStrings(this: AndroidDriver, language: string | null = null): Promise<StringRecord> {
|
|
17
15
|
if (!language) {
|
|
18
16
|
language = await this.adb.getDeviceLanguage();
|
|
19
17
|
this.log.info(`No language specified, returning strings for: ${language}`);
|
|
@@ -105,11 +103,7 @@ async function extractStringsFromResources(
|
|
|
105
103
|
}
|
|
106
104
|
}
|
|
107
105
|
|
|
108
|
-
async function fetchLocaleSuggestions(
|
|
109
|
-
this: AndroidDriver,
|
|
110
|
-
language?: string,
|
|
111
|
-
country?: string,
|
|
112
|
-
): Promise<Locale[]> {
|
|
106
|
+
async function fetchLocaleSuggestions(this: AndroidDriver, language?: string, country?: string): Promise<Locale[]> {
|
|
113
107
|
const supportedLocales = await this.settingsApp.listSupportedLocales();
|
|
114
108
|
const suggestedLocales = supportedLocales.filter(
|
|
115
109
|
(locale) =>
|
package/lib/commands/shell.ts
CHANGED
|
@@ -2,8 +2,9 @@ import {util} from '@appium/support';
|
|
|
2
2
|
import {errors} from 'appium/driver.js';
|
|
3
3
|
import {exec} from 'teen_process';
|
|
4
4
|
import type {ExecError} from 'teen_process';
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
import type {AndroidDriver} from '../driver.js';
|
|
7
|
+
import {ADB_SHELL_FEATURE} from '../utils.js';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Executes a shell command on the device via ADB.
|
|
@@ -39,12 +40,7 @@ export async function mobileShell<T extends boolean>(
|
|
|
39
40
|
throw new errors.InvalidArgumentError(`The 'command' argument is mandatory`);
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
const adbArgs = [
|
|
43
|
-
...this.adb.executable.defaultArgs,
|
|
44
|
-
'shell',
|
|
45
|
-
command,
|
|
46
|
-
...(Array.isArray(args) ? args : [args]),
|
|
47
|
-
];
|
|
43
|
+
const adbArgs = [...this.adb.executable.defaultArgs, 'shell', command, ...(Array.isArray(args) ? args : [args])];
|
|
48
44
|
this.log.debug(`Running '${this.adb.executable.path} ${util.quote(adbArgs)}'`);
|
|
49
45
|
try {
|
|
50
46
|
const {stdout, stderr} = await exec(this.adb.executable.path, adbArgs, {timeout});
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import {fs, logger, system, util} from '@appium/support';
|
|
2
|
-
import {waitForCondition} from 'asyncbox';
|
|
3
1
|
import {spawn} from 'node:child_process';
|
|
4
2
|
import http from 'node:http';
|
|
5
3
|
import net from 'node:net';
|
|
6
4
|
import url from 'node:url';
|
|
5
|
+
|
|
6
|
+
import {fs, logger, system, util} from '@appium/support';
|
|
7
|
+
import type {AppiumLogger} from '@appium/types';
|
|
8
|
+
import type {ADB} from 'appium-adb';
|
|
9
|
+
import {waitForCondition} from 'asyncbox';
|
|
7
10
|
import {checkPortStatus} from 'portscanner';
|
|
8
11
|
import {SubProcess, exec} from 'teen_process';
|
|
12
|
+
|
|
9
13
|
import type {AndroidDriver} from '../driver.js';
|
|
10
|
-
import type {ADB} from 'appium-adb';
|
|
11
|
-
import type {AppiumLogger} from '@appium/types';
|
|
12
14
|
import type {DeviceInfo, InitGStreamerPipelineOpts} from './types.js';
|
|
13
15
|
|
|
14
16
|
const RECORDING_INTERVAL_SEC = 5;
|
|
@@ -91,22 +93,16 @@ export async function mobileStartScreenStreaming(
|
|
|
91
93
|
if (this._screenStreamingProps === undefined) {
|
|
92
94
|
await verifyStreamingRequirements(this.adb);
|
|
93
95
|
} else {
|
|
94
|
-
this.log.info(
|
|
95
|
-
`The screen streaming session is already running. ` +
|
|
96
|
-
`Stop it first in order to start a new one.`,
|
|
97
|
-
);
|
|
96
|
+
this.log.info(`The screen streaming session is already running. Stop it first in order to start a new one.`);
|
|
98
97
|
return;
|
|
99
98
|
}
|
|
100
99
|
if ((await checkPortStatus(port, host)) === 'open') {
|
|
101
|
-
this.log.info(
|
|
102
|
-
`The port #${port} at ${host} is busy. ` + `Assuming the screen streaming is already running`,
|
|
103
|
-
);
|
|
100
|
+
this.log.info(`The port #${port} at ${host} is busy. Assuming the screen streaming is already running`);
|
|
104
101
|
return;
|
|
105
102
|
}
|
|
106
103
|
if ((await checkPortStatus(tcpPort, TCP_HOST)) === 'open') {
|
|
107
104
|
throw this.log.errorWithException(
|
|
108
|
-
`The port #${tcpPort} at ${TCP_HOST} is busy.
|
|
109
|
-
`Make sure there are no leftovers from previous sessions.`,
|
|
105
|
+
`The port #${tcpPort} at ${TCP_HOST} is busy. Make sure there are no leftovers from previous sessions.`,
|
|
110
106
|
);
|
|
111
107
|
}
|
|
112
108
|
this._screenStreamingProps = undefined;
|
|
@@ -139,12 +135,7 @@ export async function mobileStartScreenStreaming(
|
|
|
139
135
|
let mjpegConnectTimeoutId: ReturnType<typeof setTimeout> | undefined;
|
|
140
136
|
const mjpegConnectTimeoutPromise = new Promise<never>((_resolve, reject) => {
|
|
141
137
|
mjpegConnectTimeoutId = setTimeout(
|
|
142
|
-
() =>
|
|
143
|
-
reject(
|
|
144
|
-
new Error(
|
|
145
|
-
`Cannot connect to the streaming server within ${STREAMING_STARTUP_TIMEOUT_MS}ms`,
|
|
146
|
-
),
|
|
147
|
-
),
|
|
138
|
+
() => reject(new Error(`Cannot connect to the streaming server within ${STREAMING_STARTUP_TIMEOUT_MS}ms`)),
|
|
148
139
|
STREAMING_STARTUP_TIMEOUT_MS,
|
|
149
140
|
);
|
|
150
141
|
});
|
|
@@ -160,9 +151,7 @@ export async function mobileStartScreenStreaming(
|
|
|
160
151
|
);
|
|
161
152
|
|
|
162
153
|
if (pathname && currentPathname !== pathname) {
|
|
163
|
-
this.log.info(
|
|
164
|
-
'Rejecting the broadcast request since it does not match the given pathname',
|
|
165
|
-
);
|
|
154
|
+
this.log.info('Rejecting the broadcast request since it does not match the given pathname');
|
|
166
155
|
res.writeHead(404, {
|
|
167
156
|
Connection: 'close',
|
|
168
157
|
'Content-Type': 'text/plain; charset=utf-8',
|
|
@@ -174,8 +163,7 @@ export async function mobileStartScreenStreaming(
|
|
|
174
163
|
|
|
175
164
|
this.log.info('Starting MJPEG broadcast');
|
|
176
165
|
res.writeHead(200, {
|
|
177
|
-
'Cache-Control':
|
|
178
|
-
'no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0',
|
|
166
|
+
'Cache-Control': 'no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0',
|
|
179
167
|
Pragma: 'no-cache',
|
|
180
168
|
Connection: 'close',
|
|
181
169
|
'Content-Type': `multipart/x-mixed-replace; boundary=${BOUNDARY_STRING}`,
|
|
@@ -253,8 +241,7 @@ export async function mobileStopScreenStreaming(this: AndroidDriver): Promise<vo
|
|
|
253
241
|
return;
|
|
254
242
|
}
|
|
255
243
|
|
|
256
|
-
const {deviceStreamingProc, gstreamerPipeline, mjpegSocket, mjpegServer} =
|
|
257
|
-
this._screenStreamingProps;
|
|
244
|
+
const {deviceStreamingProc, gstreamerPipeline, mjpegSocket, mjpegServer} = this._screenStreamingProps;
|
|
258
245
|
|
|
259
246
|
try {
|
|
260
247
|
mjpegSocket.end();
|
|
@@ -296,9 +283,7 @@ function createStreamingLogger(streamName: string, udid: string): AppiumLogger {
|
|
|
296
283
|
|
|
297
284
|
async function verifyStreamingRequirements(adb: ADB): Promise<void> {
|
|
298
285
|
if (!(await adb.shell(['which', SCREENRECORD_BINARY])).trim()) {
|
|
299
|
-
throw new Error(
|
|
300
|
-
`The required '${SCREENRECORD_BINARY}' binary is not available on the device under test`,
|
|
301
|
-
);
|
|
286
|
+
throw new Error(`The required '${SCREENRECORD_BINARY}' binary is not available on the device under test`);
|
|
302
287
|
}
|
|
303
288
|
|
|
304
289
|
const gstreamerCheckPromises: Promise<void>[] = [];
|
|
@@ -349,8 +334,7 @@ async function getDeviceInfo(adb: ADB, log?: AppiumLogger): Promise<DeviceInfo>
|
|
|
349
334
|
if (!match) {
|
|
350
335
|
log?.debug(output);
|
|
351
336
|
throw new Error(
|
|
352
|
-
`Cannot parse the device ${key} from the adb command output.
|
|
353
|
-
`Check the server log for more details.`,
|
|
337
|
+
`Cannot parse the device ${key} from the adb command output. Check the server log for more details.`,
|
|
354
338
|
);
|
|
355
339
|
}
|
|
356
340
|
result[key] = parseInt(match[1], 10);
|
|
@@ -416,9 +400,7 @@ async function initDeviceStreamingProc(
|
|
|
416
400
|
intervalMs: 300,
|
|
417
401
|
});
|
|
418
402
|
} catch (e) {
|
|
419
|
-
throw log.errorWithException(
|
|
420
|
-
`Cannot start the screen streaming process. Original error: ${(e as Error).message}`,
|
|
421
|
-
);
|
|
403
|
+
throw log.errorWithException(`Cannot start the screen streaming process. Original error: ${(e as Error).message}`);
|
|
422
404
|
} finally {
|
|
423
405
|
deviceStreaming.stderr.removeListener('data', errorsListener);
|
|
424
406
|
deviceStreaming.stdout.removeListener('data', startupListener);
|
|
@@ -501,9 +483,7 @@ async function initGstreamerPipeline(
|
|
|
501
483
|
);
|
|
502
484
|
} catch (e) {
|
|
503
485
|
didFail = true;
|
|
504
|
-
throw log.errorWithException(
|
|
505
|
-
`Cannot start the screen streaming pipeline. Original error: ${(e as Error).message}`,
|
|
506
|
-
);
|
|
486
|
+
throw log.errorWithException(`Cannot start the screen streaming pipeline. Original error: ${(e as Error).message}`);
|
|
507
487
|
} finally {
|
|
508
488
|
if (!logPipelineDetails || didFail) {
|
|
509
489
|
gstreamerPipeline.removeListener('output', gstOutputListener);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {util} from '@appium/support';
|
|
2
2
|
import type {StringRecord} from '@appium/types';
|
|
3
|
+
import {errors} from 'appium/driver.js';
|
|
4
|
+
|
|
3
5
|
import type {AndroidDriver} from '../driver.js';
|
|
4
6
|
import type {StatusBarCommand, WindowProperties} from './types.js';
|
|
5
|
-
import {util} from '@appium/support';
|
|
6
7
|
|
|
7
8
|
const WINDOW_TITLE_PATTERN = /^\s+Window\s#\d+\sWindow\{[0-9a-f]+\s\w+\s([\w-]+)\}:$/;
|
|
8
9
|
const FRAME_PATTERN = /\bm?[Ff]rame=\[([0-9.-]+),([0-9.-]+)\]\[([0-9.-]+),([0-9.-]+)\]/;
|
|
@@ -38,12 +39,9 @@ export async function getSystemBars(this: AndroidDriver): Promise<StringRecord>
|
|
|
38
39
|
try {
|
|
39
40
|
stdout = await this.adb.shell(['dumpsys', 'window', 'windows']);
|
|
40
41
|
} catch (e) {
|
|
41
|
-
throw new Error(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
cause: e,
|
|
45
|
-
},
|
|
46
|
-
);
|
|
42
|
+
throw new Error(`Cannot retrieve system bars details. Original error: ${(e as Error).message}`, {
|
|
43
|
+
cause: e,
|
|
44
|
+
});
|
|
47
45
|
}
|
|
48
46
|
return parseWindows.bind(this)(stdout);
|
|
49
47
|
}
|
|
@@ -105,11 +103,7 @@ export async function mobilePerformStatusBarCommand(
|
|
|
105
103
|
* @returns Parsed properties object
|
|
106
104
|
* @throws {Error} If there was an issue while parsing the properties string
|
|
107
105
|
*/
|
|
108
|
-
export function parseWindowProperties(
|
|
109
|
-
this: AndroidDriver,
|
|
110
|
-
name: string,
|
|
111
|
-
props: string[],
|
|
112
|
-
): WindowProperties {
|
|
106
|
+
export function parseWindowProperties(this: AndroidDriver, name: string, props: string[]): WindowProperties {
|
|
113
107
|
const result = structuredClone(DEFAULT_WINDOW_PROPERTIES);
|
|
114
108
|
const propLines = props.join('\n');
|
|
115
109
|
const frameMatch = FRAME_PATTERN.exec(propLines);
|
package/lib/commands/time.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import dayjs from 'dayjs';
|
|
2
|
-
import utc from 'dayjs/plugin/utc.js';
|
|
3
2
|
import customParseFormat from 'dayjs/plugin/customParseFormat.js';
|
|
3
|
+
import utc from 'dayjs/plugin/utc.js';
|
|
4
|
+
|
|
4
5
|
import type {AndroidDriver} from '../driver.js';
|
|
5
6
|
|
|
6
7
|
dayjs.extend(utc);
|
|
@@ -14,13 +15,8 @@ const DATETIME_FORMAT_ISO8601 = 'YYYY-MM-DDTHH:mm:ssZ';
|
|
|
14
15
|
* @param format The format string for the time. Defaults to ISO8601 format.
|
|
15
16
|
* @returns Promise that resolves to the formatted device time string.
|
|
16
17
|
*/
|
|
17
|
-
export async function getDeviceTime(
|
|
18
|
-
this
|
|
19
|
-
format: string = DATETIME_FORMAT_ISO8601,
|
|
20
|
-
): Promise<string> {
|
|
21
|
-
this.log.debug(
|
|
22
|
-
`Attempting to capture Android device date and time. The format specifier is '${format}'`,
|
|
23
|
-
);
|
|
18
|
+
export async function getDeviceTime(this: AndroidDriver, format: string = DATETIME_FORMAT_ISO8601): Promise<string> {
|
|
19
|
+
this.log.debug(`Attempting to capture Android device date and time. The format specifier is '${format}'`);
|
|
24
20
|
const deviceTimestamp = (await this.adb.shell(['date', '+%Y-%m-%dT%T%z'])).trim();
|
|
25
21
|
this.log.debug(`Got device timestamp: ${deviceTimestamp}`);
|
|
26
22
|
const parsedTimestamp = dayjs.utc(deviceTimestamp, 'YYYY-MM-DDTHH:mm:ssZZ');
|
package/lib/commands/types.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import type {HTTPMethod, StringRecord} from '@appium/types';
|
|
2
|
-
import type {AndroidDriverCaps} from '../driver.js';
|
|
3
|
-
import type {SubProcess} from 'teen_process';
|
|
4
|
-
import type {timing} from '@appium/support';
|
|
5
1
|
import type {ChildProcess} from 'node:child_process';
|
|
6
|
-
import type {Socket} from 'node:net';
|
|
7
2
|
import type {Server} from 'node:http';
|
|
3
|
+
import type {Socket} from 'node:net';
|
|
4
|
+
|
|
5
|
+
import type {timing} from '@appium/support';
|
|
6
|
+
import type {HTTPMethod, StringRecord} from '@appium/types';
|
|
7
|
+
import type {SubProcess} from 'teen_process';
|
|
8
|
+
|
|
9
|
+
import type {AndroidDriverCaps} from '../driver.js';
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* @privateRemarks probably better defined in `appium-adb`
|
|
@@ -21,8 +23,7 @@ export type GsmVoiceState = 'on' | 'off';
|
|
|
21
23
|
|
|
22
24
|
export type PowerACState = 'on' | 'off';
|
|
23
25
|
|
|
24
|
-
export type NetworkSpeed =
|
|
25
|
-
'gsm' | 'scsd' | 'gprs' | 'edge' | 'umts' | 'hsdpa' | 'lte' | 'evdo' | 'full';
|
|
26
|
+
export type NetworkSpeed = 'gsm' | 'scsd' | 'gprs' | 'edge' | 'umts' | 'hsdpa' | 'lte' | 'evdo' | 'full';
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* Returned by `queryAppState`
|
|
@@ -138,9 +139,7 @@ export interface WebviewsMapping {
|
|
|
138
139
|
* [8000, [9000, 9100]]
|
|
139
140
|
* ```
|
|
140
141
|
*/
|
|
141
|
-
export type PortSpec = Array<
|
|
142
|
-
number | string | [startPort: number | string, endPort: number | string]
|
|
143
|
-
>;
|
|
142
|
+
export type PortSpec = Array<number | string | [startPort: number | string, endPort: number | string]>;
|
|
144
143
|
|
|
145
144
|
export interface DoSetElementValueOpts {
|
|
146
145
|
elementId: string;
|
package/lib/doctor/checks.ts
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import {resolveExecutablePath} from './utils.js';
|
|
2
|
-
import {system, fs, doctor, console} from '@appium/support';
|
|
3
1
|
import path from 'node:path';
|
|
4
|
-
|
|
2
|
+
|
|
3
|
+
import {system, fs, doctor, console} from '@appium/support';
|
|
5
4
|
import type {IDoctorCheck, AppiumLogger, DoctorCheckResult} from '@appium/types';
|
|
5
|
+
import {getAndroidBinaryPath, getSdkRootFromEnv} from 'appium-adb';
|
|
6
|
+
|
|
7
|
+
import {resolveExecutablePath} from './utils.js';
|
|
6
8
|
|
|
7
9
|
const JAVA_HOME_VAR_NAME = system.isWindows() ? '%JAVA_HOME%' : '$JAVA_HOME';
|
|
8
|
-
const ENVIRONMENT_VARS_TUTORIAL_URL =
|
|
9
|
-
|
|
10
|
-
const JAVA_HOME_TUTORIAL =
|
|
11
|
-
'https://docs.oracle.com/cd/E21454_01/html/821-2531/inst_jdk_javahome_t.html';
|
|
10
|
+
const ENVIRONMENT_VARS_TUTORIAL_URL = 'https://github.com/appium/java-client/blob/master/docs/environment.md';
|
|
11
|
+
const JAVA_HOME_TUTORIAL = 'https://docs.oracle.com/cd/E21454_01/html/821-2531/inst_jdk_javahome_t.html';
|
|
12
12
|
const ANDROID_SDK_LINK1 = 'https://developer.android.com/studio#cmdline-tools';
|
|
13
13
|
const ANDROID_SDK_LINK2 = 'https://developer.android.com/studio/intro/update#sdk-manager';
|
|
14
14
|
const BUNDLETOOL_RELEASES_LINK = 'https://github.com/google/bundletool/releases/';
|
|
15
|
-
const GSTREAMER_INSTALL_LINK =
|
|
16
|
-
'https://gstreamer.freedesktop.org/documentation/installing/index.html?gi-language=c';
|
|
15
|
+
const GSTREAMER_INSTALL_LINK = 'https://gstreamer.freedesktop.org/documentation/installing/index.html?gi-language=c';
|
|
17
16
|
const FFMPEG_INSTALL_LINK = 'https://www.ffmpeg.org/download.html';
|
|
18
17
|
|
|
19
18
|
export interface EnvVarCheckOptions {
|
|
@@ -47,14 +46,10 @@ class EnvVarAndPathCheck implements IDoctorCheck {
|
|
|
47
46
|
|
|
48
47
|
const stat = await fs.stat(varValue);
|
|
49
48
|
if (this.opts.expectDir && !stat.isDirectory()) {
|
|
50
|
-
return doctor.nok(
|
|
51
|
-
`${this.varName} is expected to be a valid folder, got a file path instead`,
|
|
52
|
-
);
|
|
49
|
+
return doctor.nok(`${this.varName} is expected to be a valid folder, got a file path instead`);
|
|
53
50
|
}
|
|
54
51
|
if (this.opts.expectFile && stat.isDirectory()) {
|
|
55
|
-
return doctor.nok(
|
|
56
|
-
`${this.varName} is expected to be a valid file, got a folder path instead`,
|
|
57
|
-
);
|
|
52
|
+
return doctor.nok(`${this.varName} is expected to be a valid file, got a folder path instead`);
|
|
58
53
|
}
|
|
59
54
|
|
|
60
55
|
return doctor.ok(`${this.varName} is set to: ${varValue}`);
|
|
@@ -203,9 +198,7 @@ export class OptionalGstreamerCheck implements IDoctorCheck {
|
|
|
203
198
|
? doctor.okOptional(
|
|
204
199
|
`${this.GSTREAMER_BINARY} and ${this.GST_INSPECT_BINARY} are installed at: ${gstreamerPath} and ${gstInspectPath}`,
|
|
205
200
|
)
|
|
206
|
-
: doctor.nokOptional(
|
|
207
|
-
`${this.GSTREAMER_BINARY} and/or ${this.GST_INSPECT_BINARY} cannot be found`,
|
|
208
|
-
);
|
|
201
|
+
: doctor.nokOptional(`${this.GSTREAMER_BINARY} and/or ${this.GST_INSPECT_BINARY} cannot be found`);
|
|
209
202
|
}
|
|
210
203
|
|
|
211
204
|
async fix(): Promise<string> {
|
package/lib/driver.ts
CHANGED
|
@@ -10,12 +10,34 @@ import type {
|
|
|
10
10
|
import type {ADB, LogcatListener} from 'appium-adb';
|
|
11
11
|
import type {Chromedriver as AppiumChromedriver} from 'appium-chromedriver';
|
|
12
12
|
import {BaseDriver} from 'appium/driver.js';
|
|
13
|
-
import {ANDROID_DRIVER_CONSTRAINTS} from './constraints.js';
|
|
14
|
-
import type {AndroidDriverConstraints} from './constraints.js';
|
|
15
|
-
import {newMethodMap} from './method-map.js';
|
|
16
13
|
import {SettingsApp} from 'io.appium.settings';
|
|
17
|
-
import {
|
|
18
|
-
|
|
14
|
+
import {LRUCache} from 'lru-cache';
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
getThirdPartyPackages,
|
|
18
|
+
uninstallOtherPackages,
|
|
19
|
+
installOtherApks,
|
|
20
|
+
installAUT,
|
|
21
|
+
resetAUT,
|
|
22
|
+
background,
|
|
23
|
+
mobileBackgroundApp,
|
|
24
|
+
getCurrentActivity,
|
|
25
|
+
getCurrentPackage,
|
|
26
|
+
mobileClearApp,
|
|
27
|
+
mobileInstallApp,
|
|
28
|
+
installApp,
|
|
29
|
+
mobileIsAppInstalled,
|
|
30
|
+
mobileRemoveApp,
|
|
31
|
+
mobileTerminateApp,
|
|
32
|
+
mobileListApps,
|
|
33
|
+
terminateApp,
|
|
34
|
+
removeApp,
|
|
35
|
+
activateApp,
|
|
36
|
+
queryAppState,
|
|
37
|
+
isAppInstalled,
|
|
38
|
+
} from './commands/app-management.js';
|
|
39
|
+
import {mobileGetUiMode, mobileSetUiMode} from './commands/appearance.js';
|
|
40
|
+
import {mobileBluetooth} from './commands/bluetooth.js';
|
|
19
41
|
import {
|
|
20
42
|
getContexts,
|
|
21
43
|
setContext,
|
|
@@ -38,12 +60,8 @@ import {
|
|
|
38
60
|
setWindow,
|
|
39
61
|
notifyBiDiContextChange,
|
|
40
62
|
} from './commands/context/exports.js';
|
|
41
|
-
import {
|
|
42
|
-
|
|
43
|
-
createADB,
|
|
44
|
-
getLaunchInfo,
|
|
45
|
-
initDevice,
|
|
46
|
-
} from './commands/device/common.js';
|
|
63
|
+
import {CHROME_BROWSER_PACKAGE_ACTIVITY} from './commands/context/helpers.js';
|
|
64
|
+
import {getDeviceInfoFromCaps, createADB, getLaunchInfo, initDevice} from './commands/device/common.js';
|
|
47
65
|
import {
|
|
48
66
|
fingerprint,
|
|
49
67
|
mobileFingerprint,
|
|
@@ -64,32 +82,7 @@ import {
|
|
|
64
82
|
sensorSet,
|
|
65
83
|
} from './commands/device/emulator-actions.js';
|
|
66
84
|
import {mobileExecEmuConsoleCommand} from './commands/device/emulator-console.js';
|
|
67
|
-
import {
|
|
68
|
-
getThirdPartyPackages,
|
|
69
|
-
uninstallOtherPackages,
|
|
70
|
-
installOtherApks,
|
|
71
|
-
installAUT,
|
|
72
|
-
resetAUT,
|
|
73
|
-
background,
|
|
74
|
-
mobileBackgroundApp,
|
|
75
|
-
getCurrentActivity,
|
|
76
|
-
getCurrentPackage,
|
|
77
|
-
mobileClearApp,
|
|
78
|
-
mobileInstallApp,
|
|
79
|
-
installApp,
|
|
80
|
-
mobileIsAppInstalled,
|
|
81
|
-
mobileRemoveApp,
|
|
82
|
-
mobileTerminateApp,
|
|
83
|
-
mobileListApps,
|
|
84
|
-
terminateApp,
|
|
85
|
-
removeApp,
|
|
86
|
-
activateApp,
|
|
87
|
-
queryAppState,
|
|
88
|
-
isAppInstalled,
|
|
89
|
-
} from './commands/app-management.js';
|
|
90
|
-
import {mobileGetUiMode, mobileSetUiMode} from './commands/appearance.js';
|
|
91
85
|
import {mobileDeviceidle} from './commands/deviceidle.js';
|
|
92
|
-
import {mobileBluetooth} from './commands/bluetooth.js';
|
|
93
86
|
import {
|
|
94
87
|
getAttribute,
|
|
95
88
|
getName,
|
|
@@ -121,6 +114,7 @@ import {
|
|
|
121
114
|
mobileResetGeolocation,
|
|
122
115
|
} from './commands/geolocation.js';
|
|
123
116
|
import {performActions} from './commands/gestures.js';
|
|
117
|
+
import {mobileInjectEmulatorCameraImage} from './commands/image-injection.js';
|
|
124
118
|
import {
|
|
125
119
|
isIMEActivated,
|
|
126
120
|
availableIMEEngines,
|
|
@@ -145,6 +139,7 @@ import {
|
|
|
145
139
|
longPressKeyCode,
|
|
146
140
|
mobilePerformEditorAction,
|
|
147
141
|
} from './commands/keyboard.js';
|
|
142
|
+
import {reset, closeApp, launchApp} from './commands/legacy.js';
|
|
148
143
|
import {lock, unlock, mobileUnlock, isLocked} from './commands/lock/exports.js';
|
|
149
144
|
import {
|
|
150
145
|
supportedLogTypes,
|
|
@@ -160,8 +155,6 @@ import {
|
|
|
160
155
|
mobileStopMediaProjectionRecording,
|
|
161
156
|
} from './commands/media-projection.js';
|
|
162
157
|
import {mobileSendTrimMemory} from './commands/memory.js';
|
|
163
|
-
import {mobileNfc} from './commands/nfc.js';
|
|
164
|
-
import {mobileInjectEmulatorCameraImage} from './commands/image-injection.js';
|
|
165
158
|
import {
|
|
166
159
|
getWindowRect,
|
|
167
160
|
getWindowSize,
|
|
@@ -183,12 +176,8 @@ import {
|
|
|
183
176
|
toggleFlightMode,
|
|
184
177
|
toggleWiFi,
|
|
185
178
|
} from './commands/network.js';
|
|
186
|
-
import {
|
|
187
|
-
|
|
188
|
-
getPerformanceDataTypes,
|
|
189
|
-
mobileGetPerformanceData,
|
|
190
|
-
} from './commands/performance.js';
|
|
191
|
-
import {reset, closeApp, launchApp} from './commands/legacy.js';
|
|
179
|
+
import {mobileNfc} from './commands/nfc.js';
|
|
180
|
+
import {getPerformanceData, getPerformanceDataTypes, mobileGetPerformanceData} from './commands/performance.js';
|
|
192
181
|
import {mobileChangePermissions, mobileGetPermissions} from './commands/permissions.js';
|
|
193
182
|
import {startRecordingScreen, stopRecordingScreen} from './commands/recordscreen.js';
|
|
194
183
|
import {getStrings, ensureDeviceLocale} from './commands/resources.js';
|
|
@@ -196,9 +185,12 @@ import {mobileShell} from './commands/shell.js';
|
|
|
196
185
|
import {mobileStartScreenStreaming, mobileStopScreenStreaming} from './commands/streamscreen.js';
|
|
197
186
|
import {getSystemBars, mobilePerformStatusBarCommand} from './commands/system-bars.js';
|
|
198
187
|
import {getDeviceTime, mobileGetDeviceTime} from './commands/time.js';
|
|
199
|
-
import {executeMethodMap} from './execute-method-map.js';
|
|
200
|
-
import {LRUCache} from 'lru-cache';
|
|
201
188
|
import type {ScreenRecordingProperties, ScreenStreamingProps} from './commands/types.js';
|
|
189
|
+
import {ANDROID_DRIVER_CONSTRAINTS} from './constraints.js';
|
|
190
|
+
import type {AndroidDriverConstraints} from './constraints.js';
|
|
191
|
+
import {executeMethodMap} from './execute-method-map.js';
|
|
192
|
+
import {newMethodMap} from './method-map.js';
|
|
193
|
+
import {parseArray, removeAllSessionWebSocketHandlers} from './utils.js';
|
|
202
194
|
|
|
203
195
|
export type AndroidDriverCaps = DriverCaps<AndroidDriverConstraints>;
|
|
204
196
|
export type W3CAndroidDriverCaps = W3CDriverCaps<AndroidDriverConstraints>;
|
|
@@ -454,13 +446,7 @@ class AndroidDriver
|
|
|
454
446
|
constructor(opts: InitialOpts = {} as InitialOpts, shouldValidateCaps = true) {
|
|
455
447
|
super(opts, shouldValidateCaps);
|
|
456
448
|
|
|
457
|
-
this.locatorStrategies = [
|
|
458
|
-
'xpath',
|
|
459
|
-
'id',
|
|
460
|
-
'class name',
|
|
461
|
-
'accessibility id',
|
|
462
|
-
'-android uiautomator',
|
|
463
|
-
];
|
|
449
|
+
this.locatorStrategies = ['xpath', 'id', 'class name', 'accessibility id', '-android uiautomator'];
|
|
464
450
|
this.desiredCapConstraints = structuredClone(ANDROID_DRIVER_CONSTRAINTS);
|
|
465
451
|
this.sessionChromedrivers = {};
|
|
466
452
|
this.jwpProxyActive = false;
|
|
@@ -482,9 +468,7 @@ class AndroidDriver
|
|
|
482
468
|
}
|
|
483
469
|
|
|
484
470
|
get isChromeSession(): boolean {
|
|
485
|
-
return Object.keys(CHROME_BROWSER_PACKAGE_ACTIVITY).includes(
|
|
486
|
-
(this.opts.browserName || '').toLowerCase(),
|
|
487
|
-
);
|
|
471
|
+
return Object.keys(CHROME_BROWSER_PACKAGE_ACTIVITY).includes((this.opts.browserName || '').toLowerCase());
|
|
488
472
|
}
|
|
489
473
|
|
|
490
474
|
isEmulator(): boolean {
|
|
@@ -500,14 +484,10 @@ class AndroidDriver
|
|
|
500
484
|
if (caps.browserName) {
|
|
501
485
|
if (caps.app) {
|
|
502
486
|
// warn if the capabilities have both `app` and `browser, although this is common with selenium grid
|
|
503
|
-
this.log.warn(
|
|
504
|
-
`The desired capabilities should generally not include both an 'app' and a 'browserName'`,
|
|
505
|
-
);
|
|
487
|
+
this.log.warn(`The desired capabilities should generally not include both an 'app' and a 'browserName'`);
|
|
506
488
|
}
|
|
507
489
|
if (caps.appPackage) {
|
|
508
|
-
throw this.log.errorWithException(
|
|
509
|
-
`The desired should not include both of an 'appPackage' and a 'browserName'`,
|
|
510
|
-
);
|
|
490
|
+
throw this.log.errorWithException(`The desired should not include both of an 'appPackage' and a 'browserName'`);
|
|
511
491
|
}
|
|
512
492
|
}
|
|
513
493
|
|
|
@@ -531,9 +511,7 @@ class AndroidDriver
|
|
|
531
511
|
this.adb?.logcat?.removeAllListeners();
|
|
532
512
|
await this.adb?.stopLogcat();
|
|
533
513
|
} catch (e) {
|
|
534
|
-
this.log.warn(
|
|
535
|
-
`Cannot stop the logcat process. Original error: ${e instanceof Error ? e.message : String(e)}`,
|
|
536
|
-
);
|
|
514
|
+
this.log.warn(`Cannot stop the logcat process. Original error: ${e instanceof Error ? e.message : String(e)}`);
|
|
537
515
|
}
|
|
538
516
|
|
|
539
517
|
if (this._bidiServerLogListener) {
|