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
@@ -93,7 +93,7 @@ async function createService(udid, remotePath) {
93
93
  /**
94
94
  * Save the given base64 data chunk as a binary file on the Simulator under test.
95
95
  *
96
- * @param {Object} device - The device object, which represents the device under test.
96
+ * @param {import('../driver').Simulator} device - The device object, which represents the device under test.
97
97
  * This object is expected to have the `udid` property containing the
98
98
  * valid device ID.
99
99
  * @param {string} remotePath - The remote path on the device. This variable can be prefixed with
@@ -140,7 +140,7 @@ async function pushFileToSimulator(device, remotePath, base64Data) {
140
140
  /**
141
141
  * Save the given base64 data chunk as a binary file on the device under test.
142
142
  *
143
- * @param {Object} device - The device object, which represents the device under test.
143
+ * @param {import('../real-device').RealDevice} device - The device object, which represents the device under test.
144
144
  * This object is expected to have the `udid` property containing the
145
145
  * valid device ID.
146
146
  * @param {string} remotePath - The remote path on the device. This variable can be prefixed with
@@ -179,7 +179,7 @@ async function deleteFileOrFolder(device, remotePath, isSimulator) {
179
179
  * Get the content of given file or folder from iOS Simulator and return it as base-64 encoded string.
180
180
  * Folder content is recursively packed into a zip archive.
181
181
  *
182
- * @param {Object} device - The device object, which represents the device under test.
182
+ * @param {import('../driver').Simulator} device - The device object, which represents the device under test.
183
183
  * This object is expected to have the `udid` property containing the
184
184
  * valid device ID.
185
185
  * @param {string} remotePath - The path to a file or a folder, which exists in the corresponding application
@@ -225,7 +225,7 @@ async function pullFromSimulator(device, remotePath, isFile) {
225
225
  * Get the content of given file or folder from the real device under test and return it as base-64 encoded string.
226
226
  * Folder content is recursively packed into a zip archive.
227
227
  *
228
- * @param {Object} device - The device object, which represents the device under test.
228
+ * @param {import('../real-device').RealDevice} device - The device object, which represents the device under test.
229
229
  * This object is expected to have the `udid` property containing the
230
230
  * valid device ID.
231
231
  * @param {string} remotePath - The path to an existing remote file on the device. This variable can be prefixed with
@@ -266,7 +266,7 @@ async function pullFromRealDevice(device, remotePath, isFile) {
266
266
  /**
267
267
  * Remove the file or folder from the device
268
268
  *
269
- * @param {Object} device - The device object, which represents the device under test.
269
+ * @param {import('../driver').Simulator} device - The device object, which represents the device under test.
270
270
  * This object is expected to have the `udid` property containing the
271
271
  * valid device ID.
272
272
  * @param {string} remotePath - The path to a file or a folder, which exists in the corresponding application
@@ -304,7 +304,7 @@ async function deleteFromSimulator(device, remotePath) {
304
304
  /**
305
305
  * Remove the file or folder from the device
306
306
  *
307
- * @param {Object} device - The device object, which represents the device under test.
307
+ * @param {import('../real-device').RealDevice} device - The device object, which represents the device under test.
308
308
  * This object is expected to have the `udid` property containing the
309
309
  * valid device ID.
310
310
  * @param {string} remotePath - The path to an existing remote file on the device. This variable can be prefixed with
@@ -361,10 +361,8 @@ export default {
361
361
  base64Data = Buffer.from(base64Data).toString('utf8');
362
362
  }
363
363
  return this.isSimulator()
364
- ? // @ts-expect-error - do not assign arbitrary properties to `this.opts`
365
- await pushFileToSimulator(this.opts.device, remotePath, base64Data)
366
- : // @ts-expect-error - do not assign arbitrary properties to `this.opts`
367
- await pushFileToRealDevice(this.opts.device, remotePath, base64Data);
364
+ ? await pushFileToSimulator(/** @type {import('../driver').Simulator} */ (this.device), remotePath, base64Data)
365
+ : await pushFileToRealDevice(/** @type {import('../real-device').RealDevice} */ (this.device), remotePath, base64Data);
368
366
  },
