appium-xcuitest-driver 10.2.2 → 10.4.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 +12 -0
- package/build/lib/commands/active-app-info.d.ts +9 -0
- package/build/lib/commands/active-app-info.d.ts.map +1 -0
- package/build/lib/commands/active-app-info.js +14 -0
- package/build/lib/commands/active-app-info.js.map +1 -0
- package/build/lib/commands/alert.d.ts +42 -45
- package/build/lib/commands/alert.d.ts.map +1 -1
- package/build/lib/commands/alert.js +66 -62
- package/build/lib/commands/alert.js.map +1 -1
- package/build/lib/commands/app-management.d.ts +150 -153
- package/build/lib/commands/app-management.d.ts.map +1 -1
- package/build/lib/commands/app-management.js +300 -286
- package/build/lib/commands/app-management.js.map +1 -1
- package/build/lib/commands/app-strings.d.ts +14 -17
- package/build/lib/commands/app-strings.d.ts.map +1 -1
- package/build/lib/commands/app-strings.js +23 -24
- package/build/lib/commands/app-strings.js.map +1 -1
- package/build/lib/commands/appearance.d.ts +19 -22
- package/build/lib/commands/appearance.d.ts.map +1 -1
- package/build/lib/commands/appearance.js +56 -56
- package/build/lib/commands/appearance.js.map +1 -1
- package/build/lib/commands/audit.d.ts +22 -17
- package/build/lib/commands/audit.d.ts.map +1 -1
- package/build/lib/commands/audit.js +17 -18
- package/build/lib/commands/audit.js.map +1 -1
- package/build/lib/commands/battery.d.ts +11 -14
- package/build/lib/commands/battery.d.ts.map +1 -1
- package/build/lib/commands/battery.js +36 -37
- package/build/lib/commands/battery.js.map +1 -1
- package/build/lib/commands/biometric.d.ts +30 -33
- package/build/lib/commands/biometric.d.ts.map +1 -1
- package/build/lib/commands/biometric.js +42 -41
- package/build/lib/commands/biometric.js.map +1 -1
- package/build/lib/commands/certificate.d.ts +48 -45
- package/build/lib/commands/certificate.d.ts.map +1 -1
- package/build/lib/commands/certificate.js +218 -205
- package/build/lib/commands/certificate.js.map +1 -1
- package/build/lib/commands/clipboard.d.ts +19 -22
- package/build/lib/commands/clipboard.d.ts.map +1 -1
- package/build/lib/commands/clipboard.js +30 -30
- package/build/lib/commands/clipboard.js.map +1 -1
- package/build/lib/commands/condition.d.ts +49 -26
- package/build/lib/commands/condition.d.ts.map +1 -1
- package/build/lib/commands/condition.js +87 -86
- package/build/lib/commands/condition.js.map +1 -1
- package/build/lib/commands/content-size.d.ts +26 -29
- package/build/lib/commands/content-size.d.ts.map +1 -1
- package/build/lib/commands/content-size.js +36 -36
- package/build/lib/commands/content-size.js.map +1 -1
- package/build/lib/commands/context.d.ts +161 -108
- package/build/lib/commands/context.d.ts.map +1 -1
- package/build/lib/commands/context.js +530 -517
- package/build/lib/commands/context.js.map +1 -1
- package/build/lib/commands/deviceInfo.d.ts +9 -12
- package/build/lib/commands/deviceInfo.d.ts.map +1 -1
- package/build/lib/commands/deviceInfo.js +17 -18
- package/build/lib/commands/deviceInfo.js.map +1 -1
- package/build/lib/commands/element.d.ts +102 -105
- package/build/lib/commands/element.d.ts.map +1 -1
- package/build/lib/commands/element.js +337 -323
- package/build/lib/commands/element.js.map +1 -1
- package/build/lib/commands/execute.d.ts +24 -19
- package/build/lib/commands/execute.d.ts.map +1 -1
- package/build/lib/commands/execute.js +63 -62
- package/build/lib/commands/execute.js.map +1 -1
- package/build/lib/commands/file-movement.d.ts +77 -80
- package/build/lib/commands/file-movement.d.ts.map +1 -1
- package/build/lib/commands/file-movement.js +130 -124
- package/build/lib/commands/file-movement.js.map +1 -1
- package/build/lib/commands/find.d.ts +18 -21
- package/build/lib/commands/find.d.ts.map +1 -1
- package/build/lib/commands/find.js +158 -156
- package/build/lib/commands/find.js.map +1 -1
- package/build/lib/commands/general.d.ts +124 -116
- package/build/lib/commands/general.d.ts.map +1 -1
- package/build/lib/commands/general.js +248 -232
- package/build/lib/commands/general.js.map +1 -1
- package/build/lib/commands/geolocation.d.ts +43 -46
- package/build/lib/commands/geolocation.d.ts.map +1 -1
- package/build/lib/commands/geolocation.js +10 -11
- package/build/lib/commands/geolocation.js.map +1 -1
- package/build/lib/commands/gesture.d.ts +273 -276
- package/build/lib/commands/gesture.d.ts.map +1 -1
- package/build/lib/commands/gesture.js +506 -492
- package/build/lib/commands/gesture.js.map +1 -1
- package/build/lib/commands/increase-contrast.d.ts +20 -23
- package/build/lib/commands/increase-contrast.d.ts.map +1 -1
- package/build/lib/commands/increase-contrast.js +30 -30
- package/build/lib/commands/increase-contrast.js.map +1 -1
- package/build/lib/commands/iohid.d.ts +1370 -1373
- package/build/lib/commands/iohid.d.ts.map +1 -1
- package/build/lib/commands/iohid.js +30 -31
- package/build/lib/commands/iohid.js.map +1 -1
- package/build/lib/commands/keyboard.d.ts +29 -32
- package/build/lib/commands/keyboard.d.ts.map +1 -1
- package/build/lib/commands/keyboard.js +53 -51
- package/build/lib/commands/keyboard.js.map +1 -1
- package/build/lib/commands/keychains.d.ts +9 -12
- package/build/lib/commands/keychains.d.ts.map +1 -1
- package/build/lib/commands/keychains.js +13 -14
- package/build/lib/commands/keychains.js.map +1 -1
- package/build/lib/commands/localization.d.ts +16 -19
- package/build/lib/commands/localization.d.ts.map +1 -1
- package/build/lib/commands/localization.js +25 -26
- package/build/lib/commands/localization.js.map +1 -1
- package/build/lib/commands/location.d.ts +36 -39
- package/build/lib/commands/location.d.ts.map +1 -1
- package/build/lib/commands/location.js +99 -98
- package/build/lib/commands/location.js.map +1 -1
- package/build/lib/commands/lock.d.ts +21 -24
- package/build/lib/commands/lock.d.ts.map +1 -1
- package/build/lib/commands/lock.js +39 -38
- package/build/lib/commands/lock.js.map +1 -1
- package/build/lib/commands/log.d.ts +43 -37
- package/build/lib/commands/log.d.ts.map +1 -1
- package/build/lib/commands/log.js +174 -171
- package/build/lib/commands/log.js.map +1 -1
- package/build/lib/commands/memory.d.ts +9 -12
- package/build/lib/commands/memory.d.ts.map +1 -1
- package/build/lib/commands/memory.js +37 -39
- package/build/lib/commands/memory.js.map +1 -1
- package/build/lib/commands/navigation.d.ts +30 -33
- package/build/lib/commands/navigation.d.ts.map +1 -1
- package/build/lib/commands/navigation.js +92 -92
- package/build/lib/commands/navigation.js.map +1 -1
- package/build/lib/commands/notifications.d.ts +26 -29
- package/build/lib/commands/notifications.d.ts.map +1 -1
- package/build/lib/commands/notifications.js +53 -53
- package/build/lib/commands/notifications.js.map +1 -1
- package/build/lib/commands/pasteboard.d.ts +21 -24
- package/build/lib/commands/pasteboard.d.ts.map +1 -1
- package/build/lib/commands/pasteboard.js +37 -37
- package/build/lib/commands/pasteboard.js.map +1 -1
- package/build/lib/commands/pcap.d.ts +39 -26
- package/build/lib/commands/pcap.d.ts.map +1 -1
- package/build/lib/commands/pcap.js +81 -81
- package/build/lib/commands/pcap.js.map +1 -1
- package/build/lib/commands/performance.d.ts +63 -44
- package/build/lib/commands/performance.d.ts.map +1 -1
- package/build/lib/commands/performance.js +105 -105
- package/build/lib/commands/performance.js.map +1 -1
- package/build/lib/commands/permissions.d.ts +33 -36
- package/build/lib/commands/permissions.d.ts.map +1 -1
- package/build/lib/commands/permissions.js +66 -65
- package/build/lib/commands/permissions.js.map +1 -1
- package/build/lib/commands/proxy-helper.d.ts +12 -15
- package/build/lib/commands/proxy-helper.d.ts.map +1 -1
- package/build/lib/commands/proxy-helper.js +53 -54
- package/build/lib/commands/proxy-helper.js.map +1 -1
- package/build/lib/commands/record-audio.d.ts +49 -29
- package/build/lib/commands/record-audio.d.ts.map +1 -1
- package/build/lib/commands/record-audio.js +100 -104
- package/build/lib/commands/record-audio.js.map +1 -1
- package/build/lib/commands/recordscreen.d.ts +54 -18
- package/build/lib/commands/recordscreen.d.ts.map +1 -1
- package/build/lib/commands/recordscreen.js +127 -129
- package/build/lib/commands/recordscreen.js.map +1 -1
- package/build/lib/commands/screenshots.d.ts +14 -17
- package/build/lib/commands/screenshots.d.ts.map +1 -1
- package/build/lib/commands/screenshots.js +108 -107
- package/build/lib/commands/screenshots.js.map +1 -1
- package/build/lib/commands/simctl.d.ts +11 -14
- package/build/lib/commands/simctl.d.ts.map +1 -1
- package/build/lib/commands/simctl.js +23 -26
- package/build/lib/commands/simctl.js.map +1 -1
- package/build/lib/commands/source.d.ts +14 -17
- package/build/lib/commands/source.d.ts.map +1 -1
- package/build/lib/commands/source.js +40 -43
- package/build/lib/commands/source.js.map +1 -1
- package/build/lib/commands/timeouts.d.ts +44 -33
- package/build/lib/commands/timeouts.d.ts.map +1 -1
- package/build/lib/commands/timeouts.js +65 -63
- package/build/lib/commands/timeouts.js.map +1 -1
- package/build/lib/commands/web.d.ts +247 -197
- package/build/lib/commands/web.d.ts.map +1 -1
- package/build/lib/commands/web.js +815 -786
- package/build/lib/commands/web.js.map +1 -1
- package/build/lib/commands/xctest-record-screen.d.ts +63 -66
- package/build/lib/commands/xctest-record-screen.d.ts.map +1 -1
- package/build/lib/commands/xctest-record-screen.js +103 -102
- package/build/lib/commands/xctest-record-screen.js.map +1 -1
- package/build/lib/commands/xctest.d.ts +55 -51
- package/build/lib/commands/xctest.d.ts.map +1 -1
- package/build/lib/commands/xctest.js +116 -117
- package/build/lib/commands/xctest.js.map +1 -1
- package/build/lib/driver.d.ts +278 -1597
- package/build/lib/driver.d.ts.map +1 -1
- package/build/lib/driver.js +320 -236
- package/build/lib/driver.js.map +1 -1
- package/build/lib/execute-method-map.d.ts.map +1 -1
- package/build/lib/execute-method-map.js +9 -0
- package/build/lib/execute-method-map.js.map +1 -1
- package/build/lib/real-device.d.ts +1 -1
- package/build/lib/real-device.d.ts.map +1 -1
- package/build/lib/real-device.js +2 -2
- package/build/lib/real-device.js.map +1 -1
- package/lib/commands/active-app-info.js +12 -0
- package/lib/commands/alert.js +68 -65
- package/lib/commands/app-management.js +308 -301
- package/lib/commands/app-strings.js +24 -26
- package/lib/commands/appearance.js +54 -56
- package/lib/commands/audit.js +18 -20
- package/lib/commands/battery.js +35 -37
- package/lib/commands/biometric.js +44 -46
- package/lib/commands/certificate.js +226 -215
- package/lib/commands/clipboard.js +30 -32
- package/lib/commands/condition.js +98 -100
- package/lib/commands/content-size.js +36 -38
- package/lib/commands/context.js +495 -490
- package/lib/commands/deviceInfo.js +19 -20
- package/lib/commands/element.js +367 -357
- package/lib/commands/execute.js +72 -72
- package/lib/commands/file-movement.js +132 -134
- package/lib/commands/find.js +160 -159
- package/lib/commands/general.js +238 -231
- package/lib/commands/geolocation.js +6 -14
- package/lib/commands/gesture.js +525 -515
- package/lib/commands/increase-contrast.js +30 -32
- package/lib/commands/iohid.js +32 -34
- package/lib/commands/keyboard.js +49 -51
- package/lib/commands/keychains.js +12 -14
- package/lib/commands/localization.js +24 -26
- package/lib/commands/location.js +102 -104
- package/lib/commands/lock.js +38 -38
- package/lib/commands/log.js +197 -198
- package/lib/commands/memory.js +40 -43
- package/lib/commands/navigation.js +96 -100
- package/lib/commands/notifications.js +57 -59
- package/lib/commands/pasteboard.js +37 -39
- package/lib/commands/pcap.js +84 -86
- package/lib/commands/performance.js +132 -133
- package/lib/commands/permissions.js +67 -69
- package/lib/commands/proxy-helper.js +60 -61
- package/lib/commands/record-audio.js +115 -120
- package/lib/commands/recordscreen.js +145 -149
- package/lib/commands/screenshots.js +116 -116
- package/lib/commands/simctl.js +25 -29
- package/lib/commands/source.js +42 -46
- package/lib/commands/timeouts.js +59 -63
- package/lib/commands/web.js +878 -858
- package/lib/commands/xctest-record-screen.js +103 -105
- package/lib/commands/xctest.js +134 -139
- package/lib/driver.js +288 -236
- package/lib/execute-method-map.ts +9 -0
- package/lib/real-device.js +2 -2
- package/npm-shrinkwrap.json +440 -76
- package/package.json +2 -1
- package/build/lib/commands/activeAppInfo.d.ts +0 -12
- package/build/lib/commands/activeAppInfo.d.ts.map +0 -1
- package/build/lib/commands/activeAppInfo.js +0 -15
- package/build/lib/commands/activeAppInfo.js.map +0 -1
- package/build/lib/commands/index.d.ts +0 -96
- package/build/lib/commands/index.d.ts.map +0 -1
- package/build/lib/commands/index.js +0 -100
- package/build/lib/commands/index.js.map +0 -1
- package/build/lib/real-device-clients/devicectl.d.ts +0 -204
- package/build/lib/real-device-clients/devicectl.d.ts.map +0 -1
- package/build/lib/real-device-clients/devicectl.js +0 -264
- package/build/lib/real-device-clients/devicectl.js.map +0 -1
- package/lib/commands/activeAppInfo.js +0 -14
- package/lib/commands/index.js +0 -95
- package/lib/real-device-clients/devicectl.js +0 -291
|
@@ -91,115 +91,113 @@ async function retrieveXcTestScreenRecording(uuid) {
|
|
|
91
91
|
: await retrieveRecodingFromSimulator.bind(this)(uuid);
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
94
|
+
/**
|
|
95
|
+
* Start a new screen recording via XCTest.
|
|
96
|
+
*
|
|
97
|
+
* Even though the feature is available for real devices
|
|
98
|
+
* there is no possibility to delete stored video files yet,
|
|
99
|
+
* which may lead to internal storage overload.
|
|
100
|
+
* That is why it was put under a security feature flag.
|
|
101
|
+
*
|
|
102
|
+
* If the recording is already running this API is a noop.
|
|
103
|
+
*
|
|
104
|
+
* @since Xcode 15/iOS 17
|
|
105
|
+
* @param {number} [fps] FPS value
|
|
106
|
+
* @param {number} [codec] Video codec, where 0 is h264, 1 is HEVC
|
|
107
|
+
* @returns {Promise<XcTestScreenRecordingInfo>} The information
|
|
108
|
+
* about a newly created or a running the screen recording.
|
|
109
|
+
* @throws {Error} If screen recording has failed to start.
|
|
110
|
+
* @this {XCUITestDriver}
|
|
111
|
+
*/
|
|
112
|
+
export async function mobileStartXctestScreenRecording(fps, codec) {
|
|
113
|
+
if (this.isRealDevice()) {
|
|
114
|
+
// This feature might be used to abuse real devices as there is no
|
|
115
|
+
// reliable way (yet) to cleanup video recordings stored there
|
|
116
|
+
// by the testmanagerd daemon
|
|
117
|
+
this.assertFeatureEnabled(FEATURE_NAME);
|
|
118
|
+
}
|
|
120
119
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
120
|
+
const opts = {};
|
|
121
|
+
if (_.isInteger(codec)) {
|
|
122
|
+
opts.codec = codec;
|
|
123
|
+
}
|
|
124
|
+
if (_.isInteger(fps)) {
|
|
125
|
+
opts.fps = fps;
|
|
126
|
+
}
|
|
127
|
+
const response = /** @type {XcTestScreenRecordingInfo} */ (
|
|
128
|
+
await this.proxyCommand('/wda/video/start', 'POST', opts)
|
|
129
|
+
);
|
|
130
|
+
this.log.info(`Started a new screen recording: ${JSON.stringify(response)}`);
|
|
131
|
+
return response;
|
|
132
|
+
}
|
|
134
133
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
134
|
+
/**
|
|
135
|
+
* Retrieves information about the current running screen recording.
|
|
136
|
+
* If no screen recording is running then `null` is returned.
|
|
137
|
+
*
|
|
138
|
+
* @returns {Promise<XcTestScreenRecordingInfo?>}
|
|
139
|
+
*/
|
|
140
|
+
export async function mobileGetXctestScreenRecordingInfo() {
|
|
141
|
+
return /** @type {XcTestScreenRecordingInfo?} */ (
|
|
142
|
+
await this.proxyCommand('/wda/video', 'GET')
|
|
143
|
+
);
|
|
144
|
+
}
|
|
146
145
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
146
|
+
/**
|
|
147
|
+
* Stop screen recording previously started by mobileStartXctestScreenRecording API.
|
|
148
|
+
*
|
|
149
|
+
* An error is thrown if no screen recording is running.
|
|
150
|
+
*
|
|
151
|
+
* The resulting movie is returned as base-64 string or is uploaded to
|
|
152
|
+
* a remote location if corresponding options have been provided.
|
|
153
|
+
*
|
|
154
|
+
* The resulting movie is automatically deleted FOR SIMULATORS ONLY.
|
|
155
|
+
* In order to clean it up from a real device it is necessary to properly
|
|
156
|
+
* shut down XCTest by calling `GET /wda/shutdown` API to the WebDriverAgent server running
|
|
157
|
+
* on the device directly or by doing factory reset.
|
|
158
|
+
*
|
|
159
|
+
* @since Xcode 15/iOS 17
|
|
160
|
+
* @param {string} [remotePath] The path to the remote location, where the resulting video should be
|
|
161
|
+
* uploaded.
|
|
162
|
+
* The following protocols are supported: `http`, `https`, `ftp`. Null or empty
|
|
163
|
+
* string value (the default setting) means the content of resulting file
|
|
164
|
+
* should be encoded as Base64 and passed as the endpoint response value. An
|
|
165
|
+
* exception will be thrown if the generated media file is too big to fit into
|
|
166
|
+
* the available process memory.
|
|
167
|
+
* @param {string} [user] The name of the user for the remote authentication.
|
|
168
|
+
* Only works if `remotePath` is provided.
|
|
169
|
+
* @param {string} [pass] The password for the remote authentication.
|
|
170
|
+
* Only works if `remotePath` is provided.
|
|
171
|
+
* @param {import('@appium/types').HTTPHeaders} [headers] Additional headers mapping for multipart http(s) uploads
|
|
172
|
+
* @param {string} [fileFieldName] The name of the form field where the file content BLOB should be stored for
|
|
173
|
+
* http(s) uploads
|
|
174
|
+
* @param {Record<string, any> | [string, any][]} [formFields] Additional form fields for multipart http(s) uploads
|
|
175
|
+
* @param {'PUT' | 'POST' | 'PATCH'} [method='PUT'] The http multipart upload method name.
|
|
176
|
+
* Only works if `remotePath` is provided.
|
|
177
|
+
* @returns {Promise<XcTestScreenRecording>}
|
|
178
|
+
* @throws {Error} If there was an error while retrieving the video
|
|
179
|
+
* file or the file content cannot be uploaded to the remote location.
|
|
180
|
+
* @this {XCUITestDriver}
|
|
181
|
+
*/
|
|
182
|
+
export async function mobileStopXctestScreenRecording(remotePath, user, pass, headers, fileFieldName, formFields, method) {
|
|
183
|
+
const screenRecordingInfo = await this.mobileGetXctestScreenRecordingInfo();
|
|
184
|
+
if (!screenRecordingInfo) {
|
|
185
|
+
throw new Error('There is no active screen recording. Did you start one beforehand?');
|
|
186
|
+
}
|
|
188
187
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
};
|
|
188
|
+
this.log.debug(`Stopping the active screen recording: ${JSON.stringify(screenRecordingInfo)}`);
|
|
189
|
+
await this.proxyCommand('/wda/video/stop', 'POST', {});
|
|
190
|
+
const videoPath = await retrieveXcTestScreenRecording.bind(this)(screenRecordingInfo.uuid);
|
|
191
|
+
const result = /** @type {XcTestScreenRecording} */ (screenRecordingInfo);
|
|
192
|
+
try {
|
|
193
|
+
result.payload = await encodeBase64OrUpload(videoPath, remotePath, {
|
|
194
|
+
user, pass, headers, fileFieldName, formFields, method
|
|
195
|
+
});
|
|
196
|
+
} finally {
|
|
197
|
+
await fs.rimraf(videoPath);
|
|
198
|
+
}
|
|
199
|
+
return result;
|
|
200
|
+
}
|
|
203
201
|
|
|
204
202
|
/**
|
|
205
203
|
* @typedef {import('../driver').XCUITestDriver} XCUITestDriver
|
package/lib/commands/xctest.js
CHANGED
|
@@ -3,9 +3,6 @@ import {logger} from 'appium/support';
|
|
|
3
3
|
import _ from 'lodash';
|
|
4
4
|
import {errors} from 'appium/driver';
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
* @type {360000}
|
|
8
|
-
*/
|
|
9
6
|
const XCTEST_TIMEOUT = 360000; // 60 minute timeout
|
|
10
7
|
|
|
11
8
|
const xctestLog = logger.getLogger('XCTest');
|
|
@@ -133,156 +130,154 @@ export function parseXCTestStdout(stdout) {
|
|
|
133
130
|
* @property {XCTestResult[]} results The output of the failed test (if there is output)
|
|
134
131
|
*/
|
|
135
132
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
133
|
+
/**
|
|
134
|
+
* Run a native XCTest script.
|
|
135
|
+
*
|
|
136
|
+
* Launches a subprocess that runs the XC Test and blocks until it is completed. Parses the stdout of the process and returns its result as an array.
|
|
137
|
+
*
|
|
138
|
+
* **Facebook's [IDB](https://github.com/facebook/idb) tool is required** to run such tests; see [the idb docs](https://fbidb.io/docs/test-execution/) for reference.
|
|
139
|
+
*
|
|
140
|
+
* @param {string} testRunnerBundleId - Test app bundle (e.g.: `io.appium.XCTesterAppUITests.xctrunner`)
|
|
141
|
+
* @param {string} appUnderTestBundleId - App-under-test bundle
|
|
142
|
+
* @param {string} xcTestBundleId - XCTest bundle ID
|
|
143
|
+
* @param {string[]} args - Launch arguments to start the test with (see [reference documentation](https://developer.apple.com/documentation/xctest/xcuiapplication/1500477-launcharguments))
|
|
144
|
+
* @param {'app'|'ui'|'logic'} testType - XC test type
|
|
145
|
+
* @param {import('@appium/types').StringRecord} [env] - Environment variables passed to test
|
|
146
|
+
* @param {number} timeout - Timeout (in ms) for session completion.
|
|
147
|
+
* @throws {XCUITestError} Error thrown if subprocess returns non-zero exit code
|
|
148
|
+
* @returns {Promise<import('./types').RunXCTestResult>} The array of test results
|
|
149
|
+
* @this {XCUITestDriver}
|
|
150
|
+
*/
|
|
151
|
+
export async function mobileRunXCTest(
|
|
152
|
+
testRunnerBundleId,
|
|
153
|
+
appUnderTestBundleId,
|
|
154
|
+
xcTestBundleId,
|
|
155
|
+
args = [],
|
|
156
|
+
testType = 'ui',
|
|
157
|
+
env,
|
|
158
|
+
timeout = XCTEST_TIMEOUT,
|
|
159
|
+
) {
|
|
160
|
+
const subproc = await assertIDB(this.opts).runXCUITest(
|
|
156
161
|
testRunnerBundleId,
|
|
157
162
|
appUnderTestBundleId,
|
|
158
163
|
xcTestBundleId,
|
|
159
|
-
args
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
let mostRecentLogObject = null;
|
|
172
|
-
let xctestTimeout;
|
|
173
|
-
let lastErrorMessage = null;
|
|
174
|
-
if (timeout > 0) {
|
|
175
|
-
xctestTimeout = setTimeout(
|
|
176
|
-
() =>
|
|
177
|
-
reject(
|
|
178
|
-
new errors.TimeoutError(
|
|
179
|
-
`Timed out after '${timeout}ms' waiting for XCTest to complete`,
|
|
180
|
-
),
|
|
164
|
+
{env, args, testType},
|
|
165
|
+
);
|
|
166
|
+
return await new B((resolve, reject) => {
|
|
167
|
+
let mostRecentLogObject = null;
|
|
168
|
+
let xctestTimeout;
|
|
169
|
+
let lastErrorMessage = null;
|
|
170
|
+
if (timeout > 0) {
|
|
171
|
+
xctestTimeout = setTimeout(
|
|
172
|
+
() =>
|
|
173
|
+
reject(
|
|
174
|
+
new errors.TimeoutError(
|
|
175
|
+
`Timed out after '${timeout}ms' waiting for XCTest to complete`,
|
|
181
176
|
),
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
177
|
+
),
|
|
178
|
+
timeout,
|
|
179
|
+
);
|
|
180
|
+
}
|
|
185
181
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
}
|
|
182
|
+
subproc.on('output', (stdout, stderr) => {
|
|
183
|
+
if (stdout) {
|
|
184
|
+
try {
|
|
185
|
+
mostRecentLogObject = parseXCTestStdout(stdout);
|
|
186
|
+
} catch (err) {
|
|
187
|
+
// Fails if log parsing fails.
|
|
188
|
+
// This is in case IDB changes the way that logs are formatted and
|
|
189
|
+
// it breaks 'parseXCTestStdout'. If that happens we still want the process
|
|
190
|
+
// to finish
|
|
191
|
+
this.log.warn(`Failed to parse logs from test output: '${stdout}'`);
|
|
192
|
+
this.log.debug(err.stack);
|
|
198
193
|
}
|
|
194
|
+
}
|
|
199
195
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
196
|
+
if (stderr) {
|
|
197
|
+
lastErrorMessage = stderr;
|
|
198
|
+
xctestLog.error(stderr);
|
|
199
|
+
}
|
|
200
|
+
if (stdout) {
|
|
201
|
+
xctestLog.info(stdout);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
208
204
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
220
|
-
return reject(err);
|
|
205
|
+
subproc.on('exit', (code, signal) => {
|
|
206
|
+
clearTimeout(xctestTimeout);
|
|
207
|
+
if (code !== 0) {
|
|
208
|
+
const err = /** @type {any} */ (new Error(lastErrorMessage || mostRecentLogObject));
|
|
209
|
+
err.code = code;
|
|
210
|
+
if (signal != null) {
|
|
211
|
+
err.signal = signal;
|
|
212
|
+
}
|
|
213
|
+
if (mostRecentLogObject) {
|
|
214
|
+
err.result = mostRecentLogObject;
|
|
221
215
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
216
|
+
return reject(err);
|
|
217
|
+
}
|
|
218
|
+
resolve({
|
|
219
|
+
code,
|
|
220
|
+
signal,
|
|
221
|
+
results: mostRecentLogObject,
|
|
222
|
+
passed: true,
|
|
228
223
|
});
|
|
229
224
|
});
|
|
230
|
-
}
|
|
225
|
+
});
|
|
226
|
+
}
|
|
231
227
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
228
|
+
/**
|
|
229
|
+
* Installs an XCTest bundle to the device under test.
|
|
230
|
+
*
|
|
231
|
+
* **Facebook's [IDB](https://github.com/facebook/idb) tool is required** for this command to work.
|
|
232
|
+
*
|
|
233
|
+
* @param {string} xctestApp - Path of the XCTest app (URL or filename with extension `.app`)
|
|
234
|
+
* @returns {Promise<void>}
|
|
235
|
+
* @this {XCUITestDriver}
|
|
236
|
+
*/
|
|
237
|
+
export async function mobileInstallXCTestBundle(xctestApp) {
|
|
238
|
+
if (!_.isString(xctestApp)) {
|
|
239
|
+
throw new errors.InvalidArgumentError(
|
|
240
|
+
`'xctestApp' is a required parameter for 'installXCTestBundle' and ` +
|
|
241
|
+
`must be a string. Found '${xctestApp}'`,
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
xctestLog.info(`Installing bundle '${xctestApp}'`);
|
|
245
|
+
const idb = assertIDB(this.opts);
|
|
246
|
+
const res = await this.helpers.configureApp(xctestApp, '.xctest');
|
|
247
|
+
await idb.installXCTestBundle(res);
|
|
248
|
+
}
|
|
253
249
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
250
|
+
/**
|
|
251
|
+
* List XCTest bundles that are installed on the device.
|
|
252
|
+
*
|
|
253
|
+
* **Facebook's [IDB](https://github.com/facebook/idb) tool is required** for this command to work.
|
|
254
|
+
*
|
|
255
|
+
* @returns {Promise<string[]>} List of XCTest bundles (e.g.: `XCTesterAppUITests.XCTesterAppUITests/testLaunchPerformance`)
|
|
256
|
+
* @this {XCUITestDriver}
|
|
257
|
+
*/
|
|
258
|
+
export async function mobileListXCTestBundles() {
|
|
259
|
+
return await assertIDB(this.opts).listXCTestBundles();
|
|
260
|
+
}
|
|
265
261
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
};
|
|
262
|
+
/**
|
|
263
|
+
* List XCTests in a test bundle
|
|
264
|
+
*
|
|
265
|
+
* **Facebook's [IDB](https://github.com/facebook/idb) tool is required** for this command to work.
|
|
266
|
+
* @param {string} bundle - Bundle ID of the XCTest
|
|
267
|
+
*
|
|
268
|
+
* @returns {Promise<string[]>} The list of xctests in the test bundle (e.g., `['XCTesterAppUITests.XCTesterAppUITests/testExample', 'XCTesterAppUITests.XCTesterAppUITests/testLaunchPerformance']`)
|
|
269
|
+
* @this {XCUITestDriver}
|
|
270
|
+
*/
|
|
271
|
+
export async function mobileListXCTestsInTestBundle(bundle) {
|
|
272
|
+
if (!_.isString(bundle)) {
|
|
273
|
+
throw new errors.InvalidArgumentError(
|
|
274
|
+
`'bundle' is a required parameter for 'listXCTestsInTestBundle' and ` +
|
|
275
|
+
`must be a string. Found '${bundle}'`,
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
const idb = assertIDB(this.opts);
|
|
279
|
+
return await idb.listXCTestsInTestBundle(bundle);
|
|
280
|
+
}
|
|
286
281
|
|
|
287
282
|
/**
|
|
288
283
|
* @typedef {import('../driver').XCUITestDriver} XCUITestDriver
|