Skip to content

Commit 8868b1a

Browse files
feat: Save tunnel registry using strong box (#2585)
* Introduce remote xpc tunnel creation Co-authored-by: SrinivasanTarget <srinivasan.sekar1990@gmail.com>
1 parent 8a11e9c commit 8868b1a

4 files changed

Lines changed: 395 additions & 20 deletions

File tree

docs/reference/scripts.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,7 @@ appium driver run xcuitest <script-name>
1717
|`open-wda`|Opens the WebDriverAgent project in Xcode|
1818
|`build-wda`|Builds the WebDriverAgent project using the first available iPhone simulator and the latest iOS supported by the current Xcode version by default|
1919
|`build-wda --sdk=17.5 --name="iPhone 15"`|Builds the WebDriverAgent project using the iPhone 15 simulator with iOS 17.5. If `--sdk` and `--name` params are not specified - the latest iOS and the first available iPhone simulator will be used|
20+
|`tunnel-creation`|Creates tunnels for connected iOS devices, starts CoreDeviceProxy, and sets up a tunnel registry server. Requires sudo access to communicate with iOS devices|
21+
|`tunnel-creation --udid=<device-udid>` or `-u <device-udid>`|Creates a tunnel for a specific iOS device with the given UDID|
22+
|`tunnel-creation --packet-stream-base-port=<port>`|Specifies the base port for packet stream servers (default: 50000)|
23+
|`tunnel-creation --tunnel-registry-port=<port>`|Specifies the port for the tunnel registry server (default: 42314)|

lib/ios-fs-helpers.js

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,12 @@ export async function pullFolder(afcService, remoteRootPath) {
9797
readStream.pipe(writeStream);
9898
if (pullPromises.length >= MAX_IO_CHUNK_SIZE) {
9999
await B.any(pullPromises);
100+
for (let i = pullPromises.length - 1; i >= 0; i--) {
101+
if (pullPromises[i].isFulfilled()) {
102+
pullPromises.splice(i, 1);
103+
}
104+
}
100105
}
101-
// @ts-ignore
102-
_.remove(pullPromises, (p) => p.isFulfilled());
103106
});
104107
// Wait for the rest of files to be pulled
105108
if (!_.isEmpty(pullPromises)) {
@@ -163,10 +166,8 @@ async function remoteMkdirp(afcService, remoteRoot) {
163166
* folder structure is created automatically if necessary.
164167
* @param {PushFileOptions} [opts={}]
165168
*/
166-
export async function pushFile (afcService, localPathOrPayload, remotePath, opts = {}) {
167-
const {
168-
timeoutMs = IO_TIMEOUT_MS,
169-
} = opts;
169+
export async function pushFile(afcService, localPathOrPayload, remotePath, opts = {}) {
170+
const {timeoutMs = IO_TIMEOUT_MS} = opts;
170171
const timer = new timing.Timer().start();
171172
await remoteMkdirp(afcService, path.dirname(remotePath));
172173
const source = Buffer.isBuffer(localPathOrPayload)
@@ -209,9 +210,9 @@ export async function pushFile (afcService, localPathOrPayload, remotePath, opts
209210
: (await fs.stat(localPathOrPayload)).size;
210211
log.debug(
211212
`Successfully pushed the file payload (${util.toReadableSizeString(fileSize)}) ` +
212-
`to the remote location '${remotePath}' in ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`
213+
`to the remote location '${remotePath}' in ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`,
213214
);
214-
};
215+
}
215216

216217
/**
217218
* @typedef {Object} PushFolderOptions
@@ -236,11 +237,13 @@ export async function pushFolder(afcService, srcRootPath, dstRootPath, opts = {}
236237
const {timeoutMs = IO_TIMEOUT_MS, enableParallelPush = false} = opts;
237238

238239
const timer = new timing.Timer().start();
239-
const allItems = /** @type {import('path-scurry').Path[]} */ (/** @type {unknown} */ (
240-
await fs.glob('**', {
241-
cwd: srcRootPath,
242-
withFileTypes: true,
243-
}))
240+
const allItems = /** @type {import('path-scurry').Path[]} */ (
241+
/** @type {unknown} */ (
242+
await fs.glob('**', {
243+
cwd: srcRootPath,
244+
withFileTypes: true,
245+
})
246+
)
244247
);
245248
log.debug(`Successfully scanned the tree structure of '${srcRootPath}'`);
246249
// top-level folders go first
@@ -319,12 +322,19 @@ export async function pushFolder(afcService, srcRootPath, dstRootPath, opts = {}
319322
throw new TimeoutError(`Timed out after ${elapsedMs} ms`);
320323
}
321324
}
322-
// @ts-ignore
323-
_.remove(pushPromises, (p) => p.isFulfilled());
325+
for (let i = pushPromises.length - 1; i >= 0; i--) {
326+
if (pushPromises[i].isFulfilled()) {
327+
pushPromises.splice(i, 1);
328+
}
329+
}
324330
}
325331
if (!_.isEmpty(pushPromises)) {
326-
// handle the rest of push promises
327-
await B.all(pushPromises).timeout(Math.max(timeoutMs - timer.getDuration().asMilliSeconds, 60000));
332+
const remainingPromises = pushPromises.filter((p) => !p.isFulfilled());
333+
if (remainingPromises.length > 0) {
334+
await B.all(remainingPromises).timeout(
335+
Math.max(timeoutMs - timer.getDuration().asMilliSeconds, 60000),
336+
);
337+
}
328338
}
329339
} else {
330340
log.debug(`Proceeding to serial files push`);

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
"mainClass": "XCUITestDriver",
3333
"scripts": {
3434
"build-wda": "./scripts/build-wda.js",
35-
"open-wda": "./scripts/open-wda.js"
35+
"open-wda": "./scripts/open-wda.js",
36+
"tunnel-creation": "./scripts/tunnel-creation.mjs"
3637
},
3738
"schema": {
3839
"$schema": "http://json-schema.org/draft-07/schema",
@@ -76,6 +77,7 @@
7677
],
7778
"types": "./build/index.d.ts",
7879
"dependencies": {
80+
"@appium/strongbox": "^0.x",
7981
"@colors/colors": "^1.6.0",
8082
"appium-idb": "^1.6.13",
8183
"appium-ios-device": "^2.8.0",
@@ -97,8 +99,8 @@
9799
"semver": "^7.5.4",
98100
"source-map-support": "^0.x",
99101
"teen_process": "^2.2.0",
100-
"ws": "^8.13.0",
101-
"winston": "3.17.0"
102+
"winston": "3.17.0",
103+
"ws": "^8.13.0"
102104
},
103105
"scripts": {
104106
"build": "tsc -b",

0 commit comments

Comments
 (0)