appium-android-driver 5.14.7 → 6.0.1
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 +7 -0
- package/build/lib/commands/actions.d.ts +6 -224
- package/build/lib/commands/actions.d.ts.map +1 -1
- package/build/lib/commands/actions.js +306 -405
- package/build/lib/commands/actions.js.map +1 -1
- package/build/lib/commands/alert.d.ts +7 -9
- package/build/lib/commands/alert.d.ts.map +1 -1
- package/build/lib/commands/alert.js +24 -18
- package/build/lib/commands/alert.js.map +1 -1
- package/build/lib/commands/app-management.d.ts +7 -313
- package/build/lib/commands/app-management.d.ts.map +1 -1
- package/build/lib/commands/app-management.js +135 -293
- package/build/lib/commands/app-management.js.map +1 -1
- package/build/lib/commands/context.d.ts +8 -92
- package/build/lib/commands/context.d.ts.map +1 -1
- package/build/lib/commands/context.js +381 -439
- package/build/lib/commands/context.js.map +1 -1
- package/build/lib/commands/element.d.ts +8 -35
- package/build/lib/commands/element.d.ts.map +1 -1
- package/build/lib/commands/element.js +153 -136
- package/build/lib/commands/element.js.map +1 -1
- package/build/lib/commands/emu-console.d.ts +6 -48
- package/build/lib/commands/emu-console.d.ts.map +1 -1
- package/build/lib/commands/emu-console.js +19 -34
- package/build/lib/commands/emu-console.js.map +1 -1
- package/build/lib/commands/execute.d.ts +6 -5
- package/build/lib/commands/execute.d.ts.map +1 -1
- package/build/lib/commands/execute.js +77 -66
- package/build/lib/commands/execute.js.map +1 -1
- package/build/lib/commands/file-actions.d.ts +7 -128
- package/build/lib/commands/file-actions.d.ts.map +1 -1
- package/build/lib/commands/file-actions.js +183 -219
- package/build/lib/commands/file-actions.js.map +1 -1
- package/build/lib/commands/find.d.ts +8 -12
- package/build/lib/commands/find.d.ts.map +1 -1
- package/build/lib/commands/find.js +19 -23
- package/build/lib/commands/find.js.map +1 -1
- package/build/lib/commands/general.d.ts +9 -132
- package/build/lib/commands/general.d.ts.map +1 -1
- package/build/lib/commands/general.js +281 -312
- package/build/lib/commands/general.js.map +1 -1
- package/build/lib/commands/ime.d.ts +7 -10
- package/build/lib/commands/ime.d.ts.map +1 -1
- package/build/lib/commands/ime.js +47 -35
- package/build/lib/commands/ime.js.map +1 -1
- package/build/lib/commands/index.d.ts +27 -2
- package/build/lib/commands/index.d.ts.map +1 -1
- package/build/lib/commands/index.js +41 -19
- package/build/lib/commands/index.js.map +1 -1
- package/build/lib/commands/intent.d.ts +7 -417
- package/build/lib/commands/intent.d.ts.map +1 -1
- package/build/lib/commands/intent.js +104 -216
- package/build/lib/commands/intent.js.map +1 -1
- package/build/lib/commands/keyboard.d.ts +6 -5
- package/build/lib/commands/keyboard.d.ts.map +1 -1
- package/build/lib/commands/keyboard.js +16 -8
- package/build/lib/commands/keyboard.js.map +1 -1
- package/build/lib/commands/log.d.ts +7 -44
- package/build/lib/commands/log.d.ts.map +1 -1
- package/build/lib/commands/log.js +146 -108
- package/build/lib/commands/log.js.map +1 -1
- package/build/lib/commands/media-projection.d.ts +7 -143
- package/build/lib/commands/media-projection.d.ts.map +1 -1
- package/build/lib/commands/media-projection.js +113 -140
- package/build/lib/commands/media-projection.js.map +1 -1
- package/build/lib/commands/mixins.d.ts +740 -0
- package/build/lib/commands/mixins.d.ts.map +1 -0
- package/build/lib/commands/mixins.js +19 -0
- package/build/lib/commands/mixins.js.map +1 -0
- package/build/lib/commands/network.d.ts +7 -138
- package/build/lib/commands/network.d.ts.map +1 -1
- package/build/lib/commands/network.js +212 -254
- package/build/lib/commands/network.js.map +1 -1
- package/build/lib/commands/performance.d.ts +24 -70
- package/build/lib/commands/performance.d.ts.map +1 -1
- package/build/lib/commands/performance.js +144 -100
- package/build/lib/commands/performance.js.map +1 -1
- package/build/lib/commands/permissions.d.ts +8 -92
- package/build/lib/commands/permissions.d.ts.map +1 -1
- package/build/lib/commands/permissions.js +75 -87
- package/build/lib/commands/permissions.js.map +1 -1
- package/build/lib/commands/recordscreen.d.ts +7 -193
- package/build/lib/commands/recordscreen.d.ts.map +1 -1
- package/build/lib/commands/recordscreen.js +151 -182
- package/build/lib/commands/recordscreen.js.map +1 -1
- package/build/lib/commands/shell.d.ts +7 -7
- package/build/lib/commands/shell.d.ts.map +1 -1
- package/build/lib/commands/shell.js +40 -33
- package/build/lib/commands/shell.js.map +1 -1
- package/build/lib/commands/streamscreen.d.ts +9 -103
- package/build/lib/commands/streamscreen.d.ts.map +1 -1
- package/build/lib/commands/streamscreen.js +261 -218
- package/build/lib/commands/streamscreen.js.map +1 -1
- package/build/lib/commands/system-bars.d.ts +22 -90
- package/build/lib/commands/system-bars.d.ts.map +1 -1
- package/build/lib/commands/system-bars.js +76 -74
- package/build/lib/commands/system-bars.js.map +1 -1
- package/build/lib/commands/touch.d.ts +10 -29
- package/build/lib/commands/touch.d.ts.map +1 -1
- package/build/lib/commands/touch.js +301 -285
- package/build/lib/commands/touch.js.map +1 -1
- package/build/lib/commands/types.d.ts +978 -0
- package/build/lib/commands/types.d.ts.map +1 -0
- package/build/lib/commands/types.js +3 -0
- package/build/lib/commands/types.js.map +1 -0
- package/build/lib/constraints.d.ts +291 -0
- package/build/lib/constraints.d.ts.map +1 -0
- package/build/lib/{desired-caps.js → constraints.js} +103 -102
- package/build/lib/constraints.js.map +1 -0
- package/build/lib/driver.d.ts +68 -37
- package/build/lib/driver.d.ts.map +1 -1
- package/build/lib/driver.js +123 -80
- package/build/lib/driver.js.map +1 -1
- package/build/lib/helpers/android.d.ts +164 -0
- package/build/lib/helpers/android.d.ts.map +1 -0
- package/build/lib/helpers/android.js +819 -0
- package/build/lib/helpers/android.js.map +1 -0
- package/build/lib/helpers/index.d.ts +7 -0
- package/build/lib/helpers/index.d.ts.map +1 -0
- package/build/lib/helpers/index.js +29 -0
- package/build/lib/helpers/index.js.map +1 -0
- package/build/lib/helpers/types.d.ts +121 -0
- package/build/lib/helpers/types.d.ts.map +1 -0
- package/build/lib/helpers/types.js +3 -0
- package/build/lib/helpers/types.js.map +1 -0
- package/build/lib/helpers/unlock.d.ts +32 -0
- package/build/lib/helpers/unlock.d.ts.map +1 -0
- package/build/lib/helpers/unlock.js +273 -0
- package/build/lib/helpers/unlock.js.map +1 -0
- package/build/lib/helpers/webview.d.ts +74 -0
- package/build/lib/helpers/webview.d.ts.map +1 -0
- package/build/lib/helpers/webview.js +421 -0
- package/build/lib/helpers/webview.js.map +1 -0
- package/build/lib/index.d.ts +9 -0
- package/build/lib/index.d.ts.map +1 -0
- package/build/lib/index.js +37 -0
- package/build/lib/index.js.map +1 -0
- package/build/lib/method-map.d.ts +0 -8
- package/build/lib/method-map.d.ts.map +1 -1
- package/build/lib/method-map.js +63 -74
- package/build/lib/method-map.js.map +1 -1
- package/build/lib/stubs.d.ts +0 -1
- package/build/lib/stubs.d.ts.map +1 -1
- package/build/lib/stubs.js +1 -0
- package/build/lib/stubs.js.map +1 -1
- package/build/lib/utils.d.ts +1 -1
- package/build/lib/utils.d.ts.map +1 -1
- package/lib/commands/actions.js +351 -464
- package/lib/commands/alert.js +27 -17
- package/lib/commands/app-management.js +156 -314
- package/lib/commands/context.js +457 -441
- package/lib/commands/element.js +201 -157
- package/lib/commands/emu-console.js +25 -45
- package/lib/commands/execute.js +106 -90
- package/lib/commands/file-actions.js +222 -240
- package/lib/commands/find.ts +103 -0
- package/lib/commands/general.js +327 -339
- package/lib/commands/ime.js +50 -34
- package/lib/commands/{index.js → index.ts} +20 -24
- package/lib/commands/intent.js +108 -249
- package/lib/commands/keyboard.js +20 -8
- package/lib/commands/log.js +172 -116
- package/lib/commands/media-projection.js +134 -161
- package/lib/commands/mixins.ts +966 -0
- package/lib/commands/network.js +252 -281
- package/lib/commands/performance.js +203 -132
- package/lib/commands/permissions.js +108 -109
- package/lib/commands/recordscreen.js +212 -209
- package/lib/commands/shell.js +51 -40
- package/lib/commands/streamscreen.js +355 -289
- package/lib/commands/system-bars.js +92 -83
- package/lib/commands/touch.js +357 -294
- package/lib/commands/types.ts +1097 -0
- package/lib/{desired-caps.js → constraints.ts} +106 -103
- package/lib/{driver.js → driver.ts} +278 -132
- package/lib/helpers/android.ts +1143 -0
- package/lib/helpers/index.ts +6 -0
- package/lib/helpers/types.ts +134 -0
- package/lib/helpers/unlock.ts +329 -0
- package/lib/helpers/webview.ts +582 -0
- package/lib/index.ts +18 -0
- package/lib/method-map.js +87 -98
- package/lib/stubs.ts +0 -1
- package/package.json +26 -19
- package/build/index.js +0 -51
- package/build/lib/android-helpers.d.ts +0 -136
- package/build/lib/android-helpers.d.ts.map +0 -1
- package/build/lib/android-helpers.js +0 -855
- package/build/lib/android-helpers.js.map +0 -1
- package/build/lib/commands/coverage.d.ts +0 -5
- package/build/lib/commands/coverage.d.ts.map +0 -1
- package/build/lib/commands/coverage.js +0 -19
- package/build/lib/commands/coverage.js.map +0 -1
- package/build/lib/desired-caps.d.ts +0 -353
- package/build/lib/desired-caps.d.ts.map +0 -1
- package/build/lib/desired-caps.js.map +0 -1
- package/build/lib/unlock-helpers.d.ts +0 -38
- package/build/lib/unlock-helpers.d.ts.map +0 -1
- package/build/lib/unlock-helpers.js +0 -266
- package/build/lib/unlock-helpers.js.map +0 -1
- package/build/lib/webview-helpers.d.ts +0 -224
- package/build/lib/webview-helpers.d.ts.map +0 -1
- package/build/lib/webview-helpers.js +0 -528
- package/build/lib/webview-helpers.js.map +0 -1
- package/index.js +0 -24
- package/lib/android-helpers.js +0 -983
- package/lib/commands/coverage.js +0 -18
- package/lib/commands/find.js +0 -82
- package/lib/unlock-helpers.js +0 -278
- package/lib/webview-helpers.js +0 -602
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import {fs, net, tempDir, util} from '@appium/support';
|
|
4
|
+
import {waitForCondition} from 'asyncbox';
|
|
5
5
|
import B from 'bluebird';
|
|
6
|
-
import
|
|
6
|
+
import _ from 'lodash';
|
|
7
7
|
import moment from 'moment';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import {SETTINGS_HELPER_PKG_ID} from '../helpers';
|
|
10
|
+
import {mixin} from './mixins';
|
|
11
11
|
|
|
12
12
|
// https://github.com/appium/io.appium.settings#internal-audio--video-recording
|
|
13
13
|
const DEFAULT_EXT = '.mp4';
|
|
@@ -21,8 +21,14 @@ const RECORDING_ACTION_STOP = `${SETTINGS_HELPER_PKG_ID}.recording.ACTION_STOP`;
|
|
|
21
21
|
const RECORDINGS_ROOT = `/storage/emulated/0/Android/data/${SETTINGS_HELPER_PKG_ID}/files`;
|
|
22
22
|
const DEFAULT_FILENAME_FORMAT = 'YYYY-MM-DDTHH-mm-ss';
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
/**
|
|
25
|
+
*
|
|
26
|
+
* @param {string} localFile
|
|
27
|
+
* @param {string} [remotePath]
|
|
28
|
+
* @param {import('./types').StopMediaProjectionRecordingOpts} uploadOptions
|
|
29
|
+
* @returns
|
|
30
|
+
*/
|
|
31
|
+
async function uploadRecordedMedia(localFile, remotePath, uploadOptions = {}) {
|
|
26
32
|
if (_.isEmpty(remotePath)) {
|
|
27
33
|
return (await util.toInMemoryBase64(localFile)).toString();
|
|
28
34
|
}
|
|
@@ -36,6 +42,9 @@ async function uploadRecordedMedia (localFile, remotePath = null, uploadOptions
|
|
|
36
42
|
formFields,
|
|
37
43
|
uploadTimeout: timeout,
|
|
38
44
|
} = uploadOptions;
|
|
45
|
+
/**
|
|
46
|
+
* @type {Omit<import('./types').StopMediaProjectionRecordingOpts, 'uploadTimeout'> & {auth?: {user: string, pass: string}, timeout?: number}}
|
|
47
|
+
*/
|
|
39
48
|
const options = {
|
|
40
49
|
method: method || 'PUT',
|
|
41
50
|
headers,
|
|
@@ -46,52 +55,64 @@ async function uploadRecordedMedia (localFile, remotePath = null, uploadOptions
|
|
|
46
55
|
if (user && pass) {
|
|
47
56
|
options.auth = {user, pass};
|
|
48
57
|
}
|
|
49
|
-
await net.uploadFile(localFile, remotePath, options);
|
|
58
|
+
await net.uploadFile(localFile, /** @type {string} */ (remotePath), options);
|
|
50
59
|
return '';
|
|
51
60
|
}
|
|
52
61
|
|
|
53
|
-
|
|
62
|
+
/**
|
|
63
|
+
*
|
|
64
|
+
* @param {string} name
|
|
65
|
+
* @returns {string}
|
|
66
|
+
*/
|
|
67
|
+
function adjustMediaExtension(name) {
|
|
54
68
|
return _.toLower(name).endsWith(DEFAULT_EXT) ? name : `${name}${DEFAULT_EXT}`;
|
|
55
69
|
}
|
|
56
70
|
|
|
57
|
-
|
|
71
|
+
/**
|
|
72
|
+
*
|
|
73
|
+
* @param {ADB} adb
|
|
74
|
+
*/
|
|
75
|
+
async function verifyMediaProjectionRecordingIsSupported(adb) {
|
|
58
76
|
const apiLevel = await adb.getApiLevel();
|
|
59
77
|
if (apiLevel < MIN_API_LEVEL) {
|
|
60
|
-
throw new Error(
|
|
61
|
-
`
|
|
78
|
+
throw new Error(
|
|
79
|
+
`Media projection-based recording is not available on API Level ${apiLevel}. ` +
|
|
80
|
+
`Minimum required API Level is ${MIN_API_LEVEL}.`
|
|
81
|
+
);
|
|
62
82
|
}
|
|
63
83
|
}
|
|
64
84
|
|
|
65
|
-
|
|
66
85
|
class MediaProjectionRecorder {
|
|
67
|
-
|
|
86
|
+
/**
|
|
87
|
+
* @param {ADB} adb
|
|
88
|
+
*/
|
|
89
|
+
constructor(adb) {
|
|
68
90
|
this.adb = adb;
|
|
69
91
|
}
|
|
70
92
|
|
|
71
|
-
async isRunning
|
|
93
|
+
async isRunning() {
|
|
72
94
|
const stdout = await this.adb.shell([
|
|
73
|
-
'dumpsys',
|
|
95
|
+
'dumpsys',
|
|
96
|
+
'activity',
|
|
97
|
+
'services',
|
|
98
|
+
RECORDING_SERVICE_NAME,
|
|
74
99
|
]);
|
|
75
100
|
return stdout.includes(RECORDING_SERVICE_NAME);
|
|
76
101
|
}
|
|
77
102
|
|
|
78
|
-
|
|
103
|
+
/**
|
|
104
|
+
*
|
|
105
|
+
* @param {import('./types').StartMediaProjectionRecordingOpts} opts
|
|
106
|
+
* @returns {Promise<boolean>}
|
|
107
|
+
*/
|
|
108
|
+
async start(opts = {}) {
|
|
79
109
|
if (await this.isRunning()) {
|
|
80
110
|
return false;
|
|
81
111
|
}
|
|
82
112
|
|
|
83
113
|
await this.cleanup();
|
|
84
|
-
const {
|
|
85
|
-
|
|
86
|
-
maxDurationSec,
|
|
87
|
-
priority,
|
|
88
|
-
resolution,
|
|
89
|
-
} = opts;
|
|
90
|
-
const args = [
|
|
91
|
-
'am', 'start',
|
|
92
|
-
'-n', RECORDING_ACTIVITY_NAME,
|
|
93
|
-
'-a', RECORDING_ACTION_START,
|
|
94
|
-
];
|
|
114
|
+
const {filename, maxDurationSec, priority, resolution} = opts;
|
|
115
|
+
const args = ['am', 'start', '-n', RECORDING_ACTIVITY_NAME, '-a', RECORDING_ACTION_START];
|
|
95
116
|
if (filename) {
|
|
96
117
|
args.push('--es', 'filename', filename);
|
|
97
118
|
}
|
|
@@ -107,11 +128,13 @@ class MediaProjectionRecorder {
|
|
|
107
128
|
await this.adb.shell(args);
|
|
108
129
|
await new B((resolve, reject) => {
|
|
109
130
|
setTimeout(async () => {
|
|
110
|
-
if (!await this.isRunning()) {
|
|
111
|
-
return reject(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
131
|
+
if (!(await this.isRunning())) {
|
|
132
|
+
return reject(
|
|
133
|
+
new Error(
|
|
134
|
+
`The media projection recording is not running after ${RECORDING_STARTUP_TIMEOUT_MS}ms. ` +
|
|
135
|
+
`Please check the logcat output for more details.`
|
|
136
|
+
)
|
|
137
|
+
);
|
|
115
138
|
}
|
|
116
139
|
resolve();
|
|
117
140
|
}, RECORDING_STARTUP_TIMEOUT_MS);
|
|
@@ -119,11 +142,11 @@ class MediaProjectionRecorder {
|
|
|
119
142
|
return true;
|
|
120
143
|
}
|
|
121
144
|
|
|
122
|
-
async cleanup
|
|
145
|
+
async cleanup() {
|
|
123
146
|
await this.adb.shell([`rm -f ${RECORDINGS_ROOT}/*`]);
|
|
124
147
|
}
|
|
125
148
|
|
|
126
|
-
async pullRecent
|
|
149
|
+
async pullRecent() {
|
|
127
150
|
const recordings = await this.adb.ls(RECORDINGS_ROOT, ['-tr']);
|
|
128
151
|
if (_.isEmpty(recordings)) {
|
|
129
152
|
return null;
|
|
@@ -135,15 +158,18 @@ class MediaProjectionRecorder {
|
|
|
135
158
|
return dstPath;
|
|
136
159
|
}
|
|
137
160
|
|
|
138
|
-
async stop
|
|
139
|
-
if (!await this.isRunning()) {
|
|
161
|
+
async stop() {
|
|
162
|
+
if (!(await this.isRunning())) {
|
|
140
163
|
return false;
|
|
141
164
|
}
|
|
142
165
|
|
|
143
166
|
await this.adb.shell([
|
|
144
|
-
'am',
|
|
145
|
-
'
|
|
146
|
-
'-
|
|
167
|
+
'am',
|
|
168
|
+
'start',
|
|
169
|
+
'-n',
|
|
170
|
+
RECORDING_ACTIVITY_NAME,
|
|
171
|
+
'-a',
|
|
172
|
+
RECORDING_ACTION_STOP,
|
|
147
173
|
]);
|
|
148
174
|
try {
|
|
149
175
|
await waitForCondition(async () => !(await this.isRunning()), {
|
|
@@ -153,137 +179,84 @@ class MediaProjectionRecorder {
|
|
|
153
179
|
} catch (e) {
|
|
154
180
|
throw new Error(
|
|
155
181
|
`The attempt to stop the current media projection recording timed out after ` +
|
|
156
|
-
|
|
182
|
+
`${RECORDING_STOP_TIMEOUT_MS}ms`
|
|
157
183
|
);
|
|
158
184
|
}
|
|
159
185
|
return true;
|
|
160
186
|
}
|
|
161
187
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
188
|
/**
|
|
165
|
-
* @
|
|
166
|
-
*
|
|
167
|
-
* @property {string?} resolution Maximum supported resolution on-device (Detected
|
|
168
|
-
* automatically by the app itself), which usually equals to Full HD 1920x1080 on most
|
|
169
|
-
* phones however you can change it to following supported resolutions
|
|
170
|
-
* as well: "1920x1080", "1280x720", "720x480", "320x240", "176x144".
|
|
171
|
-
* @property {number?} maxDurationSec [900] Default value: 900 seconds which means
|
|
172
|
-
* maximum allowed duration is 15 minute, you can increase it if your test takes
|
|
173
|
-
* longer than that.
|
|
174
|
-
* @property {string?} priority [high] Means recording thread priority is maximum
|
|
175
|
-
* however if you face performance drops during testing with recording enabled, you
|
|
176
|
-
* can reduce recording priority to "normal" or "low".
|
|
177
|
-
* @property {string?} filename You can type recording video file name as you want,
|
|
178
|
-
* but recording currently supports only "mp4" format so your filename must end with ".mp4".
|
|
179
|
-
* An invalid file name will fail to start the recording.
|
|
180
|
-
* If not provided then the current timestamp will be used as file name.
|
|
189
|
+
* @type {import('./mixins').MediaProjectionMixin & ThisType<import('../driver').AndroidDriver>}
|
|
190
|
+
* @satisfies {import('@appium/types').ExternalDriver}
|
|
181
191
|
*/
|
|
192
|
+
const MediaProjectionMixin = {
|
|
193
|
+
async mobileStartMediaProjectionRecording(options = {}) {
|
|
194
|
+
const adb = /** @type {ADB} */ (this.adb);
|
|
195
|
+
await verifyMediaProjectionRecordingIsSupported(adb);
|
|
182
196
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const didStart = await recorder.start({
|
|
202
|
-
resolution,
|
|
203
|
-
priority,
|
|
204
|
-
maxDurationSec,
|
|
205
|
-
filename: fname,
|
|
206
|
-
});
|
|
207
|
-
if (didStart) {
|
|
208
|
-
this.log.info(`A new media projection recording '${fname}' has been successfully started`);
|
|
209
|
-
} else {
|
|
210
|
-
this.log.info('Another media projection recording is already in progress. There is nothing to start');
|
|
211
|
-
}
|
|
212
|
-
return didStart;
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Checks if a media projection-based recording is currently running.
|
|
217
|
-
*
|
|
218
|
-
* @returns {boolean} True if a recording is in progress.
|
|
219
|
-
* @throws {Error} If a recording is not supported on the device under test.
|
|
220
|
-
*/
|
|
221
|
-
commands.mobileIsMediaProjectionRecordingRunning = async function mobileIsMediaProjectionRecordingRunning () {
|
|
222
|
-
await verifyMediaProjectionRecordingIsSupported(this.adb);
|
|
197
|
+
const {resolution, priority, maxDurationSec, filename} = options;
|
|
198
|
+
const recorder = new MediaProjectionRecorder(adb);
|
|
199
|
+
const fname = adjustMediaExtension(filename || moment().format(DEFAULT_FILENAME_FORMAT));
|
|
200
|
+
const didStart = await recorder.start({
|
|
201
|
+
resolution,
|
|
202
|
+
priority,
|
|
203
|
+
maxDurationSec,
|
|
204
|
+
filename: fname,
|
|
205
|
+
});
|
|
206
|
+
if (didStart) {
|
|
207
|
+
this.log.info(`A new media projection recording '${fname}' has been successfully started`);
|
|
208
|
+
} else {
|
|
209
|
+
this.log.info(
|
|
210
|
+
'Another media projection recording is already in progress. There is nothing to start'
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
return didStart;
|
|
214
|
+
},
|
|
223
215
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
216
|
+
async mobileIsMediaProjectionRecordingRunning() {
|
|
217
|
+
const adb = /** @type {ADB} */ (this.adb);
|
|
218
|
+
await verifyMediaProjectionRecordingIsSupported(adb);
|
|
227
219
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
* @property {string?} remotePath The path to the remote location, where the resulting video should be uploaded.
|
|
232
|
-
* The following protocols are supported: http/https, ftp.
|
|
233
|
-
* Null or empty string value (the default setting) means the content of resulting
|
|
234
|
-
* file should be encoded as Base64 and passed as the endpoont response value.
|
|
235
|
-
* An exception will be thrown if the generated media file is too big to
|
|
236
|
-
* fit into the available process memory.
|
|
237
|
-
* @property {string?} user The name of the user for the remote authentication.
|
|
238
|
-
* @property {string?} pass The password for the remote authentication.
|
|
239
|
-
* @property {string?} method The http multipart upload method name. The 'PUT' one is used by default.
|
|
240
|
-
* @property {Object?} headers Additional headers mapping for multipart http(s) uploads
|
|
241
|
-
* @property {string?} fileFieldName [file] The name of the form field, where the file content BLOB should be stored for
|
|
242
|
-
* http(s) uploads
|
|
243
|
-
* @property {Object|Array<Pair>?} formFields Additional form fields for multipart http(s) uploads
|
|
244
|
-
* @property {number?} uploadTimeout - The actual media upload request timeout in milliseconds;
|
|
245
|
-
* defaults to @appium/support net DEFAULT_TIMEOUT_MS
|
|
246
|
-
*/
|
|
220
|
+
const recorder = new MediaProjectionRecorder(adb);
|
|
221
|
+
return await recorder.isRunning();
|
|
222
|
+
},
|
|
247
223
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
* If the recording has been already finished before this API has been called
|
|
252
|
-
* then the most recent recorded file is returned.
|
|
253
|
-
*
|
|
254
|
-
* @param {?StopRecordingOptions} options Available options.
|
|
255
|
-
* @returns {string} Base64-encoded content of the recorded media file if 'remotePath'
|
|
256
|
-
* parameter is falsy or an empty string.
|
|
257
|
-
* @throws {Error} If there was an error while stopping a recording,
|
|
258
|
-
* fetching the content of the remote media file,
|
|
259
|
-
* or if a recording is not supported on the device under test.
|
|
260
|
-
*/
|
|
261
|
-
commands.mobileStopMediaProjectionRecording = async function mobileStopMediaProjectionRecording (options = {}) {
|
|
262
|
-
await verifyMediaProjectionRecordingIsSupported(this.adb);
|
|
224
|
+
async mobileStopMediaProjectionRecording(options = {}) {
|
|
225
|
+
const adb = /** @type {ADB} */ (this.adb);
|
|
226
|
+
await verifyMediaProjectionRecordingIsSupported(adb);
|
|
263
227
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
228
|
+
const recorder = new MediaProjectionRecorder(adb);
|
|
229
|
+
if (await recorder.stop()) {
|
|
230
|
+
this.log.info(
|
|
231
|
+
'Successfully stopped a media projection recording. Pulling the recorded media'
|
|
232
|
+
);
|
|
233
|
+
} else {
|
|
234
|
+
this.log.info('Media projection recording is not running. There is nothing to stop');
|
|
235
|
+
}
|
|
236
|
+
const recentRecordingPath = await recorder.pullRecent();
|
|
237
|
+
if (!recentRecordingPath) {
|
|
238
|
+
throw new Error(`No recent media projection recording have been found. Did you start any?`);
|
|
239
|
+
}
|
|
274
240
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
241
|
+
const {remotePath} = options;
|
|
242
|
+
if (_.isEmpty(remotePath)) {
|
|
243
|
+
const {size} = await fs.stat(recentRecordingPath);
|
|
244
|
+
this.log.debug(
|
|
245
|
+
`The size of the resulting media projection recording is ${util.toReadableSizeString(size)}`
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
try {
|
|
249
|
+
return await uploadRecordedMedia(recentRecordingPath, remotePath, options);
|
|
250
|
+
} finally {
|
|
251
|
+
await fs.rimraf(path.dirname(recentRecordingPath));
|
|
252
|
+
}
|
|
253
|
+
},
|
|
285
254
|
};
|
|
286
255
|
|
|
256
|
+
mixin(MediaProjectionMixin);
|
|
287
257
|
|
|
288
|
-
export
|
|
289
|
-
|
|
258
|
+
export default MediaProjectionMixin;
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* @typedef {import('appium-adb').ADB} ADB
|
|
262
|
+
*/
|