369
367
 
370
368
  /**
@@ -398,10 +396,8 @@ export default {
398
396
  );
399
397
  }
400
398
  return this.isSimulator()
401
- ? // @ts-expect-error - do not assign arbitrary properties to `this.opts`
402
- await pullFromSimulator(this.opts.device, remotePath, true)
403
- : // @ts-expect-error - do not assign arbitrary properties to `this.opts`
404
- await pullFromRealDevice(this.opts.device, remotePath, true);
399
+ ? await pullFromSimulator(/** @type {import('../driver').Simulator} */ (this.device), remotePath, true)
400
+ : await pullFromRealDevice(/** @type {import('../real-device').RealDevice} */ (this.device), remotePath, true);
405
401
  },
406
402
 
407
403
  /**
@@ -427,8 +423,7 @@ export default {
427
423
  if (!remotePath.endsWith('/')) {
428
424
  remotePath = `${remotePath}/`;
429
425
  }
430
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
431
- await deleteFileOrFolder(this.opts.device, remotePath, this.isSimulator());
426
+ await deleteFileOrFolder(this.device, remotePath, this.isSimulator());
432
427
  },
433
428
 
434
429
  /**
@@ -445,8 +440,7 @@ export default {
445
440
  `'${remotePath}' is given instead`,
446
441
  );
447
442
  }
448
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
449
- await deleteFileOrFolder(this.opts.device, remotePath, this.isSimulator());
443
+ await deleteFileOrFolder(this.device, remotePath, this.isSimulator());
450
444
  },
451
445
 
452
446
  /**
@@ -463,10 +457,8 @@ export default {
463
457
  remotePath = `${remotePath}/`;
464
458
  }
465
459
  return this.isSimulator()
466
- ? // @ts-expect-error - do not assign arbitrary properties to `this.opts`
467
- await pullFromSimulator(this.opts.device, remotePath, false)
468
- : // @ts-expect-error - do not assign arbitrary properties to `this.opts`
469
- await pullFromRealDevice(this.opts.device, remotePath, false);
460
+ ? await pullFromSimulator(/** @type {import('../driver').Simulator} */ (this.device), remotePath, false)
461
+ : await pullFromRealDevice(/** @type {import('../real-device').RealDevice} */ (this.device), remotePath, false);
470
462
  },
471
463
 
472
464
  /**
@@ -169,8 +169,7 @@ const commands = {
169
169
  if (this.isRealDevice()) {
170
170
  await this.proxyCommand('/url', 'POST', {url});
171
171
  } else {
172
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
173
- await this.opts.device.simctl.openUrl(url);
172
+ await /** @type {import('../driver').Simulator} */ (this.device).simctl.openUrl(url);
174
173
  }
175
174
  },
176
175
  /**
@@ -57,8 +57,7 @@ const commands = {
57
57
  if (!this.isSimulator()) {
58
58
  throw new errors.UnknownError('Shake is not supported on real devices');
59
59
  }
60
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
61
- await this.opts.device.shake();
60
+ await /** @type {import('../driver').Simulator} */ (this.device).shake();
62
61
  },
63
62
  /**
64
63
  * @this {XCUITestDriver}
@@ -14,7 +14,7 @@ export default {
14
14
  */
15
15
  async mobileClearKeychains() {
16
16
  assertSimulator(this);
17
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
18
- await this.opts.device.clearKeychains();
17
+
18
+ await /** @type {import('../driver').Simulator} */ (this.device).clearKeychains();
19
19
  },
20
20
  };
@@ -27,9 +27,6 @@ export default {
27
27
  // Assign skipSyncUiDialogTranslation: true option in order to avoid shutting down the WDA session
28
28
  localizationOptions.language = Object.assign(language, {skipSyncUiDialogTranslation: true});
29
29
  }
