appium-android-driver 12.4.7 → 12.4.8
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/file-actions.d.ts +37 -19
- package/build/lib/commands/file-actions.d.ts.map +1 -1
- package/build/lib/commands/file-actions.js +44 -58
- package/build/lib/commands/file-actions.js.map +1 -1
- package/build/lib/commands/intent.d.ts +103 -107
- package/build/lib/commands/intent.d.ts.map +1 -1
- package/build/lib/commands/intent.js +103 -97
- package/build/lib/commands/intent.js.map +1 -1
- package/build/lib/commands/recordscreen.d.ts +25 -40
- package/build/lib/commands/recordscreen.d.ts.map +1 -1
- package/build/lib/commands/recordscreen.js +46 -63
- package/build/lib/commands/recordscreen.js.map +1 -1
- package/build/lib/commands/types.d.ts.map +1 -1
- package/build/lib/driver.d.ts +2 -1
- package/build/lib/driver.d.ts.map +1 -1
- package/build/lib/driver.js.map +1 -1
- package/lib/commands/{file-actions.js → file-actions.ts} +88 -74
- package/lib/commands/intent.ts +422 -0
- package/lib/commands/{recordscreen.js → recordscreen.ts} +77 -73
- package/lib/commands/types.ts +17 -0
- package/lib/driver.ts +2 -1
- package/package.json +1 -1
- package/lib/commands/intent.js +0 -409
|
@@ -31,18 +31,19 @@ const SUPPORTED_EXTRA_TYPES = [
|
|
|
31
31
|
'sal',
|
|
32
32
|
];
|
|
33
33
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* @
|
|
37
|
-
* @param
|
|
38
|
-
* @param
|
|
39
|
-
* @param
|
|
40
|
-
* @param
|
|
41
|
-
* @param
|
|
42
|
-
* @param
|
|
43
|
-
* @param
|
|
44
|
-
* @param
|
|
45
|
-
* @
|
|
34
|
+
* Starts an Android activity.
|
|
35
|
+
*
|
|
36
|
+
* @deprecated Use {@link mobileStartActivity} instead.
|
|
37
|
+
* @param appPackage The package name of the application to start.
|
|
38
|
+
* @param appActivity The activity name to start.
|
|
39
|
+
* @param appWaitPackage The package name to wait for. Defaults to `appPackage` if not provided.
|
|
40
|
+
* @param appWaitActivity The activity name to wait for. Defaults to `appActivity` if not provided.
|
|
41
|
+
* @param intentAction The intent action to use.
|
|
42
|
+
* @param intentCategory The intent category to use.
|
|
43
|
+
* @param intentFlags The intent flags to use.
|
|
44
|
+
* @param optionalIntentArguments Optional intent arguments.
|
|
45
|
+
* @param dontStopAppOnReset If `true`, does not stop the app on reset. If not provided, uses the capability value.
|
|
46
|
+
* @returns Promise that resolves when the activity is started.
|
|
46
47
|
*/
|
|
47
48
|
async function startActivity(appPackage, appActivity, appWaitPackage, appWaitActivity, intentAction, intentCategory, intentFlags, optionalIntentArguments, dontStopAppOnReset) {
|
|
48
49
|
this.log.debug(`Starting package '${appPackage}' and activity '${appActivity}'`);
|
|
@@ -51,8 +52,7 @@ async function startActivity(appPackage, appActivity, appWaitPackage, appWaitAct
|
|
|
51
52
|
if (!support_1.util.hasValue(dontStopAppOnReset)) {
|
|
52
53
|
dontStopAppOnReset = !!this.opts.dontStopAppOnReset;
|
|
53
54
|
}
|
|
54
|
-
|
|
55
|
-
let args = {
|
|
55
|
+
const args = {
|
|
56
56
|
pkg: appPackage,
|
|
57
57
|
activity: appActivity,
|
|
58
58
|
waitPkg: appWaitPackage || appPackage,
|
|
@@ -68,34 +68,35 @@ async function startActivity(appPackage, appActivity, appWaitPackage, appWaitAct
|
|
|
68
68
|
await this.adb.startApp(args);
|
|
69
69
|
}
|
|
70
70
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
71
|
+
* Starts an Android activity using the activity manager.
|
|
72
|
+
*
|
|
73
|
+
* @param wait Set it to `true` if you want to block the method call
|
|
73
74
|
* until the activity manager's process returns the control to the system.
|
|
74
|
-
* false by default.
|
|
75
|
-
* @param
|
|
76
|
-
* app before starting the activity
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* for more details on possible windowing modes (constants starting with
|
|
82
|
-
* `WINDOWING_MODE_`).
|
|
83
|
-
* @param {string | number} [activityType] The activity type to launch the activity as.
|
|
75
|
+
* `false` by default.
|
|
76
|
+
* @param stop Set it to `true` to force stop the target
|
|
77
|
+
* app before starting the activity. `false` by default.
|
|
78
|
+
* @param windowingMode The windowing mode to launch the activity into.
|
|
79
|
+
* Check https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/WindowConfiguration.java
|
|
80
|
+
* for more details on possible windowing modes (constants starting with `WINDOWING_MODE_`).
|
|
81
|
+
* @param activityType The activity type to launch the activity as.
|
|
84
82
|
* Check https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/WindowConfiguration.java
|
|
85
83
|
* for more details on possible activity types (constants starting with `ACTIVITY_TYPE_`).
|
|
86
|
-
* @param
|
|
87
|
-
* @param
|
|
88
|
-
* @param
|
|
89
|
-
*
|
|
90
|
-
* @param
|
|
91
|
-
* @param
|
|
92
|
-
* @param
|
|
93
|
-
* @param
|
|
94
|
-
* @param
|
|
95
|
-
* @param
|
|
96
|
-
* @param
|
|
97
|
-
* @param
|
|
98
|
-
*
|
|
84
|
+
* @param display The display identifier to launch the activity into.
|
|
85
|
+
* @param user The user ID for which the activity is started.
|
|
86
|
+
* @param intent The name of the activity intent to start, for example
|
|
87
|
+
* `com.some.package.name/.YourActivitySubClassName`.
|
|
88
|
+
* @param action Action name.
|
|
89
|
+
* @param pkg Package name.
|
|
90
|
+
* @param uri Unified resource identifier.
|
|
91
|
+
* @param mimeType Mime type.
|
|
92
|
+
* @param identifier Optional identifier.
|
|
93
|
+
* @param component Component name.
|
|
94
|
+
* @param categories One or more category names.
|
|
95
|
+
* @param extras Optional intent arguments. Must be represented as array of arrays,
|
|
96
|
+
* where each subarray item contains two or three string items: value type, key name and the value itself.
|
|
97
|
+
* See {@link IntentOpts} for supported value types.
|
|
98
|
+
* @param flags Intent startup-specific flags as a hexadecimal string.
|
|
99
|
+
* @returns Promise that resolves to the command output string.
|
|
99
100
|
*/
|
|
100
101
|
async function mobileStartActivity(wait, stop, windowingMode, activityType, display, user, intent, action, pkg, uri, mimeType, identifier, component, categories, extras, flags) {
|
|
101
102
|
const cmd = [
|
|
@@ -135,23 +136,26 @@ async function mobileStartActivity(wait, stop, windowingMode, activityType, disp
|
|
|
135
136
|
return await this.adb.shell(cmd);
|
|
136
137
|
}
|
|
137
138
|
/**
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* @param
|
|
143
|
-
*
|
|
144
|
-
* @param
|
|
145
|
-
*
|
|
146
|
-
* @param
|
|
147
|
-
* @param
|
|
148
|
-
* @param
|
|
149
|
-
* @param
|
|
150
|
-
* @param
|
|
151
|
-
* @param
|
|
152
|
-
* @param
|
|
153
|
-
* @param
|
|
154
|
-
*
|
|
139
|
+
* Sends a broadcast intent to the Android system.
|
|
140
|
+
*
|
|
141
|
+
* @param receiverPermission Require receiver to hold the given permission.
|
|
142
|
+
* @param allowBackgroundActivityStarts Whether the receiver may start activities even if in the background.
|
|
143
|
+
* @param user The user ID for which the broadcast is sent.
|
|
144
|
+
* The `current` alias assumes the current user ID. `all` by default.
|
|
145
|
+
* @param intent The name of the activity intent to broadcast, for example
|
|
146
|
+
* `com.some.package.name/.YourServiceSubClassName`.
|
|
147
|
+
* @param action Action name.
|
|
148
|
+
* @param pkg Package name.
|
|
149
|
+
* @param uri Unified resource identifier.
|
|
150
|
+
* @param mimeType Mime type.
|
|
151
|
+
* @param identifier Optional identifier.
|
|
152
|
+
* @param component Component name.
|
|
153
|
+
* @param categories One or more category names.
|
|
154
|
+
* @param extras Optional intent arguments. Must be represented as array of arrays,
|
|
155
|
+
* where each subarray item contains two or three string items: value type, key name and the value itself.
|
|
156
|
+
* See {@link IntentOpts} for supported value types.
|
|
157
|
+
* @param flags Intent startup-specific flags as a hexadecimal string.
|
|
158
|
+
* @returns Promise that resolves to the command output string.
|
|
155
159
|
*/
|
|
156
160
|
async function mobileBroadcast(receiverPermission, allowBackgroundActivityStarts, user, intent, action, pkg, uri, mimeType, identifier, component, categories, extras, flags) {
|
|
157
161
|
const cmd = ['am', 'broadcast'];
|
|
@@ -179,22 +183,26 @@ async function mobileBroadcast(receiverPermission, allowBackgroundActivityStarts
|
|
|
179
183
|
return await this.adb.shell(cmd);
|
|
180
184
|
}
|
|
181
185
|
/**
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
* @param
|
|
187
|
-
*
|
|
188
|
-
* @param
|
|
189
|
-
*
|
|
190
|
-
* @param
|
|
191
|
-
* @param
|
|
192
|
-
* @param
|
|
193
|
-
* @param
|
|
194
|
-
* @param
|
|
195
|
-
* @param
|
|
196
|
-
* @param
|
|
197
|
-
* @
|
|
186
|
+
* Starts an Android service.
|
|
187
|
+
*
|
|
188
|
+
* @param foreground Set it to `true` if your service must be started as foreground service.
|
|
189
|
+
* This option is ignored if the API level of the device under test is below 26 (Android 8).
|
|
190
|
+
* @param user The user ID for which the service is started.
|
|
191
|
+
* The `current` user id is used by default.
|
|
192
|
+
* @param intent The name of the activity intent to start, for example
|
|
193
|
+
* `com.some.package.name/.YourServiceSubClassName`.
|
|
194
|
+
* @param action Action name.
|
|
195
|
+
* @param pkg Package name.
|
|
196
|
+
* @param uri Unified resource identifier.
|
|
197
|
+
* @param mimeType Mime type.
|
|
198
|
+
* @param identifier Optional identifier.
|
|
199
|
+
* @param component Component name.
|
|
200
|
+
* @param categories One or more category names.
|
|
201
|
+
* @param extras Optional intent arguments. Must be represented as array of arrays,
|
|
202
|
+
* where each subarray item contains two or three string items: value type, key name and the value itself.
|
|
203
|
+
* See {@link IntentOpts} for supported value types.
|
|
204
|
+
* @param flags Intent startup-specific flags as a hexadecimal string.
|
|
205
|
+
* @returns Promise that resolves to the command output string.
|
|
198
206
|
*/
|
|
199
207
|
async function mobileStartService(foreground, user, intent, action, pkg, uri, mimeType, identifier, component, categories, extras, flags) {
|
|
200
208
|
const cmd = ['am'];
|
|
@@ -217,19 +225,24 @@ async function mobileStartService(foreground, user, intent, action, pkg, uri, mi
|
|
|
217
225
|
return await this.adb.shell(cmd);
|
|
218
226
|
}
|
|
219
227
|
/**
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
* @param
|
|
223
|
-
* @param
|
|
224
|
-
*
|
|
225
|
-
* @param
|
|
226
|
-
* @param
|
|
227
|
-
* @param
|
|
228
|
-
* @param
|
|
229
|
-
* @param
|
|
230
|
-
* @param
|
|
231
|
-
* @param
|
|
232
|
-
* @
|
|
228
|
+
* Stops an Android service.
|
|
229
|
+
*
|
|
230
|
+
* @param user The user ID for which the service is stopped.
|
|
231
|
+
* @param intent The name of the activity intent to stop, for example
|
|
232
|
+
* `com.some.package.name/.YourServiceSubClassName`.
|
|
233
|
+
* @param action Action name.
|
|
234
|
+
* @param pkg Package name.
|
|
235
|
+
* @param uri Unified resource identifier.
|
|
236
|
+
* @param mimeType Mime type.
|
|
237
|
+
* @param identifier Optional identifier.
|
|
238
|
+
* @param component Component name.
|
|
239
|
+
* @param categories One or more category names.
|
|
240
|
+
* @param extras Optional intent arguments. Must be represented as array of arrays,
|
|
241
|
+
* where each subarray item contains two or three string items: value type, key name and the value itself.
|
|
242
|
+
* See {@link IntentOpts} for supported value types.
|
|
243
|
+
* @param flags Intent startup-specific flags as a hexadecimal string.
|
|
244
|
+
* @returns Promise that resolves to the command output string.
|
|
245
|
+
* If the service was already stopped, returns the error message.
|
|
233
246
|
*/
|
|
234
247
|
async function mobileStopService(user, intent, action, pkg, uri, mimeType, identifier, component, categories, extras, flags) {
|
|
235
248
|
const cmd = [
|
|
@@ -256,18 +269,14 @@ async function mobileStopService(user, intent, action, pkg, uri, mimeType, ident
|
|
|
256
269
|
}
|
|
257
270
|
catch (e) {
|
|
258
271
|
// https://github.com/appium/appium-uiautomator2-driver/issues/792
|
|
259
|
-
|
|
260
|
-
|
|
272
|
+
const err = e;
|
|
273
|
+
if (err.code === 255 && err.stderr?.includes('Service stopped')) {
|
|
274
|
+
return err.stderr;
|
|
261
275
|
}
|
|
262
276
|
throw e;
|
|
263
277
|
}
|
|
264
278
|
}
|
|
265
279
|
// #region Internal helpers
|
|
266
|
-
/**
|
|
267
|
-
*
|
|
268
|
-
* @param {import('./types').IntentOpts} opts
|
|
269
|
-
* @returns {string[]}
|
|
270
|
-
*/
|
|
271
280
|
function parseIntentSpec(opts = {}) {
|
|
272
281
|
const { intent, action, uri, mimeType, identifier, categories, component, extras, flags } = opts;
|
|
273
282
|
const resultArgs = [];
|
|
@@ -309,9 +318,9 @@ function parseIntentSpec(opts = {}) {
|
|
|
309
318
|
throw new driver_1.errors.InvalidArgumentError(`Extra argument '${item}' must be an array`);
|
|
310
319
|
}
|
|
311
320
|
const [type, key, value] = item;
|
|
312
|
-
if (!
|
|
321
|
+
if (!SUPPORTED_EXTRA_TYPES.includes(type)) {
|
|
313
322
|
throw new driver_1.errors.InvalidArgumentError(`Extra argument type '${type}' is not known. ` +
|
|
314
|
-
`Supported intent argument types are: ${SUPPORTED_EXTRA_TYPES}`);
|
|
323
|
+
`Supported intent argument types are: ${SUPPORTED_EXTRA_TYPES.join(', ')}`);
|
|
315
324
|
}
|
|
316
325
|
if (lodash_1.default.isEmpty(key) || (lodash_1.default.isString(key) && lodash_1.default.trim(key) === '')) {
|
|
317
326
|
throw new driver_1.errors.InvalidArgumentError(`Extra argument's key in '${JSON.stringify(item)}' must be a valid string identifier`);
|
|
@@ -334,7 +343,4 @@ function parseIntentSpec(opts = {}) {
|
|
|
334
343
|
return resultArgs;
|
|
335
344
|
}
|
|
336
345
|
// #endregion
|
|
337
|
-
/**
|
|
338
|
-
* @typedef {import('appium-adb').ADB} ADB
|
|
339
|
-
*/
|
|
340
346
|
//# sourceMappingURL=intent.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intent.js","sourceRoot":"","sources":["../../../lib/commands/intent.
|
|
1
|
+
{"version":3,"file":"intent.js","sourceRoot":"","sources":["../../../lib/commands/intent.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,47 +1,32 @@
|
|
|
1
|
+
import type { AndroidDriver } from '../driver';
|
|
2
|
+
import type { StartScreenRecordingOpts, StopScreenRecordingOpts } from './types';
|
|
1
3
|
/**
|
|
4
|
+
* Starts screen recording on the Android device.
|
|
2
5
|
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
+
* This method uses Android's `screenrecord` command to capture the screen.
|
|
7
|
+
* The recording can be configured with various options such as video size,
|
|
8
|
+
* bit rate, time limit, and more.
|
|
9
|
+
*
|
|
10
|
+
* @param options Recording options. See {@link StartScreenRecordingOpts} for details.
|
|
11
|
+
* @returns Promise that resolves to the result of stopping any previous recording,
|
|
12
|
+
* or an empty string if no previous recording was active.
|
|
13
|
+
* @throws {Error} If screen recording is not supported on the device or emulator,
|
|
14
|
+
* or if the time limit is invalid.
|
|
6
15
|
*/
|
|
7
|
-
export function startRecordingScreen(this:
|
|
8
|
-
export class startRecordingScreen {
|
|
9
|
-
/**
|
|
10
|
-
*
|
|
11
|
-
* @this {import('../driver').AndroidDriver}
|
|
12
|
-
* @param {import('./types').StartScreenRecordingOpts} [options={}]
|
|
13
|
-
* @returns {Promise<string>}
|
|
14
|
-
*/
|
|
15
|
-
constructor(this: import("../driver").AndroidDriver, options?: import("./types").StartScreenRecordingOpts);
|
|
16
|
-
_screenRecordingProperties: {
|
|
17
|
-
timer: timing.Timer;
|
|
18
|
-
videoSize: string | undefined;
|
|
19
|
-
timeLimit: string | number;
|
|
20
|
-
currentTimeLimit: string | number;
|
|
21
|
-
bitRate: string | number | undefined;
|
|
22
|
-
bugReport: boolean | undefined;
|
|
23
|
-
records: never[];
|
|
24
|
-
recordingProcess: null;
|
|
25
|
-
stopped: boolean;
|
|
26
|
-
};
|
|
27
|
-
}
|
|
16
|
+
export declare function startRecordingScreen(this: AndroidDriver, options?: StartScreenRecordingOpts): Promise<string>;
|
|
28
17
|
/**
|
|
18
|
+
* Stops screen recording and returns the recorded video.
|
|
19
|
+
*
|
|
20
|
+
* This method stops any active screen recording session and returns the recorded
|
|
21
|
+
* video as a base64-encoded string or uploads it to a remote location if specified.
|
|
22
|
+
* If multiple recording chunks were created (for long recordings), they will be
|
|
23
|
+
* merged using ffmpeg if available.
|
|
29
24
|
*
|
|
30
|
-
* @
|
|
31
|
-
* @
|
|
32
|
-
*
|
|
25
|
+
* @param options Stop recording options. See {@link StopScreenRecordingOpts} for details.
|
|
26
|
+
* @returns Promise that resolves to the recorded video as a base64-encoded string
|
|
27
|
+
* if `remotePath` is not provided, or an empty string if the video was uploaded to a remote location.
|
|
28
|
+
* @throws {Error} If screen recording is not supported, no recording was active,
|
|
29
|
+
* or if the recording process cannot be stopped.
|
|
33
30
|
*/
|
|
34
|
-
export function stopRecordingScreen(this:
|
|
35
|
-
export class stopRecordingScreen {
|
|
36
|
-
/**
|
|
37
|
-
*
|
|
38
|
-
* @this {import('../driver').AndroidDriver}
|
|
39
|
-
* @param {import('./types').StopScreenRecordingOpts} [options={}]
|
|
40
|
-
* @returns {Promise<string>}
|
|
41
|
-
*/
|
|
42
|
-
constructor(this: import("../driver").AndroidDriver, options?: import("./types").StopScreenRecordingOpts);
|
|
43
|
-
_screenRecordingProperties: any;
|
|
44
|
-
}
|
|
45
|
-
export type ADB = import("appium-adb").ADB;
|
|
46
|
-
import { timing } from '@appium/support';
|
|
31
|
+
export declare function stopRecordingScreen(this: AndroidDriver, options?: StopScreenRecordingOpts): Promise<string>;
|
|
47
32
|
//# sourceMappingURL=recordscreen.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recordscreen.d.ts","sourceRoot":"","sources":["../../../lib/commands/recordscreen.
|
|
1
|
+
{"version":3,"file":"recordscreen.d.ts","sourceRoot":"","sources":["../../../lib/commands/recordscreen.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,WAAW,CAAC;AAE7C,OAAO,KAAK,EAAC,wBAAwB,EAAE,uBAAuB,EAA4B,MAAM,SAAS,CAAC;AAc1G;;;;;;;;;;;;GAYG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,aAAa,EACnB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,MAAM,CAAC,CAsDjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,aAAa,EACnB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,MAAM,CAAC,CA6EjB"}
|
|
@@ -22,10 +22,17 @@ const MIN_EMULATOR_API_LEVEL = 27;
|
|
|
22
22
|
const FFMPEG_BINARY = `ffmpeg${support_1.system.isWindows() ? '.exe' : ''}`;
|
|
23
23
|
const ADB_PULL_TIMEOUT = 5 * 60 * 1000;
|
|
24
24
|
/**
|
|
25
|
+
* Starts screen recording on the Android device.
|
|
25
26
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
27
|
+
* This method uses Android's `screenrecord` command to capture the screen.
|
|
28
|
+
* The recording can be configured with various options such as video size,
|
|
29
|
+
* bit rate, time limit, and more.
|
|
30
|
+
*
|
|
31
|
+
* @param options Recording options. See {@link StartScreenRecordingOpts} for details.
|
|
32
|
+
* @returns Promise that resolves to the result of stopping any previous recording,
|
|
33
|
+
* or an empty string if no previous recording was active.
|
|
34
|
+
* @throws {Error} If screen recording is not supported on the device or emulator,
|
|
35
|
+
* or if the time limit is invalid.
|
|
29
36
|
*/
|
|
30
37
|
async function startRecordingScreen(options = {}) {
|
|
31
38
|
await verifyScreenRecordIsSupported(this.adb, this.isEmulator());
|
|
@@ -41,7 +48,8 @@ async function startRecordingScreen(options = {}) {
|
|
|
41
48
|
}
|
|
42
49
|
if (!lodash_1.default.isEmpty(this._screenRecordingProperties)) {
|
|
43
50
|
// XXX: this doesn't need to be done in serial, does it?
|
|
44
|
-
|
|
51
|
+
const props = this._screenRecordingProperties;
|
|
52
|
+
for (const record of props.records || []) {
|
|
45
53
|
await this.adb.rimraf(record);
|
|
46
54
|
}
|
|
47
55
|
this._screenRecordingProperties = undefined;
|
|
@@ -51,7 +59,7 @@ async function startRecordingScreen(options = {}) {
|
|
|
51
59
|
throw new Error(`The timeLimit value must be in range [1, ${MAX_TIME_SEC}] seconds. ` +
|
|
52
60
|
`The value of '${timeLimit}' has been passed instead.`);
|
|
53
61
|
}
|
|
54
|
-
|
|
62
|
+
const recordingProps = {
|
|
55
63
|
timer: new support_1.timing.Timer().start(),
|
|
56
64
|
videoSize,
|
|
57
65
|
timeLimit,
|
|
@@ -62,56 +70,66 @@ async function startRecordingScreen(options = {}) {
|
|
|
62
70
|
recordingProcess: null,
|
|
63
71
|
stopped: false,
|
|
64
72
|
};
|
|
65
|
-
|
|
73
|
+
this._screenRecordingProperties = recordingProps;
|
|
74
|
+
await scheduleScreenRecord.bind(this)(recordingProps);
|
|
66
75
|
return result;
|
|
67
76
|
}
|
|
68
77
|
/**
|
|
78
|
+
* Stops screen recording and returns the recorded video.
|
|
79
|
+
*
|
|
80
|
+
* This method stops any active screen recording session and returns the recorded
|
|
81
|
+
* video as a base64-encoded string or uploads it to a remote location if specified.
|
|
82
|
+
* If multiple recording chunks were created (for long recordings), they will be
|
|
83
|
+
* merged using ffmpeg if available.
|
|
69
84
|
*
|
|
70
|
-
* @
|
|
71
|
-
* @
|
|
72
|
-
*
|
|
85
|
+
* @param options Stop recording options. See {@link StopScreenRecordingOpts} for details.
|
|
86
|
+
* @returns Promise that resolves to the recorded video as a base64-encoded string
|
|
87
|
+
* if `remotePath` is not provided, or an empty string if the video was uploaded to a remote location.
|
|
88
|
+
* @throws {Error} If screen recording is not supported, no recording was active,
|
|
89
|
+
* or if the recording process cannot be stopped.
|
|
73
90
|
*/
|
|
74
91
|
async function stopRecordingScreen(options = {}) {
|
|
75
92
|
await verifyScreenRecordIsSupported(this.adb, this.isEmulator());
|
|
76
|
-
|
|
77
|
-
|
|
93
|
+
const props = this._screenRecordingProperties;
|
|
94
|
+
if (!lodash_1.default.isEmpty(props)) {
|
|
95
|
+
props.stopped = true;
|
|
78
96
|
}
|
|
79
97
|
try {
|
|
80
98
|
await terminateBackgroundScreenRecording(this.adb, false);
|
|
81
99
|
}
|
|
82
100
|
catch (err) {
|
|
83
|
-
this.log.warn(
|
|
84
|
-
if (!lodash_1.default.isEmpty(
|
|
101
|
+
this.log.warn(err.message);
|
|
102
|
+
if (!lodash_1.default.isEmpty(props)) {
|
|
85
103
|
this.log.warn('The resulting video might be corrupted');
|
|
86
104
|
}
|
|
87
105
|
}
|
|
88
|
-
if (lodash_1.default.isEmpty(
|
|
106
|
+
if (lodash_1.default.isEmpty(props)) {
|
|
89
107
|
this.log.info(`Screen recording has not been previously started by Appium. There is nothing to stop`);
|
|
90
108
|
return '';
|
|
91
109
|
}
|
|
92
|
-
if (
|
|
110
|
+
if (props.recordingProcess?.isRunning) {
|
|
93
111
|
try {
|
|
94
|
-
await
|
|
112
|
+
await props.recordingProcess.stop('SIGINT', PROCESS_SHUTDOWN_TIMEOUT);
|
|
95
113
|
}
|
|
96
114
|
catch {
|
|
97
115
|
throw this.log.errorWithException(`Unable to stop screen recording within ${PROCESS_SHUTDOWN_TIMEOUT}ms`);
|
|
98
116
|
}
|
|
99
|
-
|
|
117
|
+
props.recordingProcess = null;
|
|
100
118
|
}
|
|
101
|
-
if (lodash_1.default.isEmpty(
|
|
119
|
+
if (lodash_1.default.isEmpty(props.records)) {
|
|
102
120
|
throw this.log.errorWithException(`No screen recordings have been stored on the device so far. ` +
|
|
103
121
|
`Are you sure the ${SCREENRECORD_BINARY} utility works as expected?`);
|
|
104
122
|
}
|
|
105
123
|
const tmpRoot = await support_1.tempDir.openDir();
|
|
106
124
|
try {
|
|
107
125
|
const localRecords = [];
|
|
108
|
-
for (const pathOnDevice of
|
|
126
|
+
for (const pathOnDevice of props.records) {
|
|
109
127
|
const relativePath = path_1.default.resolve(tmpRoot, path_1.default.posix.basename(pathOnDevice));
|
|
110
128
|
localRecords.push(relativePath);
|
|
111
129
|
await this.adb.pull(pathOnDevice, relativePath, { timeout: ADB_PULL_TIMEOUT });
|
|
112
130
|
await this.adb.rimraf(pathOnDevice);
|
|
113
131
|
}
|
|
114
|
-
let resultFilePath =
|
|
132
|
+
let resultFilePath = lodash_1.default.last(localRecords);
|
|
115
133
|
if (localRecords.length > 1) {
|
|
116
134
|
this.log.info(`Got ${localRecords.length} screen recordings. Trying to merge them`);
|
|
117
135
|
try {
|
|
@@ -119,7 +137,7 @@ async function stopRecordingScreen(options = {}) {
|
|
|
119
137
|
}
|
|
120
138
|
catch (e) {
|
|
121
139
|
this.log.warn(`Cannot merge the recorded files. The most recent screen recording is going to be returned as the result. ` +
|
|
122
|
-
`Original error: ${
|
|
140
|
+
`Original error: ${e.message}`);
|
|
123
141
|
}
|
|
124
142
|
}
|
|
125
143
|
if (lodash_1.default.isEmpty(options.remotePath)) {
|
|
@@ -134,21 +152,11 @@ async function stopRecordingScreen(options = {}) {
|
|
|
134
152
|
}
|
|
135
153
|
}
|
|
136
154
|
// #region Internal helpers
|
|
137
|
-
/**
|
|
138
|
-
*
|
|
139
|
-
* @param {string} localFile
|
|
140
|
-
* @param {string} [remotePath]
|
|
141
|
-
* @param {import('./types').StopScreenRecordingOpts} uploadOptions
|
|
142
|
-
* @returns {Promise<string>}
|
|
143
|
-
*/
|
|
144
155
|
async function uploadRecordedMedia(localFile, remotePath, uploadOptions = {}) {
|
|
145
156
|
if (lodash_1.default.isEmpty(remotePath)) {
|
|
146
157
|
return (await support_1.util.toInMemoryBase64(localFile)).toString();
|
|
147
158
|
}
|
|
148
159
|
const { user, pass, method, headers, fileFieldName, formFields } = uploadOptions;
|
|
149
|
-
/**
|
|
150
|
-
* @type {import('@appium/support').NetOptions & import('@appium/support').HttpUploadOptions}
|
|
151
|
-
*/
|
|
152
160
|
const options = {
|
|
153
161
|
method: method || 'PUT',
|
|
154
162
|
headers,
|
|
@@ -158,25 +166,15 @@ async function uploadRecordedMedia(localFile, remotePath, uploadOptions = {}) {
|
|
|
158
166
|
if (user && pass) {
|
|
159
167
|
options.auth = { user, pass };
|
|
160
168
|
}
|
|
161
|
-
await support_1.net.uploadFile(localFile,
|
|
169
|
+
await support_1.net.uploadFile(localFile, remotePath, options);
|
|
162
170
|
return '';
|
|
163
171
|
}
|
|
164
|
-
/**
|
|
165
|
-
*
|
|
166
|
-
* @param {ADB} adb
|
|
167
|
-
* @param {boolean} isEmulator
|
|
168
|
-
*/
|
|
169
172
|
async function verifyScreenRecordIsSupported(adb, isEmulator) {
|
|
170
173
|
const apiLevel = await adb.getApiLevel();
|
|
171
174
|
if (isEmulator && apiLevel < MIN_EMULATOR_API_LEVEL) {
|
|
172
175
|
throw new Error(`Screen recording does not work on emulators running Android API level less than ${MIN_EMULATOR_API_LEVEL}`);
|
|
173
176
|
}
|
|
174
177
|
}
|
|
175
|
-
/**
|
|
176
|
-
* @this {import('../driver').AndroidDriver}
|
|
177
|
-
* @param {import('@appium/types').StringRecord} recordingProperties
|
|
178
|
-
* @returns {Promise<void>}
|
|
179
|
-
*/
|
|
180
178
|
async function scheduleScreenRecord(recordingProperties) {
|
|
181
179
|
if (recordingProperties.stopped) {
|
|
182
180
|
return;
|
|
@@ -184,7 +182,7 @@ async function scheduleScreenRecord(recordingProperties) {
|
|
|
184
182
|
const { timer, videoSize, bitRate, timeLimit, bugReport } = recordingProperties;
|
|
185
183
|
let currentTimeLimit = MAX_RECORDING_TIME_SEC;
|
|
186
184
|
if (support_1.util.hasValue(recordingProperties.currentTimeLimit)) {
|
|
187
|
-
const currentTimeLimitInt = parseInt(recordingProperties.currentTimeLimit, 10);
|
|
185
|
+
const currentTimeLimitInt = parseInt(String(recordingProperties.currentTimeLimit), 10);
|
|
188
186
|
if (!isNaN(currentTimeLimitInt) && currentTimeLimitInt < MAX_RECORDING_TIME_SEC) {
|
|
189
187
|
currentTimeLimit = currentTimeLimitInt;
|
|
190
188
|
}
|
|
@@ -202,12 +200,12 @@ async function scheduleScreenRecord(recordingProperties) {
|
|
|
202
200
|
}
|
|
203
201
|
const currentDuration = timer.getDuration().asSeconds.toFixed(0);
|
|
204
202
|
this.log.debug(`The overall screen recording duration is ${currentDuration}s so far`);
|
|
205
|
-
const timeLimitInt = parseInt(timeLimit, 10);
|
|
206
|
-
if (isNaN(timeLimitInt) || currentDuration >= timeLimitInt) {
|
|
203
|
+
const timeLimitInt = parseInt(String(timeLimit), 10);
|
|
204
|
+
if (isNaN(timeLimitInt) || Number(currentDuration) >= timeLimitInt) {
|
|
207
205
|
this.log.debug('There is no need to start the next recording chunk');
|
|
208
206
|
return;
|
|
209
207
|
}
|
|
210
|
-
recordingProperties.currentTimeLimit = timeLimitInt - currentDuration;
|
|
208
|
+
recordingProperties.currentTimeLimit = timeLimitInt - Number(currentDuration);
|
|
211
209
|
const chunkDuration = recordingProperties.currentTimeLimit < MAX_RECORDING_TIME_SEC
|
|
212
210
|
? recordingProperties.currentTimeLimit
|
|
213
211
|
: MAX_RECORDING_TIME_SEC;
|
|
@@ -218,7 +216,7 @@ async function scheduleScreenRecord(recordingProperties) {
|
|
|
218
216
|
await scheduleScreenRecord.bind(this)(recordingProperties);
|
|
219
217
|
}
|
|
220
218
|
catch (e) {
|
|
221
|
-
this.log.error(
|
|
219
|
+
this.log.error(e.stack);
|
|
222
220
|
recordingProperties.stopped = true;
|
|
223
221
|
}
|
|
224
222
|
})();
|
|
@@ -237,12 +235,6 @@ async function scheduleScreenRecord(recordingProperties) {
|
|
|
237
235
|
recordingProperties.records.push(pathOnDevice);
|
|
238
236
|
recordingProperties.recordingProcess = recordingProc;
|
|
239
237
|
}
|
|
240
|
-
/**
|
|
241
|
-
*
|
|
242
|
-
* @this {import('../driver').AndroidDriver}
|
|
243
|
-
* @param {string[]} mediaFiles
|
|
244
|
-
* @returns {Promise<string>}
|
|
245
|
-
*/
|
|
246
238
|
async function mergeScreenRecords(mediaFiles) {
|
|
247
239
|
try {
|
|
248
240
|
await support_1.fs.which(FFMPEG_BINARY);
|
|
@@ -260,12 +252,6 @@ async function mergeScreenRecords(mediaFiles) {
|
|
|
260
252
|
await (0, teen_process_1.exec)(FFMPEG_BINARY, args);
|
|
261
253
|
return result;
|
|
262
254
|
}
|
|
263
|
-
/**
|
|
264
|
-
*
|
|
265
|
-
* @param {ADB} adb
|
|
266
|
-
* @param {boolean} force
|
|
267
|
-
* @returns {Promise<boolean>}
|
|
268
|
-
*/
|
|
269
255
|
async function terminateBackgroundScreenRecording(adb, force = true) {
|
|
270
256
|
const isScreenrecordRunning = async () => lodash_1.default.includes(await adb.listProcessStatus(), SCREENRECORD_BINARY);
|
|
271
257
|
if (!await isScreenrecordRunning()) {
|
|
@@ -280,11 +266,8 @@ async function terminateBackgroundScreenRecording(adb, force = true) {
|
|
|
280
266
|
return true;
|
|
281
267
|
}
|
|
282
268
|
catch (err) {
|
|
283
|
-
throw new Error(`Unable to stop the background screen recording: ${
|
|
269
|
+
throw new Error(`Unable to stop the background screen recording: ${err.message}`);
|
|
284
270
|
}
|
|
285
271
|
}
|
|
286
272
|
// #endregion
|
|
287
|
-
/**
|
|
288
|
-
* @typedef {import('appium-adb').ADB} ADB
|
|
289
|
-
*/
|
|
290
273
|
//# sourceMappingURL=recordscreen.js.map
|