@limrun/appium-xcuitest-driver 10.4.3-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 (444) hide show
  1. package/CHANGELOG.md +2600 -0
  2. package/LICENSE +201 -0
  3. package/README.md +55 -0
  4. package/build/index.d.ts +5 -0
  5. package/build/index.js +41 -0
  6. package/build/lib/app-infos-cache.d.ts +62 -0
  7. package/build/lib/app-infos-cache.d.ts.map +1 -0
  8. package/build/lib/app-infos-cache.js +180 -0
  9. package/build/lib/app-infos-cache.js.map +1 -0
  10. package/build/lib/app-utils.d.ts +89 -0
  11. package/build/lib/app-utils.d.ts.map +1 -0
  12. package/build/lib/app-utils.js +657 -0
  13. package/build/lib/app-utils.js.map +1 -0
  14. package/build/lib/commands/active-app-info.d.ts +9 -0
  15. package/build/lib/commands/active-app-info.d.ts.map +1 -0
  16. package/build/lib/commands/active-app-info.js +14 -0
  17. package/build/lib/commands/active-app-info.js.map +1 -0
  18. package/build/lib/commands/advanced-battery-types.d.ts +444 -0
  19. package/build/lib/commands/advanced-battery-types.d.ts.map +1 -0
  20. package/build/lib/commands/advanced-battery-types.js +8 -0
  21. package/build/lib/commands/advanced-battery-types.js.map +1 -0
  22. package/build/lib/commands/alert.d.ts +45 -0
  23. package/build/lib/commands/alert.d.ts.map +1 -0
  24. package/build/lib/commands/alert.js +87 -0
  25. package/build/lib/commands/alert.js.map +1 -0
  26. package/build/lib/commands/app-management.d.ts +153 -0
  27. package/build/lib/commands/app-management.d.ts.map +1 -0
  28. package/build/lib/commands/app-management.js +323 -0
  29. package/build/lib/commands/app-management.js.map +1 -0
  30. package/build/lib/commands/app-strings.d.ts +16 -0
  31. package/build/lib/commands/app-strings.d.ts.map +1 -0
  32. package/build/lib/commands/app-strings.js +30 -0
  33. package/build/lib/commands/app-strings.js.map +1 -0
  34. package/build/lib/commands/appearance.d.ts +22 -0
  35. package/build/lib/commands/appearance.d.ts.map +1 -0
  36. package/build/lib/commands/appearance.js +74 -0
  37. package/build/lib/commands/appearance.js.map +1 -0
  38. package/build/lib/commands/audit.d.ts +43 -0
  39. package/build/lib/commands/audit.d.ts.map +1 -0
  40. package/build/lib/commands/audit.js +31 -0
  41. package/build/lib/commands/audit.js.map +1 -0
  42. package/build/lib/commands/battery.d.ts +13 -0
  43. package/build/lib/commands/battery.d.ts.map +1 -0
  44. package/build/lib/commands/battery.js +49 -0
  45. package/build/lib/commands/battery.js.map +1 -0
  46. package/build/lib/commands/bidi/constants.d.ts +6 -0
  47. package/build/lib/commands/bidi/constants.d.ts.map +1 -0
  48. package/build/lib/commands/bidi/constants.js +10 -0
  49. package/build/lib/commands/bidi/constants.js.map +1 -0
  50. package/build/lib/commands/bidi/models.d.ts +9 -0
  51. package/build/lib/commands/bidi/models.d.ts.map +1 -0
  52. package/build/lib/commands/bidi/models.js +54 -0
  53. package/build/lib/commands/bidi/models.js.map +1 -0
  54. package/build/lib/commands/bidi/types.d.ts +26 -0
  55. package/build/lib/commands/bidi/types.d.ts.map +1 -0
  56. package/build/lib/commands/bidi/types.js +4 -0
  57. package/build/lib/commands/bidi/types.js.map +1 -0
  58. package/build/lib/commands/biometric.d.ts +32 -0
  59. package/build/lib/commands/biometric.d.ts.map +1 -0
  60. package/build/lib/commands/biometric.js +54 -0
  61. package/build/lib/commands/biometric.js.map +1 -0
  62. package/build/lib/commands/certificate.d.ts +50 -0
  63. package/build/lib/commands/certificate.d.ts.map +1 -0
  64. package/build/lib/commands/certificate.js +454 -0
  65. package/build/lib/commands/certificate.js.map +1 -0
  66. package/build/lib/commands/clipboard.d.ts +21 -0
  67. package/build/lib/commands/clipboard.d.ts.map +1 -0
  68. package/build/lib/commands/clipboard.js +36 -0
  69. package/build/lib/commands/clipboard.js.map +1 -0
  70. package/build/lib/commands/condition.d.ts +102 -0
  71. package/build/lib/commands/condition.d.ts.map +1 -0
  72. package/build/lib/commands/condition.js +146 -0
  73. package/build/lib/commands/condition.js.map +1 -0
  74. package/build/lib/commands/content-size.d.ts +30 -0
  75. package/build/lib/commands/content-size.d.ts.map +1 -0
  76. package/build/lib/commands/content-size.js +67 -0
  77. package/build/lib/commands/content-size.js.map +1 -0
  78. package/build/lib/commands/context.d.ts +191 -0
  79. package/build/lib/commands/context.d.ts.map +1 -0
  80. package/build/lib/commands/context.js +625 -0
  81. package/build/lib/commands/context.js.map +1 -0
  82. package/build/lib/commands/deviceInfo.d.ts +12 -0
  83. package/build/lib/commands/deviceInfo.d.ts.map +1 -0
  84. package/build/lib/commands/deviceInfo.js +25 -0
  85. package/build/lib/commands/deviceInfo.js.map +1 -0
  86. package/build/lib/commands/element.d.ts +108 -0
  87. package/build/lib/commands/element.d.ts.map +1 -0
  88. package/build/lib/commands/element.js +395 -0
  89. package/build/lib/commands/element.js.map +1 -0
  90. package/build/lib/commands/enum.d.ts +105 -0
  91. package/build/lib/commands/enum.d.ts.map +1 -0
  92. package/build/lib/commands/enum.js +113 -0
  93. package/build/lib/commands/enum.js.map +1 -0
  94. package/build/lib/commands/execute.d.ts +33 -0
  95. package/build/lib/commands/execute.d.ts.map +1 -0
  96. package/build/lib/commands/execute.js +142 -0
  97. package/build/lib/commands/execute.js.map +1 -0
  98. package/build/lib/commands/file-movement.d.ts +90 -0
  99. package/build/lib/commands/file-movement.d.ts.map +1 -0
  100. package/build/lib/commands/file-movement.js +477 -0
  101. package/build/lib/commands/file-movement.js.map +1 -0
  102. package/build/lib/commands/find.d.ts +21 -0
  103. package/build/lib/commands/find.d.ts.map +1 -0
  104. package/build/lib/commands/find.js +199 -0
  105. package/build/lib/commands/find.js.map +1 -0
  106. package/build/lib/commands/general.d.ts +137 -0
  107. package/build/lib/commands/general.d.ts.map +1 -0
  108. package/build/lib/commands/general.js +270 -0
  109. package/build/lib/commands/general.js.map +1 -0
  110. package/build/lib/commands/geolocation.d.ts +57 -0
  111. package/build/lib/commands/geolocation.d.ts.map +1 -0
  112. package/build/lib/commands/geolocation.js +58 -0
  113. package/build/lib/commands/geolocation.js.map +1 -0
  114. package/build/lib/commands/gesture.d.ts +283 -0
  115. package/build/lib/commands/gesture.d.ts.map +1 -0
  116. package/build/lib/commands/gesture.js +565 -0
  117. package/build/lib/commands/gesture.js.map +1 -0
  118. package/build/lib/commands/hid-event.d.ts +2773 -0
  119. package/build/lib/commands/hid-event.d.ts.map +1 -0
  120. package/build/lib/commands/hid-event.js +1633 -0
  121. package/build/lib/commands/hid-event.js.map +1 -0
  122. package/build/lib/commands/increase-contrast.d.ts +24 -0
  123. package/build/lib/commands/increase-contrast.d.ts.map +1 -0
  124. package/build/lib/commands/increase-contrast.js +49 -0
  125. package/build/lib/commands/increase-contrast.js.map +1 -0
  126. package/build/lib/commands/iohid.d.ts +1372 -0
  127. package/build/lib/commands/iohid.d.ts.map +1 -0
  128. package/build/lib/commands/iohid.js +63 -0
  129. package/build/lib/commands/iohid.js.map +1 -0
  130. package/build/lib/commands/keyboard.d.ts +32 -0
  131. package/build/lib/commands/keyboard.d.ts.map +1 -0
  132. package/build/lib/commands/keyboard.js +67 -0
  133. package/build/lib/commands/keyboard.js.map +1 -0
  134. package/build/lib/commands/keychains.d.ts +10 -0
  135. package/build/lib/commands/keychains.d.ts.map +1 -0
  136. package/build/lib/commands/keychains.js +22 -0
  137. package/build/lib/commands/keychains.js.map +1 -0
  138. package/build/lib/commands/localization.d.ts +17 -0
  139. package/build/lib/commands/localization.d.ts.map +1 -0
  140. package/build/lib/commands/localization.js +34 -0
  141. package/build/lib/commands/localization.js.map +1 -0
  142. package/build/lib/commands/location.d.ts +40 -0
  143. package/build/lib/commands/location.d.ts.map +1 -0
  144. package/build/lib/commands/location.js +121 -0
  145. package/build/lib/commands/location.js.map +1 -0
  146. package/build/lib/commands/lock.d.ts +23 -0
  147. package/build/lib/commands/lock.d.ts.map +1 -0
  148. package/build/lib/commands/lock.js +49 -0
  149. package/build/lib/commands/lock.js.map +1 -0
  150. package/build/lib/commands/log.d.ts +68 -0
  151. package/build/lib/commands/log.d.ts.map +1 -0
  152. package/build/lib/commands/log.js +287 -0
  153. package/build/lib/commands/log.js.map +1 -0
  154. package/build/lib/commands/memory.d.ts +11 -0
  155. package/build/lib/commands/memory.d.ts.map +1 -0
  156. package/build/lib/commands/memory.js +49 -0
  157. package/build/lib/commands/memory.js.map +1 -0
  158. package/build/lib/commands/navigation.d.ts +44 -0
  159. package/build/lib/commands/navigation.d.ts.map +1 -0
  160. package/build/lib/commands/navigation.js +121 -0
  161. package/build/lib/commands/navigation.js.map +1 -0
  162. package/build/lib/commands/notifications.d.ts +28 -0
  163. package/build/lib/commands/notifications.d.ts.map +1 -0
  164. package/build/lib/commands/notifications.js +64 -0
  165. package/build/lib/commands/notifications.js.map +1 -0
  166. package/build/lib/commands/pasteboard.d.ts +23 -0
  167. package/build/lib/commands/pasteboard.d.ts.map +1 -0
  168. package/build/lib/commands/pasteboard.js +43 -0
  169. package/build/lib/commands/pasteboard.js.map +1 -0
  170. package/build/lib/commands/pcap.d.ts +54 -0
  171. package/build/lib/commands/pcap.d.ts.map +1 -0
  172. package/build/lib/commands/pcap.js +149 -0
  173. package/build/lib/commands/pcap.js.map +1 -0
  174. package/build/lib/commands/performance.d.ts +85 -0
  175. package/build/lib/commands/performance.d.ts.map +1 -0
  176. package/build/lib/commands/performance.js +331 -0
  177. package/build/lib/commands/performance.js.map +1 -0
  178. package/build/lib/commands/permissions.d.ts +36 -0
  179. package/build/lib/commands/permissions.d.ts.map +1 -0
  180. package/build/lib/commands/permissions.js +80 -0
  181. package/build/lib/commands/permissions.js.map +1 -0
  182. package/build/lib/commands/proxy-helper.d.ts +15 -0
  183. package/build/lib/commands/proxy-helper.d.ts.map +1 -0
  184. package/build/lib/commands/proxy-helper.js +117 -0
  185. package/build/lib/commands/proxy-helper.js.map +1 -0
  186. package/build/lib/commands/record-audio.d.ts +69 -0
  187. package/build/lib/commands/record-audio.d.ts.map +1 -0
  188. package/build/lib/commands/record-audio.js +228 -0
  189. package/build/lib/commands/record-audio.js.map +1 -0
  190. package/build/lib/commands/recordscreen.d.ts +89 -0
  191. package/build/lib/commands/recordscreen.d.ts.map +1 -0
  192. package/build/lib/commands/recordscreen.js +326 -0
  193. package/build/lib/commands/recordscreen.js.map +1 -0
  194. package/build/lib/commands/screenshots.d.ts +16 -0
  195. package/build/lib/commands/screenshots.d.ts.map +1 -0
  196. package/build/lib/commands/screenshots.js +129 -0
  197. package/build/lib/commands/screenshots.js.map +1 -0
  198. package/build/lib/commands/simctl.d.ts +27 -0
  199. package/build/lib/commands/simctl.d.ts.map +1 -0
  200. package/build/lib/commands/simctl.js +65 -0
  201. package/build/lib/commands/simctl.js.map +1 -0
  202. package/build/lib/commands/source.d.ts +16 -0
  203. package/build/lib/commands/source.d.ts.map +1 -0
  204. package/build/lib/commands/source.js +128 -0
  205. package/build/lib/commands/source.js.map +1 -0
  206. package/build/lib/commands/timeouts.d.ts +53 -0
  207. package/build/lib/commands/timeouts.d.ts.map +1 -0
  208. package/build/lib/commands/timeouts.js +71 -0
  209. package/build/lib/commands/timeouts.js.map +1 -0
  210. package/build/lib/commands/types.d.ts +539 -0
  211. package/build/lib/commands/types.d.ts.map +1 -0
  212. package/build/lib/commands/types.js +3 -0
  213. package/build/lib/commands/types.js.map +1 -0
  214. package/build/lib/commands/web.d.ts +297 -0
  215. package/build/lib/commands/web.d.ts.map +1 -0
  216. package/build/lib/commands/web.js +1029 -0
  217. package/build/lib/commands/web.js.map +1 -0
  218. package/build/lib/commands/xctest-record-screen.d.ts +92 -0
  219. package/build/lib/commands/xctest-record-screen.d.ts.map +1 -0
  220. package/build/lib/commands/xctest-record-screen.js +193 -0
  221. package/build/lib/commands/xctest-record-screen.js.map +1 -0
  222. package/build/lib/commands/xctest.d.ts +71 -0
  223. package/build/lib/commands/xctest.d.ts.map +1 -0
  224. package/build/lib/commands/xctest.js +257 -0
  225. package/build/lib/commands/xctest.js.map +1 -0
  226. package/build/lib/css-converter.d.ts +10 -0
  227. package/build/lib/css-converter.d.ts.map +1 -0
  228. package/build/lib/css-converter.js +258 -0
  229. package/build/lib/css-converter.js.map +1 -0
  230. package/build/lib/desired-caps.d.ts +506 -0
  231. package/build/lib/desired-caps.d.ts.map +1 -0
  232. package/build/lib/desired-caps.js +400 -0
  233. package/build/lib/desired-caps.js.map +1 -0
  234. package/build/lib/device-connections-factory.d.ts +13 -0
  235. package/build/lib/device-connections-factory.d.ts.map +1 -0
  236. package/build/lib/device-connections-factory.js +244 -0
  237. package/build/lib/device-connections-factory.js.map +1 -0
  238. package/build/lib/device-log/helpers.d.ts +10 -0
  239. package/build/lib/device-log/helpers.d.ts.map +1 -0
  240. package/build/lib/device-log/helpers.js +37 -0
  241. package/build/lib/device-log/helpers.js.map +1 -0
  242. package/build/lib/device-log/ios-crash-log.d.ts +34 -0
  243. package/build/lib/device-log/ios-crash-log.d.ts.map +1 -0
  244. package/build/lib/device-log/ios-crash-log.js +141 -0
  245. package/build/lib/device-log/ios-crash-log.js.map +1 -0
  246. package/build/lib/device-log/ios-device-log.d.ts +19 -0
  247. package/build/lib/device-log/ios-device-log.d.ts.map +1 -0
  248. package/build/lib/device-log/ios-device-log.js +42 -0
  249. package/build/lib/device-log/ios-device-log.js.map +1 -0
  250. package/build/lib/device-log/ios-log.d.ts +24 -0
  251. package/build/lib/device-log/ios-log.d.ts.map +1 -0
  252. package/build/lib/device-log/ios-log.js +50 -0
  253. package/build/lib/device-log/ios-log.js.map +1 -0
  254. package/build/lib/device-log/ios-performance-log.d.ts +18 -0
  255. package/build/lib/device-log/ios-performance-log.d.ts.map +1 -0
  256. package/build/lib/device-log/ios-performance-log.js +43 -0
  257. package/build/lib/device-log/ios-performance-log.js.map +1 -0
  258. package/build/lib/device-log/ios-simulator-log.d.ts +38 -0
  259. package/build/lib/device-log/ios-simulator-log.d.ts.map +1 -0
  260. package/build/lib/device-log/ios-simulator-log.js +184 -0
  261. package/build/lib/device-log/ios-simulator-log.js.map +1 -0
  262. package/build/lib/device-log/line-consuming-log.d.ts +9 -0
  263. package/build/lib/device-log/line-consuming-log.d.ts.map +1 -0
  264. package/build/lib/device-log/line-consuming-log.js +16 -0
  265. package/build/lib/device-log/line-consuming-log.js.map +1 -0
  266. package/build/lib/device-log/safari-console-log.d.ts +67 -0
  267. package/build/lib/device-log/safari-console-log.d.ts.map +1 -0
  268. package/build/lib/device-log/safari-console-log.js +81 -0
  269. package/build/lib/device-log/safari-console-log.js.map +1 -0
  270. package/build/lib/device-log/safari-network-log.d.ts +75 -0
  271. package/build/lib/device-log/safari-network-log.d.ts.map +1 -0
  272. package/build/lib/device-log/safari-network-log.js +47 -0
  273. package/build/lib/device-log/safari-network-log.js.map +1 -0
  274. package/build/lib/doctor/checks.d.ts +3 -0
  275. package/build/lib/doctor/checks.d.ts.map +1 -0
  276. package/build/lib/doctor/checks.js +39 -0
  277. package/build/lib/doctor/checks.js.map +1 -0
  278. package/build/lib/doctor/optional-checks.d.ts +46 -0
  279. package/build/lib/doctor/optional-checks.d.ts.map +1 -0
  280. package/build/lib/doctor/optional-checks.js +129 -0
  281. package/build/lib/doctor/optional-checks.js.map +1 -0
  282. package/build/lib/doctor/required-checks.d.ts +42 -0
  283. package/build/lib/doctor/required-checks.d.ts.map +1 -0
  284. package/build/lib/doctor/required-checks.js +94 -0
  285. package/build/lib/doctor/required-checks.js.map +1 -0
  286. package/build/lib/doctor/utils.d.ts +8 -0
  287. package/build/lib/doctor/utils.d.ts.map +1 -0
  288. package/build/lib/doctor/utils.js +21 -0
  289. package/build/lib/doctor/utils.js.map +1 -0
  290. package/build/lib/driver.d.ts +2429 -0
  291. package/build/lib/driver.d.ts.map +1 -0
  292. package/build/lib/driver.js +1967 -0
  293. package/build/lib/driver.js.map +1 -0
  294. package/build/lib/execute-method-map.d.ts +552 -0
  295. package/build/lib/execute-method-map.d.ts.map +1 -0
  296. package/build/lib/execute-method-map.js +586 -0
  297. package/build/lib/execute-method-map.js.map +1 -0
  298. package/build/lib/ios-fs-helpers.d.ts +75 -0
  299. package/build/lib/ios-fs-helpers.d.ts.map +1 -0
  300. package/build/lib/ios-fs-helpers.js +370 -0
  301. package/build/lib/ios-fs-helpers.js.map +1 -0
  302. package/build/lib/ios-generic-simulators.d.ts +6 -0
  303. package/build/lib/ios-generic-simulators.d.ts.map +1 -0
  304. package/build/lib/ios-generic-simulators.js +14 -0
  305. package/build/lib/ios-generic-simulators.js.map +1 -0
  306. package/build/lib/logger.d.ts +3 -0
  307. package/build/lib/logger.d.ts.map +1 -0
  308. package/build/lib/logger.js +6 -0
  309. package/build/lib/logger.js.map +1 -0
  310. package/build/lib/method-map.d.ts +229 -0
  311. package/build/lib/method-map.d.ts.map +1 -0
  312. package/build/lib/method-map.js +200 -0
  313. package/build/lib/method-map.js.map +1 -0
  314. package/build/lib/real-device-clients/base-device-client.d.ts +22 -0
  315. package/build/lib/real-device-clients/base-device-client.d.ts.map +1 -0
  316. package/build/lib/real-device-clients/base-device-client.js +14 -0
  317. package/build/lib/real-device-clients/base-device-client.js.map +1 -0
  318. package/build/lib/real-device-clients/py-ios-device-client.d.ts +21 -0
  319. package/build/lib/real-device-clients/py-ios-device-client.d.ts.map +1 -0
  320. package/build/lib/real-device-clients/py-ios-device-client.js +125 -0
  321. package/build/lib/real-device-clients/py-ios-device-client.js.map +1 -0
  322. package/build/lib/real-device-management.d.ts +53 -0
  323. package/build/lib/real-device-management.d.ts.map +1 -0
  324. package/build/lib/real-device-management.js +128 -0
  325. package/build/lib/real-device-management.js.map +1 -0
  326. package/build/lib/real-device.d.ts +112 -0
  327. package/build/lib/real-device.d.ts.map +1 -0
  328. package/build/lib/real-device.js +352 -0
  329. package/build/lib/real-device.js.map +1 -0
  330. package/build/lib/simulator-management.d.ts +96 -0
  331. package/build/lib/simulator-management.d.ts.map +1 -0
  332. package/build/lib/simulator-management.js +278 -0
  333. package/build/lib/simulator-management.js.map +1 -0
  334. package/build/lib/stubs.d.ts +3 -0
  335. package/build/lib/stubs.d.ts.map +1 -0
  336. package/build/lib/stubs.js +3 -0
  337. package/build/lib/stubs.js.map +1 -0
  338. package/build/lib/types.d.ts +31 -0
  339. package/build/lib/types.d.ts.map +1 -0
  340. package/build/lib/types.js +3 -0
  341. package/build/lib/types.js.map +1 -0
  342. package/build/lib/utils.d.ts +191 -0
  343. package/build/lib/utils.d.ts.map +1 -0
  344. package/build/lib/utils.js +549 -0
  345. package/build/lib/utils.js.map +1 -0
  346. package/build/lib/xcrun.d.ts +3 -0
  347. package/build/lib/xcrun.d.ts.map +1 -0
  348. package/build/lib/xcrun.js +17 -0
  349. package/build/lib/xcrun.js.map +1 -0
  350. package/index.js +7 -0
  351. package/lib/app-infos-cache.js +187 -0
  352. package/lib/app-utils.js +710 -0
  353. package/lib/commands/active-app-info.js +12 -0
  354. package/lib/commands/advanced-battery-types.ts +454 -0
  355. package/lib/commands/alert.js +88 -0
  356. package/lib/commands/app-management.js +346 -0
  357. package/lib/commands/app-strings.js +30 -0
  358. package/lib/commands/appearance.js +71 -0
  359. package/lib/commands/audit.js +31 -0
  360. package/lib/commands/battery.js +45 -0
  361. package/lib/commands/bidi/constants.ts +6 -0
  362. package/lib/commands/bidi/models.ts +55 -0
  363. package/lib/commands/bidi/types.ts +31 -0
  364. package/lib/commands/biometric.js +53 -0
  365. package/lib/commands/certificate.js +497 -0
  366. package/lib/commands/clipboard.js +35 -0
  367. package/lib/commands/condition.js +155 -0
  368. package/lib/commands/content-size.js +68 -0
  369. package/lib/commands/context.js +705 -0
  370. package/lib/commands/deviceInfo.js +27 -0
  371. package/lib/commands/element.js +423 -0
  372. package/lib/commands/enum.ts +108 -0
  373. package/lib/commands/execute.js +153 -0
  374. package/lib/commands/file-movement.js +510 -0
  375. package/lib/commands/find.js +205 -0
  376. package/lib/commands/general.js +278 -0
  377. package/lib/commands/geolocation.js +56 -0
  378. package/lib/commands/gesture.js +596 -0
  379. package/lib/commands/hid-event.ts +1634 -0
  380. package/lib/commands/increase-contrast.js +50 -0
  381. package/lib/commands/iohid.js +64 -0
  382. package/lib/commands/keyboard.js +62 -0
  383. package/lib/commands/keychains.js +18 -0
  384. package/lib/commands/localization.js +30 -0
  385. package/lib/commands/location.js +131 -0
  386. package/lib/commands/lock.js +46 -0
  387. package/lib/commands/log.js +327 -0
  388. package/lib/commands/memory.js +51 -0
  389. package/lib/commands/navigation.js +125 -0
  390. package/lib/commands/notifications.js +66 -0
  391. package/lib/commands/pasteboard.js +42 -0
  392. package/lib/commands/pcap.js +168 -0
  393. package/lib/commands/performance.js +392 -0
  394. package/lib/commands/permissions.js +85 -0
  395. package/lib/commands/proxy-helper.js +122 -0
  396. package/lib/commands/record-audio.js +264 -0
  397. package/lib/commands/recordscreen.js +391 -0
  398. package/lib/commands/screenshots.js +137 -0
  399. package/lib/commands/simctl.js +71 -0
  400. package/lib/commands/source.js +131 -0
  401. package/lib/commands/timeouts.js +68 -0
  402. package/lib/commands/types.ts +648 -0
  403. package/lib/commands/web.js +1113 -0
  404. package/lib/commands/xctest-record-screen.js +204 -0
  405. package/lib/commands/xctest.js +285 -0
  406. package/lib/css-converter.js +311 -0
  407. package/lib/desired-caps.js +396 -0
  408. package/lib/device-connections-factory.js +269 -0
  409. package/lib/device-log/helpers.ts +40 -0
  410. package/lib/device-log/ios-crash-log.ts +166 -0
  411. package/lib/device-log/ios-device-log.ts +51 -0
  412. package/lib/device-log/ios-log.ts +70 -0
  413. package/lib/device-log/ios-performance-log.ts +50 -0
  414. package/lib/device-log/ios-simulator-log.ts +202 -0
  415. package/lib/device-log/line-consuming-log.ts +16 -0
  416. package/lib/device-log/safari-console-log.ts +117 -0
  417. package/lib/device-log/safari-network-log.ts +120 -0
  418. package/lib/doctor/checks.ts +3 -0
  419. package/lib/doctor/optional-checks.ts +173 -0
  420. package/lib/doctor/required-checks.ts +120 -0
  421. package/lib/doctor/utils.ts +18 -0
  422. package/lib/driver.js +2316 -0
  423. package/lib/execute-method-map.ts +585 -0
  424. package/lib/ios-fs-helpers.js +355 -0
  425. package/lib/ios-generic-simulators.js +11 -0
  426. package/lib/logger.js +5 -0
  427. package/lib/method-map.js +196 -0
  428. package/lib/real-device-clients/base-device-client.ts +34 -0
  429. package/lib/real-device-clients/py-ios-device-client.ts +149 -0
  430. package/lib/real-device-management.js +133 -0
  431. package/lib/real-device.js +347 -0
  432. package/lib/simulator-management.js +324 -0
  433. package/lib/stubs.ts +3 -0
  434. package/lib/types.ts +33 -0
  435. package/lib/utils.js +551 -0
  436. package/lib/xcrun.js +16 -0
  437. package/package.json +175 -0
  438. package/scripts/build-docs.js +56 -0
  439. package/scripts/build-wda.js +42 -0
  440. package/scripts/download-wda-sim.mjs +68 -0
  441. package/scripts/image-mounter.mjs +239 -0
  442. package/scripts/open-wda.mjs +15 -0
  443. package/scripts/tunnel-creation.mjs +359 -0
  444. package/scripts/utils.js +16 -0
