appium-xcuitest-driver 7.6.1 → 7.7.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.
Files changed (126) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/build/lib/commands/app-management.d.ts.map +1 -1
  3. package/build/lib/commands/app-management.js +9 -17
  4. package/build/lib/commands/app-management.js.map +1 -1
  5. package/build/lib/commands/appearance.d.ts.map +1 -1
  6. package/build/lib/commands/appearance.js +2 -4
  7. package/build/lib/commands/appearance.js.map +1 -1
  8. package/build/lib/commands/biometric.d.ts.map +1 -1
  9. package/build/lib/commands/biometric.js +3 -6
  10. package/build/lib/commands/biometric.js.map +1 -1
  11. package/build/lib/commands/certificate.d.ts +1 -1
  12. package/build/lib/commands/certificate.d.ts.map +1 -1
  13. package/build/lib/commands/certificate.js +3 -5
  14. package/build/lib/commands/certificate.js.map +1 -1
  15. package/build/lib/commands/condition.d.ts.map +1 -1
  16. package/build/lib/commands/condition.js +2 -4
  17. package/build/lib/commands/condition.js.map +1 -1
  18. package/build/lib/commands/context.d.ts.map +1 -1
  19. package/build/lib/commands/context.js +1 -2
  20. package/build/lib/commands/context.js.map +1 -1
  21. package/build/lib/commands/deviceInfo.d.ts.map +1 -1
  22. package/build/lib/commands/deviceInfo.js +1 -2
  23. package/build/lib/commands/deviceInfo.js.map +1 -1
  24. package/build/lib/commands/file-movement.d.ts.map +1 -1
  25. package/build/lib/commands/file-movement.js +14 -22
  26. package/build/lib/commands/file-movement.js.map +1 -1
  27. package/build/lib/commands/general.d.ts.map +1 -1
  28. package/build/lib/commands/general.js +1 -2
  29. package/build/lib/commands/general.js.map +1 -1
  30. package/build/lib/commands/gesture.d.ts.map +1 -1
  31. package/build/lib/commands/gesture.js +1 -2
  32. package/build/lib/commands/gesture.js.map +1 -1
  33. package/build/lib/commands/keychains.js +1 -2
  34. package/build/lib/commands/keychains.js.map +1 -1
  35. package/build/lib/commands/localization.d.ts.map +1 -1
  36. package/build/lib/commands/localization.js +1 -3
  37. package/build/lib/commands/localization.js.map +1 -1
  38. package/build/lib/commands/location.d.ts.map +1 -1
  39. package/build/lib/commands/location.js +1 -2
  40. package/build/lib/commands/location.js.map +1 -1
  41. package/build/lib/commands/log.d.ts.map +1 -1
  42. package/build/lib/commands/log.js +2 -4
  43. package/build/lib/commands/log.js.map +1 -1
  44. package/build/lib/commands/memory.d.ts.map +1 -1
  45. package/build/lib/commands/memory.js +2 -2
  46. package/build/lib/commands/memory.js.map +1 -1
  47. package/build/lib/commands/notifications.d.ts +1 -1
  48. package/build/lib/commands/notifications.d.ts.map +1 -1
  49. package/build/lib/commands/notifications.js +1 -2
  50. package/build/lib/commands/notifications.js.map +1 -1
  51. package/build/lib/commands/pasteboard.d.ts.map +1 -1
  52. package/build/lib/commands/pasteboard.js +2 -4
  53. package/build/lib/commands/pasteboard.js.map +1 -1
  54. package/build/lib/commands/pcap.d.ts.map +1 -1
  55. package/build/lib/commands/pcap.js +1 -2
  56. package/build/lib/commands/pcap.js.map +1 -1
  57. package/build/lib/commands/performance.d.ts.map +1 -1
  58. package/build/lib/commands/performance.js +4 -9
  59. package/build/lib/commands/performance.js.map +1 -1
  60. package/build/lib/commands/permissions.d.ts.map +1 -1
  61. package/build/lib/commands/permissions.js +2 -4
  62. package/build/lib/commands/permissions.js.map +1 -1
  63. package/build/lib/commands/recordscreen.d.ts.map +1 -1
  64. package/build/lib/commands/recordscreen.js +1 -2
  65. package/build/lib/commands/recordscreen.js.map +1 -1
  66. package/build/lib/commands/screenshots.d.ts +3 -2
  67. package/build/lib/commands/screenshots.d.ts.map +1 -1
  68. package/build/lib/commands/screenshots.js +8 -3
  69. package/build/lib/commands/screenshots.js.map +1 -1
  70. package/build/lib/commands/web.d.ts.map +1 -1
  71. package/build/lib/commands/web.js +1 -2
  72. package/build/lib/commands/web.js.map +1 -1
  73. package/build/lib/commands/xctest-record-screen.d.ts.map +1 -1
  74. package/build/lib/commands/xctest-record-screen.js +2 -4
  75. package/build/lib/commands/xctest-record-screen.js.map +1 -1
  76. package/build/lib/commands/xctest.d.ts.map +1 -1
  77. package/build/lib/commands/xctest.js +2 -4
  78. package/build/lib/commands/xctest.js.map +1 -1
  79. package/build/lib/driver.d.ts +26 -8
  80. package/build/lib/driver.d.ts.map +1 -1
  81. package/build/lib/driver.js +75 -77
  82. package/build/lib/driver.js.map +1 -1
  83. package/build/lib/py-ios-device-client.d.ts +1 -1
  84. package/build/lib/real-device-management.d.ts +30 -27
  85. package/build/lib/real-device-management.d.ts.map +1 -1
  86. package/build/lib/real-device-management.js +34 -35
  87. package/build/lib/real-device-management.js.map +1 -1
  88. package/build/lib/real-device.d.ts +36 -9
  89. package/build/lib/real-device.d.ts.map +1 -1
  90. package/build/lib/real-device.js +46 -15
  91. package/build/lib/real-device.js.map +1 -1
  92. package/build/lib/simulator-management.d.ts +58 -68
  93. package/build/lib/simulator-management.d.ts.map +1 -1
  94. package/build/lib/simulator-management.js +74 -66
  95. package/build/lib/simulator-management.js.map +1 -1
  96. package/lib/commands/app-management.js +11 -18
  97. package/lib/commands/appearance.js +4 -4
  98. package/lib/commands/biometric.js +3 -6
  99. package/lib/commands/certificate.js +3 -5
  100. package/lib/commands/condition.js +2 -4
  101. package/lib/commands/context.js +1 -2
  102. package/lib/commands/deviceInfo.js +1 -2
  103. package/lib/commands/file-movement.js +14 -22
  104. package/lib/commands/general.js +1 -2
  105. package/lib/commands/gesture.js +1 -2
  106. package/lib/commands/keychains.js +2 -2
  107. package/lib/commands/localization.js +1 -4
  108. package/lib/commands/location.js +1 -2
  109. package/lib/commands/log.js +2 -4
  110. package/lib/commands/memory.js +2 -2
  111. package/lib/commands/notifications.js +1 -2
  112. package/lib/commands/pasteboard.js +4 -4
  113. package/lib/commands/pcap.js +1 -2
  114. package/lib/commands/performance.js +4 -8
  115. package/lib/commands/permissions.js +6 -4
  116. package/lib/commands/recordscreen.js +1 -2
  117. package/lib/commands/screenshots.js +8 -3
  118. package/lib/commands/web.js +1 -2
  119. package/lib/commands/xctest-record-screen.js +2 -4
  120. package/lib/commands/xctest.js +2 -4
  121. package/lib/driver.js +79 -78
  122. package/lib/real-device-management.js +37 -44
  123. package/lib/real-device.js +47 -17
  124. package/lib/simulator-management.js +83 -82
  125. package/npm-shrinkwrap.json +7 -29
  126. package/package.json +2 -2
