appium-xcuitest-driver 7.6.1 → 7.7.1

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 +14 -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 +89 -83
  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 +91 -86
  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 +14 -36
  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) {
@@ -829,16 +834,20 @@ class XCUITestDriver extends BaseDriver {
829
834
  errorMsg += `. Make sure you follow the tutorial at ${WDA_REAL_DEV_TUTORIAL_URL}`;
830
835
  }
831
836
  if (this.opts.usePreinstalledWDA) {
832
- // In case the bundle id process start got failed because of
833
- // auth popup in the device. Then, the bundle id process itself started. It is safe to stop it here.
834
- await this.mobileKillApp(this.wda.bundleIdForXctest);
837
+ try {
838
+ // In case the bundle id process start got failed because of
839
+ // auth popup in the device. Then, the bundle id process itself started. It is safe to stop it here.
840
+ await this.mobileKillApp(this.wda.bundleIdForXctest);
841
+ } catch (ign) {};
835
842
  // Mostly it failed to start the WDA process as no the bundle id
836
843
  // e.g. '<bundle id of WDA> not found on device <udid>'
837
- throw new Error(
838
- `Unable to launch WebDriverAgent. Original error: ${err.message}. ` +
839
- `Make sure the application ${this.wda.bundleIdForXctest} exists and it is launchable. ` +
840
- `${WDA_REAL_DEV_TUTORIAL_URL} may help to complete the preparation.`,
841
- );
844
+
845
+ errorMsg = `Unable to launch WebDriverAgent. Original error: ${err.message}. ` +
846
+ `Make sure the application ${this.wda.bundleIdForXctest} exists and it is launchable.`;
847
+ if (this.isRealDevice()) {
848
+ errorMsg += ` ${WDA_REAL_DEV_TUTORIAL_URL} may help to complete the preparation.`;
849
+ };
850
+ throw new Error(errorMsg);
842
851
  } else {
843
852
  await quitAndUninstall(errorMsg);
844
853
  }
@@ -886,16 +895,14 @@ class XCUITestDriver extends BaseDriver {
886
895
 
887
896
  /**
888
897
  *
889
- * @param {XCUITestDriverOpts} [opts]
898
+ * @param {boolean} [enforceSimulatorShutdown=false]
890
899
  */
891
- async runReset(opts) {
900
+ async runReset(enforceSimulatorShutdown = false) {
892
901
  this.logEvent('resetStarted');
893
902
  if (this.isRealDevice()) {
894
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
895
- await runRealDeviceReset(this.opts.device, opts || this.opts);
903
+ await runRealDeviceReset.bind(this)();
896
904
  } else {
897
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
898
- await runSimulatorReset(this.opts.device, opts || this.opts);
905
+ await runSimulatorReset.bind(this)(enforceSimulatorShutdown);
899
906
  }
900
907
  this.logEvent('resetComplete');
901
908
  }
@@ -944,18 +951,13 @@ class XCUITestDriver extends BaseDriver {
944
951
  }
945
952
 
946
953
  if (this.opts.resetOnSessionStartOnly === false) {
947
- await this.runReset(
948
- Object.assign({}, this.opts, {
949
- enforceSimulatorShutdown: true,
950
- }),
951
- );
954
+ await this.runReset(true);
952
955
  }
953
956
 
954
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
955
- const simulatorDevice = this.isSimulator() ? this.opts.device : null;
957
+ const simulatorDevice = this.isSimulator() ? /** @type {Simulator} */ (this.device) : null;
956
958
  if (simulatorDevice && this.lifecycleData.createSim) {
957
959
  this.log.debug(`Deleting simulator created for this run (udid: '${simulatorDevice.udid}')`);
958
- await shutdownSimulator(simulatorDevice);
960
+ await shutdownSimulator.bind(this)();
959
961
  await simulatorDevice.delete();
960
962
  }
961
963
 
@@ -1168,19 +1170,16 @@ class XCUITestDriver extends BaseDriver {
1168
1170
  this.opts.deviceName = translateDeviceName(this.opts.platformVersion, this.opts.deviceName);
1169
1171
 
1170
1172
  const setupVersionCaps = async () => {
1173
+ const iosSdkVersion = await getAndCheckIosSdkVersion();
1171
1174
  // @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) {
1175
+ this.opts.iosSdkVersion = iosSdkVersion;
1176
+ this.log.info(`iOS SDK Version set to '${iosSdkVersion}'`);
1177
+ if (!this.opts.platformVersion && iosSdkVersion) {
1177
1178
  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}'. ` +
1179
+ `No platformVersion specified. Using the latest version Xcode supports: '${iosSdkVersion}'. ` +
1180
1180
  `This may cause problems if a simulator does not exist for this platform version.`,
1181
1181
  );
1182
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1183
- this.opts.platformVersion = normalizePlatformVersion(this.opts.iosSdkVersion);
1182
+ this.opts.platformVersion = normalizePlatformVersion(iosSdkVersion);
1184
1183
  }
1185
1184
  };
1186
1185
 
@@ -1195,11 +1194,10 @@ class XCUITestDriver extends BaseDriver {
1195
1194
  );
1196
1195
  await setupVersionCaps();
1197
1196
 
1198
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1199
- const device = await getExistingSim(this.opts);
1197
+ const device = await getExistingSim.bind(this)();
1200
1198
  if (!device) {
1201
1199
  // No matching Simulator is found. Throw an error
1202
- this.log.errorAndThrow(
1200
+ throw this.log.errorWithException(
1203
1201
  `Cannot detect udid for ${this.opts.deviceName} Simulator running iOS ${this.opts.platformVersion}`,
1204
1202
  );
1205
1203
  }
@@ -1221,6 +1219,7 @@ class XCUITestDriver extends BaseDriver {
1221
1219
  try {
1222
1220
  const device = await getSimulator(this.opts.udid, {
1223
1221
  devicesSetPath: this.opts.simulatorDevicesSetPath,
1222
+ logger: this.log,
1224
1223
  });
1225
1224
  return {device, realDevice: false, udid: this.opts.udid};
1226
1225
  } catch (ign) {
@@ -1230,7 +1229,7 @@ class XCUITestDriver extends BaseDriver {
1230
1229
  }
1231
1230
  }
1232
1231
 
1233
- const device = getRealDeviceObj(this.opts.udid, this.log);
1232
+ const device = getRealDeviceObj.bind(this)();
1234
1233
  return {device, realDevice: true, udid: this.opts.udid};
1235
1234
  }
1236
1235
 
@@ -1245,8 +1244,7 @@ class XCUITestDriver extends BaseDriver {
1245
1244
  );
1246
1245
  } else {
1247
1246
  // 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);
1247
+ const device = await getExistingSim.bind(this)();
1250
1248
  // check for an existing simulator
1251
1249
  if (device) {
1252
1250
  return {device, realDevice: false, udid: device.udid};
@@ -1260,20 +1258,21 @@ class XCUITestDriver extends BaseDriver {
1260
1258
  }
1261
1259
 
1262
1260
  async startSim() {
1261
+ /** @type {import('appium-ios-simulator').DevicePreferences} */
1262
+ const devicePreferences = {};
1263
+ /** @type {import('appium-ios-simulator').RunOptions} */
1263
1264
  const runOpts = {
1264
1265
  scaleFactor: this.opts.scaleFactor,
1265
1266
  connectHardwareKeyboard: !!this.opts.connectHardwareKeyboard,
1266
1267
  pasteboardAutomaticSync: this.opts.simulatorPasteboardAutomaticSync ?? 'off',
1267
1268
  isHeadless: !!this.opts.isHeadless,
1268
1269
  tracePointer: this.opts.simulatorTracePointer,
1269
- devicePreferences: {},
1270
+ devicePreferences,
1270
1271
  };
1271
1272
 
1272
1273
  // 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;
1274
+ if (this.opts.simulatorWindowCenter) {
1275
+ devicePreferences.SimulatorWindowCenter = this.opts.simulatorWindowCenter;
1277
1276
  }
1278
1277
 
1279
1278
  if (_.isInteger(this.opts.simulatorStartupTimeout)) {
@@ -1285,23 +1284,22 @@ class XCUITestDriver extends BaseDriver {
1285
1284
  const orientation = _.isString(this.opts.orientation) && this.opts.orientation.toUpperCase();
1286
1285
  switch (orientation) {
1287
1286
  case 'LANDSCAPE':
1288
- runOpts.devicePreferences.SimulatorWindowOrientation = 'LandscapeLeft';
1289
- runOpts.devicePreferences.SimulatorWindowRotationAngle = 90;
1287
+ devicePreferences.SimulatorWindowOrientation = 'LandscapeLeft';
1288
+ devicePreferences.SimulatorWindowRotationAngle = 90;
1290
1289
  break;
1291
1290
  case 'PORTRAIT':
1292
- runOpts.devicePreferences.SimulatorWindowOrientation = 'Portrait';
1293
- runOpts.devicePreferences.SimulatorWindowRotationAngle = 0;
1291
+ devicePreferences.SimulatorWindowOrientation = 'Portrait';
1292
+ devicePreferences.SimulatorWindowRotationAngle = 0;
1294
1293
  break;
1295
1294
  }
1296
1295
 
1297
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1298
- await this.opts.device.run(runOpts);
1296
+ await /** @type {Simulator} */ (this.device).run(runOpts);
1299
1297
  }
1300
1298
 
1301
1299
  async createSim() {
1302
1300
  this.lifecycleData.createSim = true;
1303
1301
  // create sim for caps
1304
- const sim = await createSim(this.opts);
1302
+ const sim = await createSim.bind(this)();
1305
1303
  this.log.info(`Created simulator with udid '${sim.udid}'.`);
1306
1304
  return sim;
1307
1305
  }
@@ -1670,15 +1668,13 @@ class XCUITestDriver extends BaseDriver {
1670
1668
  const {install, skipUninstall} = await this.checkAutInstallationState();
1671
1669
  if (install) {
1672
1670
  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, {
1671
+ await installToRealDevice.bind(this)(this.opts.app, this.opts.bundleId, {
1675
1672
  skipUninstall,
1676
1673
  timeout: this.opts.appPushTimeout,
1677
1674
  strategy: this.opts.appInstallStrategy,
1678
1675
  });
1679
1676
  } 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, {
1677
+ await installToSimulator.bind(this)(this.opts.app, this.opts.bundleId, {
1682
1678
  skipUninstall,
1683
1679
  newSimulator: this.lifecycleData?.createSim,
1684
1680
  });
@@ -1693,6 +1689,10 @@ class XCUITestDriver extends BaseDriver {
1693
1689
  }
1694
1690
  }
1695
1691
 
1692
+ /**
1693
+ * @param {string|string[]} otherApps
1694
+ * @returns {Promise<void>}
1695
+ */
1696
1696
  async installOtherApps(otherApps) {
1697
1697
  /** @type {string[]|undefined} */
1698
1698
  let appsList;
@@ -1712,9 +1712,7 @@ class XCUITestDriver extends BaseDriver {
1712
1712
  const appIds = await B.all(appPaths.map((appPath) => extractBundleId(appPath)));
1713
1713
  for (const [appId, appPath] of _.zip(appIds, appPaths)) {
1714
1714
  if (this.isRealDevice()) {
1715
- await installToRealDevice(
1716
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1717
- this.opts.device,
1715
+ await installToRealDevice.bind(this)(
1718
1716
  appPath,
1719
1717
  appId,
1720
1718
  {
@@ -1724,10 +1722,7 @@ class XCUITestDriver extends BaseDriver {
1724
1722
  },
1725
1723
  );
1726
1724
  } 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
1725
+ await installToSimulator.bind(this)(
1731
1726
  appPath,
1732
1727
  appId,
1733
1728
  {
@@ -1738,6 +1733,10 @@ class XCUITestDriver extends BaseDriver {
1738
1733
  }
1739
1734
  }
1740
1735
 
1736
+ /**
1737
+ * @param {string} orientation
1738
+ * @returns {Promise<void>}
1739
+ */
1741
1740
  async setInitialOrientation(orientation) {
1742
1741
  const dstOrientation = _.toUpper(orientation);
1743
1742
  if (!SUPPORTED_ORIENATIONS.includes(dstOrientation)) {
@@ -1756,6 +1755,10 @@ class XCUITestDriver extends BaseDriver {
1756
1755
  }
1757
1756
  }
1758
1757
 
1758
+ /**
1759
+ * @param {string} [cmdName]
1760
+ * @returns {number|undefined}
1761
+ */
1759
1762
  _getCommandTimeout(cmdName) {
1760
1763
  if (this.opts.commandTimeouts) {
1761
1764
  if (cmdName && _.has(this.opts.commandTimeouts, cmdName)) {
@@ -1792,14 +1795,11 @@ class XCUITestDriver extends BaseDriver {
1792
1795
  `Installing prebuilt WDA at '${this.opts.prebuiltWDAPath}'. ` +
1793
1796
  `Bundle identifier: ${candidateBundleId}.`
1794
1797
  );
1795
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1796
- const device = this.opts.device;
1797
1798
 
1798
1799
  // Note: The CFBundleVersion in the test bundle was always 1.
1799
1800
  // It may not be able to compare with the installed versio.
1800
1801
  if (this.isRealDevice()) {
1801
- await installToRealDevice(
1802
- device,
1802
+ await installToRealDevice.bind(this)(
1803
1803
  this.opts.prebuiltWDAPath,
1804
1804
  candidateBundleId,
1805
1805
  {
@@ -1809,7 +1809,10 @@ class XCUITestDriver extends BaseDriver {
1809
1809
  },
1810
1810
  );
1811
1811
  } else {
1812
- await installToSimulator(device, this.opts.prebuiltWDAPath, candidateBundleId);
1812
+ await installToSimulator.bind(this)(
1813
+ this.opts.prebuiltWDAPath,
1814
+ candidateBundleId
1815
+ );
1813
1816
  }
1814
1817
  }
1815
1818
 
@@ -2266,4 +2269,6 @@ export {XCUITestDriver};
2266
2269
  * @typedef {import('./commands/types').FullContext} FullContext
2267
2270
  * @typedef {import('./types').WDACapabilities} WDACapabilities
2268
2271
  * @typedef {import('appium-xcode').XcodeVersion} XcodeVersion
2269
- */
2272
+ * @typedef {import('appium-ios-simulator').Simulator} Simulator
2273
+ * @typedef {import('./real-device').RealDevice} RealDevice
2274
+ */
@@ -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
- };