@limrun/appium-xcuitest-driver 10.11.0-lim.3 → 10.14.6-lim.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 (285) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/build/lib/commands/active-app-info.d.ts +4 -3
  3. package/build/lib/commands/active-app-info.d.ts.map +1 -1
  4. package/build/lib/commands/active-app-info.js +2 -3
  5. package/build/lib/commands/active-app-info.js.map +1 -1
  6. package/build/lib/commands/alert.d.ts +26 -31
  7. package/build/lib/commands/alert.d.ts.map +1 -1
  8. package/build/lib/commands/alert.js +20 -29
  9. package/build/lib/commands/alert.js.map +1 -1
  10. package/build/lib/commands/app-management.d.ts +99 -76
  11. package/build/lib/commands/app-management.d.ts.map +1 -1
  12. package/build/lib/commands/app-management.js +83 -73
  13. package/build/lib/commands/app-management.js.map +1 -1
  14. package/build/lib/commands/app-strings.d.ts +6 -7
  15. package/build/lib/commands/app-strings.d.ts.map +1 -1
  16. package/build/lib/commands/app-strings.js +3 -8
  17. package/build/lib/commands/app-strings.js.map +1 -1
  18. package/build/lib/commands/appearance.d.ts +7 -9
  19. package/build/lib/commands/appearance.d.ts.map +1 -1
  20. package/build/lib/commands/appearance.js +13 -19
  21. package/build/lib/commands/appearance.js.map +1 -1
  22. package/build/lib/commands/audit.d.ts +5 -33
  23. package/build/lib/commands/audit.d.ts.map +1 -1
  24. package/build/lib/commands/audit.js +3 -16
  25. package/build/lib/commands/audit.js.map +1 -1
  26. package/build/lib/commands/battery.d.ts +4 -4
  27. package/build/lib/commands/battery.d.ts.map +1 -1
  28. package/build/lib/commands/battery.js +3 -7
  29. package/build/lib/commands/battery.js.map +1 -1
  30. package/build/lib/commands/biometric.d.ts +12 -14
  31. package/build/lib/commands/biometric.d.ts.map +1 -1
  32. package/build/lib/commands/biometric.js +10 -19
  33. package/build/lib/commands/biometric.js.map +1 -1
  34. package/build/lib/commands/certificate.d.ts +14 -19
  35. package/build/lib/commands/certificate.d.ts.map +1 -1
  36. package/build/lib/commands/certificate.js +24 -31
  37. package/build/lib/commands/certificate.js.map +1 -1
  38. package/build/lib/commands/clipboard.d.ts +9 -11
  39. package/build/lib/commands/clipboard.d.ts.map +1 -1
  40. package/build/lib/commands/clipboard.js +8 -13
  41. package/build/lib/commands/clipboard.js.map +1 -1
  42. package/build/lib/commands/condition.d.ts +9 -72
  43. package/build/lib/commands/condition.d.ts.map +1 -1
  44. package/build/lib/commands/condition.js +5 -66
  45. package/build/lib/commands/condition.js.map +1 -1
  46. package/build/lib/commands/content-size.d.ts +16 -19
  47. package/build/lib/commands/content-size.d.ts.map +1 -1
  48. package/build/lib/commands/content-size.js +14 -22
  49. package/build/lib/commands/content-size.js.map +1 -1
  50. package/build/lib/commands/context.d.ts +130 -161
  51. package/build/lib/commands/context.d.ts.map +1 -1
  52. package/build/lib/commands/context.js +123 -108
  53. package/build/lib/commands/context.js.map +1 -1
  54. package/build/lib/commands/device-info.d.ts +13 -0
  55. package/build/lib/commands/device-info.d.ts.map +1 -0
  56. package/build/lib/commands/device-info.js +20 -0
  57. package/build/lib/commands/device-info.js.map +1 -0
  58. package/build/lib/commands/element.d.ts +83 -67
  59. package/build/lib/commands/element.d.ts.map +1 -1
  60. package/build/lib/commands/element.js +111 -134
  61. package/build/lib/commands/element.js.map +1 -1
  62. package/build/lib/commands/execute.d.ts +10 -22
  63. package/build/lib/commands/execute.d.ts.map +1 -1
  64. package/build/lib/commands/execute.js +13 -29
  65. package/build/lib/commands/execute.js.map +1 -1
  66. package/build/lib/commands/file-movement.d.ts +31 -42
  67. package/build/lib/commands/file-movement.d.ts.map +1 -1
  68. package/build/lib/commands/file-movement.js +146 -205
  69. package/build/lib/commands/file-movement.js.map +1 -1
  70. package/build/lib/commands/find.d.ts +20 -12
  71. package/build/lib/commands/find.d.ts.map +1 -1
  72. package/build/lib/commands/find.js +27 -65
  73. package/build/lib/commands/find.js.map +1 -1
  74. package/build/lib/commands/general.d.ts +84 -80
  75. package/build/lib/commands/general.d.ts.map +1 -1
  76. package/build/lib/commands/general.js +67 -54
  77. package/build/lib/commands/general.js.map +1 -1
  78. package/build/lib/commands/geolocation.d.ts +16 -36
  79. package/build/lib/commands/geolocation.d.ts.map +1 -1
  80. package/build/lib/commands/geolocation.js +8 -25
  81. package/build/lib/commands/geolocation.js.map +1 -1
  82. package/build/lib/commands/gesture.d.ts +103 -119
  83. package/build/lib/commands/gesture.d.ts.map +1 -1
  84. package/build/lib/commands/gesture.js +98 -138
  85. package/build/lib/commands/gesture.js.map +1 -1
  86. package/build/lib/commands/increase-contrast.d.ts +10 -13
  87. package/build/lib/commands/increase-contrast.d.ts.map +1 -1
  88. package/build/lib/commands/increase-contrast.js +8 -16
  89. package/build/lib/commands/increase-contrast.js.map +1 -1
  90. package/build/lib/commands/iohid.d.ts +6 -1359
  91. package/build/lib/commands/iohid.d.ts.map +1 -1
  92. package/build/lib/commands/iohid.js +5 -10
  93. package/build/lib/commands/iohid.js.map +1 -1
  94. package/build/lib/commands/keyboard.d.ts +16 -13
  95. package/build/lib/commands/keyboard.d.ts.map +1 -1
  96. package/build/lib/commands/keyboard.js +14 -18
  97. package/build/lib/commands/keyboard.js.map +1 -1
  98. package/build/lib/commands/keychains.d.ts +2 -2
  99. package/build/lib/commands/keychains.d.ts.map +1 -1
  100. package/build/lib/commands/keychains.js +1 -4
  101. package/build/lib/commands/keychains.js.map +1 -1
  102. package/build/lib/commands/localization.d.ts +7 -6
  103. package/build/lib/commands/localization.d.ts.map +1 -1
  104. package/build/lib/commands/localization.js +7 -8
  105. package/build/lib/commands/localization.js.map +1 -1
  106. package/build/lib/commands/location.d.ts +8 -11
  107. package/build/lib/commands/location.d.ts.map +1 -1
  108. package/build/lib/commands/location.js +7 -15
  109. package/build/lib/commands/location.js.map +1 -1
  110. package/build/lib/commands/lock.d.ts +6 -10
  111. package/build/lib/commands/lock.d.ts.map +1 -1
  112. package/build/lib/commands/lock.js +3 -10
  113. package/build/lib/commands/lock.js.map +1 -1
  114. package/build/lib/commands/log.d.ts +42 -44
  115. package/build/lib/commands/log.d.ts.map +1 -1
  116. package/build/lib/commands/log.js +32 -53
  117. package/build/lib/commands/log.js.map +1 -1
  118. package/build/lib/commands/memory.d.ts +4 -5
  119. package/build/lib/commands/memory.d.ts.map +1 -1
  120. package/build/lib/commands/memory.js +3 -8
  121. package/build/lib/commands/memory.js.map +1 -1
  122. package/build/lib/commands/navigation.d.ts +14 -26
  123. package/build/lib/commands/navigation.d.ts.map +1 -1
  124. package/build/lib/commands/navigation.js +22 -32
  125. package/build/lib/commands/navigation.js.map +1 -1
  126. package/build/lib/commands/notifications.d.ts +10 -10
  127. package/build/lib/commands/notifications.d.ts.map +1 -1
  128. package/build/lib/commands/notifications.js +8 -12
  129. package/build/lib/commands/notifications.js.map +1 -1
  130. package/build/lib/commands/pasteboard.d.ts +9 -10
  131. package/build/lib/commands/pasteboard.d.ts.map +1 -1
  132. package/build/lib/commands/pasteboard.js +8 -13
  133. package/build/lib/commands/pasteboard.js.map +1 -1
  134. package/build/lib/commands/pcap.d.ts +18 -38
  135. package/build/lib/commands/pcap.d.ts.map +1 -1
  136. package/build/lib/commands/pcap.js +9 -14
  137. package/build/lib/commands/pcap.js.map +1 -1
  138. package/build/lib/commands/performance.d.ts +36 -55
  139. package/build/lib/commands/performance.d.ts.map +1 -1
  140. package/build/lib/commands/performance.js +93 -86
  141. package/build/lib/commands/performance.js.map +1 -1
  142. package/build/lib/commands/permissions.d.ts +15 -17
  143. package/build/lib/commands/permissions.d.ts.map +1 -1
  144. package/build/lib/commands/permissions.js +12 -18
  145. package/build/lib/commands/permissions.js.map +1 -1
  146. package/build/lib/commands/proxy-helper.d.ts +11 -11
  147. package/build/lib/commands/proxy-helper.d.ts.map +1 -1
  148. package/build/lib/commands/proxy-helper.js +15 -24
  149. package/build/lib/commands/proxy-helper.js.map +1 -1
  150. package/build/lib/commands/record-audio.d.ts +25 -52
  151. package/build/lib/commands/record-audio.d.ts.map +1 -1
  152. package/build/lib/commands/record-audio.js +17 -19
  153. package/build/lib/commands/record-audio.js.map +1 -1
  154. package/build/lib/commands/recordscreen.d.ts +31 -62
  155. package/build/lib/commands/recordscreen.d.ts.map +1 -1
  156. package/build/lib/commands/recordscreen.js +29 -28
  157. package/build/lib/commands/recordscreen.js.map +1 -1
  158. package/build/lib/commands/screenshots.d.ts +15 -9
  159. package/build/lib/commands/screenshots.d.ts.map +1 -1
  160. package/build/lib/commands/screenshots.js +16 -16
  161. package/build/lib/commands/screenshots.js.map +1 -1
  162. package/build/lib/commands/simctl.d.ts +16 -22
  163. package/build/lib/commands/simctl.d.ts.map +1 -1
  164. package/build/lib/commands/simctl.js +13 -17
  165. package/build/lib/commands/simctl.js.map +1 -1
  166. package/build/lib/commands/source.d.ts +10 -8
  167. package/build/lib/commands/source.d.ts.map +1 -1
  168. package/build/lib/commands/source.js +11 -14
  169. package/build/lib/commands/source.js.map +1 -1
  170. package/build/lib/commands/timeouts.d.ts +25 -32
  171. package/build/lib/commands/timeouts.d.ts.map +1 -1
  172. package/build/lib/commands/timeouts.js +19 -15
  173. package/build/lib/commands/timeouts.js.map +1 -1
  174. package/build/lib/commands/types.d.ts +80 -0
  175. package/build/lib/commands/types.d.ts.map +1 -1
  176. package/build/lib/commands/web.d.ts +199 -202
  177. package/build/lib/commands/web.d.ts.map +1 -1
  178. package/build/lib/commands/web.js +216 -175
  179. package/build/lib/commands/web.js.map +1 -1
  180. package/build/lib/commands/xctest-record-screen.d.ts +17 -47
  181. package/build/lib/commands/xctest-record-screen.d.ts.map +1 -1
  182. package/build/lib/commands/xctest-record-screen.js +28 -59
  183. package/build/lib/commands/xctest-record-screen.js.map +1 -1
  184. package/build/lib/commands/xctest.d.ts +37 -37
  185. package/build/lib/commands/xctest.d.ts.map +1 -1
  186. package/build/lib/commands/xctest.js +38 -50
  187. package/build/lib/commands/xctest.js.map +1 -1
  188. package/build/lib/desired-caps.js +1 -1
  189. package/build/lib/device/log/ios-simulator-log.d.ts.map +1 -1
  190. package/build/lib/device/log/ios-simulator-log.js +2 -0
  191. package/build/lib/device/log/ios-simulator-log.js.map +1 -1
  192. package/build/lib/device/simulator-management.d.ts.map +1 -1
  193. package/build/lib/device/simulator-management.js +4 -5
  194. package/build/lib/device/simulator-management.js.map +1 -1
  195. package/build/lib/device-log/ios-crash-log.d.ts +1 -1
  196. package/build/lib/device-log/ios-crash-log.d.ts.map +1 -1
  197. package/build/lib/device-log/ios-simulator-log.d.ts +1 -1
  198. package/build/lib/device-log/ios-simulator-log.d.ts.map +1 -1
  199. package/build/lib/doctor/optional-checks.d.ts +0 -9
  200. package/build/lib/doctor/optional-checks.d.ts.map +1 -1
  201. package/build/lib/doctor/optional-checks.js +1 -30
  202. package/build/lib/doctor/optional-checks.js.map +1 -1
  203. package/build/lib/driver.d.ts +11 -3
  204. package/build/lib/driver.d.ts.map +1 -1
  205. package/build/lib/driver.js +36 -12
  206. package/build/lib/driver.js.map +1 -1
  207. package/build/lib/execute-method-map.d.ts.map +1 -1
  208. package/build/lib/execute-method-map.js +0 -9
  209. package/build/lib/execute-method-map.js.map +1 -1
  210. package/build/lib/simulator-management.js +3 -3
  211. package/build/lib/simulator-management.js.map +1 -1
  212. package/lib/commands/active-app-info.ts +15 -0
  213. package/lib/commands/alert.ts +98 -0
  214. package/lib/commands/app-management.ts +414 -0
  215. package/lib/commands/{app-strings.js → app-strings.ts} +10 -9
  216. package/lib/commands/appearance.ts +70 -0
  217. package/lib/commands/audit.ts +25 -0
  218. package/lib/commands/{battery.js → battery.ts} +10 -12
  219. package/lib/commands/biometric.ts +52 -0
  220. package/lib/commands/{certificate.js → certificate.ts} +55 -50
  221. package/lib/commands/clipboard.ts +37 -0
  222. package/lib/commands/{condition.js → condition.ts} +21 -77
  223. package/lib/commands/content-size.ts +67 -0
  224. package/lib/commands/{context.js → context.ts} +174 -146
  225. package/lib/commands/device-info.ts +24 -0
  226. package/lib/commands/element.ts +419 -0
  227. package/lib/commands/{execute.js → execute.ts} +42 -38
  228. package/lib/commands/{file-movement.js → file-movement.ts} +212 -235
  229. package/lib/commands/find.ts +277 -0
  230. package/lib/commands/{general.js → general.ts} +102 -77
  231. package/lib/commands/geolocation.ts +55 -0
  232. package/lib/commands/{gesture.js → gesture.ts} +225 -183
  233. package/lib/commands/increase-contrast.ts +49 -0
  234. package/lib/commands/{iohid.js → iohid.ts} +15 -13
  235. package/lib/commands/keyboard.ts +70 -0
  236. package/lib/commands/keychains.ts +16 -0
  237. package/lib/commands/{localization.js → localization.ts} +22 -12
  238. package/lib/commands/{location.js → location.ts} +19 -22
  239. package/lib/commands/lock.ts +43 -0
  240. package/lib/commands/{log.js → log.ts} +68 -68
  241. package/lib/commands/{memory.js → memory.ts} +9 -9
  242. package/lib/commands/{navigation.js → navigation.ts} +42 -39
  243. package/lib/commands/{notifications.js → notifications.ts} +22 -14
  244. package/lib/commands/pasteboard.ts +44 -0
  245. package/lib/commands/{pcap.js → pcap.ts} +28 -28
  246. package/lib/commands/{performance.js → performance.ts} +133 -114
  247. package/lib/commands/permissions.ts +90 -0
  248. package/lib/commands/{proxy-helper.js → proxy-helper.ts} +26 -26
  249. package/lib/commands/{record-audio.js → record-audio.ts} +35 -33
  250. package/lib/commands/{recordscreen.js → recordscreen.ts} +78 -50
  251. package/lib/commands/{screenshots.js → screenshots.ts} +27 -21
  252. package/lib/commands/simctl.ts +82 -0
  253. package/lib/commands/{source.js → source.ts} +23 -20
  254. package/lib/commands/timeouts.ts +95 -0
  255. package/lib/commands/types.ts +86 -0
  256. package/lib/commands/{web.js → web.ts} +314 -264
  257. package/lib/commands/{xctest-record-screen.js → xctest-record-screen.ts} +54 -71
  258. package/lib/commands/{xctest.js → xctest.ts} +78 -71
  259. package/lib/desired-caps.ts +1 -1
  260. package/lib/device/log/ios-simulator-log.ts +2 -0
  261. package/lib/device/simulator-management.ts +3 -6
  262. package/lib/doctor/optional-checks.ts +0 -33
  263. package/lib/driver.ts +38 -13
  264. package/lib/execute-method-map.ts +0 -9
  265. package/package.json +6 -5
  266. package/lib/commands/active-app-info.js +0 -12
  267. package/lib/commands/alert.js +0 -88
  268. package/lib/commands/app-management.js +0 -346
  269. package/lib/commands/appearance.js +0 -71
  270. package/lib/commands/audit.js +0 -31
  271. package/lib/commands/biometric.js +0 -52
  272. package/lib/commands/clipboard.js +0 -35
  273. package/lib/commands/content-size.js +0 -68
  274. package/lib/commands/deviceInfo.js +0 -27
  275. package/lib/commands/element.js +0 -423
  276. package/lib/commands/find.js +0 -205
  277. package/lib/commands/geolocation.js +0 -56
  278. package/lib/commands/increase-contrast.js +0 -50
  279. package/lib/commands/keyboard.js +0 -62
  280. package/lib/commands/keychains.js +0 -17
  281. package/lib/commands/lock.js +0 -46
  282. package/lib/commands/pasteboard.js +0 -43
  283. package/lib/commands/permissions.js +0 -85
  284. package/lib/commands/simctl.js +0 -71
  285. package/lib/commands/timeouts.js +0 -68