@@ -0,0 +1,705 @@
1
+ import {createRemoteDebugger, RemoteDebugger} from 'appium-remote-debugger';
2
+ import {errors, isErrorType} from 'appium/driver';
3
+ import {util, timing} from 'appium/support';
4
+ import {IOSPerformanceLog} from '../device-log/ios-performance-log';
5
+ import _ from 'lodash';
6
+ import { NATIVE_WIN } from '../utils';
7
+ import {
8
+ makeContextUpdatedEvent,
9
+ makeObsoleteContextUpdatedEvent,
10
+ } from './bidi/models';
11
+ import { BIDI_EVENT_NAME } from './bidi/constants';
12
+ import { assignBiDiLogListener } from './log';
13
+
14
+ const WEBVIEW_WIN = 'WEBVIEW';
15
+ const WEBVIEW_BASE = `${WEBVIEW_WIN}_`;
16
+ const DEFAULT_REMOTE_DEBUGGER_CONNECT_TIMEOUT_MS = 5000;
17
+ const DEFAULT_LIST_WEB_FRAMES_RETRIES = 20;
18
+ const DEFAULT_NATIVE_WINDOW_HANDLE = '1';
19
+
20
+
21
+ /**
22
+ * @this {XCUITestDriver}
23
+ * @param {boolean} [useUrl=false]
24
+ * @returns {Promise<import('./types').ViewContext[]>}
25
+ */
26
+ export async function getContextsAndViews(useUrl = true) {
27
+ this.log.debug('Retrieving contexts and views');
28
+ const webviews = await this.listWebFrames(useUrl);
29
+ /**
30
+ * @type {import('./types').ViewContext[]}
31
+ */
32
+ const ctxs = [{id: NATIVE_WIN, view: {}}];
33
+ this.contexts = [NATIVE_WIN];
34
+ for (const view of webviews) {
35
+ ctxs.push({id: `${WEBVIEW_BASE}${view.id}`, view});
36
+ this.contexts.push(view.id.toString());
37
+ }
38
+ return ctxs;
39
+ }
40
+
41
+ /**
42
+ * @deprecated this method is not used anywhere and will be removed in the future
43
+ * @this {XCUITestDriver}
44
+ * @returns {boolean}
45
+ */
46
+ export function useNewSafari() {
47
+ return this.isSimulator() && this.isSafari();
48
+ }
49
+
50
+ /**
51
+ * @this {XCUITestDriver}
52
+ * @returns {Promise<void>}
53
+ */
54
+ export async function activateRecentWebview() {
55
+ this.log.debug('Activating a recent webview');
56
+ const timer = new timing.Timer().start();
57
+ const contextId = await this.getRecentWebviewContextId(/.*/, /.*/);
58
+ if (contextId) {
59
+ this.log.info(`Picking webview '${contextId}' after ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`);
60
+ await this.setContext(contextId);
61
+ return;
62
+ }
63
+ const appDict = (/** @type {RemoteDebugger} */ (this.remote)).appDict;
64
+ const errSuffix = `Make sure your web application is debuggable ` +
65
+ `and could be inspected in Safari Web Inspector.`;
66
+ if (_.isEmpty(appDict)) {
67
+ throw new Error(
68
+ `The remote debugger did not return any connected web applications after ` +
69
+ `${timer.getDuration().asMilliSeconds.toFixed(0)}ms. ` +
70
+ `${errSuffix} ` +
71
+ `You may try to change the 'webviewConnectTimeout' capability value to ` +
72
+ `customize the retrieval timeout.`
73
+ );
74
+ }
75
+ const errSuffix2 = `${errSuffix} You may try to change the 'webviewConnectRetries' ` +
76
+ `capability value to customize the amount of pages retrieval retries.`;
77
+ const appsWithPages = _.values(appDict).filter(({pageArray}) => !_.isEmpty(pageArray));
78
+ if (appsWithPages.length > 0) {
79
+ throw new Error(
80
+ `The remote debugger returned ${util.pluralize('web application', appsWithPages.length, true)} ` +
81
+ `with pages after ${timer.getDuration().asMilliSeconds.toFixed(0)}ms, ` +
82
+ `although none of them matched our page search criteria. ${errSuffix2}`
83
+ );
84
+ } else {
85
+ throw new Error(
86
+ `The remote debugger returned ${util.pluralize('web application', _.size(appDict), true)}, ` +
87
+ `but none of them had pages after ${timer.getDuration().asMilliSeconds.toFixed(0)}ms. ` +
88
+ `${errSuffix2} Also, in rare cases the device restart or device OS upgrade may fix this ` +
89
+ `issue if none of the above advices helps.`
90
+ );
91
+ }
92
+ }
93
+
94
+ /**
95
+ * @this {XCUITestDriver}
96
+ * @returns {Promise<import('../types').Page[]>}
97
+ */
98
+ export async function listWebFrames(useUrl = true) {
99
+ const shouldFilterByUrl = useUrl && !this.isRealDevice() && !!this.getCurrentUrl();
100
+ this.log.debug(
101
+ `Selecting by url: ${shouldFilterByUrl}` +
102
+ (shouldFilterByUrl ? ` (expected url: '${this.getCurrentUrl()}')` : '')
103
+ );
104
+
105
+ if (!this.remote) {
106
+ await this.connectToRemoteDebugger();
107
+ }
108
+ const doListPages = async (/** @type {number} */ retries) => {
109
+ try {
110
+ const pageArray = await (/** @type {RemoteDebugger} */ (this.remote)).selectApp(
111
+ shouldFilterByUrl ? this.getCurrentUrl() : undefined,
112
+ retries,
113
+ this.opts.ignoreAboutBlankUrl,
114
+ );
115
+ if (_.isEmpty(pageArray)) {
116
+ // we have no web frames, but continue anyway
117
+ this.log.debug(`No web frames found after ${util.pluralize('retry', retries, true)}`);
118
+ }
119
+ return pageArray;
120
+ } catch (err) {
121
+ this.log.debug(
122
+ `No available web pages after ${util.pluralize('retry', retries, true)}: ${err.message}`
123
+ );
124
+ return [];
125
+ }
126
+ };
127
+
128
+ /** @type {number} */
129
+ const maxRetriesCount = _.isInteger(this.opts.webviewConnectRetries)
130
+ ? Math.max(/** @type {number} */ (this.opts.webviewConnectRetries), 1)
131
+ : DEFAULT_LIST_WEB_FRAMES_RETRIES;
132
+ this.log.debug(
133
+ `About to select a web application with ${util.pluralize('retry', maxRetriesCount, true)} ` +
134
+ `and 500ms interval between each retry. Consider customizing the value of 'webviewConnectRetries' ` +
135
+ `capability to change the amount of retries.`
136
+ );
137
+ return await doListPages(maxRetriesCount);
138
+ }
139
+
140
+ /**
141
+ * @this {XCUITestDriver}
142
+ * @returns {Promise<void>}
143
+ */
144
+ export async function connectToRemoteDebugger() {
145
+ this.remote = await this.getNewRemoteDebugger();
146
+
147
+ // @ts-ignore static is fine
148
+ this.remote.on(RemoteDebugger.EVENT_PAGE_CHANGE, this.onPageChange.bind(this));
149
+ // @ts-ignore static is fine
150
+ this.remote.on(RemoteDebugger.EVENT_FRAMES_DETACHED, () => {
151
+ if (!_.isEmpty(this.curWebFrames)) {
152
+ const curWebFrames = this.curWebFrames;
153
+ this.log.debug(
154
+ `Clearing ${util.pluralize('frame', curWebFrames.length, true)}: ${curWebFrames.join(
155
+ ', ',
156
+ )}`,
157
+ );
158
+ }
159
+ this.curWebFrames = [];
160
+ });
161
+
162
+ const timeoutMs = this.opts.webviewConnectTimeout ?? DEFAULT_REMOTE_DEBUGGER_CONNECT_TIMEOUT_MS;
163
+ const apps = await this.remote.connect(timeoutMs);
164
+ if (_.isEmpty(apps)) {
165
+ this.log.info(
166
+ `The remote debugger did not report any active web applications within ${timeoutMs}ms timeout. ` +
167
+ `Consider increasing the value of 'webviewConnectTimeout' capability to wait longer ` +
168
+ `on slower devices.`
169
+ );
170
+ }
171
+ }
172
+
173
+ /**
174
+ * Retrieves the list of available contexts.
175
+ *
176
+ * The list includes extended context information, like URLs and page names.
177
+ * This is different from the standard `getContexts` API, because the latter
178
+ * only has web view names without any additional information.
179
+ *
180
+ * @remarks In situations where multiple web views are available at once, the
181
+ * client code would have to connect to each of them in order to detect the
182
+ * one which needs to be interacted with. This extra effort is not needed with
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}
187
+ */
188
+ export async function mobileGetContexts(waitForWebviewMs = 0) {
189
+ // make sure it is a number, so the duration check works properly
190
+ if (!_.isNumber(waitForWebviewMs)) {
191
+ waitForWebviewMs = parseInt(waitForWebviewMs, 10);
192
+ if (isNaN(waitForWebviewMs)) {
193
+ waitForWebviewMs = 0;
194
+ }
195
+ }
196
+
197
+ const curOpt = this.opts.fullContextList;
198
+ this.opts.fullContextList = true;
199
+
200
+ const timer = new timing.Timer().start();
201
+ try {
202
+ /** @type {FullContext[]} */
203
+ let contexts;
204
+ do {
205
+ contexts = /** @type {FullContext[]} */ (await this.getContexts());
206
+
207
+ if (contexts.length >= 2) {
208
+ this.log.debug(
209
+ `Found webview context after ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`,
210
+ );
211
+ return contexts;
212
+ }
213
+ this.log.debug(`No webviews found in ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`);
214
+ } while (timer.getDuration().asMilliSeconds < waitForWebviewMs);
215
+ return contexts;
216
+ } finally {
217
+ // reset the option so there are no side effects
218
+ this.opts.fullContextList = curOpt;
219
+ }
220
+ }
221
+
222
+ /**
223
+ * @this {XCUITestDriver}
224
+ * @param {import('./types').PageChangeNotification} pageChangeNotification
225
+ * @returns {Promise<void>}
226
+ */
227
+ export async function onPageChange(pageChangeNotification) {
228
+ this.log.debug(
229
+ `Remote debugger notified us of a new page listing: ${JSON.stringify(
230
+ pageChangeNotification,
231
+ )}`,
232
+ );
233
+ if (this.selectingNewPage) {
234
+ this.log.debug('We are in the middle of selecting a page, ignoring');
235
+ return;
236
+ }
237
+ if (!this.remote?.isConnected) {
238
+ this.log.debug('We have not yet connected, ignoring');
239
+ return;
240
+ }
241
+
242
+ const {appIdKey, pageArray} = pageChangeNotification;
243
+
244
+ /** @type {string[]} */
245
+ const newIds = [];
246
+ /** @type {string[]} */
247
+ const newPages = [];
248
+ /** @type {string|null} */
249
+ let keyId = null;
250
+ for (const page of pageArray) {
251
+ const id = page.id.toString();
252
+ newIds.push(id);
253
+ if (page.isKey) {
254
+ keyId = id;
255
+ }
256
+ const contextId = `${appIdKey}.${id}`;
257
+
258
+ // add if this is a new page
259
+ if (!_.includes(this.contexts, contextId)) {
260
+ if (isUrlIgnored(page.url, this.opts.safariIgnoreWebHostnames)) {
261
+ this.log.info(
262
+ `Not tracking '${page.url}' page because it is blacklisted. ` +
263
+ `'safariIgnoreWebHostnames'=${this.opts.safariIgnoreWebHostnames}`,
264
+ );
265
+ } else {
266
+ newPages.push(id);
267
+ this.contexts.push(contextId);
268
+ }
269
+ }
270
+ }
271
+
272
+ if (!keyId) {
273
+ // if there is no key id, pull the first id from the page array and use that
274
+ // as a stand in
275
+ this.log.debug('No key id found. Choosing first id from page array');
276
+ keyId = newIds[0] || null;
277
+ }
278
+
279
+ if (!util.hasValue(this.curContext)) {
280
+ this.log.debug('We do not appear to have window set yet, ignoring');
281
+ return;
282
+ }
283
+ const [curAppIdKey, curPageIdKey] = this.curContext.split('.');
284
+ if (curAppIdKey !== appIdKey) {
285
+ this.log.debug('Page change not referring to currently selected app, ignoring.');
286
+ return;
287
+ }
288
+
289
+ /** @type {string|null} */
290
+ let newPage = null;
291
+ if (newPages.length) {
292
+ newPage = /** @type {string} */ (_.last(newPages));
293
+ this.log.debug(`We have new pages, selecting page '${newPage}'`);
294
+ } else if (!_.includes(newIds, curPageIdKey)) {
295
+ this.log.debug(
296
+ 'New page listing from remote debugger does not contain ' +
297
+ 'current window; assuming it is closed',
298
+ );
299
+ if (!util.hasValue(keyId)) {
300
+ this.log.error(
301
+ 'Do not have our current window anymore, and there ' +
302
+ 'are not any more to load! Doing nothing...',
303
+ );
304
+ this.setCurrentUrl(undefined);
305
+ return;
306
+ }
307
+
308
+ this.log.debug(`Debugger already selected page '${keyId}', ` + `confirming that choice.`);
309
+ this.curContext = `${appIdKey}.${keyId}`;
310
+ newPage = keyId;
311
+ } else {
312
+ // at this point, there are no new pages, and the current page still exists
313
+ this.log.debug('New page listing is same as old, doing nothing');
314
+ }
315
+
316
+ // make sure that the page listing isn't indicating a redirect
317
+ if (util.hasValue(this.curContext)) {
318
+ const currentPageId = parseInt(String(_.last(this.curContext.split('.'))), 10);
319
+ const page = _.find(pageArray, (p) => parseInt(String(p.id), 10) === currentPageId);
320
+ if (page && page.url !== this.getCurrentUrl()) {
321
+ this.log.debug(`Redirected from '${this.getCurrentUrl()}' to '${page.url}'`);
322
+ this.setCurrentUrl(page.url);
323
+ }
324
+ }
325
+
326
+ if (util.hasValue(newPage)) {
327
+ this.selectingNewPage = true;
328
+ const oldContext = this.curContext;
329
+ this.curContext = `${appIdKey}.${newPage}`;
330
+ try {
331
+ await this.remote.selectPage(appIdKey, parseInt(newPage, 10));
332
+ await notifyBiDiContextChange.bind(this)();
333
+ } catch (e) {
334
+ this.log.warn(`Failed to select page: ${e.message}`);
335
+ this.curContext = oldContext;
336
+ } finally {
337
+ this.selectingNewPage = false;
338
+ }
339
+ }
340
+ }
341
+
342
+ /**
343
+ * @this {XCUITestDriver}
344
+ * @returns {Promise<void>}
345
+ */
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');
349
+ }
350
+
351
+ if (closeWindowBeforeDisconnecting) {
352
+ await this.closeWindow();
353
+ }
354
+ await this.remote.disconnect();
355
+ this.curContext = null;
356
+ await notifyBiDiContextChange.bind(this)();
357
+ this.curWebFrames = [];
358
+ this.remote = null;
359
+ }
360
+
361
+ /**
362
+ * @this {XCUITestDriver}
363
+ * @param {string|undefined|null} url
364
+ */
365
+ export function setCurrentUrl(url) {
366
+ this._currentUrl = url;
367
+ }
368
+
369
+ /**
370
+ * @this {XCUITestDriver}
371
+ * @returns {string|undefined|null}
372
+ */
373
+ export function getCurrentUrl() {
374
+ return this._currentUrl;
375
+ }
376
+
377
+ /**
378
+ * @param {RegExp} titleRegExp
379
+ * @param {RegExp} urlRegExp
380
+ * @this {XCUITestDriver}
381
+ * @returns {Promise<string|undefined>}
382
+ */
383
+ export async function getRecentWebviewContextId(titleRegExp, urlRegExp) {
384
+ if (!_.isRegExp(titleRegExp) && !_.isRegExp(urlRegExp)) {
385
+ throw new errors.InvalidArgumentError(
386
+ 'A regular expression for either web view title or url must be provided',
387
+ );
388
+ }
389
+
390
+ const currentUrl = this.getCurrentUrl();
391
+ const contexts = _.filter(await this.getContextsAndViews(false), 'view');
392
+ // first try to match by current url
393
+ if (currentUrl) {
394
+ const ctx = contexts.find(({view}) => (view?.url || '') === currentUrl);
395
+ if (ctx) {
396
+ return ctx.id;
397
+ }
398
+ }
399
+ // if not, try to match by regular expression
400
+ return contexts.find(
401
+ ({view}) =>
402
+ (view?.title && titleRegExp?.test(view.title)) || (view?.url && urlRegExp?.test(view.url)),
403
+ )?.id;
404
+ }
405
+
406
+ /**
407
+ * @this {XCUITestDriver}
408
+ * @returns {boolean}
409
+ */
410
+ export function isWebContext() {
411
+ return !!this.curContext && this.curContext !== NATIVE_WIN;
412
+ }
413
+
414
+ /**
415
+ * @this {XCUITestDriver}
416
+ * @returns {boolean}
417
+ */
418
+ export function isWebview() {
419
+ return this.isWebContext();
420
+ }
421
+
422
+ /**
423
+ * @this {XCUITestDriver}
424
+ * @returns {Promise<RemoteDebugger>}
425
+ */
426
+ export async function getNewRemoteDebugger() {
427
+ const socketPath = this.isRealDevice()
428
+ ? undefined
429
+ : (await /** @type {import('../driver').Simulator} */ (this.device).getWebInspectorSocket() ?? undefined);
430
+ return createRemoteDebugger(
431
+ {
432
+ bundleId: this.opts.bundleId,
433
+ additionalBundleIds: this.opts.additionalWebviewBundleIds,
434
+ isSafari: this.isSafari(),
435
+ includeSafari: this.opts.includeSafariInWebviews,
436
+ pageLoadMs: this.pageLoadMs,
437
+ platformVersion: this.opts.platformVersion,
438
+ socketPath,
439
+ remoteDebugProxy: this.opts.remoteDebugProxy,
440
+ garbageCollectOnExecute: util.hasValue(this.opts.safariGarbageCollect)
441
+ ? !!this.opts.safariGarbageCollect
442
+ : false,
443
+ udid: this.opts.udid,
444
+ logAllCommunication: this.opts.safariLogAllCommunication,
445
+ logAllCommunicationHexDump: this.opts.safariLogAllCommunicationHexDump,
446
+ socketChunkSize: this.opts.safariSocketChunkSize,
447
+ webInspectorMaxFrameLength: this.opts.safariWebInspectorMaxFrameLength,
448
+ pageLoadStrategy: this.caps.pageLoadStrategy,
449
+ },
450
+ this.isRealDevice(),
451
+ );
452
+ }
453
+
454
+ /**
455
+ * @this {XCUITestDriver}
456
+ * @returns {Promise<string>}
457
+ */
458
+ export async function getCurrentContext() {
459
+ if (this.curContext && this.curContext !== NATIVE_WIN) {
460
+ return `${WEBVIEW_BASE}${this.curContext}`;
461
+ }
462
+ return NATIVE_WIN;
463
+ }
464
+
465
+ /**
466
+ * Set context
467
+ *
468
+ * @param {string|Context} name - The name of context to set. It could be 'null' as NATIVE_WIN.
469
+ * @param {any} [callback] The callback. (It is not called in this method)
470
+ * @param {boolean} [skipReadyCheck=false] - Whether it waits for the new context is ready
471
+ * @this {XCUITestDriver}
472
+ * @returns {Promise<void>}
473
+ */
474
+ export async function setContext(name, callback, skipReadyCheck = false) {
475
+ function alreadyInContext(desired, current) {
476
+ return (
477
+ desired === current ||
478
+ (desired === null && current === NATIVE_WIN) ||
479
+ (desired === NATIVE_WIN && current === null)
480
+ );
481
+ }
482
+ function isNativeContext(context) {
483
+ return context === NATIVE_WIN || context === null;
484
+ }
485
+
486
+ // allow the full context list to be passed in
487
+ const strName = String(typeof name === 'object' && name.id ? name.id : name);
488
+
489
+ this.log.debug(
490
+ `Attempting to set context to '${strName || NATIVE_WIN}' from '${
491
+ this.curContext ? this.curContext : NATIVE_WIN
492
+ }'`,
493
+ );
494
+
495
+ if (
496
+ alreadyInContext(strName, this.curContext) ||
497
+ alreadyInContext(_.replace(strName, WEBVIEW_BASE, ''), this.curContext)
498
+ ) {
499
+ // already in the named context, no need to do anything
500
+ this.log.debug(`Already in '${strName || NATIVE_WIN}' context. Doing nothing.`);
501
+ return;
502
+ }
503
+ if (isNativeContext(strName)) {
504
+ // switching into the native context
505
+ this.curContext = null;
506
+ await notifyBiDiContextChange.bind(this)();
507
+ return;
508
+ }
509
+
510
+ // switching into a webview context
511
+
512
+ // if contexts have not already been retrieved, get them
513
+ if (_.isUndefined(this.contexts)) {
514
+ await this.getContexts();
515
+ }
516
+
517
+ let contextId = _.replace(strName, WEBVIEW_BASE, '');
518
+ if (contextId === '') {
519
+ // allow user to pass in "WEBVIEW" without an index
520
+ // the second context will be the first webview as
521
+ // the first is always NATIVE_APP
522
+ contextId = /** @type {string[]} */ (this.contexts)[1];
523
+ }
524
+ if (!_.includes(this.contexts, contextId)) {
525
+ throw new errors.NoSuchContextError();
526
+ }
527
+
528
+ const oldContext = this.curContext;
529
+ this.curContext = this.curWindowHandle = contextId;
530
+
531
+ // `contextId` will be in the form of `appId.pageId` in this case
532
+ const [appIdKey, pageIdKey] = _.map(contextId.split('.'), (id) => parseInt(id, 10));
533
+ try {
534
+ this.selectingNewPage = true;
535
+ await (/** @type {RemoteDebugger} */ (this.remote)).selectPage(appIdKey, pageIdKey, skipReadyCheck);
536
+ await notifyBiDiContextChange.bind(this)();
537
+ } catch (err) {
538
+ this.curContext = this.curWindowHandle = oldContext;
539
+ throw err;
540
+ } finally {
541
+ this.selectingNewPage = false;
542
+ }
543
+
544
+ // attempt to start performance logging, if requested
545
+ if (this.opts.enablePerformanceLogging && this.remote) {
546
+ const context = this.curContext;
547
+ this.log.debug(`Starting performance log on '${context}'`);
548
+ [this.logs.performance,] = assignBiDiLogListener.bind(this)(
549
+ new IOSPerformanceLog({
550
+ remoteDebugger: this.remote,
551
+ log: this.log,
552
+ }), {
553
+ type: 'performance',
554
+ context,
555
+ }
556
+ );
557
+ await this.logs.performance?.startCapture();
558
+ }
559
+
560
+ // start safari logging if the logs handlers are active
561
+ if (name && name !== NATIVE_WIN && this.logs) {
562
+ if (this.logs.safariConsole) {
563
+ (/** @type {RemoteDebugger} */ (this.remote)).startConsole(
564
+ this.logs.safariConsole.onConsoleLogEvent.bind(this.logs.safariConsole),
565
+ );
566
+ }
567
+ if (this.logs.safariNetwork) {
568
+ (/** @type {RemoteDebugger} */ (this.remote)).startNetwork(
569
+ this.logs.safariNetwork.onNetworkEvent.bind(this.logs.safariNetwork),
570
+ );
571
+ }
572
+ }
573
+ }
574
+
575
+ /**
576
+ * @this {XCUITestDriver}
577
+ * @returns {Promise<string[]|FullContext[]>}
578
+ */
579
+ export async function getContexts() {
580
+ this.log.debug('Getting list of available contexts');
581
+ const contexts = await this.getContextsAndViews(false);
582
+
583
+ if (this.opts.fullContextList) {
584
+ return /** @type {import('./types').FullContext[]} */ (
585
+ contexts.map((context) => ({
586
+ id: context.id.toString(),
587
+ title: context.view?.title,
588
+ url: context.view?.url,
589
+ bundleId: context.view?.bundleId,
590
+ }))
591
+ );
592
+ }
593
+ return /** @type {string[]} */ (contexts.map((context) => context.id.toString()));
594
+ }
595
+
596
+ /**
597
+ * @this {XCUITestDriver}
598
+ * @param {string} name
599
+ * @param {boolean} [skipReadyCheck]
600
+ * @returns {Promise<void>}
601
+ */
602
+ export async function setWindow(name, skipReadyCheck) {
603
+ if (!this.isWebContext()) {
604
+ // https://github.com/appium/appium/issues/20710
605
+ return;
606
+ }
607
+ try {
608
+ await this.setContext(name, _.noop, skipReadyCheck);
609
+ } catch (err) {
610
+ // translate the error in terms of windows
611
+ throw isErrorType(err, errors.NoSuchContextError) ? new errors.NoSuchWindowError() : err;
612
+ }
613
+ }
614
+
615
+ /**
616
+ * @this {XCUITestDriver}
617
+ * @returns {Promise<string>}
618
+ */
619
+ export async function getWindowHandle() {
620
+ if (!this.isWebContext()) {
621
+ // https://github.com/appium/appium/issues/20710
622
+ return DEFAULT_NATIVE_WINDOW_HANDLE;
623
+ }
624
+ if (!this.curContext) {
625
+ throw new errors.InvalidContextError();
626
+ }
627
+ this.log.debug(`Getting current window handle`);
628
+ return this.curContext;
629
+ }
630
+
631
+ /**
632
+ * @this {XCUITestDriver}
633
+ * @returns {Promise<string[]>}
634
+ */
635
+ export async function getWindowHandles() {
636
+ if (!this.isWebContext()) {
637
+ // https://github.com/appium/appium/issues/20710
638
+ return [DEFAULT_NATIVE_WINDOW_HANDLE];
639
+ }
640
+ this.log.debug('Getting list of available window handles');
641
+ const contexts = await this.getContextsAndViews(false);
642
+ return (
643
+ contexts
644
+ // get rid of the native app context
645
+ .filter((context) => context.id !== NATIVE_WIN)
646
+ // get the `app.id` format expected
647
+ .map((context) =>
648
+ // This is non-nullable because the `FullContext` having `id` `NATIVE_WIN`
649
+ // _looks like_ the only with an empty view.
650
+ context.view?.id?.toString() ?? ''
651
+ )
652
+ );
653
+ }
654
+
655
+ /**
656
+ * Checks if a URL is blacklisted in the 'safariIgnoreWebHostnames' capability
657
+ *
658
+ * @param {string} url
659
+ * @param {string} [safariIgnoreWebHostnames]
660
+ * @returns {boolean}
661
+ */
662
+ function isUrlIgnored(url, safariIgnoreWebHostnames) {
663
+ if (!safariIgnoreWebHostnames || _.isEmpty(safariIgnoreWebHostnames)) {
664
+ return false;
665
+ }
666
+
667
+ const ignoredHosts = safariIgnoreWebHostnames
668
+ .split(',')
669
+ .map((b) => b.trim())
670
+ .filter((b) => !_.isEmpty(b));
671
+ for (const ignoredHost of ignoredHosts) {
672
+ if (ignoredHost === 'about:blank' && url === 'about:blank') {
673
+ return true;
674
+ } else {
675
+ try {
676
+ const hostname = new URL(url).hostname;
677
+ if (hostname === ignoredHost) {
678
+ return true;
679
+ }
680
+ } catch {
681
+ // do nothing if invalid URL
682
+ }
683
+ }
684
+ }
685
+ return false;
686
+ }
687
+
688
+ /**
689
+ * https://github.com/appium/appium/issues/20741
690
+ *
691
+ * @this {XCUITestDriver}
692
+ * @returns {Promise<void>}
693
+ */
694
+ export async function notifyBiDiContextChange() {
695
+ const name = await this.getCurrentContext();
696
+ this.eventEmitter.emit(BIDI_EVENT_NAME, makeContextUpdatedEvent(name));
697
+ this.eventEmitter.emit(BIDI_EVENT_NAME, makeObsoleteContextUpdatedEvent(name));
698
+ }
699
+
700
+
701
+ /**
702
+ * @typedef {import('../driver').XCUITestDriver} XCUITestDriver
703
+ * @typedef {import('./types').Context} Context
704
+ * @typedef {import('./types').FullContext} FullContext
705
+ */