appium-xcuitest-driver 7.7.0 → 7.7.2

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 (134) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/build/lib/app-utils.d.ts.map +1 -1
  3. package/build/lib/app-utils.js +1 -2
  4. package/build/lib/app-utils.js.map +1 -1
  5. package/build/lib/commands/activeAppInfo.d.ts +1 -1
  6. package/build/lib/commands/activeAppInfo.d.ts.map +1 -1
  7. package/build/lib/commands/alert.d.ts +6 -6
  8. package/build/lib/commands/alert.d.ts.map +1 -1
  9. package/build/lib/commands/app-management.d.ts +13 -13
  10. package/build/lib/commands/app-management.d.ts.map +1 -1
  11. package/build/lib/commands/app-management.js +9 -6
  12. package/build/lib/commands/app-management.js.map +1 -1
  13. package/build/lib/commands/app-strings.d.ts +1 -1
  14. package/build/lib/commands/app-strings.d.ts.map +1 -1
  15. package/build/lib/commands/appearance.d.ts +2 -2
  16. package/build/lib/commands/appearance.d.ts.map +1 -1
  17. package/build/lib/commands/appearance.js +2 -4
  18. package/build/lib/commands/appearance.js.map +1 -1
  19. package/build/lib/commands/audit.d.ts +1 -1
  20. package/build/lib/commands/audit.d.ts.map +1 -1
  21. package/build/lib/commands/battery.d.ts +1 -1
  22. package/build/lib/commands/battery.d.ts.map +1 -1
  23. package/build/lib/commands/biometric.d.ts +3 -3
  24. package/build/lib/commands/biometric.d.ts.map +1 -1
  25. package/build/lib/commands/certificate.d.ts +2 -2
  26. package/build/lib/commands/certificate.d.ts.map +1 -1
  27. package/build/lib/commands/certificate.js +1 -2
  28. package/build/lib/commands/certificate.js.map +1 -1
  29. package/build/lib/commands/clipboard.d.ts +2 -2
  30. package/build/lib/commands/clipboard.d.ts.map +1 -1
  31. package/build/lib/commands/condition.d.ts +3 -3
  32. package/build/lib/commands/condition.d.ts.map +1 -1
  33. package/build/lib/commands/context.d.ts +20 -20
  34. package/build/lib/commands/context.d.ts.map +1 -1
  35. package/build/lib/commands/context.js +1 -2
  36. package/build/lib/commands/context.js.map +1 -1
  37. package/build/lib/commands/deviceInfo.d.ts +1 -1
  38. package/build/lib/commands/deviceInfo.d.ts.map +1 -1
  39. package/build/lib/commands/element.d.ts +18 -18
  40. package/build/lib/commands/element.d.ts.map +1 -1
  41. package/build/lib/commands/file-movement.d.ts +8 -8
  42. package/build/lib/commands/file-movement.d.ts.map +1 -1
  43. package/build/lib/commands/find.d.ts +4 -4
  44. package/build/lib/commands/find.d.ts.map +1 -1
  45. package/build/lib/commands/general.d.ts +19 -19
  46. package/build/lib/commands/general.d.ts.map +1 -1
  47. package/build/lib/commands/geolocation.d.ts +3 -3
  48. package/build/lib/commands/geolocation.d.ts.map +1 -1
  49. package/build/lib/commands/gesture.d.ts +19 -19
  50. package/build/lib/commands/gesture.d.ts.map +1 -1
  51. package/build/lib/commands/iohid.d.ts +1 -1
  52. package/build/lib/commands/keyboard.d.ts +4 -4
  53. package/build/lib/commands/keyboard.d.ts.map +1 -1
  54. package/build/lib/commands/keychains.d.ts +1 -1
  55. package/build/lib/commands/keychains.d.ts.map +1 -1
  56. package/build/lib/commands/localization.d.ts +1 -1
  57. package/build/lib/commands/localization.d.ts.map +1 -1
  58. package/build/lib/commands/location.d.ts +3 -3
  59. package/build/lib/commands/location.d.ts.map +1 -1
  60. package/build/lib/commands/lock.d.ts +3 -3
  61. package/build/lib/commands/lock.d.ts.map +1 -1
  62. package/build/lib/commands/log.d.ts +4 -4
  63. package/build/lib/commands/log.d.ts.map +1 -1
  64. package/build/lib/commands/memory.d.ts +1 -1
  65. package/build/lib/commands/memory.d.ts.map +1 -1
  66. package/build/lib/commands/memory.js +1 -2
  67. package/build/lib/commands/memory.js.map +1 -1
  68. package/build/lib/commands/navigation.d.ts +5 -5
  69. package/build/lib/commands/navigation.d.ts.map +1 -1
  70. package/build/lib/commands/notifications.d.ts +2 -2
  71. package/build/lib/commands/notifications.d.ts.map +1 -1
  72. package/build/lib/commands/pasteboard.d.ts +2 -2
  73. package/build/lib/commands/pasteboard.d.ts.map +1 -1
  74. package/build/lib/commands/pcap.d.ts +2 -2
  75. package/build/lib/commands/pcap.d.ts.map +1 -1
  76. package/build/lib/commands/performance.d.ts +2 -2
  77. package/build/lib/commands/performance.d.ts.map +1 -1
  78. package/build/lib/commands/permissions.d.ts +3 -3
  79. package/build/lib/commands/permissions.d.ts.map +1 -1
  80. package/build/lib/commands/proxy-helper.d.ts +1 -1
  81. package/build/lib/commands/proxy-helper.d.ts.map +1 -1
  82. package/build/lib/commands/record-audio.d.ts +2 -2
  83. package/build/lib/commands/record-audio.d.ts.map +1 -1
  84. package/build/lib/commands/recordscreen.d.ts +2 -2
  85. package/build/lib/commands/recordscreen.d.ts.map +1 -1
  86. package/build/lib/commands/screenshots.d.ts +3 -3
  87. package/build/lib/commands/screenshots.d.ts.map +1 -1
  88. package/build/lib/commands/source.d.ts +2 -2
  89. package/build/lib/commands/source.d.ts.map +1 -1
  90. package/build/lib/commands/timeouts.d.ts +7 -7
  91. package/build/lib/commands/timeouts.d.ts.map +1 -1
  92. package/build/lib/commands/web.d.ts +32 -32
  93. package/build/lib/commands/web.d.ts.map +1 -1
  94. package/build/lib/commands/web.js +5 -10
  95. package/build/lib/commands/web.js.map +1 -1
  96. package/build/lib/commands/xctest-record-screen.d.ts +2 -2
  97. package/build/lib/commands/xctest-record-screen.d.ts.map +1 -1
  98. package/build/lib/commands/xctest.d.ts +4 -4
  99. package/build/lib/commands/xctest.d.ts.map +1 -1
  100. package/build/lib/css-converter.d.ts.map +1 -1
  101. package/build/lib/css-converter.js +5 -15
  102. package/build/lib/css-converter.js.map +1 -1
  103. package/build/lib/desired-caps.d.ts +4 -0
  104. package/build/lib/desired-caps.d.ts.map +1 -1
  105. package/build/lib/desired-caps.js +3 -0
  106. package/build/lib/desired-caps.js.map +1 -1
  107. package/build/lib/driver.d.ts +54 -65
  108. package/build/lib/driver.d.ts.map +1 -1
  109. package/build/lib/driver.js +61 -72
  110. package/build/lib/driver.js.map +1 -1
  111. package/build/lib/real-device-management.d.ts +4 -4
  112. package/build/lib/real-device-management.d.ts.map +1 -1
  113. package/build/lib/simulator-management.d.ts +8 -8
  114. package/build/lib/simulator-management.d.ts.map +1 -1
  115. package/build/lib/types.d.ts +0 -18
  116. package/build/lib/types.d.ts.map +1 -1
  117. package/build/lib/utils.d.ts +4 -1
  118. package/build/lib/utils.d.ts.map +1 -1
  119. package/build/lib/utils.js +4 -1
  120. package/build/lib/utils.js.map +1 -1
  121. package/lib/app-utils.js +1 -2
  122. package/lib/commands/app-management.js +9 -7
  123. package/lib/commands/appearance.js +2 -4
  124. package/lib/commands/certificate.js +1 -2
  125. package/lib/commands/context.js +2 -2
  126. package/lib/commands/memory.js +1 -2
  127. package/lib/commands/web.js +3 -7
  128. package/lib/css-converter.js +17 -15
  129. package/lib/desired-caps.js +3 -0
  130. package/lib/driver.js +68 -75
  131. package/lib/types.ts +0 -19
  132. package/lib/utils.js +4 -1
  133. package/npm-shrinkwrap.json +9 -9
  134. package/package.json +1 -1
