appium-xcuitest-driver 10.8.3 → 10.8.4
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/app-management.js +1 -1
- package/build/lib/commands/app-management.js.map +1 -1
- package/build/lib/commands/file-movement.d.ts.map +1 -1
- package/build/lib/commands/file-movement.js +4 -4
- package/build/lib/commands/file-movement.js.map +1 -1
- package/build/lib/commands/memory.js +1 -1
- package/build/lib/commands/memory.js.map +1 -1
- package/build/lib/commands/performance.d.ts.map +1 -1
- package/build/lib/commands/performance.js +13 -4
- package/build/lib/commands/performance.js.map +1 -1
- package/build/lib/commands/xctest-record-screen.js +1 -1
- package/build/lib/commands/xctest-record-screen.js.map +1 -1
- package/build/lib/device/device-connections-factory.d.ts +18 -0
- package/build/lib/device/device-connections-factory.d.ts.map +1 -0
- package/build/lib/{device-connections-factory.js → device/device-connections-factory.js} +57 -41
- package/build/lib/device/device-connections-factory.js.map +1 -0
- package/build/lib/device/real-device-management.d.ts +146 -0
- package/build/lib/device/real-device-management.d.ts.map +1 -0
- package/build/lib/device/real-device-management.js +727 -0
- package/build/lib/device/real-device-management.js.map +1 -0
- package/build/lib/device/simulator-management.d.ts +65 -0
- package/build/lib/device/simulator-management.d.ts.map +1 -0
- package/build/lib/{simulator-management.js → device/simulator-management.js} +23 -42
- package/build/lib/device/simulator-management.js.map +1 -0
- package/build/lib/driver.d.ts +1 -1
- package/build/lib/driver.d.ts.map +1 -1
- package/build/lib/driver.js +5 -6
- package/build/lib/driver.js.map +1 -1
- package/lib/commands/app-management.js +1 -1
- package/lib/commands/file-movement.js +8 -4
- package/lib/commands/memory.js +1 -1
- package/lib/commands/performance.js +12 -1
- package/lib/commands/xctest-record-screen.js +1 -1
- package/lib/{device-connections-factory.js → device/device-connections-factory.ts} +96 -60
- package/lib/device/real-device-management.ts +818 -0
- package/lib/{simulator-management.js → device/simulator-management.ts} +68 -61
- package/lib/driver.js +3 -5
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/build/lib/device-connections-factory.d.ts +0 -13
- package/build/lib/device-connections-factory.d.ts.map +0 -1
- package/build/lib/device-connections-factory.js.map +0 -1
- package/build/lib/ios-fs-helpers.d.ts +0 -75
- package/build/lib/ios-fs-helpers.d.ts.map +0 -1
- package/build/lib/ios-fs-helpers.js +0 -370
- package/build/lib/ios-fs-helpers.js.map +0 -1
- package/build/lib/real-device-management.d.ts +0 -53
- package/build/lib/real-device-management.d.ts.map +0 -1
- package/build/lib/real-device-management.js +0 -128
- package/build/lib/real-device-management.js.map +0 -1
- package/build/lib/real-device.d.ts +0 -112
- package/build/lib/real-device.d.ts.map +0 -1
- package/build/lib/real-device.js +0 -352
- package/build/lib/real-device.js.map +0 -1
- package/build/lib/simulator-management.d.ts +0 -96
- package/build/lib/simulator-management.d.ts.map +0 -1
- package/build/lib/simulator-management.js.map +0 -1
- package/build/lib/xcrun.d.ts +0 -3
- package/build/lib/xcrun.d.ts.map +0 -1
- package/build/lib/xcrun.js +0 -17
- package/build/lib/xcrun.js.map +0 -1
- package/lib/ios-fs-helpers.js +0 -355
- package/lib/real-device-management.js +0 -133
- package/lib/real-device.js +0 -347
- package/lib/xcrun.js +0 -16
|
@@ -5,30 +5,39 @@ import {logger, util, timing} from 'appium/support';
|
|
|
5
5
|
import {utilities} from 'appium-ios-device';
|
|
6
6
|
import {checkPortStatus} from 'portscanner';
|
|
7
7
|
import {waitForCondition} from 'asyncbox';
|
|
8
|
+
import type { AppiumLogger } from '@appium/types';
|
|
8
9
|
|
|
9
10
|
const LOCALHOST = '127.0.0.1';
|
|
10
11
|
|
|
11
12
|
class iProxy {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
private readonly localport: number;
|
|
14
|
+
private readonly deviceport: number;
|
|
15
|
+
private readonly udid: string;
|
|
16
|
+
private localServer: net.Server | null;
|
|
17
|
+
private readonly log: AppiumLogger;
|
|
18
|
+
private onBeforeProcessExit: (() => void) | null;
|
|
19
|
+
|
|
20
|
+
constructor(udid: string, localport: string | number, deviceport: string | number) {
|
|
21
|
+
this.localport = parseInt(String(localport), 10);
|
|
22
|
+
this.deviceport = parseInt(String(deviceport), 10);
|
|
15
23
|
this.udid = udid;
|
|
16
24
|
this.localServer = null;
|
|
17
25
|
this.log = logger.getLogger(`iProxy@${udid.substring(0, 8)}:${this.localport}`);
|
|
26
|
+
this.onBeforeProcessExit = null;
|
|
18
27
|
}
|
|
19
28
|
|
|
20
|
-
async start() {
|
|
29
|
+
async start(): Promise<void> {
|
|
21
30
|
if (this.localServer) {
|
|
22
31
|
return;
|
|
23
32
|
}
|
|
24
33
|
|
|
25
|
-
this.localServer = net.createServer(async (localSocket) => {
|
|
26
|
-
let remoteSocket;
|
|
34
|
+
this.localServer = net.createServer(async (localSocket: net.Socket) => {
|
|
35
|
+
let remoteSocket: any;
|
|
27
36
|
try {
|
|
28
37
|
// We can only connect to the remote socket after the local socket connection succeeds
|
|
29
38
|
remoteSocket = await utilities.connectPort(this.udid, this.deviceport);
|
|
30
39
|
} catch (e) {
|
|
31
|
-
this.log.debug(e.message);
|
|
40
|
+
this.log.debug((e as Error).message);
|
|
32
41
|
localSocket.destroy();
|
|
33
42
|
return;
|
|
34
43
|
}
|
|
@@ -42,19 +51,23 @@ class iProxy {
|
|
|
42
51
|
localSocket.destroy();
|
|
43
52
|
});
|
|
44
53
|
// not all remote socket errors are critical for the user
|
|
45
|
-
remoteSocket.on('error', (e) => this.log.debug(e));
|
|
54
|
+
remoteSocket.on('error', (e: Error) => this.log.debug(e));
|
|
46
55
|
localSocket.once('end', destroyCommChannel);
|
|
47
56
|
localSocket.once('close', () => {
|
|
48
57
|
destroyCommChannel();
|
|
49
58
|
remoteSocket.destroy();
|
|
50
59
|
});
|
|
51
|
-
localSocket.on('error', (e) => this.log.warn(e.message));
|
|
60
|
+
localSocket.on('error', (e: Error) => this.log.warn(e.message));
|
|
52
61
|
localSocket.pipe(remoteSocket);
|
|
53
62
|
remoteSocket.pipe(localSocket);
|
|
54
63
|
});
|
|
55
|
-
const listeningPromise = new B((resolve, reject) => {
|
|
56
|
-
|
|
57
|
-
|
|
64
|
+
const listeningPromise = new B<void>((resolve, reject) => {
|
|
65
|
+
if (this.localServer) {
|
|
66
|
+
this.localServer.once('listening', resolve);
|
|
67
|
+
this.localServer.once('error', reject);
|
|
68
|
+
} else {
|
|
69
|
+
reject(new Error('Local server is not initialized'));
|
|
70
|
+
}
|
|
58
71
|
});
|
|
59
72
|
this.localServer.listen(this.localport);
|
|
60
73
|
try {
|
|
@@ -63,8 +76,8 @@ class iProxy {
|
|
|
63
76
|
this.localServer = null;
|
|
64
77
|
throw e;
|
|
65
78
|
}
|
|
66
|
-
this.localServer.on('error', (e) => this.log.warn(e.message));
|
|
67
|
-
this.localServer.once('close', (e) => {
|
|
79
|
+
this.localServer.on('error', (e: Error) => this.log.warn(e.message));
|
|
80
|
+
this.localServer.once('close', (e?: Error) => {
|
|
68
81
|
if (e) {
|
|
69
82
|
this.log.info(`The connection has been closed with error ${e.message}`);
|
|
70
83
|
} else {
|
|
@@ -75,20 +88,12 @@ class iProxy {
|
|
|
75
88
|
|
|
76
89
|
this.onBeforeProcessExit = this._closeLocalServer.bind(this);
|
|
77
90
|
// Make sure we free up the socket on process exit
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
_closeLocalServer() {
|
|
82
|
-
if (!this.localServer) {
|
|
83
|
-
return;
|
|
91
|
+
if (this.onBeforeProcessExit) {
|
|
92
|
+
process.on('beforeExit', this.onBeforeProcessExit);
|
|
84
93
|
}
|
|
85
|
-
|
|
86
|
-
this.log.debug(`Closing the connection`);
|
|
87
|
-
this.localServer.close();
|
|
88
|
-
this.localServer = null;
|
|
89
94
|
}
|
|
90
95
|
|
|
91
|
-
stop() {
|
|
96
|
+
stop(): void {
|
|
92
97
|
if (this.onBeforeProcessExit) {
|
|
93
98
|
process.off('beforeExit', this.onBeforeProcessExit);
|
|
94
99
|
this.onBeforeProcessExit = null;
|
|
@@ -96,43 +101,34 @@ class iProxy {
|
|
|
96
101
|
|
|
97
102
|
this._closeLocalServer();
|
|
98
103
|
}
|
|
104
|
+
|
|
105
|
+
private _closeLocalServer(): void {
|
|
106
|
+
if (!this.localServer) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
this.log.debug(`Closing the connection`);
|
|
111
|
+
this.localServer.close();
|
|
112
|
+
this.localServer = null;
|
|
113
|
+
}
|
|
99
114
|
}
|
|
100
115
|
|
|
101
116
|
const log = logger.getLogger('DevCon Factory');
|
|
102
117
|
const PORT_CLOSE_TIMEOUT = 15 * 1000; // 15 seconds
|
|
103
118
|
const SPLITTER = ':';
|
|
104
119
|
|
|
105
|
-
class DeviceConnectionsFactory {
|
|
120
|
+
export class DeviceConnectionsFactory {
|
|
121
|
+
private _connectionsMapping: ConnectionMapping;
|
|
122
|
+
|
|
106
123
|
constructor() {
|
|
107
124
|
this._connectionsMapping = {};
|
|
108
125
|
}
|
|
109
126
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
return `${SPLITTER}${util.hasValue(port) ? port : ''}`;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
_toKey(udid = null, port = null) {
|
|
119
|
-
return `${util.hasValue(udid) ? udid : ''}${SPLITTER}${util.hasValue(port) ? port : ''}`;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
_releaseProxiedConnections(connectionKeys) {
|
|
123
|
-
const keys = connectionKeys.filter((k) => _.has(this._connectionsMapping[k], 'iproxy'));
|
|
124
|
-
for (const key of keys) {
|
|
125
|
-
log.info(`Releasing the listener for '${key}'`);
|
|
126
|
-
try {
|
|
127
|
-
this._connectionsMapping[key].iproxy.stop();
|
|
128
|
-
} catch (e) {
|
|
129
|
-
log.debug(e);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return keys;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
listConnections(udid = null, port = null, strict = false) {
|
|
127
|
+
listConnections(
|
|
128
|
+
udid: string | null = null,
|
|
129
|
+
port: string | number | null = null,
|
|
130
|
+
strict: boolean = false
|
|
131
|
+
): string[] {
|
|
136
132
|
if (!udid && !port) {
|
|
137
133
|
return [];
|
|
138
134
|
}
|
|
@@ -149,7 +145,11 @@ class DeviceConnectionsFactory {
|
|
|
149
145
|
);
|
|
150
146
|
}
|
|
151
147
|
|
|
152
|
-
async requestConnection(
|
|
148
|
+
async requestConnection(
|
|
149
|
+
udid?: string | null,
|
|
150
|
+
port?: string | number | null,
|
|
151
|
+
options: RequestConnectionOptions = {}
|
|
152
|
+
): Promise<void> {
|
|
153
153
|
if (!udid || !port) {
|
|
154
154
|
log.warn('Did not know how to request the connection:');
|
|
155
155
|
if (!udid) {
|
|
@@ -174,7 +174,7 @@ class DeviceConnectionsFactory {
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
if (usePortForwarding) {
|
|
177
|
-
let isPortBusy = (await checkPortStatus(port, LOCALHOST)) === 'open';
|
|
177
|
+
let isPortBusy = (await checkPortStatus(Number(port), LOCALHOST)) === 'open';
|
|
178
178
|
if (isPortBusy) {
|
|
179
179
|
log.warn(`Port #${port} is busy. Did you quit the previous driver session(s) properly?`);
|
|
180
180
|
if (!_.isEmpty(connectionsOnPort)) {
|
|
@@ -187,7 +187,7 @@ class DeviceConnectionsFactory {
|
|
|
187
187
|
await waitForCondition(
|
|
188
188
|
async () => {
|
|
189
189
|
try {
|
|
190
|
-
if ((await checkPortStatus(port, LOCALHOST)) !== 'open') {
|
|
190
|
+
if ((await checkPortStatus(Number(port), LOCALHOST)) !== 'open') {
|
|
191
191
|
log.info(
|
|
192
192
|
`Port #${port} has been successfully released after ` +
|
|
193
193
|
`${timer.getDuration().asMilliSeconds.toFixed(0)}ms`,
|
|
@@ -221,7 +221,10 @@ class DeviceConnectionsFactory {
|
|
|
221
221
|
}
|
|
222
222
|
const currentKey = this._toKey(udid, port);
|
|
223
223
|
if (usePortForwarding) {
|
|
224
|
-
|
|
224
|
+
if (!_.isInteger(devicePort)) {
|
|
225
|
+
throw new Error('devicePort is required when usePortForwarding is true');
|
|
226
|
+
}
|
|
227
|
+
const iproxy = new iProxy(udid, port, Number(devicePort));
|
|
225
228
|
try {
|
|
226
229
|
await iproxy.start();
|
|
227
230
|
this._connectionsMapping[currentKey] = {iproxy};
|
|
@@ -239,7 +242,7 @@ class DeviceConnectionsFactory {
|
|
|
239
242
|
log.info(`Successfully requested the connection for ${currentKey}`);
|
|
240
243
|
}
|
|
241
244
|
|
|
242
|
-
releaseConnection(udid = null, port = null) {
|
|
245
|
+
releaseConnection(udid: string | null = null, port: string | number | null = null): void {
|
|
243
246
|
if (!udid && !port) {
|
|
244
247
|
log.warn(
|
|
245
248
|
'Neither device UDID nor local port is set. ' +
|
|
@@ -261,9 +264,42 @@ class DeviceConnectionsFactory {
|
|
|
261
264
|
}
|
|
262
265
|
log.debug(`Cached connections count: ${_.size(this._connectionsMapping)}`);
|
|
263
266
|
}
|
|
267
|
+
|
|
268
|
+
private _udidAsToken(udid?: string | null): string {
|
|
269
|
+
return `${util.hasValue(udid) ? udid : ''}${SPLITTER}`;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
private _portAsToken(port?: string | number | null): string {
|
|
273
|
+
return `${SPLITTER}${util.hasValue(port) ? port : ''}`;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
private _toKey(udid: string | null = null, port: string | number | null = null): string {
|
|
277
|
+
return `${util.hasValue(udid) ? udid : ''}${SPLITTER}${util.hasValue(port) ? port : ''}`;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
private _releaseProxiedConnections(connectionKeys: string[]): string[] {
|
|
281
|
+
const keys = connectionKeys.filter((k) => _.has(this._connectionsMapping[k], 'iproxy'));
|
|
282
|
+
for (const key of keys) {
|
|
283
|
+
log.info(`Releasing the listener for '${key}'`);
|
|
284
|
+
try {
|
|
285
|
+
this._connectionsMapping[key].iproxy?.stop();
|
|
286
|
+
} catch (e) {
|
|
287
|
+
log.debug(e);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return keys;
|
|
291
|
+
}
|
|
264
292
|
}
|
|
265
293
|
|
|
266
|
-
const DEVICE_CONNECTIONS_FACTORY = new DeviceConnectionsFactory();
|
|
294
|
+
export const DEVICE_CONNECTIONS_FACTORY = new DeviceConnectionsFactory();
|
|
295
|
+
|
|
296
|
+
interface ConnectionMapping {
|
|
297
|
+
[key: string]: {
|
|
298
|
+
iproxy?: iProxy;
|
|
299
|
+
};
|
|
300
|
+
}
|
|
267
301
|
|
|
268
|
-
|
|
269
|
-
|
|
302
|
+
interface RequestConnectionOptions {
|
|
303
|
+
usePortForwarding?: boolean;
|
|
304
|
+
devicePort?: number | null;
|
|
305
|
+
}
|