appium-xcuitest-driver 10.14.12 → 10.15.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/file-movement.d.ts.map +1 -1
- package/build/lib/commands/file-movement.js +73 -45
- package/build/lib/commands/file-movement.js.map +1 -1
- package/build/lib/device/afc-client.d.ts +135 -0
- package/build/lib/device/afc-client.d.ts.map +1 -0
- package/build/lib/device/afc-client.js +422 -0
- package/build/lib/device/afc-client.js.map +1 -0
- package/build/lib/device/real-device-management.d.ts +13 -14
- package/build/lib/device/real-device-management.d.ts.map +1 -1
- package/build/lib/device/real-device-management.js +50 -162
- package/build/lib/device/real-device-management.js.map +1 -1
- package/build/scripts/build-wda.d.mts +2 -0
- package/build/scripts/build-wda.d.mts.map +1 -0
- package/build/scripts/build-wda.mjs +36 -0
- package/build/scripts/build-wda.mjs.map +1 -0
- package/build/scripts/download-wda-sim.d.mts +2 -0
- package/build/scripts/download-wda-sim.d.mts.map +1 -0
- package/build/scripts/download-wda-sim.mjs +62 -0
- package/build/scripts/download-wda-sim.mjs.map +1 -0
- package/build/scripts/image-mounter.d.mts +3 -0
- package/build/scripts/image-mounter.d.mts.map +1 -0
- package/build/scripts/image-mounter.mjs +189 -0
- package/build/scripts/image-mounter.mjs.map +1 -0
- package/build/scripts/open-wda.d.mts +2 -0
- package/build/scripts/open-wda.d.mts.map +1 -0
- package/build/scripts/open-wda.mjs +13 -0
- package/build/scripts/open-wda.mjs.map +1 -0
- package/build/scripts/tunnel-creation.d.mts +3 -0
- package/build/scripts/tunnel-creation.d.mts.map +1 -0
- package/build/scripts/tunnel-creation.mjs +297 -0
- package/build/scripts/tunnel-creation.mjs.map +1 -0
- package/build/scripts/utils.d.ts +8 -0
- package/build/scripts/utils.d.ts.map +1 -0
- package/build/scripts/utils.js +20 -0
- package/build/scripts/utils.js.map +1 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/lib/commands/file-movement.ts +100 -56
- package/lib/device/afc-client.ts +503 -0
- package/lib/device/real-device-management.ts +73 -166
- package/npm-shrinkwrap.json +5 -5
- package/package.json +1 -1
- package/scripts/build-wda.mjs +7 -0
- package/scripts/download-wda-sim.mjs +7 -3
- package/scripts/tunnel-creation.mjs +7 -2
- package/scripts/build-docs.js +0 -56
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
2
|
import B, {TimeoutError} from 'bluebird';
|
|
3
|
-
import {fs, tempDir,
|
|
3
|
+
import {fs, tempDir, zip, util, timing} from 'appium/support';
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import {services, utilities, INSTRUMENT_CHANNEL} from 'appium-ios-device';
|
|
6
6
|
import {buildSafariPreferences, SAFARI_BUNDLE_ID} from '../app-utils';
|
|
@@ -8,12 +8,13 @@ import {log as defaultLogger} from '../logger';
|
|
|
8
8
|
import { Devicectl } from 'node-devicectl';
|
|
9
9
|
import type { AppiumLogger } from '@appium/types';
|
|
10
10
|
import type { XCUITestDriver } from '../driver';
|
|
11
|
+
import {AfcClient} from './afc-client';
|
|
11
12
|
|
|
12
13
|
const DEFAULT_APP_INSTALLATION_TIMEOUT_MS = 8 * 60 * 1000;
|
|
13
14
|
export const IO_TIMEOUT_MS = 4 * 60 * 1000;
|
|
14
15
|
// Mobile devices use NAND memory modules for the storage,
|
|
15
16
|
// and the parallelism there is not as performant as on regular SSDs
|
|
16
|
-
const MAX_IO_CHUNK_SIZE = 8;
|
|
17
|
+
export const MAX_IO_CHUNK_SIZE = 8;
|
|
17
18
|
const APPLICATION_INSTALLED_NOTIFICATION = 'com.apple.mobile.application_installed';
|
|
18
19
|
const APPLICATION_NOTIFICATION_TIMEOUT_MS = 30 * 1000;
|
|
19
20
|
const INSTALLATION_STAGING_DIR = 'PublicStaging';
|
|
@@ -23,96 +24,52 @@ const INSTALLATION_STAGING_DIR = 'PublicStaging';
|
|
|
23
24
|
/**
|
|
24
25
|
* Retrieve a file from a real device
|
|
25
26
|
*
|
|
26
|
-
* @param
|
|
27
|
-
* 'appium-ios-device' module
|
|
27
|
+
* @param client AFC client instance
|
|
28
28
|
* @param remotePath Relative path to the file on the device
|
|
29
29
|
* @returns The file content as a buffer
|
|
30
30
|
*/
|
|
31
|
-
export async function pullFile(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}).timeout(IO_TIMEOUT_MS);
|
|
37
|
-
const buffers: Buffer[] = [];
|
|
38
|
-
stream.on('data', (data: Buffer) => buffers.push(data));
|
|
39
|
-
await pullPromise;
|
|
40
|
-
return Buffer.concat(buffers);
|
|
31
|
+
export async function pullFile(client: AfcClient, remotePath: string): Promise<Buffer> {
|
|
32
|
+
return await B.resolve(client.getFileContents(remotePath)).timeout(
|
|
33
|
+
IO_TIMEOUT_MS,
|
|
34
|
+
`Timed out after ${IO_TIMEOUT_MS}ms while pulling file from '${remotePath}'`
|
|
35
|
+
);
|
|
41
36
|
}
|
|
42
37
|
|
|
43
38
|
/**
|
|
44
39
|
* Retrieve a folder from a real device
|
|
45
40
|
*
|
|
46
|
-
* @param
|
|
47
|
-
* 'appium-ios-device' module
|
|
41
|
+
* @param client AFC client instance
|
|
48
42
|
* @param remoteRootPath Relative path to the folder on the device
|
|
49
43
|
* @returns The folder content as a zipped base64-encoded buffer
|
|
50
44
|
*/
|
|
51
|
-
export async function pullFolder(
|
|
45
|
+
export async function pullFolder(client: AfcClient, remoteRootPath: string): Promise<Buffer> {
|
|
52
46
|
const tmpFolder = await tempDir.openDir();
|
|
53
47
|
try {
|
|
54
48
|
let localTopItem: string | null = null;
|
|
55
49
|
let countFilesSuccess = 0;
|
|
56
|
-
let countFilesFail = 0;
|
|
57
50
|
let countFolders = 0;
|
|
58
|
-
const pullPromises: B<void>[] = [];
|
|
59
|
-
await afcService.walkDir(remoteRootPath, true, async (remotePath: string, isDir: boolean) => {
|
|
60
|
-
const localPath = path.join(tmpFolder, remotePath);
|
|
61
|
-
const dirname = isDir ? localPath : path.dirname(localPath);
|
|
62
|
-
if (!(await folderExists(dirname))) {
|
|
63
|
-
await mkdirp(dirname);
|
|
64
|
-
}
|
|
65
|
-
if (!localTopItem || localPath.split(path.sep).length < localTopItem.split(path.sep).length) {
|
|
66
|
-
localTopItem = localPath;
|
|
67
|
-
}
|
|
68
|
-
if (isDir) {
|
|
69
|
-
++countFolders;
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
51
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
resolve();
|
|
80
|
-
});
|
|
81
|
-
const onStreamingError = (e: Error) => {
|
|
82
|
-
readStream.unpipe(writeStream);
|
|
83
|
-
defaultLogger.warn(
|
|
84
|
-
`Cannot pull '${remotePath}' to '${localPath}'. ` +
|
|
85
|
-
`The file will be skipped. Original error: ${e.message}`,
|
|
86
|
-
);
|
|
87
|
-
++countFilesFail;
|
|
88
|
-
resolve();
|
|
89
|
-
};
|
|
90
|
-
writeStream.on('error', onStreamingError);
|
|
91
|
-
readStream.on('error', onStreamingError);
|
|
92
|
-
}).timeout(IO_TIMEOUT_MS),
|
|
93
|
-
);
|
|
94
|
-
readStream.pipe(writeStream);
|
|
95
|
-
if (pullPromises.length >= MAX_IO_CHUNK_SIZE) {
|
|
96
|
-
await B.any(pullPromises);
|
|
97
|
-
for (let i = pullPromises.length - 1; i >= 0; i--) {
|
|
98
|
-
if (pullPromises[i].isFulfilled()) {
|
|
99
|
-
pullPromises.splice(i, 1);
|
|
100
|
-
}
|
|
52
|
+
await client.pull(remoteRootPath, tmpFolder, {
|
|
53
|
+
recursive: true,
|
|
54
|
+
overwrite: true,
|
|
55
|
+
onEntry: async (remotePath: string, localPath: string, isDirectory: boolean) => {
|
|
56
|
+
if (!localTopItem || localPath.split(path.sep).length < localTopItem.split(path.sep).length) {
|
|
57
|
+
localTopItem = localPath;
|
|
101
58
|
}
|
|
102
|
-
|
|
59
|
+
if (isDirectory) {
|
|
60
|
+
++countFolders;
|
|
61
|
+
} else {
|
|
62
|
+
++countFilesSuccess;
|
|
63
|
+
}
|
|
64
|
+
},
|
|
103
65
|
});
|
|
104
|
-
|
|
105
|
-
if (!_.isEmpty(pullPromises)) {
|
|
106
|
-
await B.all(pullPromises);
|
|
107
|
-
}
|
|
66
|
+
|
|
108
67
|
defaultLogger.info(
|
|
109
|
-
`Pulled ${util.pluralize('file', countFilesSuccess, true)}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
)} ` +
|
|
115
|
-
`from '${remoteRootPath}'`,
|
|
68
|
+
`Pulled ${util.pluralize('file', countFilesSuccess, true)} and ${util.pluralize(
|
|
69
|
+
'folder',
|
|
70
|
+
countFolders,
|
|
71
|
+
true,
|
|
72
|
+
)} from '${remoteRootPath}'`,
|
|
116
73
|
);
|
|
117
74
|
return await zip.toInMemoryZip(localTopItem ? path.dirname(localTopItem) : tmpFolder, {
|
|
118
75
|
encodeToBase64: true,
|
|
@@ -125,8 +82,7 @@ export async function pullFolder(afcService: any, remoteRootPath: string): Promi
|
|
|
125
82
|
/**
|
|
126
83
|
* Pushes a file to a real device
|
|
127
84
|
*
|
|
128
|
-
* @param
|
|
129
|
-
* 'appium-ios-device' module
|
|
85
|
+
* @param client AFC client instance
|
|
130
86
|
* @param localPathOrPayload Either full path to the source file
|
|
131
87
|
* or a buffer payload to be written into the remote destination
|
|
132
88
|
* @param remotePath Relative path to the file on the device. The remote
|
|
@@ -134,49 +90,30 @@ export async function pullFolder(afcService: any, remoteRootPath: string): Promi
|
|
|
134
90
|
* @param opts Push file options
|
|
135
91
|
*/
|
|
136
92
|
export async function pushFile(
|
|
137
|
-
|
|
93
|
+
client: AfcClient,
|
|
138
94
|
localPathOrPayload: string | Buffer,
|
|
139
95
|
remotePath: string,
|
|
140
96
|
opts: PushFileOptions = {}
|
|
141
97
|
): Promise<void> {
|
|
142
98
|
const {timeoutMs = IO_TIMEOUT_MS} = opts;
|
|
143
99
|
const timer = new timing.Timer().start();
|
|
144
|
-
await remoteMkdirp(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const onStreamError = (e: Error) => {
|
|
162
|
-
if (!Buffer.isBuffer(source)) {
|
|
163
|
-
source.unpipe(writeStream);
|
|
164
|
-
}
|
|
165
|
-
defaultLogger.debug(e);
|
|
166
|
-
pushError = e;
|
|
167
|
-
};
|
|
168
|
-
writeStream.on('error', onStreamError);
|
|
169
|
-
if (!Buffer.isBuffer(source)) {
|
|
170
|
-
source.on('error', onStreamError);
|
|
171
|
-
}
|
|
172
|
-
});
|
|
173
|
-
if (Buffer.isBuffer(source)) {
|
|
174
|
-
writeStream.write(source);
|
|
175
|
-
writeStream.end();
|
|
176
|
-
} else {
|
|
177
|
-
source.pipe(writeStream);
|
|
178
|
-
}
|
|
179
|
-
await filePushPromise.timeout(Math.max(timeoutMs, 60000));
|
|
100
|
+
await remoteMkdirp(client, path.dirname(remotePath));
|
|
101
|
+
|
|
102
|
+
// AfcClient handles the branching internally
|
|
103
|
+
const pushPromise = Buffer.isBuffer(localPathOrPayload)
|
|
104
|
+
? client.setFileContents(remotePath, localPathOrPayload)
|
|
105
|
+
: client.writeFromStream(
|
|
106
|
+
remotePath,
|
|
107
|
+
fs.createReadStream(localPathOrPayload, {autoClose: true})
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
// Wrap with timeout
|
|
111
|
+
const actualTimeout = Math.max(timeoutMs, 60000);
|
|
112
|
+
await B.resolve(pushPromise).timeout(
|
|
113
|
+
actualTimeout,
|
|
114
|
+
`Timed out after ${actualTimeout}ms while pushing file to '${remotePath}'`
|
|
115
|
+
);
|
|
116
|
+
|
|
180
117
|
const fileSize = Buffer.isBuffer(localPathOrPayload)
|
|
181
118
|
? localPathOrPayload.length
|
|
182
119
|
: (await fs.stat(localPathOrPayload)).size;
|
|
@@ -189,15 +126,14 @@ export async function pushFile(
|
|
|
189
126
|
/**
|
|
190
127
|
* Pushes a folder to a real device
|
|
191
128
|
*
|
|
192
|
-
* @param
|
|
193
|
-
* 'appium-ios-device' module
|
|
129
|
+
* @param client AFC client instance
|
|
194
130
|
* @param srcRootPath The full path to the source folder
|
|
195
131
|
* @param dstRootPath The relative path to the destination folder. The folder
|
|
196
132
|
* will be deleted if already exists.
|
|
197
133
|
* @param opts Push folder options
|
|
198
134
|
*/
|
|
199
135
|
export async function pushFolder(
|
|
200
|
-
|
|
136
|
+
client: AfcClient,
|
|
201
137
|
srcRootPath: string,
|
|
202
138
|
dstRootPath: string,
|
|
203
139
|
opts: PushFolderOptions = {}
|
|
@@ -228,16 +164,16 @@ export async function pushFolder(
|
|
|
228
164
|
`Got ${util.pluralize('folder', foldersToPush.length, true)} and ` +
|
|
229
165
|
`${util.pluralize('file', filesToPush.length, true)} to push`,
|
|
230
166
|
);
|
|
231
|
-
//
|
|
167
|
+
// Create the folder structure
|
|
232
168
|
try {
|
|
233
|
-
await
|
|
169
|
+
await client.deleteDirectory(dstRootPath);
|
|
234
170
|
} catch {}
|
|
235
|
-
|
|
171
|
+
|
|
172
|
+
await client.createDirectory(dstRootPath);
|
|
236
173
|
for (const relativeFolderPath of foldersToPush) {
|
|
237
|
-
// createDirectory does not accept folder names ending with a path separator
|
|
238
174
|
const absoluteFolderPath = _.trimEnd(path.join(dstRootPath, relativeFolderPath), path.sep);
|
|
239
175
|
if (absoluteFolderPath) {
|
|
240
|
-
await
|
|
176
|
+
await client.createDirectory(absoluteFolderPath);
|
|
241
177
|
}
|
|
242
178
|
}
|
|
243
179
|
// do not forget about the root folder
|
|
@@ -250,29 +186,13 @@ export async function pushFolder(
|
|
|
250
186
|
const absoluteSourcePath = path.join(srcRootPath, relativePath);
|
|
251
187
|
const readStream = fs.createReadStream(absoluteSourcePath, {autoClose: true});
|
|
252
188
|
const absoluteDestinationPath = path.join(dstRootPath, relativePath);
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
if (pushError) {
|
|
261
|
-
reject(pushError);
|
|
262
|
-
} else {
|
|
263
|
-
resolve();
|
|
264
|
-
}
|
|
265
|
-
});
|
|
266
|
-
const onStreamError = (e: Error) => {
|
|
267
|
-
readStream.unpipe(writeStream);
|
|
268
|
-
defaultLogger.debug(e);
|
|
269
|
-
pushError = e;
|
|
270
|
-
};
|
|
271
|
-
writeStream.on('error', onStreamError);
|
|
272
|
-
readStream.on('error', onStreamError);
|
|
273
|
-
});
|
|
274
|
-
readStream.pipe(writeStream);
|
|
275
|
-
await filePushPromise.timeout(Math.max(timeoutMs - timer.getDuration().asMilliSeconds, 60000));
|
|
189
|
+
|
|
190
|
+
const pushPromise = client.writeFromStream(absoluteDestinationPath, readStream);
|
|
191
|
+
const actualTimeout = Math.max(timeoutMs - timer.getDuration().asMilliSeconds, 60000);
|
|
192
|
+
await B.resolve(pushPromise).timeout(
|
|
193
|
+
actualTimeout,
|
|
194
|
+
`Timed out after ${actualTimeout}ms while pushing '${relativePath}' to '${absoluteDestinationPath}'`
|
|
195
|
+
);
|
|
276
196
|
};
|
|
277
197
|
|
|
278
198
|
if (enableParallelPush) {
|
|
@@ -565,10 +485,11 @@ export class RealDevice {
|
|
|
565
485
|
}
|
|
566
486
|
|
|
567
487
|
/**
|
|
568
|
-
*
|
|
488
|
+
* ! This method is used by appium-webdriveragent package
|
|
569
489
|
*
|
|
490
|
+
* @param bundleName The name of CFBundleName in Info.plist
|
|
570
491
|
* @returns A list of User level apps' bundle ids which has
|
|
571
|
-
*
|
|
492
|
+
* 'CFBundleName' attribute as 'bundleName'.
|
|
572
493
|
*/
|
|
573
494
|
async getUserInstalledBundleIdsByBundleName(bundleName: string): Promise<string[]> {
|
|
574
495
|
const service = await services.startInstallationProxyService(this.udid);
|
|
@@ -753,42 +674,28 @@ function isPreferDevicectlEnabled(): boolean {
|
|
|
753
674
|
return ['yes', 'true', '1'].includes(_.toLower(process.env.APPIUM_XCUITEST_PREFER_DEVICECTL));
|
|
754
675
|
};
|
|
755
676
|
|
|
756
|
-
/**
|
|
757
|
-
* Checks a presence of a local folder.
|
|
758
|
-
*
|
|
759
|
-
* @param folderPath Full path to the local folder
|
|
760
|
-
* @returns True if the folder exists and is actually a folder
|
|
761
|
-
*/
|
|
762
|
-
async function folderExists(folderPath: string): Promise<boolean> {
|
|
763
|
-
try {
|
|
764
|
-
return (await fs.stat(folderPath)).isDirectory();
|
|
765
|
-
} catch {
|
|
766
|
-
return false;
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
|
|
770
677
|
/**
|
|
771
678
|
* Creates remote folder path recursively. Noop if the given path
|
|
772
679
|
* already exists
|
|
773
680
|
*
|
|
774
|
-
* @param
|
|
775
|
-
* 'appium-ios-device' module
|
|
681
|
+
* @param client AFC client instance
|
|
776
682
|
* @param remoteRoot The relative path to the remote folder structure
|
|
777
683
|
* to be created
|
|
778
684
|
*/
|
|
779
|
-
async function remoteMkdirp(
|
|
685
|
+
async function remoteMkdirp(client: AfcClient, remoteRoot: string): Promise<void> {
|
|
780
686
|
if (remoteRoot === '.' || remoteRoot === '/') {
|
|
781
687
|
return;
|
|
782
688
|
}
|
|
689
|
+
|
|
783
690
|
try {
|
|
784
|
-
await
|
|
691
|
+
await client.listDirectory(remoteRoot);
|
|
785
692
|
return;
|
|
786
693
|
} catch {
|
|
787
|
-
//
|
|
788
|
-
|
|
789
|
-
await remoteMkdirp(afcService, path.dirname(remoteRoot));
|
|
694
|
+
// Directory is missing, create parent first
|
|
695
|
+
await remoteMkdirp(client, path.dirname(remoteRoot));
|
|
790
696
|
}
|
|
791
|
-
|
|
697
|
+
|
|
698
|
+
await client.createDirectory(remoteRoot);
|
|
792
699
|
}
|
|
793
700
|
|
|
794
701
|
//#endregion
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "appium-xcuitest-driver",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.15.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "appium-xcuitest-driver",
|
|
9
|
-
"version": "10.
|
|
9
|
+
"version": "10.15.0",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@appium/strongbox": "^1.0.0-rc.1",
|
|
@@ -692,9 +692,9 @@
|
|
|
692
692
|
}
|
|
693
693
|
},
|
|
694
694
|
"node_modules/appium-ios-remotexpc": {
|
|
695
|
-
"version": "0.25.
|
|
696
|
-
"resolved": "https://registry.npmjs.org/appium-ios-remotexpc/-/appium-ios-remotexpc-0.25.
|
|
697
|
-
"integrity": "sha512-
|
|
695
|
+
"version": "0.25.2",
|
|
696
|
+
"resolved": "https://registry.npmjs.org/appium-ios-remotexpc/-/appium-ios-remotexpc-0.25.2.tgz",
|
|
697
|
+
"integrity": "sha512-mRMVjorxf70Q8qsDxoF8O5tDQ5N0hBYELQ6dUDnIUNI8YljcT1/SzlBnGLLfgZYuTK6ImyJhw/jifMJKjHEkrw==",
|
|
698
698
|
"license": "Apache-2.0",
|
|
699
699
|
"optional": true,
|
|
700
700
|
"dependencies": {
|
package/package.json
CHANGED
package/scripts/build-wda.mjs
CHANGED
|
@@ -10,6 +10,13 @@ const log = logger.getLogger('WDA');
|
|
|
10
10
|
async function build() {
|
|
11
11
|
const customDevice = parseArgValue('name');
|
|
12
12
|
const platformVersion = parseArgValue('sdk') || (await xcode.getMaxIOSSDK());
|
|
13
|
+
|
|
14
|
+
if (!platformVersion) {
|
|
15
|
+
throw new Error(
|
|
16
|
+
'Cannot determine iOS SDK version to build for. Please specify --sdk=<version> or ensure Xcode and its command-line tools are installed (try `xcodebuild -showsdks` or `xcode-select --print-path`).'
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
13
20
|
const iosDevices = await new Simctl().getDevices(platformVersion, 'iOS');
|
|
14
21
|
const verifyDevicePresence = (info) => {
|
|
15
22
|
if (!info) {
|
|
@@ -14,11 +14,15 @@ const destZip = (platform) => {
|
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Return installed appium-webdriveragent package version
|
|
17
|
-
* @returns {number}
|
|
17
|
+
* @returns {Promise<number>}
|
|
18
18
|
*/
|
|
19
19
|
async function webdriveragentPkgVersion() {
|
|
20
|
+
const moduleRoot = node.getModuleRootSync('appium-xcuitest-driver', import.meta.url);
|
|
21
|
+
if (!moduleRoot) {
|
|
22
|
+
throw new Error('Cannot resolve module root for appium-xcuitest-driver');
|
|
23
|
+
}
|
|
20
24
|
const pkgPath = path.join(
|
|
21
|
-
|
|
25
|
+
moduleRoot,
|
|
22
26
|
'node_modules',
|
|
23
27
|
'appium-webdriveragent',
|
|
24
28
|
'package.json'
|
|
@@ -28,7 +32,7 @@ async function webdriveragentPkgVersion() {
|
|
|
28
32
|
|
|
29
33
|
/**
|
|
30
34
|
* Prepare the working root directory.
|
|
31
|
-
* @returns {string} Root directory to download and unzip.
|
|
35
|
+
* @returns {Promise<string>} Root directory to download and unzip.
|
|
32
36
|
*/
|
|
33
37
|
async function prepareRootDir() {
|
|
34
38
|
const destDirRoot = parseArgValue('outdir');
|
|
@@ -52,7 +52,7 @@ class TunnelCreator {
|
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
54
|
* Update tunnel registry with new tunnel information
|
|
55
|
-
* @
|
|
55
|
+
* @param {import('appium-ios-remotexpc').TunnelResult[]} results - Array of tunnel results
|
|
56
56
|
* @returns {Promise<import('appium-ios-remotexpc').TunnelRegistry>} Updated tunnel registry
|
|
57
57
|
*/
|
|
58
58
|
async updateTunnelRegistry(results) {
|
|
@@ -141,11 +141,12 @@ class TunnelCreator {
|
|
|
141
141
|
|
|
142
142
|
/**
|
|
143
143
|
* Create tunnel for a single device
|
|
144
|
-
* @param {
|
|
144
|
+
* @param {import('appium-ios-remotexpc').UsbmuxDevice} device - Device object
|
|
145
145
|
* @param {import('tls').ConnectionOptions} tlsOptions - TLS options
|
|
146
146
|
* @returns {Promise<import('appium-ios-remotexpc').TunnelResult & { socket?: any; socketInfo?: import('appium-ios-remotexpc').SocketInfo }>} Tunnel result
|
|
147
147
|
*/
|
|
148
148
|
async createTunnelForDevice(device, tlsOptions) {
|
|
149
|
+
|
|
149
150
|
const udid = device.Properties.SerialNumber;
|
|
150
151
|
|
|
151
152
|
log.info(`\n--- Processing device: ${udid} ---`);
|
|
@@ -330,6 +331,10 @@ async function main() {
|
|
|
330
331
|
tunnelCreator.tunnelRegistryPort = parseInt(tunnelRegistryPort, 10);
|
|
331
332
|
}
|
|
332
333
|
|
|
334
|
+
if (!BOOTSTRAP_PATH) {
|
|
335
|
+
throw new Error(`BOOTSTRAP_PATH is null`);
|
|
336
|
+
}
|
|
337
|
+
|
|
333
338
|
const packageInfo = JSON.parse(
|
|
334
339
|
fs.readFileSync(path.join(BOOTSTRAP_PATH, 'package.json'), 'utf8'),
|
|
335
340
|
);
|
package/scripts/build-docs.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
// for simplicity this file is not transpiled and is run directly via an npm script
|
|
2
|
-
/* eslint-disable promise/prefer-await-to-callbacks */
|
|
3
|
-
/* eslint-disable promise/prefer-await-to-then */
|
|
4
|
-
|
|
5
|
-
const {deploy} = require('@appium/docutils');
|
|
6
|
-
const {logger} = require('appium/support');
|
|
7
|
-
const path = require('path');
|
|
8
|
-
const semver = require('semver');
|
|
9
|
-
const {version} = require('../package.json');
|
|
10
|
-
|
|
11
|
-
const log = logger.getLogger('Docs');
|
|
12
|
-
|
|
13
|
-
const DOCS_REMOTE = 'origin';
|
|
14
|
-
const DOCS_BRANCH = 'docs-site';
|
|
15
|
-
const DOCS_PREFIX = false;
|
|
16
|
-
const REPO_DIR = path.resolve(__dirname, '..');
|
|
17
|
-
const LATEST_ALIAS = 'latest';
|
|
18
|
-
|
|
19
|
-
const packageJson = require.resolve('../package.json');
|
|
20
|
-
|
|
21
|
-
const branch = process.env.APPIUM_DOCS_BRANCH ?? DOCS_BRANCH;
|
|
22
|
-
const deployPrefix = process.env.APPIUM_DOCS_PREFIX ?? DOCS_PREFIX;
|
|
23
|
-
const remote = process.env.APPIUM_DOCS_REMOTE ?? DOCS_REMOTE;
|
|
24
|
-
|
|
25
|
-
const push = Boolean(process.env.APPIUM_DOCS_PUBLISH);
|
|
26
|
-
|
|
27
|
-
async function main() {
|
|
28
|
-
log.info(`Building XCUI docs and committing to ${DOCS_BRANCH}`);
|
|
29
|
-
const {major, minor} = semver.parse(version);
|
|
30
|
-
const deployVersion = `${major}.${minor}`;
|
|
31
|
-
|
|
32
|
-
const mkdocsYml = path.join(REPO_DIR, 'mkdocs.yml');
|
|
33
|
-
|
|
34
|
-
log.info(`Building docs for version ${deployVersion}`);
|
|
35
|
-
await deploy({
|
|
36
|
-
mkDocsYml: mkdocsYml,
|
|
37
|
-
push,
|
|
38
|
-
branch,
|
|
39
|
-
deployPrefix,
|
|
40
|
-
remote,
|
|
41
|
-
packageJson,
|
|
42
|
-
deployVersion,
|
|
43
|
-
message: `docs: auto-build docs for appium-xcuitest-driver@${deployVersion}`,
|
|
44
|
-
alias: LATEST_ALIAS,
|
|
45
|
-
});
|
|
46
|
-
log.info(`Docs built`);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (require.main === module) {
|
|
50
|
-
main().catch((err) => {
|
|
51
|
-
console.error(err); // eslint-disable-line no-console
|
|
52
|
-
process.exitCode = 1;
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
module.exports = main;
|