@@ -390,8 +390,7 @@ export default {
390
390
  }
391
391
 
392
392
  let isCertAlreadyInstalled = false;
393
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
394
- if (util.compareVersions(this.opts.platformVersion, '>=', '12.2')) {
393
+ if (util.compareVersions(/** @type {string} */ (this.opts.platformVersion), '>=', '12.2')) {
395
394
  if (await installPost122Certificate(this, cn)) {
396
395
  await clickElement(this, Settings.Profile);
397
396
  await trustCertificateInPreferences(this, cn);
@@ -49,9 +49,9 @@ const extensions = {
49
49
  * @this {XCUITestDriver}
50
50
  */
51
51
  useNewSafari() {
52
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
53
- return !this.isRealDevice() && this.opts.safari;
52
+ return this.isSimulator() && this.isSafari();
54
53
  },
54
+
55
55
  /**
56
56
  * @this {XCUITestDriver}
57
57
  */
@@ -1,6 +1,5 @@
1
1
  import _ from 'lodash';
2
2
  import { errors } from 'appium/driver';
3
- import RealDevice from '../real-device';
4
3
 
5
4
  export default {
6
5
  /**
@@ -16,7 +15,7 @@ export default {
16
15
  throw new Error('Memory warning simulation is only supported on real devices');
17
16
  }
18
17
 
19
- const device = /** @type {RealDevice} */ (this.device);
18
+ const device = /** @type {import('../real-device').RealDevice} */ (this.device);
20
19
 
21
20
  /** @type {import('../devicectl').AppInfo[]} */
22
21
  const appInfos = await device.devicectl.listApps(bundleId);
@@ -523,8 +523,7 @@ const extensions = {
523
523
  const {
524
524
  nativeWebTapTabBarVisibility,
525
525
  nativeWebTapSmartAppBannerVisibility,
526
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
527
- safariTabBarPosition = util.compareVersions(this.opts.platformVersion, '>=', '15.0') &&
526
+ safariTabBarPosition = util.compareVersions(/** @type {string} */ (this.opts.platformVersion), '>=', '15.0') &&
528
527
  isIphone
529
528
  ? TAB_BAR_POSITION_BOTTOM
530
529
  : TAB_BAR_POSITION_TOP,
@@ -551,8 +550,7 @@ const extensions = {
551
550
  const orientation = realDims.h > realDims.w ? 'PORTRAIT' : 'LANDSCAPE';
552
551
 
553
552
  const notchOffset = isNotched
554
- ? // @ts-expect-error - do not assign arbitrary properties to `this.opts`
555
- util.compareVersions(this.opts.platformVersion, '=', '13.0')
553
+ ? util.compareVersions(/** @type {string} */ (this.opts.platformVersion), '=', '13.0')
556
554
  ? IPHONE_X_NOTCH_OFFSET_IOS_13
557
555
  : IPHONE_X_NOTCH_OFFSET_IOS
558
556
  : 0;
@@ -945,9 +943,7 @@ const extensions = {
945
943
  // restore the previous url
946
944
  await this.setUrl(currentUrl);
947
945
  }
948
- /** @type {import('../types').CalibrationData} */
949
- // @ts-ignore this.webviewCalibrationResult is always defined here
950
- const result = this.webviewCalibrationResult;
946
+ const result = /** @type {import('../types').CalibrationData} */ (this.webviewCalibrationResult);
951
947
  return {
952
948
  ...result,
953
949
  offsetX: Math.round(result.offsetX),
@@ -210,18 +210,19 @@ function parseCssRule(cssRule) {
210
210
  }
211
211
 
212
212
  let iosClassChainSelector = '';
213
- /** @type {import('css-selector-parser').AstClassName[]} */
214
- // @ts-ignore This should work
215
- const astClassNames = cssRule.items.filter(({type}) => type === 'ClassName');
213
+ const astClassNames = /** @type {import('css-selector-parser').AstClassName[]} */ (
214
+ cssRule.items.filter(({type}) => type === 'ClassName')
215
+ );
216
216
  const classNames = astClassNames.map(({name}) => name);
217
217
  if (classNames.length) {
218
218
  throw new errors.InvalidSelectorError(`'${[cssRule || '', ...classNames].join('.')}'
219
219
  is not a valid ios class. Must be a single string (e.g.: XCUIElementTypeWindow) without
220
220
  dots separating them`);
221
221
  }
222
- /** @type {import('css-selector-parser').AstTagName|undefined} */
223
- // @ts-ignore This should work
224
- const astTag = cssRule.items.find(({type}) => type === 'TagName');
222
+
223
+ const astTag = /** @type {import('css-selector-parser').AstTagName|undefined} */ (
224
+ cssRule.items.find(({type}) => type === 'TagName')
225
+ );
225
226
  let tagName = astTag?.name ?? '';
226
227
  if (tagName && tagName !== '*' && !_.startsWith(_.toLower(tagName), 'xcuielementtype')) {
227
228
  const capitalizedTagName = tagName.charAt(0).toUpperCase() + tagName.slice(1);
@@ -231,22 +232,23 @@ function parseCssRule(cssRule) {
231
232
 
232
233
  /** @type {(string|{index: string|undefined}|undefined)[]} */
233
234
  const attrs = [];
234
- /** @type {import('css-selector-parser').AstId[]} */
235
- // @ts-ignore This should work
236
- const astIds = cssRule.items.filter(({type}) => type === 'Id');
235
+
236
+ const astIds = /** @type {import('css-selector-parser').AstId[]} */ (
237
+ cssRule.items.filter(({type}) => type === 'Id')
238
+ );
237
239
  const ids = astIds.map(({name}) => name);
238
240
  if (ids.length) {
239
241
  attrs.push(`name == "${ids[0]}"`);
240
242
  }
241
- /** @type {import('css-selector-parser').AstAttribute[]} */
242
- // @ts-ignore This should work
243
- const attributes = cssRule.items.filter(({type}) => type === 'Attribute');
243
+ const attributes = /** @type {import('css-selector-parser').AstAttribute[]} */ (
244
+ cssRule.items.filter(({type}) => type === 'Attribute')
245
+ );
244
246
  for (const attr of attributes) {
245
247
  attrs.push(parseAttr(attr));
246
248
  }
247
- /** @type {import('css-selector-parser').AstPseudoClass[]} */
248
- // @ts-ignore This should work
249
- const pseudoClasses = cssRule.items.filter(({type}) => type === 'PseudoClass');
249
+ const pseudoClasses = /** @type {import('css-selector-parser').AstPseudoClass[]} */ (
250
+ cssRule.items.filter(({type}) => type === 'PseudoClass')
251
+ );
250
252
  for (const pseudo of pseudoClasses) {
251
253
  attrs.push(parsePseudo(pseudo));
252
254
  }
@@ -364,6 +364,9 @@ const desiredCapConstraints = /** @type {const} */ ({
364
364
  skipSyncUiDialogTranslation: {
365
365
  isBoolean: true,
366
366
  },
367
+ forceSimulatorSoftwareKeyboardPresence: {
368
+ isBoolean: true,
369
+ }
367
370
  });
368
371
 
369
372
  export {desiredCapConstraints, PLATFORM_NAME_IOS, PLATFORM_NAME_TVOS};
package/lib/driver.js CHANGED
@@ -181,7 +181,7 @@ const BUNDLE_VERSION_PATTERN = /CFBundleVersion\s+=\s+"?([^(;|")]+)/;
181
181
  * @privateRemarks **This class should be considered "final"**. It cannot be extended
182
182
  * due to use of public class field assignments. If extending this class becomes a hard requirement, refer to the implementation of `BaseDriver` on how to do so.
183
183
  */
184
- class XCUITestDriver extends BaseDriver {
184
+ export class XCUITestDriver extends BaseDriver {
185
185
  static newMethodMap = newMethodMap;
186
186
 
187
187
  static executeMethodMap = executeMethodMap;
@@ -256,6 +256,12 @@ class XCUITestDriver extends BaseDriver {
256
256
  /** @type {import('./commands/pcap').TrafficCapture|null} */
257
257
  _trafficCapture;
258
258
 
259
+ /** @type {Simulator|RealDevice} */
260
+ _device;
261
+
262
+ /** @type {string|null} */
263
+ _iosSdkVersion;
264
+
259
265
  /**
260
266
  *
261
267
  * @param {XCUITestDriverOpts} opts
@@ -323,8 +329,6 @@ class XCUITestDriver extends BaseDriver {
323
329
  resetIos() {
324
330
  this.opts = this.opts || {};
325
331
  this.wda = null;
326
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
327
- this.opts.device = null;
328
332
  this.jwpProxyActive = false;
329
333
  this.proxyReqRes = null;
330
334
  this.safari = false;
@@ -388,8 +392,7 @@ class XCUITestDriver extends BaseDriver {
388
392
  * @returns {Simulator|RealDevice}
389
393
  */
390
394
  get device() {
391
- // @ts-ignore This property should exist
392
- return this.opts?.device;
395
+ return this._device;
393
396
  }
394
397
 
395
398
  isXcodebuildNeeded() {
@@ -399,8 +402,6 @@ class XCUITestDriver extends BaseDriver {
399
402
  async createSession(w3cCaps1, w3cCaps2, w3cCaps3, driverData) {
400
403
  try {
401
404
  let [sessionId, caps] = await super.createSession(w3cCaps1, w3cCaps2, w3cCaps3, driverData);
402
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
403
- this.opts.sessionId = sessionId;
404
405
 
405
406
  // merge cli args to opts, and if we did merge any, revalidate opts to ensure the final set
406
407
  // is also consistent
@@ -432,20 +433,16 @@ class XCUITestDriver extends BaseDriver {
432
433
  elementResponseAttributes: DEFAULT_SETTINGS.elementResponseAttributes,
433
434
  shouldUseCompactResponses: DEFAULT_SETTINGS.shouldUseCompactResponses,
434
435
  };
435
- if (_.has(this.opts, 'elementResponseAttributes')) {
436
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
436
+ if ('elementResponseAttributes' in this.opts && _.isString(this.opts.elementResponseAttributes)) {
437
437
  wdaSettings.elementResponseAttributes = this.opts.elementResponseAttributes;
438
438
  }
439
- if (_.has(this.opts, 'shouldUseCompactResponses')) {
440
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
439
+ if ('shouldUseCompactResponses' in this.opts && _.isBoolean(this.opts.shouldUseCompactResponses)) {
441
440
  wdaSettings.shouldUseCompactResponses = this.opts.shouldUseCompactResponses;
442
441
  }
443
- if (_.has(this.opts, 'mjpegServerScreenshotQuality')) {
444
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
442
+ if ('mjpegServerScreenshotQuality' in this.opts && _.isNumber(this.opts.mjpegServerScreenshotQuality)) {
445
443
  wdaSettings.mjpegServerScreenshotQuality = this.opts.mjpegServerScreenshotQuality;
446
444
  }
447
- if (_.has(this.opts, 'mjpegServerFramerate')) {
448
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
445
+ if ('mjpegServerFramerate' in this.opts && _.isNumber(this.opts.mjpegServerFramerate)) {
449
446
  wdaSettings.mjpegServerFramerate = this.opts.mjpegServerFramerate;
450
447
  }
451
448
  if (_.has(this.opts, 'screenshotQuality')) {
@@ -486,18 +483,13 @@ class XCUITestDriver extends BaseDriver {
486
483
  this.opts.fullReset = !!this.opts.fullReset;
487
484
 
488
485
  await printUser();
489
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
490
- this.opts.iosSdkVersion = null; // For WDA and xcodebuild
486
+ this._iosSdkVersion = null; // For WDA and xcodebuild
491
487
  const {device, udid, realDevice} = await this.determineDevice();
492
488
  this.log.info(
493
489
  `Determining device to run tests on: udid: '${udid}', real device: ${realDevice}`,
494
490
  );
495
- // TODO: extract device out of opts to a separate driver property
496
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
497
- this.opts.device = device;
491
+ this._device = device;
498
492
  this.opts.udid = udid;
499
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
500
- this.opts.realDevice = realDevice;
501
493
 
502
494
  if (this.opts.simulatorDevicesSetPath) {
503
495
  if (realDevice) {
@@ -528,8 +520,7 @@ class XCUITestDriver extends BaseDriver {
528
520
  this.opts.platformVersion = normalizedVersion;
529
521
  }
530
522
 
531
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
532
- if (_.isEmpty(this.xcodeVersion) && (this.isXcodebuildNeeded() || !this.opts.realDevice)) {
523
+ if (_.isEmpty(this.xcodeVersion) && (this.isXcodebuildNeeded() || this.isSimulator())) {
533
524
  // no `webDriverAgentUrl`, or on a simulator, so we need an Xcode version
534
525
  this.xcodeVersion = await getAndCheckXcodeVersion();
535
526
  }
@@ -561,7 +552,12 @@ class XCUITestDriver extends BaseDriver {
561
552
 
562
553
  this.wda = new WebDriverAgent(
563
554
  /** @type {import('appium-xcode').XcodeVersion} */ (this.xcodeVersion),
564
- this.opts,
555
+ {
556
+ ...this.opts,
557
+ device: this.device,
558
+ realDevice: this.isRealDevice(),
559
+ iosSdkVersion: this._iosSdkVersion,
560
+ },
565
561
  this.log,
566
562
  );
567
563
  // Derived data path retrieval is an expensive operation
@@ -635,8 +631,7 @@ class XCUITestDriver extends BaseDriver {
635
631
  }
636
632
  }
637
633
 
638
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
639
- await this.startWda(this.opts.sessionId);
634
+ await this.startWda();
640
635
 
641
636
  if (_.isString(this.opts.orientation)) {
642
637
  await this.setInitialOrientation(this.opts.orientation);
@@ -715,9 +710,8 @@ class XCUITestDriver extends BaseDriver {
715
710
 
716
711
  /**
717
712
  * Start WebDriverAgentRunner
718
- * @param {string} sessionId - The id of the target session to launch WDA with.
719
713
  */
720
- async startWda(sessionId) {
714
+ async startWda() {
721
715
  // Don't cleanup the processes if webDriverAgentUrl is set
722
716
  if (!util.hasValue(this.wda.webDriverAgentUrl)) {
723
717
  await this.wda.cleanupObsoleteProcesses();
@@ -824,7 +818,7 @@ class XCUITestDriver extends BaseDriver {
824
818
  await this.preparePreinstalledWda();
825
819
  }
826
820
 
827
- this.cachedWdaStatus = await this.wda.launch(sessionId);
821
+ this.cachedWdaStatus = await this.wda.launch(/** @type {string} */ (this.sessionId));
828
822
  } catch (err) {
829
823
  this.logEvent('wdaStartFailed');
830
824
  this.log.debug(err.stack);
@@ -834,16 +828,20 @@ class XCUITestDriver extends BaseDriver {
834
828
  errorMsg += `. Make sure you follow the tutorial at ${WDA_REAL_DEV_TUTORIAL_URL}`;
835
829
  }
836
830
  if (this.opts.usePreinstalledWDA) {
837
- // In case the bundle id process start got failed because of
838
- // auth popup in the device. Then, the bundle id process itself started. It is safe to stop it here.
839
- await this.mobileKillApp(this.wda.bundleIdForXctest);
831
+ try {
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);
835
+ } catch (ign) {};
840
836
  // Mostly it failed to start the WDA process as no the bundle id
841
837
  // e.g. '<bundle id of WDA> not found on device <udid>'
842
- throw new Error(
843
- `Unable to launch WebDriverAgent. Original error: ${err.message}. ` +
844
- `Make sure the application ${this.wda.bundleIdForXctest} exists and it is launchable. ` +
845
- `${WDA_REAL_DEV_TUTORIAL_URL} may help to complete the preparation.`,
846
- );
838
+
839
+ errorMsg = `Unable to launch WebDriverAgent. Original error: ${err.message}. ` +
840
+ `Make sure the application ${this.wda.bundleIdForXctest} exists and it is launchable.`;
841
+ if (this.isRealDevice()) {
842
+ errorMsg += ` ${WDA_REAL_DEV_TUTORIAL_URL} may help to complete the preparation.`;
843
+ };
844
+ throw new Error(errorMsg);
847
845
  } else {
848
846
  await quitAndUninstall(errorMsg);
849
847
  }
@@ -1166,16 +1164,14 @@ class XCUITestDriver extends BaseDriver {
1166
1164
  this.opts.deviceName = translateDeviceName(this.opts.platformVersion, this.opts.deviceName);
1167
1165
 
1168
1166
  const setupVersionCaps = async () => {
1169
- const iosSdkVersion = await getAndCheckIosSdkVersion();
1170
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1171
- this.opts.iosSdkVersion = iosSdkVersion;
1172
- this.log.info(`iOS SDK Version set to '${iosSdkVersion}'`);
1173
- if (!this.opts.platformVersion && iosSdkVersion) {
1167
+ this._iosSdkVersion = await getAndCheckIosSdkVersion();
1168
+ this.log.info(`iOS SDK Version set to '${this._iosSdkVersion}'`);
1169
+ if (!this.opts.platformVersion && this._iosSdkVersion) {
1174
1170
  this.log.info(
1175
- `No platformVersion specified. Using the latest version Xcode supports: '${iosSdkVersion}'. ` +
1171
+ `No platformVersion specified. Using the latest version Xcode supports: '${this._iosSdkVersion}'. ` +
1176
1172
  `This may cause problems if a simulator does not exist for this platform version.`,
1177
1173
  );
1178
- this.opts.platformVersion = normalizePlatformVersion(iosSdkVersion);
1174
+ this.opts.platformVersion = normalizePlatformVersion(this._iosSdkVersion);
1179
1175
  }
1180
1176
  };
1181
1177
 
@@ -1353,7 +1349,6 @@ class XCUITestDriver extends BaseDriver {
1353
1349
  forceAppLaunch: this.opts.forceAppLaunch ?? true,
1354
1350
  useNativeCachingStrategy: this.opts.useNativeCachingStrategy ?? true,
1355
1351
  forceSimulatorSoftwareKeyboardPresence:
1356
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1357
1352
  this.opts.forceSimulatorSoftwareKeyboardPresence ??
1358
1353
  (this.opts.connectHardwareKeyboard === true ? false : true),
1359
1354
  });
@@ -1393,29 +1388,35 @@ class XCUITestDriver extends BaseDriver {
1393
1388
  return true;
1394
1389
  }
1395
1390
 
1391
+ /**
1392
+ * @returns {boolean}
1393
+ */
1396
1394
  isSafari() {
1397
1395
  return !!this.safari;
1398
1396
  }
1397
+
1399
1398
  /**
1400
- *
1401
1399
  * @returns {boolean}
1402
1400
  */
1403
1401
  isRealDevice() {
1404
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1405
- return Boolean(this.opts.realDevice);
1402
+ return 'devicectl' in (this.device ?? {});
1406
1403
  }
1407
1404
 
1405
+ /**
1406
+ * @returns {boolean}
1407
+ */
1408
1408
  isSimulator() {
1409
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1410
- return !this.opts.realDevice;
1409
+ return 'simctl' in (this.device ?? {});
1411
1410
  }
1412
1411
 
1412
+ /**
1413
+ * @param {string} strategy
1414
+ */
1413
1415
  validateLocatorStrategy(strategy) {
1414
1416
  super.validateLocatorStrategy(strategy, this.isWebContext());
1415
1417
  }
1416
1418
 
1417
1419
  /**
1418
- *
1419
1420
  * @param {any} caps
1420
1421
  * @returns {caps is import('@appium/types').DriverCaps<XCUITestDriverConstraints>}
1421
1422
  */
@@ -1552,22 +1553,6 @@ class XCUITestDriver extends BaseDriver {
1552
1553
  return true;
1553
1554
  }
1554
1555
 
1555
- /**
1556
- * @typedef {Object} AutInstallationStateOptions
1557
- * @property {Pick<XCUITestDriverOpts, "enforceAppInstall">} enforceAppInstall
1558
- * @property {Pick<XCUITestDriverOpts, "fullReset">} fullReset
1559
- * @property {Pick<XCUITestDriverOpts, "noReset">} noReset
1560
- * @property {Pick<XCUITestDriverOpts, "bundleId">} bundleId
1561
- * @property {Pick<XCUITestDriverOpts, "app">} app
1562
- * @property {Object} device - Real device object or simulator object
1563
- */
1564
-
1565
- /**
1566
- * @typedef {Object} AutInstallationState
1567
- * @property {boolean} install - If the given app should install, or not need to install.
1568
- * @property {boolean} skipUninstall - If the installed app should be uninstalled, or not.
1569
- * /
1570
-
1571
1556
  /**
1572
1557
  * Check if the given app can be installed, or should uninstall before installing it.
1573
1558
  *
@@ -1575,10 +1560,9 @@ class XCUITestDriver extends BaseDriver {
1575
1560
  * @returns {Promise<AutInstallationState>}
1576
1561
  */
1577
1562
  async checkAutInstallationState(opts) {
1578
- // @ts-expect-error - do not assign arbitrary properties to `opts`
1579
- const {enforceAppInstall, fullReset, noReset, bundleId, device, app} = opts ?? this.opts;
1563
+ const {enforceAppInstall, fullReset, noReset, bundleId, app} = opts ?? this.opts;
1580
1564
 
1581
- const wasAppInstalled = await device.isAppInstalled(bundleId);
1565
+ const wasAppInstalled = await this.device.isAppInstalled(bundleId);
1582
1566
  if (wasAppInstalled) {
1583
1567
  this.log.info(`App '${bundleId}' is already installed`);
1584
1568
  if (noReset) {
@@ -1609,8 +1593,8 @@ class XCUITestDriver extends BaseDriver {
1609
1593
  }
1610
1594
 
1611
1595
  const appBundleVersion = this.isRealDevice()
1612
- ? (await device.fetchAppInfo(bundleId))?.CFBundleVersion
1613
- : BUNDLE_VERSION_PATTERN.exec(await device.simctl.appInfo(bundleId))?.[1];
1596
+ ? (await /** @type {RealDevice} */ (this.device).fetchAppInfo(bundleId))?.CFBundleVersion
1597
+ : BUNDLE_VERSION_PATTERN.exec(await /** @type {Simulator} */ (this.device).simctl.appInfo(bundleId))?.[1];
1614
1598
  this.log.debug(`CFBundleVersion from installed app info: ${appBundleVersion}`);
1615
1599
  if (!appBundleVersion) {
1616
1600
  return {
@@ -2251,7 +2235,6 @@ function shouldSetInitialSafariUrl(opts) {
2251
2235
  }
2252
2236
 
2253
2237
  export default XCUITestDriver;
2254
- export {XCUITestDriver};
2255
2238
 
2256
2239
  /**
2257
2240
  * @template {import('@appium/types').Constraints} C
@@ -2259,6 +2242,16 @@ export {XCUITestDriver};
2259
2242
  * @typedef {import('@appium/types').ExternalDriver<C, Ctx>} ExternalDriver
2260
2243
  */
2261
2244
 
2245
+ /**
2246
+ * @typedef {Pick<XCUITestDriverOpts, 'enforceAppInstall' | 'fullReset' | 'noReset' | 'bundleId' | 'app'>} AutInstallationStateOptions
2247
+ */
2248
+
2249
+ /**
2250
+ * @typedef {Object} AutInstallationState
2251
+ * @property {boolean} install - If the given app should install, or not need to install.
2252
+ * @property {boolean} skipUninstall - If the installed app should be uninstalled, or not.
2253
+ */
2254
+
2262
2255
  /**
2263
2256
  * @typedef {typeof desiredCapConstraints} XCUITestDriverConstraints
2264
2257
  * @typedef {import('@appium/types').DriverOpts<XCUITestDriverConstraints>} XCUITestDriverOpts
@@ -2267,4 +2260,4 @@ export {XCUITestDriver};
2267
2260
  * @typedef {import('appium-xcode').XcodeVersion} XcodeVersion
2268
2261
  * @typedef {import('appium-ios-simulator').Simulator} Simulator
2269
2262
  * @typedef {import('./real-device').RealDevice} RealDevice
2270
- */
2263
+ */
package/lib/types.ts CHANGED
@@ -15,25 +15,6 @@ export interface LifecycleData {
15
15
  createSim?: boolean;
16
16
  }
17
17
 
18
- /**
19
- * All of these options are manually added to the `opts` property of the driver, which is strongly discouraged.
20
- *
21
- * Future versions of this driver should move these properties somewhere else.
22
- *
23
- * @todo If anyone knows anything about the types of these values, please fill them in.
24
- */
25
- export interface CustomOpts {
26
- device: any;
27
- realDevice: any;
28
- SimulatorWindowCenter: any;
29
- forceSimulatorSoftwareKeyboardPresence: any;
30
- iosSdkVersion: string;
31
- platformVersion: string;
32
- safari: any;
33
- sessionId: string | null;
34
- elementResponseAttributes: any;
35
- }
36
-
37
18
  export interface WDASettings {
38
19
  elementResponseAttributes: string;
39
20
  shouldUseCompactResponses: boolean;
package/lib/utils.js CHANGED
@@ -60,11 +60,14 @@ async function getAndCheckXcodeVersion() {
60
60
  return version;
61
61
  }
62
62
 
63
+ /**
64
+ * @returns {Promise<string|null>}
65
+ */
63
66
  async function getAndCheckIosSdkVersion() {
64
67
  try {
65
68
  return await xcode.getMaxIOSSDK();
66
69
  } catch (err) {
67
- log.errorAndThrow(`Could not determine iOS SDK version: ${err.message}`);
70
+ throw log.errorWithException(`Could not determine iOS SDK version: ${err.message}`);
68
71
  }
69
72
  }
70
73
 
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "appium-xcuitest-driver",
3
- "version": "7.7.0",
3
+ "version": "7.7.2",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "appium-xcuitest-driver",
9
- "version": "7.7.0",
9
+ "version": "7.7.2",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@colors/colors": "^1.6.0",
@@ -977,9 +977,9 @@
977
977
  }
978
978
  },
979
979
  "node_modules/appium-remote-debugger": {
980
- "version": "11.0.6",
981
- "resolved": "https://registry.npmjs.org/appium-remote-debugger/-/appium-remote-debugger-11.0.6.tgz",
982
- "integrity": "sha512-8j5qAFw9JWQgVpvtLj6GvhpiBHWErFTd0iBKWdYGszaISJjGScQtF7mzvw8dip0X2UGWCrIENNn2sdgevNW8Hw==",
980
+ "version": "11.0.7",
981
+ "resolved": "https://registry.npmjs.org/appium-remote-debugger/-/appium-remote-debugger-11.0.7.tgz",
982
+ "integrity": "sha512-SRrQj5125mboJG6g9driIUlmgviRMCUnqwGwPQ3dCXAJ/w1VYksTKQ8LEZXJv7/kY9ayKxEp2z8L8aGpeTawZQ==",
983
983
  "dependencies": {
984
984
  "@appium/base-driver": "^9.0.0",
985
985
  "@appium/support": "^4.0.0",
@@ -2946,11 +2946,11 @@
2946
2946
  "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
2947
2947
  },
2948
2948
  "node_modules/path-scurry": {
2949
- "version": "1.10.1",
2950
- "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz",
2951
- "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==",
2949
+ "version": "1.10.2",
2950
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz",
2951
+ "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==",
2952
2952
  "dependencies": {
2953
- "lru-cache": "^9.1.1 || ^10.0.0",
2953
+ "lru-cache": "^10.2.0",
2954
2954
  "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
2955
2955
  },
2956
2956
  "engines": {
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "xcuitest",
9
9
  "xctest"
10
10
  ],
11
- "version": "7.7.0",
11
+ "version": "7.7.2",
12
12
  "author": "Appium Contributors",
13
13
  "license": "Apache-2.0",
14
14
  "repository": {