package/lib/driver.js CHANGED
@@ -384,6 +384,14 @@ class XCUITestDriver extends BaseDriver {
384
384
  return didMerge;
385
385
  }
386
386
 
387
+ /**
388
+ * @returns {Simulator|RealDevice}
389
+ */
390
+ get device() {
391
+ // @ts-ignore This property should exist
392
+ return this.opts?.device;
393
+ }
394
+
387
395
  isXcodebuildNeeded() {
388
396
  return !(CAP_NAMES_NO_XCODEBUILD_REQUIRED.some((x) => Boolean(this.opts[x])));
389
397
  }
@@ -484,6 +492,7 @@ class XCUITestDriver extends BaseDriver {
484
492
  this.log.info(
485
493
  `Determining device to run tests on: udid: '${udid}', real device: ${realDevice}`,
486
494
  );
495
+ // TODO: extract device out of opts to a separate driver property
487
496
  // @ts-expect-error - do not assign arbitrary properties to `this.opts`
488
497
  this.opts.device = device;
489
498
  this.opts.udid = udid;
@@ -499,22 +508,18 @@ class XCUITestDriver extends BaseDriver {
499
508
  this.log.info(
500
509
  `Setting simulator devices set path to '${this.opts.simulatorDevicesSetPath}'`,
501
510
  );
502
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
503
- this.opts.device.devicesSetPath = this.opts.simulatorDevicesSetPath;
511
+ (/** @type {Simulator} */ (this.device)).devicesSetPath = this.opts.simulatorDevicesSetPath;
504
512
  }
505
513
  }
