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.
Files changed (66) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/build/lib/commands/app-management.js +1 -1
  3. package/build/lib/commands/app-management.js.map +1 -1
  4. package/build/lib/commands/file-movement.d.ts.map +1 -1
  5. package/build/lib/commands/file-movement.js +4 -4
  6. package/build/lib/commands/file-movement.js.map +1 -1
  7. package/build/lib/commands/memory.js +1 -1
  8. package/build/lib/commands/memory.js.map +1 -1
  9. package/build/lib/commands/performance.d.ts.map +1 -1
  10. package/build/lib/commands/performance.js +13 -4
  11. package/build/lib/commands/performance.js.map +1 -1
  12. package/build/lib/commands/xctest-record-screen.js +1 -1
  13. package/build/lib/commands/xctest-record-screen.js.map +1 -1
  14. package/build/lib/device/device-connections-factory.d.ts +18 -0
  15. package/build/lib/device/device-connections-factory.d.ts.map +1 -0
  16. package/build/lib/{device-connections-factory.js → device/device-connections-factory.js} +57 -41
  17. package/build/lib/device/device-connections-factory.js.map +1 -0
  18. package/build/lib/device/real-device-management.d.ts +146 -0
  19. package/build/lib/device/real-device-management.d.ts.map +1 -0
  20. package/build/lib/device/real-device-management.js +727 -0
  21. package/build/lib/device/real-device-management.js.map +1 -0
  22. package/build/lib/device/simulator-management.d.ts +65 -0
  23. package/build/lib/device/simulator-management.d.ts.map +1 -0
  24. package/build/lib/{simulator-management.js → device/simulator-management.js} +23 -42
  25. package/build/lib/device/simulator-management.js.map +1 -0
  26. package/build/lib/driver.d.ts +1 -1
  27. package/build/lib/driver.d.ts.map +1 -1
  28. package/build/lib/driver.js +5 -6
  29. package/build/lib/driver.js.map +1 -1
  30. package/lib/commands/app-management.js +1 -1
  31. package/lib/commands/file-movement.js +8 -4
  32. package/lib/commands/memory.js +1 -1
  33. package/lib/commands/performance.js +12 -1
  34. package/lib/commands/xctest-record-screen.js +1 -1
  35. package/lib/{device-connections-factory.js → device/device-connections-factory.ts} +96 -60
  36. package/lib/device/real-device-management.ts +818 -0
  37. package/lib/{simulator-management.js → device/simulator-management.ts} +68 -61
  38. package/lib/driver.js +3 -5
  39. package/npm-shrinkwrap.json +2 -2
  40. package/package.json +1 -1
  41. package/build/lib/device-connections-factory.d.ts +0 -13
  42. package/build/lib/device-connections-factory.d.ts.map +0 -1
  43. package/build/lib/device-connections-factory.js.map +0 -1
  44. package/build/lib/ios-fs-helpers.d.ts +0 -75
  45. package/build/lib/ios-fs-helpers.d.ts.map +0 -1
  46. package/build/lib/ios-fs-helpers.js +0 -370
  47. package/build/lib/ios-fs-helpers.js.map +0 -1
  48. package/build/lib/real-device-management.d.ts +0 -53
  49. package/build/lib/real-device-management.d.ts.map +0 -1
  50. package/build/lib/real-device-management.js +0 -128
  51. package/build/lib/real-device-management.js.map +0 -1
  52. package/build/lib/real-device.d.ts +0 -112
  53. package/build/lib/real-device.d.ts.map +0 -1
  54. package/build/lib/real-device.js +0 -352
  55. package/build/lib/real-device.js.map +0 -1
  56. package/build/lib/simulator-management.d.ts +0 -96
  57. package/build/lib/simulator-management.d.ts.map +0 -1
  58. package/build/lib/simulator-management.js.map +0 -1
  59. package/build/lib/xcrun.d.ts +0 -3
  60. package/build/lib/xcrun.d.ts.map +0 -1
  61. package/build/lib/xcrun.js +0 -17
  62. package/build/lib/xcrun.js.map +0 -1
  63. package/lib/ios-fs-helpers.js +0 -355
  64. package/lib/real-device-management.js +0 -133
  65. package/lib/real-device.js +0 -347
  66. 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
- constructor(udid, localport, deviceport) {
13
- this.localport = parseInt(localport, 10);
14
- this.deviceport = parseInt(deviceport, 10);
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
- /** @type {net.Server} */ (this.localServer).once('listening', resolve);
57
- /** @type {net.Server} */ (this.localServer).once('error', reject);
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
- process.on('beforeExit', this.onBeforeProcessExit);
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
- _udidAsToken(udid) {
111
- return `${util.hasValue(udid) ? udid : ''}${SPLITTER}`;
112
- }
113
-
114
- _portAsToken(port) {
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(udid, port, options = {}) {
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
- const iproxy = new iProxy(udid, port, devicePort);
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
- export {DEVICE_CONNECTIONS_FACTORY, DeviceConnectionsFactory};
269
- export default DEVICE_CONNECTIONS_FACTORY;
302
+ interface RequestConnectionOptions {
303
+ usePortForwarding?: boolean;
304
+ devicePort?: number | null;
305
+ }