appium-android-driver 13.1.2 → 13.2.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.
- package/CHANGELOG.md +6 -0
- package/build/lib/commands/app-management.d.ts.map +1 -1
- package/build/lib/commands/app-management.js +2 -3
- package/build/lib/commands/app-management.js.map +1 -1
- package/build/lib/commands/bidi/models.d.ts +7 -0
- package/build/lib/commands/bidi/models.d.ts.map +1 -1
- package/build/lib/commands/bidi/models.js +7 -0
- package/build/lib/commands/bidi/models.js.map +1 -1
- package/build/lib/commands/bidi/types.d.ts +6 -6
- package/build/lib/commands/bidi/types.d.ts.map +1 -1
- package/build/lib/commands/bluetooth.d.ts +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/exports.d.ts.map +1 -1
- package/build/lib/commands/context/exports.js +14 -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 +1 -2
- package/build/lib/commands/context/helpers.js.map +1 -1
- package/build/lib/commands/device/common.d.ts.map +1 -1
- package/build/lib/commands/device/common.js +1 -2
- package/build/lib/commands/device/common.js.map +1 -1
- package/build/lib/commands/device/utils.d.ts.map +1 -1
- package/build/lib/commands/device/utils.js +1 -2
- package/build/lib/commands/device/utils.js.map +1 -1
- package/build/lib/commands/execute.d.ts +1 -1
- package/build/lib/commands/execute.d.ts.map +1 -1
- package/build/lib/commands/execute.js +0 -1
- package/build/lib/commands/execute.js.map +1 -1
- package/build/lib/commands/geolocation.js +3 -3
- package/build/lib/commands/geolocation.js.map +1 -1
- package/build/lib/commands/lock/exports.js +2 -2
- package/build/lib/commands/lock/exports.js.map +1 -1
- package/build/lib/commands/media-projection.d.ts.map +1 -1
- package/build/lib/commands/media-projection.js +0 -1
- package/build/lib/commands/media-projection.js.map +1 -1
- package/build/lib/commands/network.d.ts.map +1 -1
- package/build/lib/commands/network.js +21 -11
- package/build/lib/commands/network.js.map +1 -1
- package/build/lib/commands/performance.d.ts.map +1 -1
- package/build/lib/commands/performance.js +68 -68
- package/build/lib/commands/performance.js.map +1 -1
- package/build/lib/commands/permissions.d.ts +4 -4
- package/build/lib/commands/permissions.d.ts.map +1 -1
- package/build/lib/commands/permissions.js +2 -4
- package/build/lib/commands/permissions.js.map +1 -1
- package/build/lib/commands/recordscreen.js +1 -1
- package/build/lib/commands/recordscreen.js.map +1 -1
- package/build/lib/commands/streamscreen.d.ts.map +1 -1
- package/build/lib/commands/streamscreen.js +65 -45
- package/build/lib/commands/streamscreen.js.map +1 -1
- package/build/lib/commands/system-bars.d.ts +4 -4
- package/build/lib/commands/system-bars.d.ts.map +1 -1
- package/build/lib/commands/system-bars.js +0 -1
- package/build/lib/commands/system-bars.js.map +1 -1
- package/build/lib/driver.d.ts +7 -7
- package/build/lib/driver.d.ts.map +1 -1
- package/build/lib/driver.js +69 -69
- package/build/lib/driver.js.map +1 -1
- package/build/lib/utils.d.ts +6 -6
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js.map +1 -1
- package/lib/commands/app-management.ts +2 -3
- package/lib/commands/bidi/models.ts +7 -0
- package/lib/commands/bidi/types.ts +10 -10
- package/lib/commands/bluetooth.ts +2 -2
- package/lib/commands/context/exports.ts +16 -4
- package/lib/commands/context/helpers.ts +1 -2
- package/lib/commands/device/common.ts +1 -2
- package/lib/commands/device/utils.ts +1 -2
- package/lib/commands/execute.ts +2 -6
- package/lib/commands/geolocation.ts +6 -10
- package/lib/commands/lock/exports.ts +2 -2
- package/lib/commands/media-projection.ts +10 -14
- package/lib/commands/network.ts +28 -22
- package/lib/commands/performance.ts +68 -68
- package/lib/commands/permissions.ts +12 -15
- package/lib/commands/recordscreen.ts +1 -1
- package/lib/commands/streamscreen.ts +77 -53
- package/lib/commands/system-bars.ts +5 -9
- package/lib/driver.ts +91 -91
- package/lib/utils.ts +7 -7
- package/package.json +1 -3
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {fs, logger, system, util} from '@appium/support';
|
|
2
2
|
import {waitForCondition} from 'asyncbox';
|
|
3
|
-
import B from 'bluebird';
|
|
4
3
|
import _ from 'lodash';
|
|
5
4
|
import {spawn} from 'node:child_process';
|
|
6
5
|
import http from 'node:http';
|
|
@@ -139,65 +138,75 @@ export async function mobileStartScreenStreaming(
|
|
|
139
138
|
|
|
140
139
|
let mjpegSocket: net.Socket | undefined;
|
|
141
140
|
let mjpegServer: http.Server | undefined;
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
141
|
+
let mjpegConnectTimeoutId: ReturnType<typeof setTimeout> | undefined;
|
|
142
|
+
const mjpegConnectTimeoutPromise = new Promise<never>((_resolve, reject) => {
|
|
143
|
+
mjpegConnectTimeoutId = setTimeout(
|
|
144
|
+
() =>
|
|
145
|
+
reject(
|
|
146
|
+
new Error(
|
|
147
|
+
`Cannot connect to the streaming server within ${STREAMING_STARTUP_TIMEOUT_MS}ms`,
|
|
148
|
+
),
|
|
149
|
+
),
|
|
150
|
+
STREAMING_STARTUP_TIMEOUT_MS,
|
|
151
|
+
);
|
|
152
|
+
});
|
|
153
|
+
const mjpegServerReadyPromise = new Promise<void>((resolve, reject) => {
|
|
154
|
+
mjpegSocket = net.createConnection(tcpPort, TCP_HOST, () => {
|
|
155
|
+
this.log.info(`Successfully connected to MJPEG stream at tcp://${TCP_HOST}:${tcpPort}`);
|
|
156
|
+
mjpegServer = http.createServer((req, res) => {
|
|
157
|
+
const remoteAddress = extractRemoteAddress(req);
|
|
158
|
+
const currentPathname = extractSafePathnameFromUrl(req.url);
|
|
159
|
+
this.log.info(
|
|
160
|
+
`Got an incoming screen broadcasting request from ${remoteAddress} ` +
|
|
161
|
+
`(${req.headers['user-agent'] || 'User Agent unknown'}) at ${currentPathname}`,
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
if (pathname && currentPathname !== pathname) {
|
|
149
165
|
this.log.info(
|
|
150
|
-
|
|
151
|
-
`(${req.headers['user-agent'] || 'User Agent unknown'}) at ${currentPathname}`,
|
|
166
|
+
'Rejecting the broadcast request since it does not match the given pathname',
|
|
152
167
|
);
|
|
153
|
-
|
|
154
|
-
if (pathname && currentPathname !== pathname) {
|
|
155
|
-
this.log.info(
|
|
156
|
-
'Rejecting the broadcast request since it does not match the given pathname',
|
|
157
|
-
);
|
|
158
|
-
res.writeHead(404, {
|
|
159
|
-
Connection: 'close',
|
|
160
|
-
'Content-Type': 'text/plain; charset=utf-8',
|
|
161
|
-
});
|
|
162
|
-
res.write(`'${currentPathname}' did not match any known endpoints`);
|
|
163
|
-
res.end();
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
this.log.info('Starting MJPEG broadcast');
|
|
168
|
-
res.writeHead(200, {
|
|
169
|
-
'Cache-Control':
|
|
170
|
-
'no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0',
|
|
171
|
-
Pragma: 'no-cache',
|
|
168
|
+
res.writeHead(404, {
|
|
172
169
|
Connection: 'close',
|
|
173
|
-
'Content-Type':
|
|
170
|
+
'Content-Type': 'text/plain; charset=utf-8',
|
|
174
171
|
});
|
|
172
|
+
res.write(`'${currentPathname}' did not match any known endpoints`);
|
|
173
|
+
res.end();
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
175
176
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
177
|
+
this.log.info('Starting MJPEG broadcast');
|
|
178
|
+
res.writeHead(200, {
|
|
179
|
+
'Cache-Control':
|
|
180
|
+
'no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0',
|
|
181
|
+
Pragma: 'no-cache',
|
|
182
|
+
Connection: 'close',
|
|
183
|
+
'Content-Type': `multipart/x-mixed-replace; boundary=${BOUNDARY_STRING}`,
|
|
179
184
|
});
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}
|
|
184
|
-
mjpegServer.on('close', () => {
|
|
185
|
-
this.log.debug(`MJPEG server at http://${host}:${port} has been closed`);
|
|
186
|
-
});
|
|
187
|
-
mjpegServer.on('listening', () => {
|
|
188
|
-
this.log.info(`Successfully started MJPEG server at http://${host}:${port}`);
|
|
189
|
-
resolve();
|
|
190
|
-
});
|
|
191
|
-
mjpegServer.listen(port, host);
|
|
185
|
+
|
|
186
|
+
if (mjpegSocket) {
|
|
187
|
+
mjpegSocket.pipe(res);
|
|
188
|
+
}
|
|
192
189
|
});
|
|
193
|
-
|
|
194
|
-
this.log.
|
|
190
|
+
mjpegServer.on('error', (e) => {
|
|
191
|
+
this.log.warn(e);
|
|
195
192
|
reject(e);
|
|
196
193
|
});
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
194
|
+
mjpegServer.on('close', () => {
|
|
195
|
+
this.log.debug(`MJPEG server at http://${host}:${port} has been closed`);
|
|
196
|
+
});
|
|
197
|
+
mjpegServer.on('listening', () => {
|
|
198
|
+
this.log.info(`Successfully started MJPEG server at http://${host}:${port}`);
|
|
199
|
+
resolve();
|
|
200
|
+
});
|
|
201
|
+
mjpegServer.listen(port, host);
|
|
202
|
+
});
|
|
203
|
+
mjpegSocket.on('error', (e) => {
|
|
204
|
+
this.log.error(e);
|
|
205
|
+
reject(e);
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
try {
|
|
209
|
+
await Promise.race([mjpegServerReadyPromise, mjpegConnectTimeoutPromise]);
|
|
201
210
|
} catch (e) {
|
|
202
211
|
if (deviceStreamingProc.kill(0)) {
|
|
203
212
|
deviceStreamingProc.kill();
|
|
@@ -212,6 +221,10 @@ export async function mobileStartScreenStreaming(
|
|
|
212
221
|
mjpegServer.close();
|
|
213
222
|
}
|
|
214
223
|
throw e;
|
|
224
|
+
} finally {
|
|
225
|
+
if (mjpegConnectTimeoutId !== undefined) {
|
|
226
|
+
clearTimeout(mjpegConnectTimeoutId);
|
|
227
|
+
}
|
|
215
228
|
}
|
|
216
229
|
|
|
217
230
|
this._screenStreamingProps = {
|
|
@@ -303,7 +316,7 @@ async function verifyStreamingRequirements(adb: ADB): Promise<void> {
|
|
|
303
316
|
})(),
|
|
304
317
|
);
|
|
305
318
|
}
|
|
306
|
-
await
|
|
319
|
+
await Promise.all(gstreamerCheckPromises);
|
|
307
320
|
|
|
308
321
|
const moduleCheckPromises: Promise<void>[] = [];
|
|
309
322
|
for (const [name, modName] of _.toPairs(REQUIRED_GST_PLUGINS)) {
|
|
@@ -319,7 +332,7 @@ async function verifyStreamingRequirements(adb: ADB): Promise<void> {
|
|
|
319
332
|
})(),
|
|
320
333
|
);
|
|
321
334
|
}
|
|
322
|
-
await
|
|
335
|
+
await Promise.all(moduleCheckPromises);
|
|
323
336
|
}
|
|
324
337
|
|
|
325
338
|
const deviceInfoRegexes = [
|
|
@@ -499,6 +512,17 @@ async function initGstreamerPipeline(
|
|
|
499
512
|
return gstreamerPipeline;
|
|
500
513
|
}
|
|
501
514
|
|
|
515
|
+
/**
|
|
516
|
+
* WHATWG URL parsing can throw on malformed input; HTTP servers must not throw synchronously in request handlers.
|
|
517
|
+
*/
|
|
518
|
+
function extractSafePathnameFromUrl(requestUrl: string | undefined): string {
|
|
519
|
+
try {
|
|
520
|
+
return new url.URL(String(requestUrl ?? '/'), 'http://127.0.0.1').pathname;
|
|
521
|
+
} catch {
|
|
522
|
+
return '/';
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
502
526
|
/**
|
|
503
527
|
* @privateRemarks This may need to be future-proofed, as `IncomingMessage.connection` is deprecated and its `socket` prop is likely private
|
|
504
528
|
*/
|
|
@@ -22,6 +22,11 @@ const DEFAULT_WINDOW_PROPERTIES: WindowProperties = {
|
|
|
22
22
|
height: 0,
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
+
interface SystemBarsResult {
|
|
26
|
+
statusBar?: WindowProperties;
|
|
27
|
+
navigationBar?: WindowProperties;
|
|
28
|
+
}
|
|
29
|
+
|
|
25
30
|
/**
|
|
26
31
|
* Gets the system bars (status bar and navigation bar) properties.
|
|
27
32
|
*
|
|
@@ -86,8 +91,6 @@ export async function mobilePerformStatusBarCommand(
|
|
|
86
91
|
return await action();
|
|
87
92
|
}
|
|
88
93
|
|
|
89
|
-
// #region Internal helpers
|
|
90
|
-
|
|
91
94
|
/**
|
|
92
95
|
* Parses window properties from adb dumpsys output
|
|
93
96
|
*
|
|
@@ -185,10 +188,3 @@ export function parseWindows(this: AndroidDriver, lines: string): SystemBarsResu
|
|
|
185
188
|
}
|
|
186
189
|
return result;
|
|
187
190
|
}
|
|
188
|
-
|
|
189
|
-
// #endregion
|
|
190
|
-
|
|
191
|
-
interface SystemBarsResult {
|
|
192
|
-
statusBar?: WindowProperties;
|
|
193
|
-
navigationBar?: WindowProperties;
|
|
194
|
-
}
|
package/lib/driver.ts
CHANGED
|
@@ -240,97 +240,6 @@ class AndroidDriver
|
|
|
240
240
|
});
|
|
241
241
|
opts: AndroidDriverOpts;
|
|
242
242
|
|
|
243
|
-
constructor(opts: InitialOpts = {} as InitialOpts, shouldValidateCaps = true) {
|
|
244
|
-
super(opts, shouldValidateCaps);
|
|
245
|
-
|
|
246
|
-
this.locatorStrategies = [
|
|
247
|
-
'xpath',
|
|
248
|
-
'id',
|
|
249
|
-
'class name',
|
|
250
|
-
'accessibility id',
|
|
251
|
-
'-android uiautomator',
|
|
252
|
-
];
|
|
253
|
-
this.desiredCapConstraints = _.cloneDeep(ANDROID_DRIVER_CONSTRAINTS);
|
|
254
|
-
this.sessionChromedrivers = {};
|
|
255
|
-
this.jwpProxyActive = false;
|
|
256
|
-
|
|
257
|
-
this.curContext = this.defaultContextName();
|
|
258
|
-
this.opts = opts as AndroidDriverOpts;
|
|
259
|
-
this._cachedActivityArgs = {};
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
get bidiProxyUrl(): string | null {
|
|
263
|
-
return this.opts.chromedriverForwardBiDi ? this._bidiProxyUrl : null;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
get settingsApp(): SettingsApp {
|
|
267
|
-
if (!this._settingsApp || this._settingsApp.adb !== this.adb) {
|
|
268
|
-
this._settingsApp = new SettingsApp({adb: this.adb});
|
|
269
|
-
}
|
|
270
|
-
return this._settingsApp;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
isEmulator(): boolean {
|
|
274
|
-
const possibleNames = [this.opts?.udid, this.adb?.curDeviceId];
|
|
275
|
-
return !!this.opts?.avd || possibleNames.some((x) => EMULATOR_PATTERN.test(String(x)));
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
get isChromeSession(): boolean {
|
|
279
|
-
return _.includes(
|
|
280
|
-
Object.keys(CHROME_BROWSER_PACKAGE_ACTIVITY),
|
|
281
|
-
(this.opts.browserName || '').toLowerCase(),
|
|
282
|
-
);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
override validateDesiredCaps(caps: any): caps is AndroidDriverCaps {
|
|
286
|
-
if (!super.validateDesiredCaps(caps)) {
|
|
287
|
-
return false;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
if (caps.browserName) {
|
|
291
|
-
if (caps.app) {
|
|
292
|
-
// warn if the capabilities have both `app` and `browser, although this is common with selenium grid
|
|
293
|
-
this.log.warn(
|
|
294
|
-
`The desired capabilities should generally not include both an 'app' and a 'browserName'`,
|
|
295
|
-
);
|
|
296
|
-
}
|
|
297
|
-
if (caps.appPackage) {
|
|
298
|
-
throw this.log.errorWithException(
|
|
299
|
-
`The desired should not include both of an 'appPackage' and a 'browserName'`,
|
|
300
|
-
);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
if (caps.uninstallOtherPackages) {
|
|
305
|
-
try {
|
|
306
|
-
parseArray(caps.uninstallOtherPackages);
|
|
307
|
-
} catch (e) {
|
|
308
|
-
throw this.log.errorWithException(
|
|
309
|
-
`Could not parse "uninstallOtherPackages" capability: ${(e as Error).message}`,
|
|
310
|
-
);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
return true;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
override async deleteSession(sessionId?: string | null) {
|
|
318
|
-
await removeAllSessionWebSocketHandlers.bind(this)();
|
|
319
|
-
|
|
320
|
-
try {
|
|
321
|
-
this.adb?.logcat?.removeAllListeners();
|
|
322
|
-
await this.adb?.stopLogcat();
|
|
323
|
-
} catch (e) {
|
|
324
|
-
this.log.warn(`Cannot stop the logcat process. Original error: ${e.message}`);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
if (this._bidiServerLogListener) {
|
|
328
|
-
this.log.unwrap().off('log', this._bidiServerLogListener);
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
await super.deleteSession(sessionId);
|
|
332
|
-
}
|
|
333
|
-
|
|
334
243
|
getContexts = getContexts;
|
|
335
244
|
getCurrentContext = getCurrentContext;
|
|
336
245
|
defaultContextName = defaultContextName;
|
|
@@ -542,6 +451,97 @@ class AndroidDriver
|
|
|
542
451
|
reset = reset;
|
|
543
452
|
closeApp = closeApp;
|
|
544
453
|
launchApp = launchApp;
|
|
454
|
+
|
|
455
|
+
constructor(opts: InitialOpts = {} as InitialOpts, shouldValidateCaps = true) {
|
|
456
|
+
super(opts, shouldValidateCaps);
|
|
457
|
+
|
|
458
|
+
this.locatorStrategies = [
|
|
459
|
+
'xpath',
|
|
460
|
+
'id',
|
|
461
|
+
'class name',
|
|
462
|
+
'accessibility id',
|
|
463
|
+
'-android uiautomator',
|
|
464
|
+
];
|
|
465
|
+
this.desiredCapConstraints = _.cloneDeep(ANDROID_DRIVER_CONSTRAINTS);
|
|
466
|
+
this.sessionChromedrivers = {};
|
|
467
|
+
this.jwpProxyActive = false;
|
|
468
|
+
|
|
469
|
+
this.curContext = this.defaultContextName();
|
|
470
|
+
this.opts = opts as AndroidDriverOpts;
|
|
471
|
+
this._cachedActivityArgs = {};
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
get bidiProxyUrl(): string | null {
|
|
475
|
+
return this.opts.chromedriverForwardBiDi ? this._bidiProxyUrl : null;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
get settingsApp(): SettingsApp {
|
|
479
|
+
if (!this._settingsApp || this._settingsApp.adb !== this.adb) {
|
|
480
|
+
this._settingsApp = new SettingsApp({adb: this.adb});
|
|
481
|
+
}
|
|
482
|
+
return this._settingsApp;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
get isChromeSession(): boolean {
|
|
486
|
+
return _.includes(
|
|
487
|
+
Object.keys(CHROME_BROWSER_PACKAGE_ACTIVITY),
|
|
488
|
+
(this.opts.browserName || '').toLowerCase(),
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
isEmulator(): boolean {
|
|
493
|
+
const possibleNames = [this.opts?.udid, this.adb?.curDeviceId];
|
|
494
|
+
return !!this.opts?.avd || possibleNames.some((x) => EMULATOR_PATTERN.test(String(x)));
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
override validateDesiredCaps(caps: any): caps is AndroidDriverCaps {
|
|
498
|
+
if (!super.validateDesiredCaps(caps)) {
|
|
499
|
+
return false;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
if (caps.browserName) {
|
|
503
|
+
if (caps.app) {
|
|
504
|
+
// warn if the capabilities have both `app` and `browser, although this is common with selenium grid
|
|
505
|
+
this.log.warn(
|
|
506
|
+
`The desired capabilities should generally not include both an 'app' and a 'browserName'`,
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
if (caps.appPackage) {
|
|
510
|
+
throw this.log.errorWithException(
|
|
511
|
+
`The desired should not include both of an 'appPackage' and a 'browserName'`,
|
|
512
|
+
);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
if (caps.uninstallOtherPackages) {
|
|
517
|
+
try {
|
|
518
|
+
parseArray(caps.uninstallOtherPackages);
|
|
519
|
+
} catch (e) {
|
|
520
|
+
throw this.log.errorWithException(
|
|
521
|
+
`Could not parse "uninstallOtherPackages" capability: ${(e as Error).message}`,
|
|
522
|
+
);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
return true;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
override async deleteSession(sessionId?: string | null) {
|
|
530
|
+
await removeAllSessionWebSocketHandlers.bind(this)();
|
|
531
|
+
|
|
532
|
+
try {
|
|
533
|
+
this.adb?.logcat?.removeAllListeners();
|
|
534
|
+
await this.adb?.stopLogcat();
|
|
535
|
+
} catch (e) {
|
|
536
|
+
this.log.warn(`Cannot stop the logcat process. Original error: ${e.message}`);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
if (this._bidiServerLogListener) {
|
|
540
|
+
this.log.unwrap().off('log', this._bidiServerLogListener);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
await super.deleteSession(sessionId);
|
|
544
|
+
}
|
|
545
545
|
}
|
|
546
546
|
|
|
547
547
|
export {AndroidDriver};
|
package/lib/utils.ts
CHANGED
|
@@ -11,6 +11,13 @@ export const GET_SERVER_LOGS_FEATURE = 'get_server_logs';
|
|
|
11
11
|
export const SET_STYLUS_HANDWRITING_FEATURE = 'set_stylus_handwriting';
|
|
12
12
|
const COLOR_CODE_PATTERN = /\u001b\[(\d+(;\d+)*)?m/g; // eslint-disable-line no-control-regex
|
|
13
13
|
|
|
14
|
+
interface LogEntryWithPrefix {
|
|
15
|
+
message: string;
|
|
16
|
+
prefix?: string;
|
|
17
|
+
timestamp?: number;
|
|
18
|
+
level?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
14
21
|
/**
|
|
15
22
|
* Assert the presence of particular keys in the given object
|
|
16
23
|
*
|
|
@@ -65,13 +72,6 @@ export async function removeAllSessionWebSocketHandlers(this: AndroidDriver): Pr
|
|
|
65
72
|
}
|
|
66
73
|
}
|
|
67
74
|
|
|
68
|
-
interface LogEntryWithPrefix {
|
|
69
|
-
message: string;
|
|
70
|
-
prefix?: string;
|
|
71
|
-
timestamp?: number;
|
|
72
|
-
level?: string;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
75
|
/**
|
|
76
76
|
*
|
|
77
77
|
* @param x
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "appium-android-driver",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.2.0",
|
|
4
4
|
"description": "Android UiAutomator and Chrome support for Appium",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"appium",
|
|
@@ -53,7 +53,6 @@
|
|
|
53
53
|
"appium-chromedriver": "^8.2.25",
|
|
54
54
|
"asyncbox": "^6.1.0",
|
|
55
55
|
"axios": "^1.x",
|
|
56
|
-
"bluebird": "^3.4.7",
|
|
57
56
|
"io.appium.settings": "^7.0.4",
|
|
58
57
|
"lodash": "^4.17.4",
|
|
59
58
|
"lru-cache": "^11.1.0",
|
|
@@ -70,7 +69,6 @@
|
|
|
70
69
|
"@appium/types": "^1.0.0-rc.1",
|
|
71
70
|
"@semantic-release/changelog": "^6.0.1",
|
|
72
71
|
"@semantic-release/git": "^10.0.1",
|
|
73
|
-
"@types/bluebird": "^3.5.38",
|
|
74
72
|
"@types/lodash": "^4.14.194",
|
|
75
73
|
"@types/mocha": "^10.0.1",
|
|
76
74
|
"@types/node": "^25.0.0",
|