appium-android-driver 12.4.8 → 12.4.10
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/element.d.ts +90 -66
- package/build/lib/commands/element.d.ts.map +1 -1
- package/build/lib/commands/element.js +74 -53
- package/build/lib/commands/element.js.map +1 -1
- package/build/lib/commands/geolocation.d.ts +44 -36
- package/build/lib/commands/geolocation.d.ts.map +1 -1
- package/build/lib/commands/geolocation.js +38 -32
- package/build/lib/commands/geolocation.js.map +1 -1
- package/build/lib/commands/log.d.ts +43 -47
- package/build/lib/commands/log.d.ts.map +1 -1
- package/build/lib/commands/log.js +30 -55
- package/build/lib/commands/log.js.map +1 -1
- package/build/lib/commands/media-projection.d.ts +32 -36
- package/build/lib/commands/media-projection.d.ts.map +1 -1
- package/build/lib/commands/media-projection.js +27 -54
- package/build/lib/commands/media-projection.js.map +1 -1
- package/build/lib/commands/network.d.ts +59 -39
- package/build/lib/commands/network.d.ts.map +1 -1
- package/build/lib/commands/network.js +65 -45
- package/build/lib/commands/network.js.map +1 -1
- package/build/lib/commands/permissions.d.ts +47 -19
- package/build/lib/commands/permissions.d.ts.map +1 -1
- package/build/lib/commands/permissions.js +21 -36
- package/build/lib/commands/permissions.js.map +1 -1
- package/build/lib/commands/system-bars.d.ts +27 -21
- package/build/lib/commands/system-bars.d.ts.map +1 -1
- package/build/lib/commands/system-bars.js +23 -40
- package/build/lib/commands/system-bars.js.map +1 -1
- package/build/lib/driver.d.ts +9 -9
- package/lib/commands/element.ts +234 -0
- package/lib/commands/{geolocation.js → geolocation.ts} +85 -54
- package/lib/commands/{log.js → log.ts} +66 -71
- package/lib/commands/{media-projection.js → media-projection.ts} +69 -68
- package/lib/commands/{network.js → network.ts} +106 -59
- package/lib/commands/{permissions.js → permissions.ts} +58 -50
- package/lib/commands/{system-bars.js → system-bars.ts} +59 -50
- package/package.json +1 -1
- package/lib/commands/element.js +0 -158
|
@@ -2,8 +2,10 @@ import _ from 'lodash';
|
|
|
2
2
|
import {fs, tempDir} from '@appium/support';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import B from 'bluebird';
|
|
5
|
+
import type {Location} from '@appium/types';
|
|
5
6
|
import {SETTINGS_HELPER_ID} from 'io.appium.settings';
|
|
6
7
|
import {getThirdPartyPackages} from './app-management';
|
|
8
|
+
import type {AndroidDriver} from '../driver';
|
|
7
9
|
|
|
8
10
|
// The value close to zero, but not zero, is needed
|
|
9
11
|
// to trick JSON generation and send a float value instead of an integer,
|
|
@@ -14,17 +16,21 @@ const GEO_EPSILON = Number.MIN_VALUE;
|
|
|
14
16
|
const MOCK_APP_IDS_STORE = '/data/local/tmp/mock_apps.json';
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* @
|
|
19
|
+
* Sets the device geolocation.
|
|
20
|
+
*
|
|
21
|
+
* @param location The geolocation object containing latitude, longitude, and altitude.
|
|
22
|
+
* @returns Promise that resolves to the current geolocation after setting it.
|
|
20
23
|
*/
|
|
21
|
-
export async function setGeoLocation(
|
|
24
|
+
export async function setGeoLocation(
|
|
25
|
+
this: AndroidDriver,
|
|
26
|
+
location: Location,
|
|
27
|
+
): Promise<Location> {
|
|
22
28
|
await this.settingsApp.setGeoLocation(location, this.isEmulator());
|
|
23
29
|
try {
|
|
24
30
|
return await this.getGeoLocation();
|
|
25
31
|
} catch (e) {
|
|
26
32
|
this.log.warn(
|
|
27
|
-
`Could not get the current geolocation info: ${
|
|
33
|
+
`Could not get the current geolocation info: ${(e as Error).message}`,
|
|
28
34
|
);
|
|
29
35
|
this.log.warn(`Returning the default zero'ed values`);
|
|
30
36
|
return {
|
|
@@ -38,28 +44,28 @@ export async function setGeoLocation(location) {
|
|
|
38
44
|
/**
|
|
39
45
|
* Set the device geolocation.
|
|
40
46
|
*
|
|
41
|
-
* @
|
|
42
|
-
* @param
|
|
43
|
-
* @param
|
|
44
|
-
* @param
|
|
45
|
-
* @param
|
|
46
|
-
* @param {number} [speed] Valid speed value.
|
|
47
|
+
* @param latitude Valid latitude value.
|
|
48
|
+
* @param longitude Valid longitude value.
|
|
49
|
+
* @param altitude Valid altitude value.
|
|
50
|
+
* @param satellites Number of satellites being tracked (1-12). Available for emulators.
|
|
51
|
+
* @param speed Valid speed value.
|
|
47
52
|
* https://developer.android.com/reference/android/location/Location#setSpeed(float)
|
|
48
|
-
* @param
|
|
53
|
+
* @param bearing Valid bearing value. Available for real devices.
|
|
49
54
|
* https://developer.android.com/reference/android/location/Location#setBearing(float)
|
|
50
|
-
* @param
|
|
55
|
+
* @param accuracy Valid accuracy value. Available for real devices.
|
|
51
56
|
* https://developer.android.com/reference/android/location/Location#setAccuracy(float),
|
|
52
57
|
* https://developer.android.com/reference/android/location/Criteria
|
|
53
58
|
*/
|
|
54
59
|
export async function mobileSetGeolocation(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
this: AndroidDriver,
|
|
61
|
+
latitude: number,
|
|
62
|
+
longitude: number,
|
|
63
|
+
altitude?: number,
|
|
64
|
+
satellites?: number,
|
|
65
|
+
speed?: number,
|
|
66
|
+
bearing?: number,
|
|
67
|
+
accuracy?: number,
|
|
68
|
+
): Promise<void> {
|
|
63
69
|
await this.settingsApp.setGeoLocation({
|
|
64
70
|
latitude,
|
|
65
71
|
longitude,
|
|
@@ -67,7 +73,7 @@ export async function mobileSetGeolocation(
|
|
|
67
73
|
satellites,
|
|
68
74
|
speed,
|
|
69
75
|
bearing,
|
|
70
|
-
accuracy
|
|
76
|
+
accuracy,
|
|
71
77
|
}, this.isEmulator());
|
|
72
78
|
}
|
|
73
79
|
|
|
@@ -78,22 +84,27 @@ export async function mobileSetGeolocation(
|
|
|
78
84
|
* installed. In case the vanilla LocationManager is used the device API level
|
|
79
85
|
* must be at version 30 (Android R) or higher.
|
|
80
86
|
*
|
|
81
|
-
* @
|
|
82
|
-
* @param {number} [timeoutMs] The maximum number of milliseconds
|
|
87
|
+
* @param timeoutMs The maximum number of milliseconds
|
|
83
88
|
* to block until GPS cache is refreshed. Providing zero or a negative
|
|
84
89
|
* value to it skips waiting completely.
|
|
85
90
|
* 20000ms by default.
|
|
86
|
-
* @returns
|
|
91
|
+
* @returns Promise that resolves when the GPS cache refresh is initiated.
|
|
87
92
|
*/
|
|
88
|
-
export async function mobileRefreshGpsCache(
|
|
93
|
+
export async function mobileRefreshGpsCache(
|
|
94
|
+
this: AndroidDriver,
|
|
95
|
+
timeoutMs?: number,
|
|
96
|
+
): Promise<void> {
|
|
89
97
|
await this.settingsApp.refreshGeoLocationCache(timeoutMs);
|
|
90
98
|
}
|
|
91
99
|
|
|
92
100
|
/**
|
|
93
|
-
*
|
|
94
|
-
*
|
|
101
|
+
* Gets the current device geolocation.
|
|
102
|
+
*
|
|
103
|
+
* @returns Promise that resolves to the current geolocation object.
|
|
95
104
|
*/
|
|
96
|
-
export async function getGeoLocation(
|
|
105
|
+
export async function getGeoLocation(
|
|
106
|
+
this: AndroidDriver,
|
|
107
|
+
): Promise<Location> {
|
|
97
108
|
const {latitude, longitude, altitude} = await this.settingsApp.getGeoLocation();
|
|
98
109
|
return {
|
|
99
110
|
latitude: parseFloat(String(latitude)) || GEO_EPSILON,
|
|
@@ -103,26 +114,35 @@ export async function getGeoLocation() {
|
|
|
103
114
|
}
|
|
104
115
|
|
|
105
116
|
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
117
|
+
* Gets the current device geolocation.
|
|
118
|
+
*
|
|
119
|
+
* @returns Promise that resolves to the current geolocation object.
|
|
108
120
|
*/
|
|
109
|
-
export async function mobileGetGeolocation(
|
|
121
|
+
export async function mobileGetGeolocation(
|
|
122
|
+
this: AndroidDriver,
|
|
123
|
+
): Promise<Location> {
|
|
110
124
|
return await this.getGeoLocation();
|
|
111
125
|
}
|
|
112
126
|
|
|
113
127
|
/**
|
|
114
|
-
*
|
|
115
|
-
*
|
|
128
|
+
* Checks if location services are enabled.
|
|
129
|
+
*
|
|
130
|
+
* @returns Promise that resolves to `true` if location services are enabled, `false` otherwise.
|
|
116
131
|
*/
|
|
117
|
-
export async function isLocationServicesEnabled(
|
|
132
|
+
export async function isLocationServicesEnabled(
|
|
133
|
+
this: AndroidDriver,
|
|
134
|
+
): Promise<boolean> {
|
|
118
135
|
return (await this.adb.getLocationProviders()).includes('gps');
|
|
119
136
|
}
|
|
120
137
|
|
|
121
138
|
/**
|
|
122
|
-
*
|
|
123
|
-
*
|
|
139
|
+
* Toggles the location services state.
|
|
140
|
+
*
|
|
141
|
+
* @returns Promise that resolves when the location services state is toggled.
|
|
124
142
|
*/
|
|
125
|
-
export async function toggleLocationServices(
|
|
143
|
+
export async function toggleLocationServices(
|
|
144
|
+
this: AndroidDriver,
|
|
145
|
+
): Promise<void> {
|
|
126
146
|
this.log.info('Toggling location services');
|
|
127
147
|
const isGpsEnabled = await this.isLocationServicesEnabled();
|
|
128
148
|
this.log.debug(
|
|
@@ -133,10 +153,14 @@ export async function toggleLocationServices() {
|
|
|
133
153
|
}
|
|
134
154
|
|
|
135
155
|
/**
|
|
136
|
-
*
|
|
137
|
-
*
|
|
156
|
+
* Resets the geolocation to the default state.
|
|
157
|
+
*
|
|
158
|
+
* @returns Promise that resolves when the geolocation is reset.
|
|
159
|
+
* @throws {Error} If called on an emulator (geolocation reset does not work on emulators).
|
|
138
160
|
*/
|
|
139
|
-
export async function mobileResetGeolocation(
|
|
161
|
+
export async function mobileResetGeolocation(
|
|
162
|
+
this: AndroidDriver,
|
|
163
|
+
): Promise<void> {
|
|
140
164
|
if (this.isEmulator()) {
|
|
141
165
|
throw new Error('Geolocation reset does not work on emulators');
|
|
142
166
|
}
|
|
@@ -146,20 +170,23 @@ export async function mobileResetGeolocation() {
|
|
|
146
170
|
// #region Internal helpers
|
|
147
171
|
|
|
148
172
|
/**
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
* @
|
|
173
|
+
* Sets the mock location permission for a specific app.
|
|
174
|
+
*
|
|
175
|
+
* @param appId The application package identifier.
|
|
176
|
+
* @returns Promise that resolves when the mock location permission is set.
|
|
152
177
|
*/
|
|
153
|
-
export async function setMockLocationApp(
|
|
178
|
+
export async function setMockLocationApp(
|
|
179
|
+
this: AndroidDriver,
|
|
180
|
+
appId: string,
|
|
181
|
+
): Promise<void> {
|
|
154
182
|
try {
|
|
155
183
|
await this.adb.shell(['appops', 'set', appId, 'android:mock_location', 'allow']);
|
|
156
184
|
} catch (err) {
|
|
157
|
-
this.log.warn(`Unable to set mock location for app '${appId}': ${err.message}`);
|
|
185
|
+
this.log.warn(`Unable to set mock location for app '${appId}': ${(err as Error).message}`);
|
|
158
186
|
return;
|
|
159
187
|
}
|
|
160
188
|
try {
|
|
161
|
-
|
|
162
|
-
let pkgIds = [];
|
|
189
|
+
let pkgIds: string[] = [];
|
|
163
190
|
if (await this.adb.fileExists(MOCK_APP_IDS_STORE)) {
|
|
164
191
|
try {
|
|
165
192
|
pkgIds = JSON.parse(await this.adb.shell(['cat', MOCK_APP_IDS_STORE]));
|
|
@@ -178,18 +205,21 @@ export async function setMockLocationApp(appId) {
|
|
|
178
205
|
await fs.rimraf(tmpRoot);
|
|
179
206
|
}
|
|
180
207
|
} catch (e) {
|
|
181
|
-
this.log.warn(`Unable to persist mock location app id '${appId}': ${e.message}`);
|
|
208
|
+
this.log.warn(`Unable to persist mock location app id '${appId}': ${(e as Error).message}`);
|
|
182
209
|
}
|
|
183
210
|
}
|
|
184
211
|
|
|
185
212
|
/**
|
|
186
|
-
*
|
|
187
|
-
*
|
|
213
|
+
* Resets the mock location permissions for all apps.
|
|
214
|
+
*
|
|
215
|
+
* @returns Promise that resolves when the mock location permissions are reset.
|
|
188
216
|
*/
|
|
189
|
-
async function resetMockLocation(
|
|
217
|
+
async function resetMockLocation(
|
|
218
|
+
this: AndroidDriver,
|
|
219
|
+
): Promise<void> {
|
|
190
220
|
try {
|
|
191
221
|
const thirdPartyPkgIdsPromise = getThirdPartyPackages.bind(this)();
|
|
192
|
-
let pkgIds = [];
|
|
222
|
+
let pkgIds: string[] = [];
|
|
193
223
|
if (await this.adb.fileExists(MOCK_APP_IDS_STORE)) {
|
|
194
224
|
try {
|
|
195
225
|
pkgIds = JSON.parse(await this.adb.shell(['cat', MOCK_APP_IDS_STORE]));
|
|
@@ -220,8 +250,9 @@ async function resetMockLocation() {
|
|
|
220
250
|
),
|
|
221
251
|
);
|
|
222
252
|
} catch (err) {
|
|
223
|
-
this.log.warn(`Unable to reset mock location: ${err.message}`);
|
|
253
|
+
this.log.warn(`Unable to reset mock location: ${(err as Error).message}`);
|
|
224
254
|
}
|
|
225
255
|
}
|
|
226
256
|
|
|
227
257
|
// #endregion Internal helpers
|
|
258
|
+
|
|
@@ -2,51 +2,42 @@ import {DEFAULT_WS_PATHNAME_PREFIX, BaseDriver} from 'appium/driver';
|
|
|
2
2
|
import _ from 'lodash';
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import WebSocket from 'ws';
|
|
5
|
+
import type {AppiumServer, WSServer} from '@appium/types';
|
|
6
|
+
import type {EventEmitter} from 'node:events';
|
|
7
|
+
import type {ADB} from 'appium-adb';
|
|
8
|
+
import type {Chromedriver} from 'appium-chromedriver';
|
|
5
9
|
import {
|
|
6
10
|
GET_SERVER_LOGS_FEATURE,
|
|
7
11
|
toLogRecord,
|
|
8
12
|
nativeLogEntryToSeleniumEntry,
|
|
13
|
+
type LogEntry,
|
|
9
14
|
} from '../utils';
|
|
10
15
|
import { NATIVE_WIN } from './context/helpers';
|
|
11
16
|
import { BIDI_EVENT_NAME } from './bidi/constants';
|
|
12
17
|
import { makeLogEntryAddedEvent } from './bidi/models';
|
|
18
|
+
import type {AndroidDriver} from '../driver';
|
|
13
19
|
|
|
14
20
|
export const supportedLogTypes = {
|
|
15
21
|
logcat: {
|
|
16
22
|
description: 'Logs for Android applications on real device and emulators via ADB',
|
|
17
|
-
|
|
18
|
-
*
|
|
19
|
-
* @param {import('../driver').AndroidDriver} self
|
|
20
|
-
* @returns
|
|
21
|
-
*/
|
|
22
|
-
getter: (self) => /** @type {ADB} */ (self.adb).getLogcatLogs(),
|
|
23
|
+
getter: (self: AndroidDriver) => (self.adb as ADB).getLogcatLogs(),
|
|
23
24
|
},
|
|
24
25
|
bugreport: {
|
|
25
26
|
description: `'adb bugreport' output for advanced issues diagnostic`,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
* @param {import('../driver').AndroidDriver} self
|
|
29
|
-
* @returns
|
|
30
|
-
*/
|
|
31
|
-
getter: async (self) => {
|
|
32
|
-
const output = await /** @type {ADB} */ (self.adb).bugreport();
|
|
27
|
+
getter: async (self: AndroidDriver) => {
|
|
28
|
+
const output = await (self.adb as ADB).bugreport();
|
|
33
29
|
const timestamp = Date.now();
|
|
34
30
|
return output.split(os.EOL).map((x) => toLogRecord(timestamp, x));
|
|
35
31
|
},
|
|
36
32
|
},
|
|
37
33
|
server: {
|
|
38
34
|
description: 'Appium server logs',
|
|
39
|
-
|
|
40
|
-
*
|
|
41
|
-
* @param {import('../driver').AndroidDriver} self
|
|
42
|
-
* @returns
|
|
43
|
-
*/
|
|
44
|
-
getter: (self) => {
|
|
35
|
+
getter: (self: AndroidDriver) => {
|
|
45
36
|
self.assertFeatureEnabled(GET_SERVER_LOGS_FEATURE);
|
|
46
37
|
return self.log.unwrap().record.map(nativeLogEntryToSeleniumEntry);
|
|
47
38
|
},
|
|
48
39
|
},
|
|
49
|
-
};
|
|
40
|
+
} as const;
|
|
50
41
|
|
|
51
42
|
/**
|
|
52
43
|
* Starts Android logcat broadcast websocket on the same host and port
|
|
@@ -56,12 +47,13 @@ export const supportedLogTypes = {
|
|
|
56
47
|
* Each connected websocket listener will receive logcat log lines
|
|
57
48
|
* as soon as they are visible to Appium.
|
|
58
49
|
*
|
|
59
|
-
* @
|
|
60
|
-
* @returns {Promise<void>}
|
|
50
|
+
* @returns Promise that resolves when the logcat broadcasting websocket is started.
|
|
61
51
|
*/
|
|
62
|
-
export async function mobileStartLogsBroadcast(
|
|
63
|
-
|
|
64
|
-
|
|
52
|
+
export async function mobileStartLogsBroadcast(
|
|
53
|
+
this: AndroidDriver,
|
|
54
|
+
): Promise<void> {
|
|
55
|
+
const server = this.server as AppiumServer;
|
|
56
|
+
const pathname = WEBSOCKET_ENDPOINT(this.sessionId as string);
|
|
65
57
|
if (!_.isEmpty(await server.getWebSocketHandlers(pathname))) {
|
|
66
58
|
this.log.debug(`The logcat broadcasting web socket server is already listening at ${pathname}`);
|
|
67
59
|
return;
|
|
@@ -78,7 +70,7 @@ export async function mobileStartLogsBroadcast() {
|
|
|
78
70
|
wss.on('connection', (ws, req) => {
|
|
79
71
|
if (req) {
|
|
80
72
|
const remoteIp = _.isEmpty(req.headers['x-forwarded-for'])
|
|
81
|
-
? req.
|
|
73
|
+
? req.socket.remoteAddress
|
|
82
74
|
: req.headers['x-forwarded-for'];
|
|
83
75
|
this.log.debug(`Established a new logcat listener web socket connection from ${remoteIp}`);
|
|
84
76
|
} else {
|
|
@@ -86,7 +78,7 @@ export async function mobileStartLogsBroadcast() {
|
|
|
86
78
|
}
|
|
87
79
|
|
|
88
80
|
if (_.isEmpty(this._logcatWebsocketListener)) {
|
|
89
|
-
this._logcatWebsocketListener = (logRecord) => {
|
|
81
|
+
this._logcatWebsocketListener = (logRecord: LogEntry) => {
|
|
90
82
|
if (ws?.readyState === WebSocket.OPEN) {
|
|
91
83
|
ws.send(logRecord.message);
|
|
92
84
|
}
|
|
@@ -112,19 +104,20 @@ export async function mobileStartLogsBroadcast() {
|
|
|
112
104
|
this.log.debug(closeMsg);
|
|
113
105
|
});
|
|
114
106
|
});
|
|
115
|
-
await server.addWebSocketHandler(pathname,
|
|
107
|
+
await server.addWebSocketHandler(pathname, wss as WSServer);
|
|
116
108
|
}
|
|
117
109
|
|
|
118
110
|
/**
|
|
119
111
|
* Stops the previously started logcat broadcasting wesocket server.
|
|
120
112
|
* This method will return immediately if no server is running.
|
|
121
113
|
*
|
|
122
|
-
* @
|
|
123
|
-
* @returns {Promise<void>}
|
|
114
|
+
* @returns Promise that resolves when the logcat broadcasting websocket is stopped.
|
|
124
115
|
*/
|
|
125
|
-
export async function mobileStopLogsBroadcast(
|
|
126
|
-
|
|
127
|
-
|
|
116
|
+
export async function mobileStopLogsBroadcast(
|
|
117
|
+
this: AndroidDriver,
|
|
118
|
+
): Promise<void> {
|
|
119
|
+
const pathname = WEBSOCKET_ENDPOINT(this.sessionId as string);
|
|
120
|
+
const server = this.server as AppiumServer;
|
|
128
121
|
if (_.isEmpty(await server.getWebSocketHandlers(pathname))) {
|
|
129
122
|
return;
|
|
130
123
|
}
|
|
@@ -137,40 +130,44 @@ export async function mobileStopLogsBroadcast() {
|
|
|
137
130
|
}
|
|
138
131
|
|
|
139
132
|
/**
|
|
140
|
-
*
|
|
141
|
-
*
|
|
133
|
+
* Gets the list of available log types.
|
|
134
|
+
*
|
|
135
|
+
* @returns Promise that resolves to an array of log type names.
|
|
142
136
|
*/
|
|
143
|
-
export async function getLogTypes(
|
|
137
|
+
export async function getLogTypes(
|
|
138
|
+
this: AndroidDriver,
|
|
139
|
+
): Promise<string[]> {
|
|
144
140
|
// XXX why doesn't `super` work here?
|
|
145
141
|
const nativeLogTypes = await BaseDriver.prototype.getLogTypes.call(this);
|
|
146
142
|
if (this.isWebContext()) {
|
|
147
|
-
const webLogTypes =
|
|
148
|
-
await /** @type {import('appium-chromedriver').Chromedriver} */ (
|
|
149
|
-
this.chromedriver
|
|
150
|
-
).jwproxy.command('/log/types', 'GET')
|
|
151
|
-
);
|
|
143
|
+
const webLogTypes = await (this.chromedriver as Chromedriver).jwproxy.command('/log/types', 'GET') as string[];
|
|
152
144
|
return [...nativeLogTypes, ...webLogTypes];
|
|
153
145
|
}
|
|
154
146
|
return nativeLogTypes;
|
|
155
147
|
}
|
|
156
148
|
|
|
157
149
|
/**
|
|
150
|
+
* Assigns a BiDi log listener to an event emitter.
|
|
151
|
+
*
|
|
158
152
|
* https://w3c.github.io/webdriver-bidi/#event-log-entryAdded
|
|
159
153
|
*
|
|
160
|
-
* @template
|
|
161
|
-
* @
|
|
162
|
-
* @param
|
|
163
|
-
* @
|
|
164
|
-
* @returns {[EE, LogListener]}
|
|
154
|
+
* @template EE The event emitter type.
|
|
155
|
+
* @param logEmitter The event emitter to attach the listener to.
|
|
156
|
+
* @param properties The BiDi listener properties.
|
|
157
|
+
* @returns A tuple containing the event emitter and the listener function.
|
|
165
158
|
*/
|
|
166
|
-
export function assignBiDiLogListener (
|
|
159
|
+
export function assignBiDiLogListener<EE extends EventEmitter>(
|
|
160
|
+
this: AndroidDriver,
|
|
161
|
+
logEmitter: EE,
|
|
162
|
+
properties: BiDiListenerProperties,
|
|
163
|
+
): [EE, LogListener] {
|
|
167
164
|
const {
|
|
168
165
|
type,
|
|
169
166
|
context = NATIVE_WIN,
|
|
170
167
|
srcEventName = 'output',
|
|
171
168
|
entryTransformer,
|
|
172
169
|
} = properties;
|
|
173
|
-
const listener = (
|
|
170
|
+
const listener: LogListener = (logEntry: LogEntry) => {
|
|
174
171
|
const finalEntry = entryTransformer ? entryTransformer(logEntry) : logEntry;
|
|
175
172
|
this.eventEmitter.emit(BIDI_EVENT_NAME, makeLogEntryAddedEvent(finalEntry, context, type));
|
|
176
173
|
};
|
|
@@ -179,42 +176,40 @@ export function assignBiDiLogListener (logEmitter, properties) {
|
|
|
179
176
|
}
|
|
180
177
|
|
|
181
178
|
/**
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
* @
|
|
179
|
+
* Gets logs of a specific type.
|
|
180
|
+
*
|
|
181
|
+
* @param logType The type of logs to retrieve.
|
|
182
|
+
* @returns Promise that resolves to the logs for the specified type.
|
|
185
183
|
*/
|
|
186
|
-
export async function getLog(
|
|
184
|
+
export async function getLog(
|
|
185
|
+
this: AndroidDriver,
|
|
186
|
+
logType: string,
|
|
187
|
+
): Promise<any> {
|
|
187
188
|
if (this.isWebContext() && !_.keys(this.supportedLogTypes).includes(logType)) {
|
|
188
|
-
return await
|
|
189
|
-
this.chromedriver
|
|
190
|
-
).jwproxy.command('/log', 'POST', {type: logType});
|
|
189
|
+
return await (this.chromedriver as Chromedriver).jwproxy.command('/log', 'POST', {type: logType});
|
|
191
190
|
}
|
|
192
|
-
// XXX why doesn't `super` work here?
|
|
193
191
|
return await BaseDriver.prototype.getLog.call(this, logType);
|
|
194
192
|
}
|
|
195
193
|
|
|
196
194
|
// #region Internal helpers
|
|
197
195
|
|
|
198
196
|
/**
|
|
199
|
-
*
|
|
200
|
-
*
|
|
197
|
+
* Generates the websocket endpoint path for logcat broadcasting.
|
|
198
|
+
*
|
|
199
|
+
* @param sessionId The session ID.
|
|
200
|
+
* @returns The websocket endpoint path.
|
|
201
201
|
*/
|
|
202
|
-
const WEBSOCKET_ENDPOINT = (sessionId) =>
|
|
202
|
+
const WEBSOCKET_ENDPOINT = (sessionId: string): string =>
|
|
203
203
|
`${DEFAULT_WS_PATHNAME_PREFIX}/session/${sessionId}/appium/device/logcat`;
|
|
204
204
|
|
|
205
|
-
|
|
206
205
|
// #endregion
|
|
207
206
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
207
|
+
export interface BiDiListenerProperties {
|
|
208
|
+
type: string;
|
|
209
|
+
srcEventName?: string;
|
|
210
|
+
context?: string;
|
|
211
|
+
entryTransformer?: (x: LogEntry) => LogEntry;
|
|
212
|
+
}
|
|
211
213
|
|
|
212
|
-
|
|
213
|
-
* @typedef {Object} BiDiListenerProperties
|
|
214
|
-
* @property {string} type
|
|
215
|
-
* @property {string} [srcEventName='output']
|
|
216
|
-
* @property {string} [context=NATIVE_WIN]
|
|
217
|
-
* @property {(x: Object) => import('../utils').LogEntry} [entryTransformer]
|
|
218
|
-
*/
|
|
214
|
+
export type LogListener = (logEntry: LogEntry) => any;
|
|
219
215
|
|
|
220
|
-
/** @typedef {(logEntry: import('../utils').LogEntry) => any} LogListener */
|