appium-xcuitest-driver 10.14.10 → 10.14.12

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.
@@ -1,6 +1,7 @@
1
1
  import { isIos18OrNewer } from '../utils';
2
2
  import type {XCUITestDriver} from '../driver';
3
3
  import type {BatteryInfo} from './types';
4
+ import {getRemoteXPCServices} from '../device/remotexpc-utils';
4
5
 
5
6
  /**
6
7
  * Reads the battery information from the device under test.
@@ -16,7 +17,7 @@ export async function mobileGetBatteryInfo(
16
17
  if (isIos18OrNewer(this.opts) && this.isRealDevice()) {
17
18
  let remoteXPCConnection;
18
19
  try {
19
- const {Services} = await import('appium-ios-remotexpc');
20
+ const Services = await getRemoteXPCServices();
20
21
  const { diagnosticsService, remoteXPC } = await Services.startDiagnosticsService(this.device.udid);
21
22
  remoteXPCConnection = remoteXPC;
22
23
  batteryInfoFromShimService = await diagnosticsService.ioregistry({
@@ -2,8 +2,48 @@ import {INSTRUMENT_CHANNEL, services} from 'appium-ios-device';
2
2
  import _ from 'lodash';
3
3
  import { isIos18OrNewer, requireRealDevice } from '../utils';
4
4
  import type {XCUITestDriver} from '../driver';
5
+ import type {AppiumLogger} from '@appium/types';
5
6
  import type {DVTServiceWithConnection} from 'appium-ios-remotexpc';
6
7
  import type {Condition} from './types';
8
+ import {getRemoteXPCServices} from '../device/remotexpc-utils';
9
+
10
+ /**
11
+ * Abstract interface for condition inducer implementations.
12
+ * This facade hides the differences between RemoteXPC and Instrument Service implementations.
13
+ */
14
+ export interface IConditionInducer {
15
+ /**
16
+ * Lists all available condition inducers
17
+ * @returns Array of available condition inducers
18
+ */
19
+ list(): Promise<Condition[]>;
20
+
21
+ /**
22
+ * Enables a condition inducer with the given profile
23
+ * @param conditionID - The condition identifier (only used by Instrument Service)
24
+ * @param profileID - The profile identifier
25
+ * @returns `true` if enabling succeeded
26
+ * @throws {Error} If a condition is already active
27
+ */
28
+ enable(conditionID: string, profileID: string): Promise<boolean>;
29
+
30
+ /**
31
+ * Disables the currently active condition inducer
32
+ * @returns `true` if disabling succeeded
33
+ */
34
+ disable(): Promise<boolean>;
35
+
36
+ /**
37
+ * Closes any open connections/resources
38
+ */
39
+ close(): Promise<void>;
40
+
41
+ /**
42
+ * Checks if a condition inducer is currently active
43
+ * @returns `true` if a condition is active
44
+ */
45
+ isActive(): boolean;
46
+ }
7
47
 