@@ -10,6 +10,11 @@ import {
10
10
  } from './bidi/models';
11
11
  import { BIDI_EVENT_NAME } from './bidi/constants';
12
12
  import { assignBiDiLogListener } from './log';
13
+ import type {XCUITestDriver} from '../driver';
14
+ import type {Page} from '../types';
15
+ import type {ViewContext, FullContext, PageChangeNotification} from './types';
16
+ import type {Simulator} from 'appium-ios-simulator';
17
+ import type { LogLevel } from '@limrun/api';
13
18
 
14
19
  const WEBVIEW_WIN = 'WEBVIEW';
15
20
  const WEBVIEW_BASE = `${WEBVIEW_WIN}_`;
@@ -19,17 +24,14 @@ const DEFAULT_NATIVE_WINDOW_HANDLE = '1';
19
24
 
20
25
 
21
26
  /**
22
- * @this {XCUITestDriver}
23
- * @param {boolean} [useUrl=false]
24
- * @returns {Promise<import('./types').ViewContext[]>}
27
+ * Retrieves the list of available contexts and their associated views.
28
+ *
29
+ * @param useUrl - Whether to filter webviews by URL
25
30
  */
26
- export async function getContextsAndViews(useUrl = true) {
31
+ export async function getContextsAndViews(this: XCUITestDriver, useUrl: boolean = true): Promise<ViewContext[]> {
27
32
  this.log.debug('Retrieving contexts and views');
28
33
  const webviews = await this.listWebFrames(useUrl);
29
- /**
30
- * @type {import('./types').ViewContext[]}
31
- */
32
- const ctxs = [{id: NATIVE_WIN, view: {}}];
34
+ const ctxs: ViewContext[] = [{id: NATIVE_WIN, view: {}}];
33
35
  this.contexts = [NATIVE_WIN];
34
36
  for (const view of webviews) {
35
37
  ctxs.push({id: `${WEBVIEW_BASE}${view.id}`, view});
@@ -39,19 +41,18 @@ export async function getContextsAndViews(useUrl = true) {
39
41
  }
40
42
 
41
43
  /**
42
- * @deprecated this method is not used anywhere and will be removed in the future
43
- * @this {XCUITestDriver}
44
- * @returns {boolean}
44
+ * @deprecated This method is not used anywhere and will be removed in the future
45
45
  */
46
- export function useNewSafari() {
46
+ export function useNewSafari(this: XCUITestDriver): boolean {
47
47
  return this.isSimulator() && this.isSafari();
48
48
  }
49
49
 
50
50
  /**
51
- * @this {XCUITestDriver}
52
- * @returns {Promise<void>}
51
+ * Activates the most recently available webview context.
52
+ *
53
+ * @throws {Error} If no webview is available or if the remote debugger cannot connect
53
54
  */
54
- export async function activateRecentWebview() {
55
+ export async function activateRecentWebview(this: XCUITestDriver): Promise<void> {
55
56
  this.log.debug('Activating a recent webview');
56
57
  const timer = new timing.Timer().start();
57
58
  const contextId = await this.getRecentWebviewContextId(/.*/, /.*/);
@@ -60,7 +61,7 @@ export async function activateRecentWebview() {
60
61
  await this.setContext(contextId);
61
62
  return;
62
63
  }
63
- const appDict = (/** @type {RemoteDebugger} */ (this.remote)).appDict;
64
+ const appDict = this.remote.appDict;
64
65
  const errSuffix = `Make sure your web application is debuggable ` +
65
66
  `and could be inspected in Safari Web Inspector.`;
66
67
  if (_.isEmpty(appDict)) {
@@ -92,22 +93,23 @@ export async function activateRecentWebview() {
92
93
  }
93
94
 
94
95
  /**
95
- * @this {XCUITestDriver}
96
- * @returns {Promise<import('../types').Page[]>}
96
+ * Lists all available web frames (pages) from the remote debugger.
97
+ *
98
+ * @param useUrl - Whether to filter pages by the current URL
97
99
  */
98
- export async function listWebFrames(useUrl = true) {
100
+ export async function listWebFrames(this: XCUITestDriver, useUrl: boolean = true): Promise<Page[]> {
99
101
  const shouldFilterByUrl = useUrl && !this.isRealDevice() && !!this.getCurrentUrl();
100
102
  this.log.debug(
101
103
  `Selecting by url: ${shouldFilterByUrl}` +
102
104
  (shouldFilterByUrl ? ` (expected url: '${this.getCurrentUrl()}')` : '')
103
105
  );
104
106
 
105
- if (!this.remote) {
107
+ if (!this._remote) {
106
108
  await this.connectToRemoteDebugger();
107
109
  }
108
- const doListPages = async (/** @type {number} */ retries) => {
110
+ const doListPages = async (retries: number): Promise<Page[]> => {
109
111
  try {
110
- const pageArray = await (/** @type {RemoteDebugger} */ (this.remote)).selectApp(
112
+ const pageArray = await this.remote.selectApp(
111
113
  shouldFilterByUrl ? this.getCurrentUrl() : undefined,
112
114
  retries,
113
115
  this.opts.ignoreAboutBlankUrl,
@@ -117,7 +119,7 @@ export async function listWebFrames(useUrl = true) {
117
119
  this.log.debug(`No web frames found after ${util.pluralize('retry', retries, true)}`);
118
120
  }
119
121
  return pageArray;
120
- } catch (err) {
122
+ } catch (err: any) {
121
123
  this.log.debug(
122
124
  `No available web pages after ${util.pluralize('retry', retries, true)}: ${err.message}`
123
125
  );
@@ -125,9 +127,8 @@ export async function listWebFrames(useUrl = true) {
125
127
  }
126
128
  };
127
129
 
128
- /** @type {number} */
129
130
  const maxRetriesCount = _.isInteger(this.opts.webviewConnectRetries)
130
- ? Math.max(/** @type {number} */ (this.opts.webviewConnectRetries), 1)
131
+ ? Math.max(this.opts.webviewConnectRetries as number, 1)
131
132
  : DEFAULT_LIST_WEB_FRAMES_RETRIES;
132
133
  this.log.debug(
133
134
  `About to select a web application with ${util.pluralize('retry', maxRetriesCount, true)} ` +
@@ -138,11 +139,10 @@ export async function listWebFrames(useUrl = true) {
138
139
  }
139
140
 
140
141
  /**
141
- * @this {XCUITestDriver}
142
- * @returns {Promise<void>}
142
+ * Establishes a connection to the remote debugger and sets up event listeners.
143
143
  */
144
- export async function connectToRemoteDebugger() {
145
- this.remote = await this.getNewRemoteDebugger();
144
+ export async function connectToRemoteDebugger(this: XCUITestDriver): Promise<void> {
145
+ this._remote = await this.getNewRemoteDebugger();
146
146
 
147
147
  // @ts-ignore static is fine
148
148
  this.remote.on(RemoteDebugger.EVENT_PAGE_CHANGE, this.onPageChange.bind(this));
@@ -181,14 +181,14 @@ export async function connectToRemoteDebugger() {
181
181
  * client code would have to connect to each of them in order to detect the
182
182
  * one which needs to be interacted with. This extra effort is not needed with
183
183
  * the information provided by this extension.
184
- * @param {number} [waitForWebviewMs=0] - The period to poll for available webview(s) (in ms)
185
- * @returns {Promise<Context[]>} The list of available context objects along with their properties.
186
- * @this {XCUITestDriver}
184
+ *
185
+ * @param waitForWebviewMs - The period to poll for available webview(s) (in ms)
186
+ * @returns The list of available context objects along with their properties.
187
187
  */
188
- export async function mobileGetContexts(waitForWebviewMs = 0) {
188
+ export async function mobileGetContexts(this: XCUITestDriver, waitForWebviewMs: number = 0): Promise<FullContext[]> {
189
189
  // make sure it is a number, so the duration check works properly
190
190
  if (!_.isNumber(waitForWebviewMs)) {
191
- waitForWebviewMs = parseInt(waitForWebviewMs, 10);
191
+ waitForWebviewMs = parseInt(String(waitForWebviewMs), 10);
192
192
  if (isNaN(waitForWebviewMs)) {
193
193
  waitForWebviewMs = 0;
194
194
  }
@@ -199,10 +199,9 @@ export async function mobileGetContexts(waitForWebviewMs = 0) {
199
199
 
200
200
  const timer = new timing.Timer().start();
201
201
  try {
202
- /** @type {FullContext[]} */
203
- let contexts;
202
+ let contexts: FullContext[];
204
203
  do {
205
- contexts = /** @type {FullContext[]} */ (await this.getContexts());
204
+ contexts = await this.getContexts() as FullContext[];
206
205
 
207
206
  if (contexts.length >= 2) {
208
207
  this.log.debug(
@@ -220,11 +219,13 @@ export async function mobileGetContexts(waitForWebviewMs = 0) {
220
219
  }
221
220
 
222
221
  /**
223
- * @this {XCUITestDriver}
224
- * @param {import('./types').PageChangeNotification} pageChangeNotification
225
- * @returns {Promise<void>}
222
+ * Handles page change notifications from the remote debugger.
223
+ *
224
+ * Updates the current context when new pages are detected or when pages are closed.
225
+ *
226
+ * @param pageChangeNotification - The notification containing page array and app ID
226
227
  */
227
- export async function onPageChange(pageChangeNotification) {
228
+ export async function onPageChange(this: XCUITestDriver, pageChangeNotification: PageChangeNotification): Promise<void> {
228
229
  this.log.debug(
229
230
  `Remote debugger notified us of a new page listing: ${JSON.stringify(
230
231
  pageChangeNotification,
@@ -234,19 +235,16 @@ export async function onPageChange(pageChangeNotification) {
234
235
  this.log.debug('We are in the middle of selecting a page, ignoring');
235
236
  return;
236
237
  }
237
- if (!this.remote?.isConnected) {
238
+ if (!this._remote?.isConnected) {
238
239
  this.log.debug('We have not yet connected, ignoring');
239
240
  return;
240
241
  }
241
242
 
242
243
  const {appIdKey, pageArray} = pageChangeNotification;
243
244
 
244
- /** @type {string[]} */
245
- const newIds = [];
246
- /** @type {string[]} */
247
- const newPages = [];
248
- /** @type {string|null} */
249
- let keyId = null;
245
+ const newIds: string[] = [];
246
+ const newPages: string[] = [];
247
+ let keyId: string | null = null;
250
248
  for (const page of pageArray) {
251
249
  const id = page.id.toString();
252
250
  newIds.push(id);
@@ -286,10 +284,9 @@ export async function onPageChange(pageChangeNotification) {
286
284
  return;
287
285
  }
288
286
 
289
- /** @type {string|null} */
290
- let newPage = null;
287
+ let newPage: string | null = null;
291
288
  if (newPages.length) {
292
- newPage = /** @type {string} */ (_.last(newPages));
289
+ newPage = _.last(newPages) as string;
293
290
  this.log.debug(`We have new pages, selecting page '${newPage}'`);
294
291
  } else if (!_.includes(newIds, curPageIdKey)) {
295
292
  this.log.debug(
@@ -330,7 +327,7 @@ export async function onPageChange(pageChangeNotification) {
330
327
  try {
331
328
  await this.remote.selectPage(appIdKey, parseInt(newPage, 10));
332
329
  await notifyBiDiContextChange.bind(this)();
333
- } catch (e) {
330
+ } catch (e: any) {
334
331
  this.log.warn(`Failed to select page: ${e.message}`);
335
332
  this.curContext = oldContext;
336
333
  } finally {
@@ -340,47 +337,58 @@ export async function onPageChange(pageChangeNotification) {
340
337
  }
341
338
 
342
339
  /**
343
- * @this {XCUITestDriver}
344
- * @returns {Promise<void>}
340
+ * Disconnects from the remote debugger and cleans up context state.
345
341
  */
346
- export async function stopRemote(closeWindowBeforeDisconnecting = false) {
347
- if (!this.remote) {
348
- throw this.log.errorWithException('Tried to leave a web frame but were not in one');
342
+ export async function stopRemote(this: XCUITestDriver): Promise<void> {
343
+ if (!this._remote) {
344
+ return;
349
345
  }
350
346
 
351
- if (closeWindowBeforeDisconnecting) {
352
- await this.closeWindow();
347
+ try {
348
+ await this.remote.disconnect();
349
+ this.curContext = null;
350
+ try {
351
+ await notifyBiDiContextChange.bind(this)();
352
+ } catch (err) {
353
+ this.log.warn(`Failed to notify BiDi context change: ${err.message}`);
354
+ }
355
+ } finally {
356
+ this.curWebFrames = [];
357
+ this._remote = null;
353
358
  }
354
- await this.remote.disconnect();
355
- this.curContext = null;
356
- await notifyBiDiContextChange.bind(this)();
357
- this.curWebFrames = [];
358
- this.remote = null;
359
359
  }
360
360
 
361
361
  /**
362
- * @this {XCUITestDriver}
363
- * @param {string|null} url
362
+ * Sets the current URL for the active webview context.
363
+ *
364
+ * @param url - The URL to set, or null to clear
364
365
  */
365
- export function setCurrentUrl(url) {
366
+ export function setCurrentUrl(this: XCUITestDriver, url: string | null): void {
366
367
  this._currentUrl = url;
367
368
  }
368
369
 
369
370
  /**
370
- * @this {XCUITestDriver}
371
- * @returns {string|undefined|null}
371
+ * Gets the current URL for the active webview context.
372
+ *
373
+ * @returns The current URL, or undefined/null if not set
372
374
  */
373
- export function getCurrentUrl() {
375
+ export function getCurrentUrl(this: XCUITestDriver): string | undefined | null {
374
376
  return this._currentUrl;
375
377
  }
376
378
 
377
379
  /**
378
- * @param {RegExp} titleRegExp
379
- * @param {RegExp} urlRegExp
380
- * @this {XCUITestDriver}
381
- * @returns {Promise<string|undefined>}
380
+ * Finds the most recent webview context ID matching the given title or URL patterns.
381
+ *
382
+ * @param titleRegExp - Regular expression to match against page titles
383
+ * @param urlRegExp - Regular expression to match against page URLs
384
+ * @returns The matching context ID, or undefined if no match is found
385
+ * @throws {errors.InvalidArgumentError} If neither regex is provided
382
386
  */
383
- export async function getRecentWebviewContextId(titleRegExp, urlRegExp) {
387
+ export async function getRecentWebviewContextId(
388
+ this: XCUITestDriver,
389
+ titleRegExp: RegExp,
390
+ urlRegExp: RegExp,
391
+ ): Promise<string | undefined> {
384
392
  if (!_.isRegExp(titleRegExp) && !_.isRegExp(urlRegExp)) {
385
393
  throw new errors.InvalidArgumentError(
386
394
  'A regular expression for either web view title or url must be provided',
@@ -404,33 +412,38 @@ export async function getRecentWebviewContextId(titleRegExp, urlRegExp) {
404
412
  }
405
413
 
406
414
  /**
407
- * @this {XCUITestDriver}
408
- * @returns {boolean}
415
+ * Checks if the current context is a web context (not native).
416
+ *
417
+ * @returns True if currently in a web context
409
418
  */
410
- export function isWebContext() {
419
+ export function isWebContext(this: XCUITestDriver): boolean {
411
420
  return !!this.curContext && this.curContext !== NATIVE_WIN;
412
421
  }
413
422
 
414
423
  /**
415
- * @this {XCUITestDriver}
416
- * @returns {boolean}
424
+ * Checks if the current context is a webview.
425
+ *
426
+ * This is an alias for {@linkcode isWebContext}.
427
+ *
428
+ * @returns True if currently in a webview context
417
429
  */
418
- export function isWebview() {
430
+ export function isWebview(this: XCUITestDriver): boolean {
419
431
  return this.isWebContext();
420
432
  }
421
433
 
422
434
  /**
423
- * @this {XCUITestDriver}
424
- * @returns {Promise<RemoteDebugger>}
435
+ * Creates a new remote debugger instance configured for the current device.
436
+ *
437
+ * @returns A configured RemoteDebugger instance
425
438
  */
426
- export async function getNewRemoteDebugger() {
439
+ export async function getNewRemoteDebugger(this: XCUITestDriver): Promise<RemoteDebugger> {
427
440
  const socketPath = this.isRealDevice()
428
441
  ? undefined
429
- : (await /** @type {import('appium-ios-simulator').Simulator} */ (this.device).getWebInspectorSocket() ?? undefined);
442
+ : (await (this.device as Simulator).getWebInspectorSocket() ?? undefined);
430
443
  return createRemoteDebugger(
431
444
  {
432
445
  bundleId: this.opts.bundleId,
433
- additionalBundleIds: /** @type {string[] | undefined} */ (this.opts.additionalWebviewBundleIds),
446
+ additionalBundleIds: this.opts.additionalWebviewBundleIds as string[] | undefined,
434
447
  isSafari: this.isSafari(),
435
448
  includeSafari: this.opts.includeSafariInWebviews,
436
449
  pageLoadMs: this.pageLoadMs,
@@ -440,7 +453,7 @@ export async function getNewRemoteDebugger() {
440
453
  garbageCollectOnExecute: util.hasValue(this.opts.safariGarbageCollect)
441
454
  ? !!this.opts.safariGarbageCollect
442
455
  : false,
443
- udid: /** @type {string} */ (this.opts.udid),
456
+ udid: this.opts.udid as string,
444
457
  logAllCommunication: this.opts.safariLogAllCommunication,
445
458
  logAllCommunicationHexDump: this.opts.safariLogAllCommunicationHexDump,
446
459
  socketChunkSize: this.opts.safariSocketChunkSize,
@@ -448,17 +461,18 @@ export async function getNewRemoteDebugger() {
448
461
  pageLoadStrategy: this.caps.pageLoadStrategy,
449
462
  limInstanceApiUrl: this.opts.limInstanceApiUrl,
450
463
  limInstanceToken: this.opts.limInstanceToken,
451
- limLogLevel: /** @type {import('@limrun/api').LogLevel} */ (this.opts.limLogLevel),
464
+ limLogLevel: this.opts.limLogLevel as LogLevel | undefined,
452
465
  },
453
466
  this.isRealDevice(),
454
467
  );
455
468
  }
456
469
 
457
470
  /**
458
- * @this {XCUITestDriver}
459
- * @returns {Promise<string>}
471
+ * Gets the identifier of the current context.
472
+ *
473
+ * @returns The context identifier (e.g., 'NATIVE_APP' or 'WEBVIEW_xxx')
460
474
  */
461
- export async function getCurrentContext() {
475
+ export async function getCurrentContext(this: XCUITestDriver): Promise<string> {
462
476
  if (this.curContext && this.curContext !== NATIVE_WIN) {
463
477
  return `${WEBVIEW_BASE}${this.curContext}`;
464
478
  }
@@ -466,28 +480,32 @@ export async function getCurrentContext() {
466
480
  }
467
481
 
468
482
  /**
469
- * Set context
483
+ * Switches to the specified context (native or webview).
470
484
  *
471
- * @param {string|Context} name - The name of context to set. It could be 'null' as NATIVE_WIN.
472
- * @param {any} [callback] The callback. (It is not called in this method)
473
- * @param {boolean} [skipReadyCheck=false] - Whether it waits for the new context is ready
474
- * @this {XCUITestDriver}
475
- * @returns {Promise<void>}
485
+ * @param name - The name of context to set. Can be 'NATIVE_APP', 'WEBVIEW_xxx', or null
486
+ * @param callback - The callback (not used, kept for compatibility)
487
+ * @param skipReadyCheck - Whether to skip waiting for the new context to be ready
488
+ * @throws {errors.NoSuchContextError} If the specified context does not exist
476
489
  */
477
- export async function setContext(name, callback, skipReadyCheck = false) {
478
- function alreadyInContext(desired, current) {
490
+ export async function setContext(
491
+ this: XCUITestDriver,
492
+ name: string | {id: string} | null,
493
+ callback?: any,
494
+ skipReadyCheck: boolean = false,
495
+ ): Promise<void> {
496
+ function alreadyInContext(desired: string | null, current: string | null): boolean {
479
497
  return (
480
498
  desired === current ||
481
499
  (desired === null && current === NATIVE_WIN) ||
482
500
  (desired === NATIVE_WIN && current === null)
483
501
  );
484
502
  }
485
- function isNativeContext(context) {
503
+ function isNativeContext(context: string | null): boolean {
486
504
  return context === NATIVE_WIN || context === null;
487
505
  }
488
506
 
489
507
  // allow the full context list to be passed in
490
- const strName = String(typeof name === 'object' && name.id ? name.id : name);
508
+ const strName = String(typeof name === 'object' && name && 'id' in name ? name.id : name);
491
509
 
492
510
  this.log.debug(
493
511
  `Attempting to set context to '${strName || NATIVE_WIN}' from '${
@@ -522,7 +540,7 @@ export async function setContext(name, callback, skipReadyCheck = false) {
522
540
  // allow user to pass in "WEBVIEW" without an index
523
541
  // the second context will be the first webview as
524
542
  // the first is always NATIVE_APP
525
- contextId = /** @type {string[]} */ (this.contexts)[1];
543
+ contextId = (this.contexts as string[])[1];
526
544
  }
527
545
  if (!_.includes(this.contexts, contextId)) {
528
546
  throw new errors.NoSuchContextError();
@@ -535,7 +553,7 @@ export async function setContext(name, callback, skipReadyCheck = false) {
535
553
  const [appIdKey, pageIdKey] = _.map(contextId.split('.'), (id) => parseInt(id, 10));
536
554
  try {
537
555
  this.selectingNewPage = true;
538
- await (/** @type {RemoteDebugger} */ (this.remote)).selectPage(appIdKey, pageIdKey, skipReadyCheck);
556
+ await this.remote.selectPage(appIdKey, pageIdKey, skipReadyCheck);
539
557
  await notifyBiDiContextChange.bind(this)();
540
558
  } catch (err) {
541
559
  this.curContext = this.curWindowHandle = oldContext;
@@ -545,7 +563,7 @@ export async function setContext(name, callback, skipReadyCheck = false) {
545
563
  }
546
564
 
547
565
  // attempt to start performance logging, if requested
548
- if (this.opts.enablePerformanceLogging && this.remote) {
566
+ if (this.opts.enablePerformanceLogging && this._remote) {
549
567
  const context = this.curContext;
550
568
  this.log.debug(`Starting performance log on '${context}'`);
551
569
  [this.logs.performance,] = assignBiDiLogListener.bind(this)(
@@ -563,46 +581,56 @@ export async function setContext(name, callback, skipReadyCheck = false) {
563
581
  // start safari logging if the logs handlers are active
564
582
  if (name && name !== NATIVE_WIN && this.logs) {
565
583
  if (this.logs.safariConsole) {
566
- (/** @type {RemoteDebugger} */ (this.remote)).startConsole(
584
+ this.remote.startConsole(
567
585
  this.logs.safariConsole.onConsoleLogEvent.bind(this.logs.safariConsole),
568
586
  );
569
587
  }
570
588
  if (this.logs.safariNetwork) {
571
- (/** @type {RemoteDebugger} */ (this.remote)).startNetwork(
589
+ this.remote.startNetwork(
572
590
  this.logs.safariNetwork.onNetworkEvent.bind(this.logs.safariNetwork),
573
- );
591
+ );
592
+ }
574
593
  }
575
594
  }
576
- }
577
595
 
578
596
  /**
579
- * @this {XCUITestDriver}
580
- * @returns {Promise<string[]|FullContext[]>}
597
+ * Gets the list of available contexts.
598
+ *
599
+ * The format depends on the `fullContextList` option:
600
+ * - If enabled, returns full context objects with title, URL, and bundleId
601
+ * - If disabled, returns simple context ID strings
602
+ *
603
+ * @returns Array of context IDs or full context objects
581
604
  */
582
- export async function getContexts() {
605
+ export async function getContexts(this: XCUITestDriver): Promise<string[] | FullContext[]> {
583
606
  this.log.debug('Getting list of available contexts');
584
607
  const contexts = await this.getContextsAndViews(false);
585
608
 
586
609
  if (this.opts.fullContextList) {
587
- return /** @type {import('./types').FullContext[]} */ (
588
- contexts.map((context) => ({
589
- id: context.id.toString(),
590
- title: context.view?.title,
591
- url: context.view?.url,
592
- bundleId: context.view?.bundleId,
593
- }))
594
- );
610
+ return contexts.map((context) => ({
611
+ id: context.id.toString(),
612
+ title: context.view?.title,
613
+ url: context.view?.url,
614
+ bundleId: context.view?.bundleId,
615
+ })) as FullContext[];
595
616
  }
596
- return /** @type {string[]} */ (contexts.map((context) => context.id.toString()));
617
+ return contexts.map((context) => context.id.toString());
597
618
  }
598
619
 
599
620
  /**
600
- * @this {XCUITestDriver}
601
- * @param {string} name
602
- * @param {boolean} [skipReadyCheck]
603
- * @returns {Promise<void>}
621
+ * Sets the current window (context) in a web context.
622
+ *
623
+ * This is a wrapper around {@linkcode setContext} that translates errors appropriately.
624
+ *
625
+ * @param name - The window/context name to switch to
626
+ * @param skipReadyCheck - Whether to skip waiting for the window to be ready
627
+ * @throws {errors.NoSuchWindowError} If the window does not exist
604
628
  */
605
- export async function setWindow(name, skipReadyCheck) {
629
+ export async function setWindow(
630
+ this: XCUITestDriver,
631
+ name: string,
632
+ skipReadyCheck?: boolean,
633
+ ): Promise<void> {
606
634
  if (!this.isWebContext()) {
607
635
  // https://github.com/appium/appium/issues/20710
608
636
  return;
@@ -616,10 +644,14 @@ export async function setWindow(name, skipReadyCheck) {
616
644
  }
617
645
 
618
646
  /**
619
- * @this {XCUITestDriver}
620
- * @returns {Promise<string>}
647
+ * Gets the handle of the current window.
648
+ *
649
+ * In native context, returns a default handle. In web context, returns the current context ID.
650
+ *
651
+ * @returns The window handle
652
+ * @throws {errors.InvalidContextError} If not in a valid context
621
653
  */
622
- export async function getWindowHandle() {
654
+ export async function getWindowHandle(this: XCUITestDriver): Promise<string> {
623
655
  if (!this.isWebContext()) {
624
656
  // https://github.com/appium/appium/issues/20710
625
657
  return DEFAULT_NATIVE_WINDOW_HANDLE;
@@ -632,10 +664,13 @@ export async function getWindowHandle() {
632
664
  }
633
665
 
634
666
  /**
635
- * @this {XCUITestDriver}
636
- * @returns {Promise<string[]>}
667
+ * Gets the list of all available window handles.
668
+ *
669
+ * In native context, returns a single default handle. In web context, returns all webview handles.
670
+ *
671
+ * @returns Array of window handle strings
637
672
  */
638
- export async function getWindowHandles() {
673
+ export async function getWindowHandles(this: XCUITestDriver): Promise<string[]> {
639
674
  if (!this.isWebContext()) {
640
675
  // https://github.com/appium/appium/issues/20710
641
676
  return [DEFAULT_NATIVE_WINDOW_HANDLE];
@@ -656,13 +691,13 @@ export async function getWindowHandles() {
656
691
  }
657
692
 
658
693
  /**
659
- * Checks if a URL is blacklisted in the 'safariIgnoreWebHostnames' capability
694
+ * Checks if a URL is blacklisted in the 'safariIgnoreWebHostnames' capability.
660
695
  *
661
- * @param {string} url
662
- * @param {string} [safariIgnoreWebHostnames]
663
- * @returns {boolean}
696
+ * @param url - The URL to check
697
+ * @param safariIgnoreWebHostnames - Comma-separated list of hostnames to ignore
698
+ * @returns True if the URL should be ignored
664
699
  */
665
- function isUrlIgnored(url, safariIgnoreWebHostnames) {
700
+ function isUrlIgnored(url: string, safariIgnoreWebHostnames?: string): boolean {
666
701
  if (!safariIgnoreWebHostnames || _.isEmpty(safariIgnoreWebHostnames)) {
667
702
  return false;
668
703
  }
@@ -689,20 +724,13 @@ function isUrlIgnored(url, safariIgnoreWebHostnames) {
689
724
  }
690
725
 
691
726
  /**
692
- * https://github.com/appium/appium/issues/20741
727
+ * Notifies BiDi clients about context changes.
693
728
  *
694
- * @this {XCUITestDriver}
695
- * @returns {Promise<void>}
729
+ * @see https://github.com/appium/appium/issues/20741
696
730
  */
697
- export async function notifyBiDiContextChange() {
731
+ export async function notifyBiDiContextChange(this: XCUITestDriver): Promise<void> {
698
732
  const name = await this.getCurrentContext();
699
733
  this.eventEmitter.emit(BIDI_EVENT_NAME, makeContextUpdatedEvent(name));
700
734
  this.eventEmitter.emit(BIDI_EVENT_NAME, makeObsoleteContextUpdatedEvent(name));
701
735
  }
702
736
 
703
-
704
- /**
705
- * @typedef {import('../driver').XCUITestDriver} XCUITestDriver
706
- * @typedef {import('./types').Context} Context
707
- * @typedef {import('./types').FullContext} FullContext
708
- */
@@ -0,0 +1,24 @@
1
+ import {utilities} from 'appium-ios-device';
2
+ import type {XCUITestDriver} from '../driver';
3
+ import type {DeviceInfo, LockdownInfo} from './types';
4
+
5
+ /**
6
+ * Returns the miscellaneous information about the device under test.
7
+ *
8
+ * Since XCUITest driver v4.2.0, this includes device information via lockdown in a real device.
9
+ *
10
+ * @returns The response of `/wda/device/info'`
11
+ */
12
+ export async function mobileGetDeviceInfo(
13
+ this: XCUITestDriver,
14
+ ): Promise<DeviceInfo | (DeviceInfo & {lockdownInfo: LockdownInfo})> {
15
+ const infoByWda = await this.proxyCommand<unknown, DeviceInfo>('/wda/device/info', 'GET');
16
+
17
+ if (this.isRealDevice()) {
18
+ const lockdownInfo = await utilities.getDeviceInfo(this.device.udid);
19
+ return {...infoByWda, ...{lockdownInfo}};
20
+ }
21
+
22
+ return infoByWda;
23
+ }
24
+