30
- return /** @type {boolean} */ (
31
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
32
- await this.opts.device.configureLocalization(localizationOptions)
33
- );
30
+ return await /** @type {import('../driver').Simulator} */ (this.device).configureLocalization(localizationOptions);
34
31
  },
35
32
  };
@@ -77,8 +77,7 @@ export default {
77
77
  }
78
78
 
79
79
  if (this.isSimulator()) {
80
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
81
- await this.opts.device.setGeolocation(`${latitude}`, `${longitude}`);
80
+ await /** @type {import('../driver').Simulator} */ (this.device).setGeolocation(`${latitude}`, `${longitude}`);
82
81
  return /** @type {Location} */ ({latitude, longitude, altitude: 0});
83
82
  }
84
83
 
@@ -103,8 +103,7 @@ export default {
103
103
  }
104
104
  if (_.isUndefined(this.logs.syslog)) {
105
105
  this.logs.crashlog = new IOSCrashLog({
106
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
107
- sim: this.opts.device,
106
+ sim: this.device,
108
107
  udid: this.isRealDevice() ? this.opts.udid : undefined,
109
108
  });
110
109
 
@@ -115,8 +114,7 @@ export default {
115
114
  });
116
115
  } else {
117
116
  this.logs.syslog = new IOSSimulatorLog({
118
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
119
- sim: this.opts.device,
117
+ sim: this.device,
120
118
  showLogs: this.opts.showIOSLog,
121
119
  xcodeVersion: this.xcodeVersion,
122
120
  iosSimulatorLogsPredicate: this.opts.iosSimulatorLogsPredicate,
@@ -1,5 +1,6 @@
1
1
  import _ from 'lodash';
2
2
  import { errors } from 'appium/driver';
3
+ import RealDevice from '../real-device';
3
4
 
4
5
  export default {
5
6
  /**
@@ -15,8 +16,7 @@ export default {
15
16
  throw new Error('Memory warning simulation is only supported on real devices');
16
17
  }
17
18
 
18
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
19
- const device = this.opts.device;
19
+ const device = /** @type {RealDevice} */ (this.device);
20
20
 
21
21
  /** @type {import('../devicectl').AppInfo[]} */
22
22
  const appInfos = await device.devicectl.listApps(bundleId);
@@ -35,8 +35,7 @@ export default {
35
35
  `Got ${JSON.stringify(payload.aps)} instead`,
36
36
  );
37
37
  }
38
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
39
- return await this.opts.device.pushNotification({
38
+ return await /** @type {import('../driver').Simulator} */ (this.device).pushNotification({
40
39
  ...payload,
41
40
  'Simulator Target Bundle': bundleId,
42
41
  });
@@ -17,8 +17,9 @@ export default {
17
17
  // can be empty string
18
18
  throw new Error('Pasteboard content is mandatory to set');
19
19
  }
20
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
21
- return await this.opts.device.simctl.setPasteboard(content, encoding);
20
+ return await /** @type {import('../driver').Simulator} */ (this.device).simctl.setPasteboard(
21
+ content, /** @type {BufferEncoding} */ (encoding)
22
+ );
22
23
  },
23
24
 
24
25
  /**
@@ -34,8 +35,7 @@ export default {
34
35
  if (!this.isSimulator()) {
35
36
  throw new Error('Getting pasteboard content is not supported on real devices');
36
37
  }
37
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
38
- return await this.opts.device.simctl.getPasteboard(encoding);
38
+ return await /** @type {import('../driver').Simulator} */ (this.device).simctl.getPasteboard(encoding);
39
39
  },
40
40
  };
41
41
 
@@ -110,8 +110,7 @@ export default {
110
110
  prefix: `appium_${util.uuidV4().substring(0, 8)}`,
111
111
  suffix: DEFAULT_EXT,
112
112
  });
113
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
114
- const trafficCollector = new TrafficCapture(this.opts.device.udid, this.log, resultPath);
113
+ const trafficCollector = new TrafficCapture(this.device.udid, this.log, resultPath);
115
114
 
116
115
  const timeoutSeconds = parseInt(String(timeLimitSec), 10);
117
116
  if (isNaN(timeoutSeconds) || timeoutSeconds > MAX_CAPTURE_TIME_SEC || timeoutSeconds <= 0) {
@@ -288,8 +288,7 @@ export default {
288
288
  for (const recorder of this._perfRecorders.filter((x) => x.profileName === profileName)) {
289
289
  if (recorder.isRunning()) {
290
290
  this.log.debug(
291
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
292
- `Performance recorder for '${profileName}' on device '${this.opts.device.udid}' ` +
291
+ `Performance recorder for '${profileName}' on device '${this.device.udid}' ` +
293
292
  ` is already running. Doing nothing`,
294
293
  );
295
294
  return;
@@ -310,8 +309,7 @@ export default {
310
309
  realPid = pid;
311
310
  }
312
311
  }
313
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
314
- const recorder = new PerfRecorder(await tempDir.openDir(), this.opts.device.udid, {
312
+ const recorder = new PerfRecorder(await tempDir.openDir(), this.device.udid, {
315
313
  timeout: parseInt(String(timeout), 10),
316
314
  profileName,
317
315
  pid: parseInt(String(realPid), 10),
@@ -364,8 +362,7 @@ export default {
364
362
  if (_.isEmpty(recorders)) {
365
363
  this.log.errorAndThrow(
366
364
  `There are no records for performance profile '${profileName}' ` +
367
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
368
- `and device ${this.opts.device.udid}. Have you started the profiling before?`,
365
+ `and device ${this.device.udid}. Have you started the profiling before?`,
369
366
  );
370
367
  }
371
368
 
@@ -374,8 +371,7 @@ export default {
374
371
  if (!(await fs.exists(resultPath))) {
375
372
  this.log.errorAndThrow(
376
373
  `There is no ${DEFAULT_EXT} file found for performance profile '${profileName}' ` +
377
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
378
- `and device ${this.opts.device.udid}. Make sure the selected profile is supported on this device`,
374
+ `and device ${this.device.udid}. Make sure the selected profile is supported on this device`,
379
375
  );
380
376
  }
381
377
 
@@ -55,8 +55,11 @@ export default {
55
55
  }
56
56
  assertSimulator(this);
57
57
 
58
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
59
- return await this.opts.device.getPermission(bundleId, service);
58
+ return /** @type {import('./types').PermissionState} */ (
59
+ await /** @type {import('../driver').Simulator} */ (this.device).getPermission(
60
+ bundleId, String(service)
61
+ )
62
+ );
60
63
  },
61
64
 
62
65
  /**
@@ -75,8 +78,7 @@ export default {
75
78
  }
76
79
  assertSimulator(this);
77
80
 
78
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
79
- await this.opts.device.setPermissions(bundleId, access);
81
+ await /** @type {import('../driver').Simulator} */ (this.device).setPermissions(bundleId, access);
80
82
  },
81
83
  };
82
84
 
@@ -225,8 +225,7 @@ export default {
225
225
  });
226
226
 
227
227
  const wdaBaseUrl = this.opts.wdaBaseUrl || WDA_BASE_URL;
228
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
229
- const screenRecorder = new ScreenRecorder(this.opts.device.udid, this.log, videoPath, {
228
+ const screenRecorder = new ScreenRecorder(this.device.udid, this.log, videoPath, {
230
229
  remotePort: this.opts.mjpegServerPort || DEFAULT_MJPEG_SERVER_PORT,
231
230
  remoteUrl: wdaBaseUrl,
232
231
  usePortForwarding: this.isRealDevice() && isLocalHost(wdaBaseUrl),
@@ -1,10 +1,12 @@
1
1
  import {retryInterval} from 'asyncbox';
2
2
  import _ from 'lodash';
3
+ import {errors} from 'appium/driver';
3
4
  import {util, imageUtil} from 'appium/support';
4
5
 
5
6
  export default {
6
7
  /**
7
8
  * @this {XCUITestDriver}
9
+ * @returns {Promise<string>}
8
10
  */
9
11
  async getScreenshot() {
10
12
  const getScreenshotFromWDA = async () => {
@@ -38,12 +40,15 @@ export default {
38
40
  // simulator attempt
39
41
  if (this.isSimulator()) {
40
42
  this.log.info(`Falling back to 'simctl io screenshot' API`);
41
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
42
- return await this.opts.device.simctl.getScreenshot();
43
+ const payload = await /** @type {import('../driver').Simulator} */ (this.device).simctl.getScreenshot();
44
+ if (!payload) {
45
+ throw new errors.UnableToCaptureScreen();
46
+ }
47
+ return payload;
43
48
  }
44
49
 
45
50
  // Retry for real devices only. Fail fast on Simulator if simctl does not work as expected
46
- return await retryInterval(2, 1000, getScreenshotFromWDA);
51
+ return /** @type {string} */ (await retryInterval(2, 1000, getScreenshotFromWDA));
47
52
  },
48
53
  /**
49
54
  * @this {XCUITestDriver}
@@ -995,8 +995,7 @@ const extensions = {
995
995
  }
996
996
 
997
997
  this.log.debug(`About to update Safari preferences: ${JSON.stringify(preferences)}`);
998
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
999
- await this.opts.device.updateSafariSettings(preferences);
998
+ await /** @type {import('../driver').Simulator} */ (this.device).updateSafariSettings(preferences);
1000
999
  },
1001
1000
  };
1002
1001
 
@@ -32,8 +32,7 @@ const SUBDIRECTORY = 'Attachments';
32
32
  * @returns {Promise<string>} The full path to the screen recording movie
33
33
  */
34
34
  async function retrieveRecodingFromSimulator(uuid) {
35
- // @ts-ignore The property is there
36
- const device = this.opts.device;
35
+ const device = /** @type {import('../driver').Simulator} */ (this.device);
37
36
  const dataRoot = /** @type {string} */ (device.getDir());
38
37
  // On Simulators the path looks like
39
38
  // $HOME/Library/Developer/CoreSimulator/Devices/F8E1968A-8443-4A9A-AB86-27C54C36A2F6/data/Containers/Data/InternalDaemon/4E3FE8DF-AD0A-41DA-B6EC-C35E5798C219/Attachments/A044DAF7-4A58-4CD5-95C3-29B4FE80C377
@@ -59,8 +58,7 @@ async function retrieveRecodingFromSimulator(uuid) {
59
58
  * @returns {Promise<string>} The full path to the screen recording movie
60
59
  */
61
60
  async function retrieveRecodingFromRealDevice(uuid) {
62
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
63
- const device = this.opts.device;
61
+ const device = /** @type {import('../real-device').RealDevice} */ (this.device);
64
62
 
65
63
  const fileNames = await device.devicectl.listFiles(DOMAIN_TYPE, DOMAIN_IDENTIFIER, {
66
64
  username: USERNAME,
@@ -16,15 +16,13 @@ const xctestLog = logger.getLogger('XCTest');
16
16
  * @param {XCUITestDriver['opts']} opts Opts object from the driver instance
17
17
  */
18
18
  export function assertIDB(opts) {
19
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
20
- if (!opts.device?.idb || !opts.launchWithIDB) {
19
+ if (!this.device?.idb || !opts.launchWithIDB) {
21
20
  throw new Error(
22
21
  `To use XCTest runner, IDB (https://github.com/facebook/idb) must be installed ` +
23
22
  `and sessions must be run with the "launchWithIDB" capability`,
24
23
  );
25
24
  }
26
- // @ts-expect-error - do not assign arbitrary properties to `this.opts`
27
- return opts.device.idb;
25
+ return this.device.idb;
28
26
  }
29
27
 
30
28
  /**