506
514
 
507
515
  // at this point if there is no platformVersion, get it from the device
508
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
509
- if (!this.opts.platformVersion && this.opts.device) {
510
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
511
- this.opts.platformVersion = await this.opts.device.getPlatformVersion();
516
+ if (!this.opts.platformVersion) {
517
+ this.opts.platformVersion = await this.device.getPlatformVersion();
512
518
  this.log.info(
513
519
  `No platformVersion specified. Using device version: '${this.opts.platformVersion}'`,
514
520
  );
515
521
  }
516
522
 
517
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
518
523
  const normalizedVersion = normalizePlatformVersion(this.opts.platformVersion);
519
524
  if (this.opts.platformVersion !== normalizedVersion) {
520
525
  this.log.info(
@@ -604,8 +609,7 @@ class XCUITestDriver extends BaseDriver {
604
609
  !this.opts.app &&
605
610
  this.opts.bundleId &&
606
611
  !this.isSafari() &&
607
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
608
- !(await this.opts.device.isAppInstalled(this.opts.bundleId))
612
+ !(await this.device.isAppInstalled(this.opts.bundleId))
609
613
  ) {
610
614
  this.log.errorAndThrow(`App with bundle identifier '${this.opts.bundleId}' unknown`);
611
615
  }
@@ -614,8 +618,7 @@ class XCUITestDriver extends BaseDriver {
614
618
  if (this.opts.permissions) {
615
619
  this.log.debug('Setting the requested permissions before WDA is started');
616
620
  for (const [bundleId, permissionsMapping] of _.toPairs(JSON.parse(this.opts.permissions))) {
617
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
618
- await this.opts.device.setPermissions(bundleId, permissionsMapping);
621
+ await /** @type {Simulator} */ (this.device).setPermissions(bundleId, permissionsMapping);
619
622
  }
620
623
  }
621
624
 
@@ -628,15 +631,14 @@ class XCUITestDriver extends BaseDriver {
628
631
  const methodName = `${
629
632
  this.opts.calendarAccessAuthorized ? 'enable' : 'disable'
630
633
  }CalendarAccess`;
631
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
632
- await this.opts.device[methodName](this.opts.bundleId);
634
+ await this.device[methodName](this.opts.bundleId);
633
635
  }
634
636
  }
635
637
 
636
638
  // @ts-expect-error - do not assign arbitrary properties to `this.opts`
637
639
  await this.startWda(this.opts.sessionId);
638
640
 
639
- if (this.opts.orientation) {
641
+ if (_.isString(this.opts.orientation)) {
640
642
  await this.setInitialOrientation(this.opts.orientation);
641
643
  this.logEvent('orientationSet');
642
644
  }
@@ -663,12 +665,11 @@ class XCUITestDriver extends BaseDriver {
663
665
  * Start the simulator and initialize based on capabilities
664
666
  */
665
667
  async initSimulator() {
666
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
667
- const device = this.opts.device;
668
+ const device = /** @type {Simulator} */ (this.device);
668
669
 
669
670
  if (this.opts.shutdownOtherSimulators) {
670
671
  this.assertFeatureEnabled(SHUTDOWN_OTHER_FEAT_NAME);
671
- await shutdownOtherSimulators(device);
672
+ await shutdownOtherSimulators.bind(this)();
672
673
  }
673
674
 
674
675
  await this.startSim();
@@ -679,17 +680,21 @@ class XCUITestDriver extends BaseDriver {
679
680
  this.logEvent('customCertInstalled');
680
681
  }
681
682
 
682
- if (await setSafariPrefs(device, this.opts)) {
683
+ if (await setSafariPrefs.bind(this)()) {
683
684
  this.log.debug('Safari preferences have been updated');
684
685
  }
685
686
 
686
- if (await setLocalizationPrefs(device, this.opts)) {
687
+ if (await setLocalizationPrefs.bind(this)()) {
687
688
  this.log.debug('Localization preferences have been updated');
688
689
  }
689
690
 
691
+ /** @type {Promise[]} */
690
692
  const promises = ['reduceMotion', 'reduceTransparency', 'autoFillPasswords']
691
693
  .filter((optName) => _.isBoolean(this.opts[optName]))
692
- .map((optName) => device[`set${_.upperFirst(optName)}`](this.opts[optName]));
694
+ .map((optName) => {
695
+ this.log.info(`Setting ${optName} to ${this.opts[optName]}`);
696
+ return device[`set${_.upperFirst(optName)}`](this.opts[optName]);
697
+ });
693
698
  await B.all(promises);
694
699
 
695
700
  if (this.opts.launchWithIDB) {
@@ -886,16 +891,14 @@ class XCUITestDriver extends BaseDriver {
886
891
 
887
892
  /**
888
893
  *
889
- * @param {XCUITestDriverOpts} [opts]
894
+ * @param {boolean} [enforceSimulatorShutdown=false]
890
895
  */
891
- async runReset(opts) {
896
+ async runReset(enforceSimulatorShutdown = false) {
892
897
  this.logEvent('resetStarted');
893
898
  if (this.isRealDevice()) {
894
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
895
- await runRealDeviceReset(this.opts.device, opts || this.opts);
899
+ await runRealDeviceReset.bind(this)();
896
900
  } else {
897
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
898
- await runSimulatorReset(this.opts.device, opts || this.opts);
901
+ await runSimulatorReset.bind(this)(enforceSimulatorShutdown);
899
902
  }
900
903
  this.logEvent('resetComplete');
901
904
  }
@@ -944,18 +947,13 @@ class XCUITestDriver extends BaseDriver {
944
947
  }
945
948
 
946
949
  if (this.opts.resetOnSessionStartOnly === false) {
947
- await this.runReset(
948
- Object.assign({}, this.opts, {
949
- enforceSimulatorShutdown: true,
950
- }),
951
- );
950
+ await this.runReset(true);
952
951
  }
953
952
 
954
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
955
- const simulatorDevice = this.isSimulator() ? this.opts.device : null;
953
+ const simulatorDevice = this.isSimulator() ? /** @type {Simulator} */ (this.device) : null;
956
954
  if (simulatorDevice && this.lifecycleData.createSim) {
957
955
  this.log.debug(`Deleting simulator created for this run (udid: '${simulatorDevice.udid}')`);
958
- await shutdownSimulator(simulatorDevice);
956
+ await shutdownSimulator.bind(this)();
959
957
  await simulatorDevice.delete();
960
958
  }
961
959
 
@@ -1168,19 +1166,16 @@ class XCUITestDriver extends BaseDriver {
1168
1166
  this.opts.deviceName = translateDeviceName(this.opts.platformVersion, this.opts.deviceName);
1169
1167
 
1170
1168
  const setupVersionCaps = async () => {
1169
+ const iosSdkVersion = await getAndCheckIosSdkVersion();
1171
1170
  // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1172
- this.opts.iosSdkVersion = await getAndCheckIosSdkVersion();
1173
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1174
- this.log.info(`iOS SDK Version set to '${this.opts.iosSdkVersion}'`);
1175
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1176
- if (!this.opts.platformVersion && this.opts.iosSdkVersion) {
1171
+ this.opts.iosSdkVersion = iosSdkVersion;
1172
+ this.log.info(`iOS SDK Version set to '${iosSdkVersion}'`);
1173
+ if (!this.opts.platformVersion && iosSdkVersion) {
1177
1174
  this.log.info(
1178
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1179
- `No platformVersion specified. Using the latest version Xcode supports: '${this.opts.iosSdkVersion}'. ` +
1175
+ `No platformVersion specified. Using the latest version Xcode supports: '${iosSdkVersion}'. ` +
1180
1176
  `This may cause problems if a simulator does not exist for this platform version.`,
1181
1177
  );
1182
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1183
- this.opts.platformVersion = normalizePlatformVersion(this.opts.iosSdkVersion);
1178
+ this.opts.platformVersion = normalizePlatformVersion(iosSdkVersion);
1184
1179
  }
1185
1180
  };
1186
1181
 
@@ -1195,11 +1190,10 @@ class XCUITestDriver extends BaseDriver {
1195
1190
  );
1196
1191
  await setupVersionCaps();
1197
1192
 
1198
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1199
- const device = await getExistingSim(this.opts);
1193
+ const device = await getExistingSim.bind(this)();
1200
1194
  if (!device) {
1201
1195
  // No matching Simulator is found. Throw an error
1202
- this.log.errorAndThrow(
1196
+ throw this.log.errorWithException(
1203
1197
  `Cannot detect udid for ${this.opts.deviceName} Simulator running iOS ${this.opts.platformVersion}`,
1204
1198
  );
1205
1199
  }
@@ -1221,6 +1215,7 @@ class XCUITestDriver extends BaseDriver {
1221
1215
  try {
1222
1216
  const device = await getSimulator(this.opts.udid, {
1223
1217
  devicesSetPath: this.opts.simulatorDevicesSetPath,
1218
+ logger: this.log,
1224
1219
  });
1225
1220
  return {device, realDevice: false, udid: this.opts.udid};
1226
1221
  } catch (ign) {
@@ -1230,7 +1225,7 @@ class XCUITestDriver extends BaseDriver {
1230
1225
  }
1231
1226
  }
1232
1227
 
1233
- const device = getRealDeviceObj(this.opts.udid, this.log);
1228
+ const device = getRealDeviceObj.bind(this)();
1234
1229
  return {device, realDevice: true, udid: this.opts.udid};
1235
1230
  }
1236
1231
 
@@ -1245,8 +1240,7 @@ class XCUITestDriver extends BaseDriver {
1245
1240
  );
1246
1241
  } else {
1247
1242
  // figure out the correct simulator to use, given the desired capabilities
1248
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1249
- const device = await getExistingSim(this.opts);
1243
+ const device = await getExistingSim.bind(this)();
1250
1244
  // check for an existing simulator
1251
1245
  if (device) {
1252
1246
  return {device, realDevice: false, udid: device.udid};
@@ -1260,20 +1254,21 @@ class XCUITestDriver extends BaseDriver {
1260
1254
  }
1261
1255
 
1262
1256
  async startSim() {
1257
+ /** @type {import('appium-ios-simulator').DevicePreferences} */
1258
+ const devicePreferences = {};
1259
+ /** @type {import('appium-ios-simulator').RunOptions} */
1263
1260
  const runOpts = {
1264
1261
  scaleFactor: this.opts.scaleFactor,
1265
1262
  connectHardwareKeyboard: !!this.opts.connectHardwareKeyboard,
1266
1263
  pasteboardAutomaticSync: this.opts.simulatorPasteboardAutomaticSync ?? 'off',
1267
1264
  isHeadless: !!this.opts.isHeadless,
1268
1265
  tracePointer: this.opts.simulatorTracePointer,
1269
- devicePreferences: {},
1266
+ devicePreferences,
1270
1267
  };
1271
1268
 
1272
1269
  // add the window center, if it is specified
1273
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1274
- if (this.opts.SimulatorWindowCenter) {
1275
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1276
- runOpts.devicePreferences.SimulatorWindowCenter = this.opts.SimulatorWindowCenter;
1270
+ if (this.opts.simulatorWindowCenter) {
1271
+ devicePreferences.SimulatorWindowCenter = this.opts.simulatorWindowCenter;
1277
1272
  }
1278
1273
 
1279
1274
  if (_.isInteger(this.opts.simulatorStartupTimeout)) {
@@ -1285,23 +1280,22 @@ class XCUITestDriver extends BaseDriver {
1285
1280
  const orientation = _.isString(this.opts.orientation) && this.opts.orientation.toUpperCase();
1286
1281
  switch (orientation) {
1287
1282
  case 'LANDSCAPE':
1288
- runOpts.devicePreferences.SimulatorWindowOrientation = 'LandscapeLeft';
1289
- runOpts.devicePreferences.SimulatorWindowRotationAngle = 90;
1283
+ devicePreferences.SimulatorWindowOrientation = 'LandscapeLeft';
1284
+ devicePreferences.SimulatorWindowRotationAngle = 90;
1290
1285
  break;
1291
1286
  case 'PORTRAIT':
1292
- runOpts.devicePreferences.SimulatorWindowOrientation = 'Portrait';
1293
- runOpts.devicePreferences.SimulatorWindowRotationAngle = 0;
1287
+ devicePreferences.SimulatorWindowOrientation = 'Portrait';
1288
+ devicePreferences.SimulatorWindowRotationAngle = 0;
1294
1289
  break;
1295
1290
  }
1296
1291
 
1297
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1298
- await this.opts.device.run(runOpts);
1292
+ await /** @type {Simulator} */ (this.device).run(runOpts);
1299
1293
  }
1300
1294
 
1301
1295
  async createSim() {
1302
1296
  this.lifecycleData.createSim = true;
1303
1297
  // create sim for caps
1304
- const sim = await createSim(this.opts);
1298
+ const sim = await createSim.bind(this)();
1305
1299
  this.log.info(`Created simulator with udid '${sim.udid}'.`);
1306
1300
  return sim;
1307
1301
  }
@@ -1670,15 +1664,13 @@ class XCUITestDriver extends BaseDriver {
1670
1664
  const {install, skipUninstall} = await this.checkAutInstallationState();
1671
1665
  if (install) {
1672
1666
  if (this.isRealDevice()) {
1673
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1674
- await installToRealDevice(this.opts.device, this.opts.app, this.opts.bundleId, {
1667
+ await installToRealDevice.bind(this)(this.opts.app, this.opts.bundleId, {
1675
1668
  skipUninstall,
1676
1669
  timeout: this.opts.appPushTimeout,
1677
1670
  strategy: this.opts.appInstallStrategy,
1678
1671
  });
1679
1672
  } else {
1680
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1681
- await installToSimulator(this.opts.device, this.opts.app, this.opts.bundleId, {
1673
+ await installToSimulator.bind(this)(this.opts.app, this.opts.bundleId, {
1682
1674
  skipUninstall,
1683
1675
  newSimulator: this.lifecycleData?.createSim,
1684
1676
  });
@@ -1693,6 +1685,10 @@ class XCUITestDriver extends BaseDriver {
1693
1685
  }
1694
1686
  }
1695
1687
 
1688
+ /**
1689
+ * @param {string|string[]} otherApps
1690
+ * @returns {Promise<void>}
1691
+ */
1696
1692
  async installOtherApps(otherApps) {
1697
1693
  /** @type {string[]|undefined} */
1698
1694
  let appsList;
@@ -1712,9 +1708,7 @@ class XCUITestDriver extends BaseDriver {
1712
1708
  const appIds = await B.all(appPaths.map((appPath) => extractBundleId(appPath)));
1713
1709
  for (const [appId, appPath] of _.zip(appIds, appPaths)) {
1714
1710
  if (this.isRealDevice()) {
1715
- await installToRealDevice(
1716
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1717
- this.opts.device,
1711
+ await installToRealDevice.bind(this)(
1718
1712
  appPath,
1719
1713
  appId,
1720
1714
  {
@@ -1724,10 +1718,7 @@ class XCUITestDriver extends BaseDriver {
1724
1718
  },
1725
1719
  );
1726
1720
  } else {
1727
- await installToSimulator(
1728
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1729
- this.opts.device,
1730
- // @ts-ignore the path should always be defined
1721
+ await installToSimulator.bind(this)(
1731
1722
  appPath,
1732
1723
  appId,
1733
1724
  {
@@ -1738,6 +1729,10 @@ class XCUITestDriver extends BaseDriver {
1738
1729
  }
1739
1730
  }
1740
1731
 
1732
+ /**
1733
+ * @param {string} orientation
1734
+ * @returns {Promise<void>}
1735
+ */
1741
1736
  async setInitialOrientation(orientation) {
1742
1737
  const dstOrientation = _.toUpper(orientation);
1743
1738
  if (!SUPPORTED_ORIENATIONS.includes(dstOrientation)) {
@@ -1756,6 +1751,10 @@ class XCUITestDriver extends BaseDriver {
1756
1751
  }
1757
1752
  }
1758
1753
 
1754
+ /**
1755
+ * @param {string} [cmdName]
1756
+ * @returns {number|undefined}
1757
+ */
1759
1758
  _getCommandTimeout(cmdName) {
1760
1759
  if (this.opts.commandTimeouts) {
1761
1760
  if (cmdName && _.has(this.opts.commandTimeouts, cmdName)) {
@@ -1792,14 +1791,11 @@ class XCUITestDriver extends BaseDriver {
1792
1791
  `Installing prebuilt WDA at '${this.opts.prebuiltWDAPath}'. ` +
1793
1792
  `Bundle identifier: ${candidateBundleId}.`
1794
1793
  );
1795
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1796
- const device = this.opts.device;
1797
1794
 
1798
1795
  // Note: The CFBundleVersion in the test bundle was always 1.
1799
1796
  // It may not be able to compare with the installed versio.
1800
1797
  if (this.isRealDevice()) {
1801
- await installToRealDevice(
1802
- device,
1798
+ await installToRealDevice.bind(this)(
1803
1799
  this.opts.prebuiltWDAPath,
1804
1800
  candidateBundleId,
1805
1801
  {
@@ -1809,7 +1805,10 @@ class XCUITestDriver extends BaseDriver {
1809
1805
  },
1810
1806
  );
1811
1807
  } else {
1812
- await installToSimulator(device, this.opts.prebuiltWDAPath, candidateBundleId);
1808
+ await installToSimulator.bind(this)(
1809
+ this.opts.prebuiltWDAPath,
1810
+ candidateBundleId
1811
+ );
1813
1812
  }
1814
1813
  }
1815
1814
 
@@ -2266,4 +2265,6 @@ export {XCUITestDriver};
2266
2265
  * @typedef {import('./commands/types').FullContext} FullContext
2267
2266
  * @typedef {import('./types').WDACapabilities} WDACapabilities
2268
2267
  * @typedef {import('appium-xcode').XcodeVersion} XcodeVersion
2269
- */
2268
+ * @typedef {import('appium-ios-simulator').Simulator} Simulator
2269
+ * @typedef {import('./real-device').RealDevice} RealDevice
2270
+ */
@@ -1,9 +1,8 @@
1
1
  import {utilities} from 'appium-ios-device';
2
2
  import RealDevice from './real-device';
3
- import log from './logger';
4
3
  import {SAFARI_BUNDLE_ID} from './app-utils';
5
4
 
6
- async function getConnectedDevices() {
5
+ export async function getConnectedDevices() {
7
6
  return await utilities.getConnectedDevices();
8
7
  }
9
8
 
@@ -11,24 +10,25 @@ async function getConnectedDevices() {
11
10
  * @param {string} udid
12
11
  * @returns {Promise<string>}
13
12
  */
14
- async function getOSVersion(udid) {
13
+ export async function getOSVersion(udid) {
15
14
  return await utilities.getOSVersion(udid);
16
15
  }
17
16
 
18
17
  /**
19
- * @param {RealDevice} device
20
- * @param {import('./driver').XCUITestDriverOpts} opts
18
+ * @this {import('./driver').XCUITestDriver}
21
19
  * @returns {Promise<void>}
22
20
  */
23
- async function resetRealDevice(device, opts) {
24
- const {bundleId, fullReset} = opts;
21
+ export async function resetRealDevice() {
22
+ const {bundleId, fullReset} = this.opts;
25
23
  if (!bundleId) {
26
24
  return;
27
25
  }
28
26
 
27
+ const device = /** @type {RealDevice} */ (this.device);
28
+
29
29
  if (bundleId === SAFARI_BUNDLE_ID) {
30
- log.debug('Reset requested. About to terminate Safari');
31
- await device.terminateApp(bundleId, opts.platformVersion);
30
+ this.log.debug('Reset requested. About to terminate Safari');
31
+ await device.terminateApp(bundleId, String(this.opts.platformVersion));
32
32
  return;
33
33
  }
34
34
 
@@ -36,33 +36,33 @@ async function resetRealDevice(device, opts) {
36
36
  return;
37
37
  }
38
38
 
39
- log.debug(`Reset: fullReset requested. Will try to uninstall the app '${bundleId}'.`);
39
+ this.log.debug(`Reset: fullReset requested. Will try to uninstall the app '${bundleId}'.`);
40
40
  if (!(await device.isAppInstalled(bundleId))) {
41
- log.debug('Reset: app not installed. No need to uninstall');
41
+ this.log.debug('Reset: app not installed. No need to uninstall');
42
42
  return;
43
43
  }
44
+
44
45
  try {
45
46
  await device.remove(bundleId);
46
47
  } catch (err) {
47
- log.error(`Reset: could not remove '${bundleId}' from device: ${err.message}`);
48
+ this.log.error(`Reset: could not remove '${bundleId}' from device: ${err.message}`);
48
49
  throw err;
49
50
  }
50
- log.debug(`Reset: removed '${bundleId}'`);
51
+ this.log.debug(`Reset: removed '${bundleId}'`);
51
52
  }
52
53
 
53
54
  /**
54
- * @param {RealDevice} device
55
- * @param {import('./driver').XCUITestDriverOpts} opts
55
+ * @this {import('./driver').XCUITestDriver}
56
56
  * @returns {Promise<void>}
57
57
  */
58
- async function runRealDeviceReset(device, opts) {
59
- if (!opts.noReset || opts.fullReset) {
60
- log.debug('Reset: running ios real device reset flow');
61
- if (!opts.noReset) {
62
- await resetRealDevice(device, opts);
58
+ export async function runRealDeviceReset() {
59
+ if (!this.opts.noReset || this.opts.fullReset) {
60
+ this.log.debug('Reset: running ios real device reset flow');
61
+ if (!this.opts.noReset) {
62
+ await resetRealDevice.bind(this)();
63
63
  }
64
64
  } else {
65
- log.debug('Reset: fullReset not set. Leaving as is');
65
+ this.log.debug('Reset: fullReset not set. Leaving as is');
66
66
  }
67
67
  }
68
68
 
@@ -76,28 +76,30 @@ async function runRealDeviceReset(device, opts) {
76
76
  */
77
77
 
78
78
  /**
79
- * @param {RealDevice} device The device instance
79
+ * @this {import('./driver').XCUITestDriver}
80
80
  * @param {string} [app] The app to the path
81
81
  * @param {string} [bundleId] The bundle id to ensure it is already installed and uninstall it
82
- * @param {InstallOptions} [opts]
82
+ * @param {InstallOptions} [opts={}]
83
83
  */
84
- async function installToRealDevice(device, app, bundleId, opts) {
84
+ export async function installToRealDevice(app, bundleId, opts = {}) {
85
+ const device = /** @type {RealDevice} */ (this.device);
86
+
85
87
  if (!device.udid || !app || !bundleId) {
86
- log.debug('No device id, app or bundle id, not installing to real device.');
88
+ this.log.debug('No device id, app or bundle id, not installing to real device.');
87
89
  return;
88
90
  }
89
91
 
90
- const {skipUninstall, strategy, timeout} = opts ?? {};
92
+ const {skipUninstall, strategy, timeout} = opts;
91
93
 
92
94
  if (!skipUninstall) {
93
- log.info(`Reset requested. Removing app with id '${bundleId}' from the device`);
95
+ this.log.info(`Reset requested. Removing app with id '${bundleId}' from the device`);
94
96
  await device.remove(bundleId);
95
97
  }
96
- log.debug(`Installing '${app}' on device with UUID '${device.udid}'...`);
98
+ this.log.debug(`Installing '${app}' on device with UUID '${device.udid}'...`);
97
99
 
98
100
  try {
99
101
  await device.install(app, timeout, strategy);
100
- log.debug('The app has been installed successfully.');
102
+ this.log.debug('The app has been installed successfully.');
101
103
  } catch (e) {
102
104
  // Want to clarify the device's application installation state in this situation.
103
105
 
@@ -113,29 +115,20 @@ async function installToRealDevice(device, app, bundleId, opts) {
113
115
  // If the error was by below error case, we could recover the situation
114
116
  // by uninstalling the device's app bundle id explicitly regard less the app exists on the device or not (e.g. offload app).
115
117
  // [XCUITest] Error installing app '/path/to.app': Unexpected data: {"Error":"MismatchedApplicationIdentifierEntitlement","ErrorDescription":"Upgrade's application-identifier entitlement string (TEAM_ID.com.kazucocoa.example) does not match installed application's application-identifier string (ANOTHER_TEAM_ID.com.kazucocoa.example); rejecting upgrade."}
116
- log.info(`The application identified by '${bundleId}' cannot be installed because it might ` +
118
+ this.log.info(`The application identified by '${bundleId}' cannot be installed because it might ` +
117
119
  `be already cached on the device, probably with a different signature. ` +
118
120
  `Will try to remove it and install a new copy. Original error: ${e.message}`);
119
121
  await device.remove(bundleId);
120
122
  await device.install(app, timeout, strategy);
121
- log.debug('The app has been installed after one retrial.');
123
+ this.log.debug('The app has been installed after one retrial.');
122
124
  }
123
125
  }
124
126
 
125
127
  /**
126
- * @param {string} udid
127
- * @param {import('@appium/types').AppiumLogger} logger
128
+ * @this {import('./driver').XCUITestDriver}
128
129
  * @returns {RealDevice}
129
130
  */
130
- function getRealDeviceObj(udid, logger) {
131
- log.debug(`Creating iDevice object with udid '${udid}'`);
132
- return new RealDevice(udid, logger);
131
+ export function getRealDeviceObj() {
132
+ this.log.debug(`Creating iDevice object with udid '${this.opts.udid}'`);
133
+ return new RealDevice(this.opts.udid, this.log);
133
134
  }
134
-
135
- export {
136
- getConnectedDevices,
137
- getOSVersion,
138
- runRealDeviceReset,
139
- installToRealDevice,
140
- getRealDeviceObj,
141
- };