8
48
  /**
9
49
  * Get all available ConditionInducer configuration information, which can be used with
@@ -14,32 +54,8 @@ import type {Condition} from './types';
14
54
  export async function listConditionInducers(this: XCUITestDriver): Promise<Condition[]> {
15
55
  requireRealDevice(this, 'Condition inducer');
16
56
 
17
- if (isIos18OrNewer(this.opts)) {
18
- let dvtConnection;
19
- try {
20
- dvtConnection = await startRemoteXPC(this.device.udid);
21
- const result = await dvtConnection.conditionInducer.list();
22
- return result as Condition[];
23
- } catch (err: any) {
24
- this.log.error(`Failed to list condition inducers via RemoteXPC: ${err.message}`);
25
- } finally {
26
- if (dvtConnection) {
27
- this.log.info(`Closing remoteXPC connection for device ${this.device.udid}`);
28
- await dvtConnection.remoteXPC.close();
29
- }
30
- }
31
- }
32
-
33
- const conditionInducerService = await services.startInstrumentService(this.device.udid);
34
- try {
35
- const ret = await conditionInducerService.callChannel(
36
- INSTRUMENT_CHANNEL.CONDITION_INDUCER,
37
- 'availableConditionInducers',
38
- );
39
- return ret.selector;
40
- } finally {
41
- conditionInducerService.close();
42
- }
57
+ const facade = this._conditionInducer ?? await createConditionInducer(this);
58
+ return await facade.list();
43
59
  }
44
60
 
45
61
  /**
@@ -67,45 +83,26 @@ export async function enableConditionInducer(
67
83
  ): Promise<boolean> {
68
84
  requireRealDevice(this, 'Condition inducer');
69
85
 
70
- if (isIos18OrNewer(this.opts)) {
71
- if (this._remoteXPCConditionInducerConnection) {
72
- throw this.log.errorWithException(
73
- `Condition inducer is already running. Disable it first in order to call enable again.`
74
- );
75
- }
76
-
77
- try {
78
- const dvtConnection = await startRemoteXPC(this.device.udid);
79
- this._remoteXPCConditionInducerConnection = dvtConnection;
80
-
81
- await dvtConnection.conditionInducer.set(profileID);
82
-
83
- this.log.info(`Successfully enabled condition profile: ${profileID}`);
84
- return true;
85
- } catch (err: any) {
86
- await closeRemoteXPC.call(this);
87
- this.log.error(`Condition inducer '${profileID}' cannot be enabled: '${err.message}'`);
88
- }
86
+ if (this._conditionInducer?.isActive()) {
87
+ throw this.log.errorWithException(
88
+ `Condition inducer is already running. Disable it first in order to call 'enable' again.`
89
+ );
89
90
  }
90
91
 
91
- if (this._conditionInducerService && !this._conditionInducerService._socketClient.destroyed) {
92
+ const facade = await createConditionInducer(this);
93
+ this._conditionInducer = facade;
94
+
95
+ try {
96
+ return await facade.enable(conditionID, profileID);
97
+ } catch (err: any) {
98
+ this._conditionInducer = null;
99
+ try {
100
+ await facade.close();
101
+ } catch {}
92
102
  throw this.log.errorWithException(
93
- `Condition inducer has been started. A condition is already active.`
103
+ `Condition inducer '${profileID}' cannot be enabled: '${err.message}'`
94
104
  );
95
105
  }
96
- this._conditionInducerService = await services.startInstrumentService(this.device.udid);
97
- const ret = await this._conditionInducerService.callChannel(
98
- INSTRUMENT_CHANNEL.CONDITION_INDUCER,
99
- 'enableConditionWithIdentifier:profileIdentifier:',
100
- conditionID,
101
- profileID,
102
- );
103
- if (!_.isBoolean(ret.selector)) {
104
- this._conditionInducerService.close();
105
- this._conditionInducerService = null;
106
- throw this.log.errorWithException(`Enable condition inducer error: '${JSON.stringify(ret.selector)}'`);
107
- }
108
- return ret.selector;
109
106
  }
110
107
 
111
108
  /**
@@ -122,57 +119,210 @@ export async function enableConditionInducer(
122
119
  export async function disableConditionInducer(this: XCUITestDriver): Promise<boolean> {
123
120
  requireRealDevice(this, 'Condition inducer');
124
121
 
125
- if (isIos18OrNewer(this.opts)) {
126
- if (!this._remoteXPCConditionInducerConnection) {
122
+ if (!this._conditionInducer) {
123
+ this.log.warn('Condition inducer is not active');
124
+ return false;
125
+ }
126
+
127
+ try {
128
+ return await this._conditionInducer.disable();
129
+ } finally {
130
+ try {
131
+ await this._conditionInducer.close();
132
+ } catch {}
133
+ this._conditionInducer = null;
134
+ }
135
+ }
136
+
137
+ // Private implementation classes and factory function
138
+
139
+ /**
140
+ * RemoteXPC-based implementation for iOS 18+
141
+ */
142
+ class RemoteXPCConditionInducer implements IConditionInducer {
143
+ private connection: DVTServiceWithConnection | null = null;
144
+
145
+ constructor(
146
+ private readonly udid: string,
147
+ private readonly log: AppiumLogger,
148
+ ) {}
149
+
150
+ async list(): Promise<Condition[]> {
151
+ let connection: DVTServiceWithConnection | null = null;
152
+ try {
153
+ connection = await this.startConnection();
154
+ const result = await connection.conditionInducer.list();
155
+ return result as Condition[];
156
+ } catch (err: any) {
157
+ this.log.error(`Failed to list condition inducers via RemoteXPC: ${err.message}`);
158
+ throw err;
159
+ } finally {
160
+ if (connection) {
161
+ this.log.info(`Closing remoteXPC connection for device ${this.udid}`);
162
+ await connection.remoteXPC.close();
163
+ }
164
+ }
165
+ }
166
+
167
+ async enable(conditionID: string, profileID: string): Promise<boolean> {
168
+ if (this.connection) {
169
+ throw new Error(
170
+ `Condition inducer is already running. Disable it first in order to call 'enable' again.`
171
+ );
172
+ }
173
+
174
+ try {
175
+ this.connection = await this.startConnection();
176
+ await this.connection.conditionInducer.set(profileID);
177
+ this.log.info(`Successfully enabled condition profile: ${profileID}`);
178
+ return true;
179
+ } catch (err: any) {
180
+ await this.close();
181
+ this.log.error(`Condition inducer '${profileID}' cannot be enabled: '${err.message}'`);
182
+ throw err;
183
+ }
184
+ }
185
+
186
+ async disable(): Promise<boolean> {
187
+ if (!this.connection) {
127
188
  this.log.warn('Condition inducer connection is not active');
128
189
  return false;
129
190
  }
130
191
 
131
192
  try {
132
- await this._remoteXPCConditionInducerConnection.conditionInducer.disable();
193
+ await this.connection.conditionInducer.disable();
133
194
  this.log.info('Successfully disabled condition inducer');
134
195
  return true;
135
196
  } catch (err: any) {
136
197
  this.log.warn(`Failed to disable condition inducer via RemoteXPC: ${err.message}`);
137
198
  return false;
138
199
  } finally {
139
- this.log.info(`Closing remoteXPC connection for device ${this.device.udid}`);
140
- await closeRemoteXPC.call(this);
200
+ this.log.info(`Closing remoteXPC connection for device ${this.udid}`);
201
+ await this.close();
141
202
  }
142
203
  }
143
204
 
144
- if (!this._conditionInducerService) {
145
- this.log.warn('Condition inducer server is not started');
146
- return false;
205
+ async close(): Promise<void> {
206
+ if (this.connection) {
207
+ await this.connection.remoteXPC.close();
208
+ this.connection = null;
209
+ }
147
210
  }
148
- try {
149
- const ret = await this._conditionInducerService.callChannel(
211
+
212
+ isActive(): boolean {
213
+ return this.connection !== null;
214
+ }
215
+
216
+ public async startConnection(): Promise<DVTServiceWithConnection> {
217
+ const Services = await getRemoteXPCServices();
218
+ return Services.startDVTService(this.udid);
219
+ }
220
+ }
221
+
222
+ /**
223
+ * Instrument Service-based implementation for iOS < 18
224
+ */
225
+ class InstrumentConditionInducer implements IConditionInducer {
226
+ private service: any | null = null; // InstrumentService type from appium-ios-device
227
+
228
+ constructor(
229
+ private readonly udid: string,
230
+ private readonly log: AppiumLogger,
231
+ ) {}
232
+
233
+ async list(): Promise<Condition[]> {
234
+ const service = await services.startInstrumentService(this.udid);
235
+ try {
236
+ const ret = await service.callChannel(
237
+ INSTRUMENT_CHANNEL.CONDITION_INDUCER,
238
+ 'availableConditionInducers',
239
+ );
240
+ return ret.selector;
241
+ } finally {
242
+ service.close();
243
+ }
244
+ }
245
+
246
+ async enable(conditionID: string, profileID: string): Promise<boolean> {
247
+ if (this.service && !this.service._socketClient.destroyed) {
248
+ throw new Error(`Condition inducer has been started. A condition is already active.`);
249
+ }
250
+
251
+ this.service = await services.startInstrumentService(this.udid);
252
+ const ret = await this.service.callChannel(
150
253
  INSTRUMENT_CHANNEL.CONDITION_INDUCER,
151
- 'disableActiveCondition',
254
+ 'enableConditionWithIdentifier:profileIdentifier:',
255
+ conditionID,
256
+ profileID,
152
257
  );
258
+
153
259
  if (!_.isBoolean(ret.selector)) {
154
- this.log.warn(`Disable condition inducer error: '${JSON.stringify(ret.selector)}'`);
155
- return false;
260
+ this.service.close();
261
+ this.service = null;
262
+ throw new Error(`Enable condition inducer error: '${JSON.stringify(ret.selector)}'`);
156
263
  }
264
+
157
265
  return ret.selector;
158
- } finally {
159
- if (this._conditionInducerService) {
160
- this._conditionInducerService.close();
161
- this._conditionInducerService = null;
266
+ }
267
+
268
+ async disable(): Promise<boolean> {
269
+ if (!this.service) {
270
+ this.log.warn('Condition inducer server has not started');
271
+ return false;
272
+ }
273
+
274
+ try {
275
+ const ret = await this.service.callChannel(
276
+ INSTRUMENT_CHANNEL.CONDITION_INDUCER,
277
+ 'disableActiveCondition',
278
+ );
279
+ if (!_.isBoolean(ret.selector)) {
280
+ this.log.warn(`Disable condition inducer error: '${JSON.stringify(ret.selector)}'`);
281
+ return false;
282
+ }
283
+ return ret.selector;
284
+ } finally {
285
+ if (this.service) {
286
+ this.service.close();
287
+ this.service = null;
288
+ }
162
289
  }
163
290
  }
164
- }
165
291
 
166
- async function startRemoteXPC(udid: string): Promise<DVTServiceWithConnection> {
167
- const {Services} = await import('appium-ios-remotexpc');
168
- return Services.startDVTService(udid);
169
- }
292
+ async close(): Promise<void> {
293
+ if (this.service) {
294
+ this.service.close();
295
+ this.service = null;
296
+ }
297
+ }
170
298
 
171
- async function closeRemoteXPC(this: XCUITestDriver): Promise<void> {
172
- if (this._remoteXPCConditionInducerConnection) {
173
- await this._remoteXPCConditionInducerConnection.remoteXPC.close();
174
- this._remoteXPCConditionInducerConnection = null;
299
+ isActive(): boolean {
300
+ return this.service !== null && !this.service._socketClient.destroyed;
175
301
  }
176
302
  }
177
303
 
304
+ /**
305
+ * Factory function to create the appropriate condition inducer implementation
306
+ * based on the iOS version
307
+ */
308
+ async function createConditionInducer(
309
+ driver: XCUITestDriver,
310
+ ): Promise<IConditionInducer> {
311
+ if (!isIos18OrNewer(driver.opts)) {
312
+ return new InstrumentConditionInducer(driver.device.udid, driver.log);
313
+ }
314
+
315
+ const xpcInducer = new RemoteXPCConditionInducer(driver.device.udid, driver.log);
316
+ try {
317
+ const connection = await xpcInducer.startConnection();
318
+ await connection.remoteXPC.close();
319
+ } catch (err: any) {
320
+ driver.log.warn(
321
+ `Unable to use RemoteXPC-based condition inducer for device ${driver.device.udid}, ` +
322
+ `falling back to the legacy implementation: ${err.message}`
323
+ );
324
+ return new InstrumentConditionInducer(driver.device.udid, driver.log);
325
+ }
326
+ return xpcInducer;
327
+ }
178
328
 
@@ -564,6 +564,33 @@ export class RealDevice {
564
564
  return true;
565
565
  }
566
566
 
567
+ /**
568
+ * @param bundleName The name of CFBundleName in Info.plist
569
+ *
570
+ * @returns A list of User level apps' bundle ids which has
571
+ * 'CFBundleName' attribute as 'bundleName'.
572
+ */
573
+ async getUserInstalledBundleIdsByBundleName(bundleName: string): Promise<string[]> {
574
+ const service = await services.startInstallationProxyService(this.udid);
575
+ try {
576
+ const applications = await service.listApplications({
577
+ applicationType: 'User', returnAttributes: ['CFBundleIdentifier', 'CFBundleName']
578
+ });
579
+ return _.reduce(
580
+ applications,
581
+ (acc: string[], {CFBundleName}, key: string) => {
582
+ if (CFBundleName === bundleName) {
583
+ acc.push(key);
584
+ }
585
+ return acc;
586
+ },
587
+ [],
588
+ );
589
+ } finally {
590
+ service.close();
591
+ }
592
+ }
593
+
567
594
  async getPlatformVersion(): Promise<string> {
568
595
  return await utilities.getOSVersion(this.udid);
569
596
  }
@@ -0,0 +1,88 @@
1
+ import {node} from 'appium/support';
2
+ import path from 'node:path';
3
+ import {readFileSync} from 'node:fs';
4
+ import type {Services} from 'appium-ios-remotexpc';
5
+
6
+ /**
7
+ * Cached RemoteXPC Services module
8
+ */
9
+ let cachedRemoteXPCServices: typeof Services | null = null;
10
+
11
+ /**
12
+ * Module root and version cached at initialization
13
+ */
14
+ const {moduleRoot, remoteXpcVersion} = fetchInstallInfo();
15
+
16
+ /**
17
+ * Get the RemoteXPC Services module dynamically
18
+ *
19
+ * This helper centralizes the import of appium-ios-remotexpc to:
20
+ * - Provide consistent error handling across all services
21
+ * - Give helpful installation instructions when the module is missing
22
+ *
23
+ * @returns The Services export from appium-ios-remotexpc
24
+ * @throws {Error} If the module cannot be imported
25
+ */
26
+ export async function getRemoteXPCServices(): Promise<typeof Services> {
27
+ if (cachedRemoteXPCServices) {
28
+ return cachedRemoteXPCServices;
29
+ }
30
+
31
+ try {
32
+ const remotexpcModule = await import('appium-ios-remotexpc');
33
+ cachedRemoteXPCServices = remotexpcModule.Services;
34
+ return cachedRemoteXPCServices;
35
+ } catch (err) {
36
+ const error = err as Error;
37
+
38
+ if (error.message.includes('Cannot find module')) {
39
+ let errorMessage =
40
+ 'Failed to import appium-ios-remotexpc module. ' +
41
+ 'This module is required for iOS 18 and above device operations.';
42
+
43
+ if (moduleRoot && remoteXpcVersion) {
44
+ errorMessage +=
45
+ ' Please install it by running: ' +
46
+ `cd "${moduleRoot}" && npm install "appium-ios-remotexpc@${remoteXpcVersion}".`;
47
+ }
48
+
49
+ errorMessage += ` Original error: ${error.message}`;
50
+ throw new Error(errorMessage);
51
+ }
52
+
53
+ throw new Error(
54
+ 'Failed to import appium-ios-remotexpc module. ' +
55
+ 'This module is required for iOS 18 and above device operations. ' +
56
+ `Original error: ${error.message}`
57
+ );
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Fetch module root and appium-ios-remotexpc version from package.json
63
+ *
64
+ * @returns Object containing moduleRoot and remoteXpcVersion
65
+ */
66
+ function fetchInstallInfo(): {
67
+ moduleRoot: string | undefined;
68
+ remoteXpcVersion: string | undefined;
69
+ } {
70
+ try {
71
+ const root = node.getModuleRootSync('appium-xcuitest-driver', __filename);
72
+ if (root) {
73
+ const packageJsonPath = path.join(root, 'package.json');
74
+ const packageJsonContent = readFileSync(packageJsonPath, 'utf8');
75
+ if (packageJsonContent) {
76
+ const packageJson = JSON.parse(packageJsonContent);
77
+ return {
78
+ moduleRoot: root,
79
+ remoteXpcVersion: packageJson.optionalDependencies?.['appium-ios-remotexpc'],
80
+ };
81
+ }
82
+ }
83
+ } catch {
84
+ // Error messages will skip install hints
85
+ }
86
+
87
+ return {moduleRoot: undefined, remoteXpcVersion: undefined};
88
+ }
package/lib/driver.ts CHANGED
@@ -39,6 +39,7 @@ import * as biometricCommands from './commands/biometric';
39
39
  import * as certificateCommands from './commands/certificate';
40
40
  import * as clipboardCommands from './commands/clipboard';
41
41
  import * as conditionCommands from './commands/condition';
42
+ import type {IConditionInducer} from './commands/condition';
42
43
  import * as contentSizeCommands from './commands/content-size';
43
44
  import * as contextCommands from './commands/context';
44
45
  import * as deviceInfoCommands from './commands/device-info';
@@ -121,7 +122,6 @@ import type { PerfRecorder } from './commands/performance';
121
122
  import type { AudioRecorder } from './commands/record-audio';
122
123
  import type { TrafficCapture } from './commands/pcap';
123
124
  import type { ScreenRecorder } from './commands/recordscreen';
124
- import type { DVTServiceWithConnection } from 'appium-ios-remotexpc';
125
125
  import type { IOSDeviceLog } from './device/log/ios-device-log';
126
126
  import type { IOSSimulatorLog } from './device/log/ios-simulator-log';
127
127
  import type { IOSCrashLog } from './device/log/ios-crash-log';
@@ -262,8 +262,7 @@ export class XCUITestDriver
262
262
  _perfRecorders: PerfRecorder[];
263
263
  webElementsCache: LRUCache<any, any>;
264
264
 
265
- _conditionInducerService: any | null; // needs types
266
- _remoteXPCConditionInducerConnection: DVTServiceWithConnection | null; // RemoteXPC DVT connection for iOS>=18 condition inducer
265
+ _conditionInducer: IConditionInducer | null; // Condition inducer facade that abstracts implementation details
267
266
  _isSafariIphone: boolean | undefined;
268
267
  _isSafariNotched: boolean | undefined;
269
268
  _waitingAtoms: WaitingAtoms;
@@ -429,7 +428,7 @@ export class XCUITestDriver
429
428
  this._perfRecorders = [];
430
429
  }
431
430
 
432
- if (this._conditionInducerService || this._remoteXPCConditionInducerConnection) {
431
+ if (this._conditionInducer) {
433
432
  try {
434
433
  await this.disableConditionInducer();
435
434
  } catch (err) {
@@ -1743,8 +1742,7 @@ export class XCUITestDriver
1743
1742
  this.pageLoadMs = 6000;
1744
1743
  this.landscapeWebCoordsOffset = 0;
1745
1744
  this._remote = null;
1746
- this._conditionInducerService = null;
1747
- this._remoteXPCConditionInducerConnection = null;
1745
+ this._conditionInducer = null;
1748
1746
 
1749
1747
  this.webElementsCache = new LRUCache({
1750
1748
  max: WEB_ELEMENTS_CACHE_SIZE,
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "appium-xcuitest-driver",
3
- "version": "10.14.10",
3
+ "version": "10.14.12",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "appium-xcuitest-driver",
9
- "version": "10.14.10",
9
+ "version": "10.14.12",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@appium/strongbox": "^1.0.0-rc.1",
@@ -321,12 +321,12 @@
321
321
  }
322
322
  },
323
323
  "node_modules/@babel/code-frame": {
324
- "version": "7.27.1",
325
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
326
- "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
324
+ "version": "7.28.6",
325
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz",
326
+ "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==",
327
327
  "license": "MIT",
328
328
  "dependencies": {
329
- "@babel/helper-validator-identifier": "^7.27.1",
329
+ "@babel/helper-validator-identifier": "^7.28.5",
330
330
  "js-tokens": "^4.0.0",
331
331
  "picocolors": "^1.1.1"
332
332
  },
@@ -692,9 +692,9 @@
692
692
  }
693
693
  },
694
694
  "node_modules/appium-ios-remotexpc": {
695
- "version": "0.25.0",
696
- "resolved": "https://registry.npmjs.org/appium-ios-remotexpc/-/appium-ios-remotexpc-0.25.0.tgz",
697
- "integrity": "sha512-inc/mZc3Dz7mtBj/CWC+m3NlWB2a14aZ4Ug6onM/7vI80N3YRsOyaSfYk1HCLwacstvDJhjEoA6bqi5LMtVwYA==",
695
+ "version": "0.25.1",
696
+ "resolved": "https://registry.npmjs.org/appium-ios-remotexpc/-/appium-ios-remotexpc-0.25.1.tgz",
697
+ "integrity": "sha512-wlCe1593QZYC72LOyyrdawKu4ZXhuDnOLyLiexmtKcbtG8liyHMq7o6QWsEUsQKZSW3O2gke3lR2Ooln89UmDQ==",
698
698
  "license": "Apache-2.0",
699
699
  "optional": true,
700
700
  "dependencies": {
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "xcuitest",
9
9
  "xctest"
10
10
  ],
11
- "version": "10.14.10",
11
+ "version": "10.14.12",
12
12
  "author": "Appium Contributors",
13
13
  "license": "Apache-2.0",
14
14
  "repository": {
@@ -31,7 +31,7 @@
31
31
  ],
32
32
  "mainClass": "XCUITestDriver",
33
33
  "scripts": {
34
- "build-wda": "./scripts/build-wda.js",
34
+ "build-wda": "./scripts/build-wda.mjs",
35
35
  "open-wda": "./scripts/open-wda.mjs",
36
36
  "tunnel-creation": "./scripts/tunnel-creation.mjs",
37
37
  "download-wda-sim": "./scripts/download-wda-sim.mjs",
@@ -1,15 +1,14 @@
1
- const {WebDriverAgent} = require('appium-webdriveragent');
2
- const xcode = require('appium-xcode');
3
- const {Simctl} = require('node-simctl');
4
- const {getSimulator} = require('appium-ios-simulator');
5
- const {logger} = require('appium/support');
6
- const {parseArgValue} = require('./utils');
1
+ import {WebDriverAgent} from 'appium-webdriveragent';
2
+ import * as xcode from 'appium-xcode';
3
+ import {Simctl} from 'node-simctl';
4
+ import {getSimulator} from 'appium-ios-simulator';
5
+ import {logger} from 'appium/support.js';
6
+ import {parseArgValue} from './utils.js';
7
7
 
8
8
  const log = logger.getLogger('WDA');
9
9
 
10
10
  async function build() {
11
11
  const customDevice = parseArgValue('name');
12
- const xcodeVersion = await xcode.getVersion(true);
13
12
  const platformVersion = parseArgValue('sdk') || (await xcode.getMaxIOSSDK());
14
13
  const iosDevices = await new Simctl().getDevices(platformVersion, 'iOS');
15
14
  const verifyDevicePresence = (info) => {
@@ -27,7 +26,7 @@ async function build() {
27
26
  platform: deviceInfo.platform,
28
27
  checkExistence: false,
29
28
  });
30
- const wda = new WebDriverAgent(xcodeVersion, {
29
+ const wda = new WebDriverAgent({
31
30
  iosSdkVersion: platformVersion,
32
31
  platformVersion,
33
32
  showXcodeLog: true,