@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,1967 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.XCUITestDriver = void 0;
40
+ const appium_idb_1 = __importDefault(require("appium-idb"));
41
+ const appium_ios_simulator_1 = require("@limrun/appium-ios-simulator");
42
+ const appium_webdriveragent_1 = require("appium-webdriveragent");
43
+ const driver_1 = require("appium/driver");
44
+ const support_1 = require("appium/support");
45
+ const async_lock_1 = __importDefault(require("async-lock"));
46
+ const asyncbox_1 = require("asyncbox");
47
+ const bluebird_1 = __importDefault(require("bluebird"));
48
+ const lodash_1 = __importDefault(require("lodash"));
49
+ const lru_cache_1 = require("lru-cache");
50
+ const node_events_1 = __importDefault(require("node:events"));
51
+ const node_path_1 = __importDefault(require("node:path"));
52
+ const node_url_1 = __importDefault(require("node:url"));
53
+ const app_utils_1 = require("./app-utils");
54
+ const activeAppInfoCommands = __importStar(require("./commands/active-app-info"));
55
+ const alertCommands = __importStar(require("./commands/alert"));
56
+ const appManagementCommands = __importStar(require("./commands/app-management"));
57
+ const appearanceCommands = __importStar(require("./commands/appearance"));
58
+ const appStringsCommands = __importStar(require("./commands/app-strings"));
59
+ const auditCommands = __importStar(require("./commands/audit"));
60
+ const batteryCommands = __importStar(require("./commands/battery"));
61
+ const biometricCommands = __importStar(require("./commands/biometric"));
62
+ const certificateCommands = __importStar(require("./commands/certificate"));
63
+ const clipboardCommands = __importStar(require("./commands/clipboard"));
64
+ const conditionCommands = __importStar(require("./commands/condition"));
65
+ const contentSizeCommands = __importStar(require("./commands/content-size"));
66
+ const contextCommands = __importStar(require("./commands/context"));
67
+ const deviceInfoCommands = __importStar(require("./commands/deviceInfo"));
68
+ const elementCommands = __importStar(require("./commands/element"));
69
+ const executeCommands = __importStar(require("./commands/execute"));
70
+ const fileMovementCommands = __importStar(require("./commands/file-movement"));
71
+ const findCommands = __importStar(require("./commands/find"));
72
+ const generalCommands = __importStar(require("./commands/general"));
73
+ const geolocationCommands = __importStar(require("./commands/geolocation"));
74
+ const gestureCommands = __importStar(require("./commands/gesture"));
75
+ const iohidCommands = __importStar(require("./commands/iohid"));
76
+ const keychainsCommands = __importStar(require("./commands/keychains"));
77
+ const keyboardCommands = __importStar(require("./commands/keyboard"));
78
+ const localizationCommands = __importStar(require("./commands/localization"));
79
+ const locationCommands = __importStar(require("./commands/location"));
80
+ const lockCommands = __importStar(require("./commands/lock"));
81
+ const logCommands = __importStar(require("./commands/log"));
82
+ const memoryCommands = __importStar(require("./commands/memory"));
83
+ const navigationCommands = __importStar(require("./commands/navigation"));
84
+ const notificationsCommands = __importStar(require("./commands/notifications"));
85
+ const pasteboardCommands = __importStar(require("./commands/pasteboard"));
86
+ const pcapCommands = __importStar(require("./commands/pcap"));
87
+ const performanceCommands = __importStar(require("./commands/performance"));
88
+ const permissionsCommands = __importStar(require("./commands/permissions"));
89
+ const proxyHelperCommands = __importStar(require("./commands/proxy-helper"));
90
+ const recordAudioCommands = __importStar(require("./commands/record-audio"));
91
+ const recordScreenCommands = __importStar(require("./commands/recordscreen"));
92
+ const screenshotCommands = __importStar(require("./commands/screenshots"));
93
+ const sourceCommands = __importStar(require("./commands/source"));
94
+ const simctlCommands = __importStar(require("./commands/simctl"));
95
+ const timeoutCommands = __importStar(require("./commands/timeouts"));
96
+ const webCommands = __importStar(require("./commands/web"));
97
+ const xctestCommands = __importStar(require("./commands/xctest"));
98
+ const xctestRecordScreenCommands = __importStar(require("./commands/xctest-record-screen"));
99
+ const increaseContrastCommands = __importStar(require("./commands/increase-contrast"));
100
+ const desired_caps_1 = require("./desired-caps");
101
+ const device_connections_factory_1 = require("./device-connections-factory");
102
+ const execute_method_map_1 = require("./execute-method-map");
103
+ const method_map_1 = require("./method-map");
104
+ const py_ios_device_client_1 = require("./real-device-clients/py-ios-device-client");
105
+ const real_device_management_1 = require("./real-device-management");
106
+ const real_device_1 = require("./real-device");
107
+ const simulator_management_1 = require("./simulator-management");
108
+ const utils_1 = require("./utils");
109
+ const app_infos_cache_1 = require("./app-infos-cache");
110
+ const context_1 = require("./commands/context");
111
+ const SHUTDOWN_OTHER_FEAT_NAME = 'shutdown_other_sims';
112
+ const CUSTOMIZE_RESULT_BUNDLE_PATH = 'customize_result_bundle_path';
113
+ const defaultServerCaps = {
114
+ webStorageEnabled: false,
115
+ locationContextEnabled: false,
116
+ browserName: '',
117
+ platform: 'MAC',
118
+ javascriptEnabled: true,
119
+ databaseEnabled: false,
120
+ takesScreenshot: true,
121
+ networkConnectionEnabled: false,
122
+ };
123
+ const WDA_SIM_STARTUP_RETRIES = 2;
124
+ const WDA_REAL_DEV_STARTUP_RETRIES = 1;
125
+ const WDA_REAL_DEV_TUTORIAL_URL = 'https://appium.github.io/appium-xcuitest-driver/latest/preparation/real-device-config/';
126
+ const WDA_STARTUP_RETRY_INTERVAL = 10000;
127
+ const DEFAULT_SETTINGS = {
128
+ nativeWebTap: false,
129
+ nativeWebTapStrict: false,
130
+ useJSONSource: false,
131
+ webScreenshotMode: 'native',
132
+ shouldUseCompactResponses: true,
133
+ elementResponseAttributes: 'type,label',
134
+ // Read https://github.com/appium/WebDriverAgent/blob/master/WebDriverAgentLib/Utilities/FBConfiguration.m for following settings' values
135
+ mjpegServerScreenshotQuality: 25,
136
+ mjpegServerFramerate: 10,
137
+ screenshotQuality: 1,
138
+ mjpegScalingFactor: 100,
139
+ // set `reduceMotion` to `null` so that it will be verified but still set either true/false
140
+ reduceMotion: null,
141
+ pageSourceExcludedAttributes: ''
142
+ };
143
+ // This lock assures, that each driver session does not
144
+ // affect shared resources of the other parallel sessions
145
+ const SHARED_RESOURCES_GUARD = new async_lock_1.default();
146
+ const WEB_ELEMENTS_CACHE_SIZE = 500;
147
+ const SUPPORTED_ORIENATIONS = ['LANDSCAPE', 'PORTRAIT'];
148
+ const DEFAULT_MJPEG_SERVER_PORT = 9100;
149
+ /* eslint-disable no-useless-escape */
150
+ /** @type {import('@appium/types').RouteMatcher[]} */
151
+ const NO_PROXY_NATIVE_LIST = [
152
+ ['DELETE', /window/],
153
+ ['GET', /^\/session\/[^\/]+$/],
154
+ ['GET', /alert_text/],
155
+ ['GET', /alert\/[^\/]+/],
156
+ ['GET', /appium/],
157
+ ['GET', /attribute/],
158
+ ['GET', /context/],
159
+ ['GET', /location/],
160
+ ['GET', /log/],
161
+ ['GET', /screenshot/],
162
+ ['GET', /size/],
163
+ ['GET', /source/],
164
+ ['GET', /timeouts$/],
165
+ ['GET', /url/],
166
+ ['GET', /window/],
167
+ ['POST', /accept_alert/],
168
+ ['POST', /actions$/],
169
+ ['DELETE', /actions$/],
170
+ ['POST', /alert_text/],
171
+ ['POST', /alert\/[^\/]+/],
172
+ ['POST', /appium/],
173
+ ['POST', /appium\/device\/is_locked/],
174
+ ['POST', /appium\/device\/lock/],
175
+ ['POST', /appium\/device\/unlock/],
176
+ ['POST', /back/],
177
+ ['POST', /clear/],
178
+ ['POST', /context/],
179
+ ['POST', /dismiss_alert/],
180
+ ['POST', /element\/active/], // MJSONWP get active element should proxy
181
+ ['POST', /element$/],
182
+ ['POST', /elements$/],
183
+ ['POST', /execute/],
184
+ ['POST', /keys/],
185
+ ['POST', /log/],
186
+ ['POST', /receive_async_response/], // always, in case context switches while waiting
187
+ ['POST', /session\/[^\/]+\/location/], // geo location, but not element location
188
+ ['POST', /shake/],
189
+ ['POST', /timeouts/],
190
+ ['POST', /url/],
191
+ ['POST', /value/],
192
+ ['POST', /window/],
193
+ ['DELETE', /cookie/],
194
+ ['GET', /cookie/],
195
+ ['POST', /cookie/],
196
+ ];
197
+ const NO_PROXY_WEB_LIST = /** @type {import('@appium/types').RouteMatcher[]} */ ([
198
+ ['GET', /attribute/],
199
+ ['GET', /element/],
200
+ ['GET', /text/],
201
+ ['GET', /title/],
202
+ ['POST', /clear/],
203
+ ['POST', /click/],
204
+ ['POST', /element/],
205
+ ['POST', /forward/],
206
+ ['POST', /frame/],
207
+ ['POST', /keys/],
208
+ ['POST', /refresh/],
209
+ ]).concat(NO_PROXY_NATIVE_LIST);
210
+ /* eslint-enable no-useless-escape */
211
+ const MEMOIZED_FUNCTIONS = ['getStatusBarHeight', 'getDevicePixelRatio', 'getScreenInfo'];
212
+ // Capabilities that do not have xcodebuild process
213
+ const CAP_NAMES_NO_XCODEBUILD_REQUIRED = ['webDriverAgentUrl', 'usePreinstalledWDA'];
214
+ const BUNDLE_VERSION_PATTERN = /CFBundleVersion\s+=\s+"?([^(;|")]+)/;
215
+ /**
216
+ * @implements {ExternalDriver<XCUITestDriverConstraints, FullContext|string>}
217
+ * @extends {BaseDriver<XCUITestDriverConstraints>}
218
+ * @privateRemarks **This class should be considered "final"**. It cannot be extended
219
+ * due to use of public class field assignments. If extending this class becomes a hard requirement, refer to the implementation of `BaseDriver` on how to do so.
220
+ */
221
+ class XCUITestDriver extends driver_1.BaseDriver {
222
+ static newMethodMap = method_map_1.newMethodMap;
223
+ static executeMethodMap = execute_method_map_1.executeMethodMap;
224
+ /** @type {string|null|undefined} */
225
+ curWindowHandle;
226
+ /**
227
+ * @type {boolean|undefined}
228
+ */
229
+ selectingNewPage;
230
+ /** @type {string[]} */
231
+ contexts;
232
+ /** @type {string|null} */
233
+ curContext;
234
+ /** @type {string[]} */
235
+ curWebFrames;
236
+ /** @type {import('./types').CalibrationData|null} */
237
+ webviewCalibrationResult;
238
+ /** @type {import('./types').AsyncPromise|undefined} */
239
+ asyncPromise;
240
+ /** @type {number|undefined} */
241
+ asyncWaitMs;
242
+ /** @type {((logRecord: {message: string}) => void)|null} */
243
+ _syslogWebsocketListener;
244
+ /** @type {import('./commands/performance').PerfRecorder[]} */
245
+ _perfRecorders;
246
+ /** @type {LRUCache} */
247
+ webElementsCache;
248
+ /**
249
+ * @type {any|null}
250
+ * @privateRemarks needs types
251
+ **/
252
+ _conditionInducerService;
253
+ /** @type {boolean|undefined} */
254
+ _isSafariIphone;
255
+ /** @type {boolean|undefined} */
256
+ _isSafariNotched;
257
+ /** @type {import('./commands/types').WaitingAtoms} */
258
+ _waitingAtoms;
259
+ /** @type {import('./types').LifecycleData} */
260
+ lifecycleData;
261
+ /** @type {import('./commands/record-audio').AudioRecorder|null} */
262
+ _audioRecorder;
263
+ /** @type {XcodeVersion|undefined} */
264
+ xcodeVersion;
265
+ /** @type {import('./commands/pcap').TrafficCapture|null} */
266
+ _trafficCapture;
267
+ /** @type {import('./commands/recordscreen').ScreenRecorder|null} */
268
+ _recentScreenRecorder;
269
+ /** @type {Simulator|RealDevice} */
270
+ _device;
271
+ /** @type {string|null} */
272
+ _iosSdkVersion;
273
+ /** @type {WebDriverAgent} */
274
+ wda;
275
+ /** @type {import('appium-remote-debugger').RemoteDebugger|null} */
276
+ remote;
277
+ /** @type {DriverLogs} */
278
+ logs;
279
+ /** @type {import('./commands/types').LogListener|undefined} */
280
+ _bidiServerLogListener;
281
+ /**
282
+ *
283
+ * @param {XCUITestDriverOpts} opts
284
+ * @param {boolean} shouldValidateCaps
285
+ */
286
+ constructor(opts = /** @type {XCUITestDriverOpts} */ ({}), shouldValidateCaps = true) {
287
+ super(opts, shouldValidateCaps);
288
+ this.locatorStrategies = [
289
+ 'xpath',
290
+ 'id',
291
+ 'name',
292
+ 'class name',
293
+ '-ios predicate string',
294
+ '-ios class chain',
295
+ 'accessibility id',
296
+ 'css selector',
297
+ ];
298
+ this.webLocatorStrategies = [
299
+ 'link text',
300
+ 'css selector',
301
+ 'tag name',
302
+ 'link text',
303
+ 'partial link text',
304
+ ];
305
+ this.curWebFrames = [];
306
+ this._perfRecorders = [];
307
+ this.desiredCapConstraints = desired_caps_1.desiredCapConstraints;
308
+ this.webElementsCache = new lru_cache_1.LRUCache({
309
+ max: WEB_ELEMENTS_CACHE_SIZE,
310
+ });
311
+ this.webviewCalibrationResult = null;
312
+ this._waitingAtoms = {
313
+ count: 0,
314
+ alertNotifier: new node_events_1.default(),
315
+ alertMonitor: bluebird_1.default.resolve(),
316
+ };
317
+ this.resetIos();
318
+ this.settings = new driver_1.DeviceSettings(DEFAULT_SETTINGS, this.onSettingsUpdate.bind(this));
319
+ this.logs = {};
320
+ this._trafficCapture = null;
321
+ // memoize functions here, so that they are done on a per-instance basis
322
+ for (const fn of MEMOIZED_FUNCTIONS) {
323
+ this[fn] = lodash_1.default.memoize(this[fn]);
324
+ }
325
+ this.lifecycleData = {};
326
+ this._audioRecorder = null;
327
+ this.appInfosCache = new app_infos_cache_1.AppInfosCache(this.log);
328
+ this.remote = null;
329
+ this.doesSupportBidi = true;
330
+ }
331
+ async onSettingsUpdate(key, value) {
332
+ // skip sending the update request to the WDA nor saving it in opts
333
+ // to not spend unnecessary time.
334
+ if (['pageSourceExcludedAttributes'].includes(key)) {
335
+ return;
336
+ }
337
+ if (key !== 'nativeWebTap' && key !== 'nativeWebTapStrict') {
338
+ return await this.proxyCommand('/appium/settings', 'POST', {
339
+ settings: { [key]: value },
340
+ });
341
+ }
342
+ this.opts[key] = !!value;
343
+ }
344
+ resetIos() {
345
+ this.opts = this.opts || {};
346
+ // @ts-ignore this is ok
347
+ this.wda = null;
348
+ this.jwpProxyActive = false;
349
+ this.proxyReqRes = null;
350
+ this.safari = false;
351
+ this.cachedWdaStatus = null;
352
+ this.curWebFrames = [];
353
+ this._currentUrl = null;
354
+ this.curContext = null;
355
+ this.xcodeVersion = undefined;
356
+ this.contexts = [];
357
+ this.implicitWaitMs = 0;
358
+ this.pageLoadMs = 6000;
359
+ this.landscapeWebCoordsOffset = 0;
360
+ this.remote = null;
361
+ this._conditionInducerService = null;
362
+ this.webElementsCache = new lru_cache_1.LRUCache({
363
+ max: WEB_ELEMENTS_CACHE_SIZE,
364
+ });
365
+ this._waitingAtoms = {
366
+ count: 0,
367
+ alertNotifier: new node_events_1.default(),
368
+ alertMonitor: bluebird_1.default.resolve(),
369
+ };
370
+ }
371
+ get driverData() {
372
+ // TODO fill out resource info here
373
+ return {};
374
+ }
375
+ async getStatus() {
376
+ const status = {
377
+ ready: true,
378
+ message: 'The driver is ready to accept new connections',
379
+ build: await (0, utils_1.getDriverInfo)(),
380
+ };
381
+ if (this.cachedWdaStatus) {
382
+ status.wda = this.cachedWdaStatus;
383
+ }
384
+ return status;
385
+ }
386
+ mergeCliArgsToOpts() {
387
+ let didMerge = false;
388
+ // this.cliArgs should never include anything we do not expect.
389
+ for (const [key, value] of Object.entries(this.cliArgs ?? {})) {
390
+ if (lodash_1.default.has(this.opts, key)) {
391
+ this.log.info(`CLI arg '${key}' with value '${value}' overwrites value '${this.opts[key]}' sent in via caps)`);
392
+ didMerge = true;
393
+ }
394
+ this.opts[key] = value;
395
+ }
396
+ return didMerge;
397
+ }
398
+ /**
399
+ * @returns {Simulator|RealDevice}
400
+ */
401
+ get device() {
402
+ return this._device;
403
+ }
404
+ isXcodebuildNeeded() {
405
+ return !(CAP_NAMES_NO_XCODEBUILD_REQUIRED.some((x) => Boolean(this.opts[x])));
406
+ }
407
+ async createSession(w3cCaps1, w3cCaps2, w3cCaps3, driverData) {
408
+ try {
409
+ let [sessionId, caps] = await super.createSession(w3cCaps1, w3cCaps2, w3cCaps3, driverData);
410
+ // merge cli args to opts, and if we did merge any, revalidate opts to ensure the final set
411
+ // is also consistent
412
+ if (this.mergeCliArgsToOpts()) {
413
+ this.validateDesiredCaps({ ...caps, ...this.cliArgs });
414
+ }
415
+ await this.start();
416
+ // merge server capabilities + desired capabilities
417
+ caps = { ...defaultServerCaps, ...caps };
418
+ // update the udid with what is actually used
419
+ caps.udid = this.opts.udid;
420
+ // ensure we track nativeWebTap capability as a setting as well
421
+ if (lodash_1.default.has(this.opts, 'nativeWebTap')) {
422
+ await this.updateSettings({ nativeWebTap: this.opts.nativeWebTap });
423
+ }
424
+ // ensure we track nativeWebTapStrict capability as a setting as well
425
+ if (lodash_1.default.has(this.opts, 'nativeWebTapStrict')) {
426
+ await this.updateSettings({ nativeWebTapStrict: this.opts.nativeWebTapStrict });
427
+ }
428
+ // ensure we track useJSONSource capability as a setting as well
429
+ if (lodash_1.default.has(this.opts, 'useJSONSource')) {
430
+ await this.updateSettings({ useJSONSource: this.opts.useJSONSource });
431
+ }
432
+ /** @type {import('appium-webdriveragent').WDASettings} */
433
+ let wdaSettings = {
434
+ elementResponseAttributes: DEFAULT_SETTINGS.elementResponseAttributes,
435
+ shouldUseCompactResponses: DEFAULT_SETTINGS.shouldUseCompactResponses,
436
+ };
437
+ if ('elementResponseAttributes' in this.opts && lodash_1.default.isString(this.opts.elementResponseAttributes)) {
438
+ wdaSettings.elementResponseAttributes = this.opts.elementResponseAttributes;
439
+ }
440
+ if ('shouldUseCompactResponses' in this.opts && lodash_1.default.isBoolean(this.opts.shouldUseCompactResponses)) {
441
+ wdaSettings.shouldUseCompactResponses = this.opts.shouldUseCompactResponses;
442
+ }
443
+ if ('mjpegServerScreenshotQuality' in this.opts && lodash_1.default.isNumber(this.opts.mjpegServerScreenshotQuality)) {
444
+ wdaSettings.mjpegServerScreenshotQuality = this.opts.mjpegServerScreenshotQuality;
445
+ }
446
+ if ('mjpegServerFramerate' in this.opts && lodash_1.default.isNumber(this.opts.mjpegServerFramerate)) {
447
+ wdaSettings.mjpegServerFramerate = this.opts.mjpegServerFramerate;
448
+ }
449
+ if (lodash_1.default.has(this.opts, 'screenshotQuality')) {
450
+ this.log.info(`Setting the quality of phone screenshot: '${this.opts.screenshotQuality}'`);
451
+ wdaSettings.screenshotQuality = this.opts.screenshotQuality;
452
+ }
453
+ // ensure WDA gets our defaults instead of whatever its own might be
454
+ await this.updateSettings(wdaSettings);
455
+ await this.handleMjpegOptions();
456
+ return /** @type {[string, import('@appium/types').DriverCaps<XCUITestDriverConstraints>]} */ ([
457
+ sessionId,
458
+ caps,
459
+ ]);
460
+ }
461
+ catch (e) {
462
+ this.log.error(JSON.stringify(e));
463
+ await this.deleteSession();
464
+ throw e;
465
+ }
466
+ }
467
+ /**
468
+ * Handles MJPEG server-related capabilities
469
+ * @returns {Promise<void>}
470
+ */
471
+ async handleMjpegOptions() {
472
+ await this.allocateMjpegServerPort();
473
+ // turn on mjpeg stream reading if requested
474
+ if (this.opts.mjpegScreenshotUrl) {
475
+ this.log.info(`Starting MJPEG stream reading URL: '${this.opts.mjpegScreenshotUrl}'`);
476
+ this.mjpegStream = new support_1.mjpeg.MJpegStream(this.opts.mjpegScreenshotUrl);
477
+ await this.mjpegStream.start();
478
+ }
479
+ }
480
+ /**
481
+ * Allocates and configures port forwarding for the MJPEG server
482
+ * @returns {Promise<void>}
483
+ * @throws {Error} If port forwarding fails and mjpegServerPort capability value is provided explicitly
484
+ */
485
+ async allocateMjpegServerPort() {
486
+ const mjpegServerPort = this.opts.mjpegServerPort || DEFAULT_MJPEG_SERVER_PORT;
487
+ this.log.debug(`Forwarding MJPEG server port ${mjpegServerPort} to local port ${mjpegServerPort}`);
488
+ try {
489
+ await device_connections_factory_1.DEVICE_CONNECTIONS_FACTORY.requestConnection(this.opts.udid, mjpegServerPort, {
490
+ devicePort: mjpegServerPort,
491
+ usePortForwarding: this.isRealDevice(),
492
+ });
493
+ }
494
+ catch (error) {
495
+ if (lodash_1.default.isUndefined(this.opts.mjpegServerPort)) {
496
+ this.log.warn(`Cannot forward the device port ${DEFAULT_MJPEG_SERVER_PORT} to the local port ${DEFAULT_MJPEG_SERVER_PORT}. ` +
497
+ `Certain features, like MJPEG-based screen recording, will be unavailable during this session. ` +
498
+ `Try to customize the value of 'mjpegServerPort' capability as a possible solution`);
499
+ }
500
+ else {
501
+ this.log.debug(error.stack);
502
+ throw new Error(`Cannot ensure MJPEG broadcast functionality by forwarding the local port ${mjpegServerPort} ` +
503
+ `requested by the 'mjpegServerPort' capability to the device port ${mjpegServerPort}. ` +
504
+ `Original error: ${error}`);
505
+ }
506
+ }
507
+ }
508
+ /**
509
+ * Returns the default URL for Safari browser
510
+ * @returns {string} The default URL
511
+ */
512
+ getDefaultUrl() {
513
+ // Setting this to some external URL slows down the session init
514
+ return `${this.getWdaLocalhostRoot()}/health`;
515
+ }
516
+ async start() {
517
+ this.opts.noReset = !!this.opts.noReset;
518
+ this.opts.fullReset = !!this.opts.fullReset;
519
+ await (0, utils_1.printUser)();
520
+ this._iosSdkVersion = null; // For WDA and xcodebuild
521
+ const { device, udid, realDevice } = await this.determineDevice();
522
+ this.log.info(`Determining device to run tests on: udid: '${udid}', real device: ${realDevice}`);
523
+ this._device = device;
524
+ this.opts.udid = udid;
525
+ if (this.opts.simulatorDevicesSetPath) {
526
+ if (realDevice) {
527
+ this.log.info(`The 'simulatorDevicesSetPath' capability is only supported for Simulator devices`);
528
+ }
529
+ else {
530
+ this.log.info(`Setting simulator devices set path to '${this.opts.simulatorDevicesSetPath}'`);
531
+ ( /** @type {Simulator} */(this.device)).devicesSetPath = this.opts.simulatorDevicesSetPath;
532
+ }
533
+ }
534
+ // at this point if there is no platformVersion, get it from the device
535
+ if (!this.opts.platformVersion) {
536
+ this.opts.platformVersion = await this.device.getPlatformVersion();
537
+ this.log.info(`No platformVersion specified. Using device version: '${this.opts.platformVersion}'`);
538
+ }
539
+ const normalizedVersion = (0, utils_1.normalizePlatformVersion)(this.opts.platformVersion);
540
+ if (this.opts.platformVersion !== normalizedVersion) {
541
+ this.log.info(`Normalized platformVersion capability value '${this.opts.platformVersion}' to '${normalizedVersion}'`);
542
+ this.opts.platformVersion = normalizedVersion;
543
+ }
544
+ this.caps.platformVersion = this.opts.platformVersion;
545
+ if (lodash_1.default.isEmpty(this.xcodeVersion) && (this.isXcodebuildNeeded() || this.isSimulator())) {
546
+ // no `webDriverAgentUrl`, or on a simulator, so we need an Xcode version
547
+ this.xcodeVersion = await (0, utils_1.getAndCheckXcodeVersion)();
548
+ }
549
+ this.logEvent('xcodeDetailsRetrieved');
550
+ if (lodash_1.default.toLower(this.opts.browserName) === 'safari') {
551
+ this.log.info('Safari test requested');
552
+ this.safari = true;
553
+ this.opts.app = undefined;
554
+ this.opts.processArguments = this.opts.processArguments || {};
555
+ real_device_management_1.applySafariStartupArgs.bind(this)();
556
+ this.opts.bundleId = app_utils_1.SAFARI_BUNDLE_ID;
557
+ this._currentUrl = this.opts.safariInitialUrl || this.getDefaultUrl();
558
+ }
559
+ else if (this.opts.app || this.opts.bundleId) {
560
+ await this.configureApp();
561
+ }
562
+ this.logEvent('appConfigured');
563
+ // fail very early if the app doesn't actually exist
564
+ // or if bundle id doesn't point to an installed app
565
+ if (this.opts.app) {
566
+ await (0, utils_1.checkAppPresent)(this.opts.app);
567
+ if (!this.opts.bundleId) {
568
+ this.opts.bundleId = await this.appInfosCache.extractBundleId(this.opts.app);
569
+ }
570
+ }
571
+ await this.runReset();
572
+ this.wda = new appium_webdriveragent_1.WebDriverAgent(
573
+ /** @type {import('@limrun/appium-xcode').XcodeVersion} */ (this.xcodeVersion), {
574
+ ...this.opts,
575
+ device: this.device,
576
+ realDevice: this.isRealDevice(),
577
+ iosSdkVersion: this._iosSdkVersion ?? undefined,
578
+ reqBasePath: this.basePath,
579
+ },
580
+ // @ts-ignore this is ok
581
+ this.log);
582
+ // Derived data path retrieval is an expensive operation
583
+ // We could start that now in background and get the cached result
584
+ // whenever it is needed
585
+ // eslint-disable-next-line promise/prefer-await-to-then
586
+ this.wda.retrieveDerivedDataPath().catch((e) => this.log.debug(e));
587
+ const memoizedLogInfo = lodash_1.default.memoize(() => {
588
+ this.log.info("'skipLogCapture' is set. Skipping starting logs such as crash, system, safari console and safari network.");
589
+ });
590
+ const startLogCapture = async () => {
591
+ if (this.opts.skipLogCapture) {
592
+ memoizedLogInfo();
593
+ return false;
594
+ }
595
+ const result = await this.startLogCapture();
596
+ if (result) {
597
+ this.logEvent('logCaptureStarted');
598
+ }
599
+ return result;
600
+ };
601
+ const isLogCaptureStarted = await startLogCapture();
602
+ this.log.info(`Setting up ${this.isRealDevice() ? 'real device' : 'simulator'}`);
603
+ if (this.isSimulator()) {
604
+ await this.initSimulator();
605
+ if (!isLogCaptureStarted) {
606
+ // Retry log capture if Simulator was not running before
607
+ await startLogCapture();
608
+ }
609
+ }
610
+ else if (this.opts.customSSLCert) {
611
+ await new py_ios_device_client_1.Pyidevice({
612
+ udid,
613
+ log: this.log,
614
+ }).installProfile({ payload: this.opts.customSSLCert });
615
+ this.logEvent('customCertInstalled');
616
+ }
617
+ await this.installAUT();
618
+ // if we only have bundle identifier and no app, fail if it is not already installed
619
+ if (!this.opts.app &&
620
+ this.opts.bundleId &&
621
+ !this.isSafari() &&
622
+ !(await this.device.isAppInstalled(this.opts.bundleId))) {
623
+ throw this.log.errorWithException(`App with bundle identifier '${this.opts.bundleId}' unknown`);
624
+ }
625
+ if (this.isSimulator()) {
626
+ if (this.opts.permissions) {
627
+ this.log.debug('Setting the requested permissions before WDA is started');
628
+ for (const [bundleId, permissionsMapping] of lodash_1.default.toPairs(JSON.parse(this.opts.permissions))) {
629
+ await /** @type {Simulator} */ (this.device).setPermissions(bundleId, permissionsMapping);
630
+ }
631
+ }
632
+ // TODO: Deprecate and remove this block together with calendarAccessAuthorized capability
633
+ if (lodash_1.default.isBoolean(this.opts.calendarAccessAuthorized)) {
634
+ this.log.warn(`The 'calendarAccessAuthorized' capability is deprecated and will be removed soon. ` +
635
+ `Consider using 'permissions' one instead with 'calendar' key`);
636
+ const methodName = `${this.opts.calendarAccessAuthorized ? 'enable' : 'disable'}CalendarAccess`;
637
+ await this.device[methodName](this.opts.bundleId);
638
+ }
639
+ }
640
+ await this.startWda();
641
+ if (lodash_1.default.isString(this.opts.orientation)) {
642
+ await this.setInitialOrientation(this.opts.orientation);
643
+ this.logEvent('orientationSet');
644
+ }
645
+ if (this.isSafari() || this.opts.autoWebview) {
646
+ await this.activateRecentWebview();
647
+ }
648
+ else {
649
+ // We want to always setup the initial context value upon session startup
650
+ await context_1.notifyBiDiContextChange.bind(this)();
651
+ }
652
+ if (this.isSafari()) {
653
+ if ((0, utils_1.shouldSetInitialSafariUrl)(this.opts)) {
654
+ this.log.info(`About to set the initial Safari URL to '${this.getCurrentUrl()}'`);
655
+ if (lodash_1.default.isNil(this.opts.safariInitialUrl) && lodash_1.default.isNil(this.opts.initialDeeplinkUrl)) {
656
+ this.log.info(`Use the 'safariInitialUrl' capability to customize it`);
657
+ }
658
+ ;
659
+ await this.setUrl(this.getCurrentUrl() || this.getDefaultUrl());
660
+ }
661
+ else {
662
+ const currentUrl = await this.getUrl();
663
+ this.log.info(`Current URL: ${currentUrl}`);
664
+ this.setCurrentUrl(currentUrl);
665
+ }
666
+ }
667
+ }
668
+ /**
669
+ * Start the simulator and initialize based on capabilities
670
+ */
671
+ async initSimulator() {
672
+ const device = /** @type {Simulator} */ (this.device);
673
+ if (this.opts.shutdownOtherSimulators) {
674
+ this.assertFeatureEnabled(SHUTDOWN_OTHER_FEAT_NAME);
675
+ await simulator_management_1.shutdownOtherSimulators.bind(this)();
676
+ }
677
+ await this.startSim();
678
+ if (this.opts.customSSLCert) {
679
+ // Simulator must be booted in order to call this helper
680
+ await device.addCertificate(this.opts.customSSLCert);
681
+ this.logEvent('customCertInstalled');
682
+ }
683
+ if (await simulator_management_1.setSafariPrefs.bind(this)()) {
684
+ this.log.debug('Safari preferences have been updated');
685
+ }
686
+ if (await simulator_management_1.setLocalizationPrefs.bind(this)()) {
687
+ this.log.debug('Localization preferences have been updated');
688
+ }
689
+ /** @type {Promise[]} */
690
+ const promises = ['reduceMotion', 'reduceTransparency', 'autoFillPasswords']
691
+ .filter((optName) => lodash_1.default.isBoolean(this.opts[optName]))
692
+ .map((optName) => {
693
+ this.log.info(`Setting ${optName} to ${this.opts[optName]}`);
694
+ return device[`set${lodash_1.default.upperFirst(optName)}`](this.opts[optName]);
695
+ });
696
+ await bluebird_1.default.all(promises);
697
+ if (this.opts.launchWithIDB) {
698
+ try {
699
+ const idb = new appium_idb_1.default({ udid: this.opts.udid });
700
+ await idb.connect();
701
+ device.idb = idb;
702
+ }
703
+ catch (e) {
704
+ this.log.debug(e.stack);
705
+ this.log.warn(`idb will not be used for Simulator interaction. Original error: ${e.message}`);
706
+ }
707
+ }
708
+ this.logEvent('simStarted');
709
+ }
710
+ /**
711
+ * Start WebDriverAgentRunner
712
+ */
713
+ async startWda() {
714
+ // Don't cleanup the processes if webDriverAgentUrl is set
715
+ if (!support_1.util.hasValue(this.wda.webDriverAgentUrl)) {
716
+ await this.wda.cleanupObsoleteProcesses();
717
+ }
718
+ const usePortForwarding = this.isRealDevice() && !this.wda.webDriverAgentUrl && (0, utils_1.isLocalHost)(this.wda.wdaBaseUrl);
719
+ await device_connections_factory_1.DEVICE_CONNECTIONS_FACTORY.requestConnection(this.opts.udid, this.wda.url.port, {
720
+ devicePort: usePortForwarding ? this.wda.wdaRemotePort : null,
721
+ usePortForwarding,
722
+ });
723
+ // Let multiple WDA binaries with different derived data folders be built in parallel
724
+ // Concurrent WDA builds from the same source will cause xcodebuild synchronization errors
725
+ let synchronizationKey = XCUITestDriver.name;
726
+ if (this.opts.useXctestrunFile || !(await this.wda.isSourceFresh())) {
727
+ // First-time compilation is an expensive operation, which is done faster if executed
728
+ // sequentially. Xcodebuild spreads the load caused by the clang compiler to all available CPU cores
729
+ const derivedDataPath = await this.wda.retrieveDerivedDataPath();
730
+ if (derivedDataPath) {
731
+ synchronizationKey = node_path_1.default.normalize(derivedDataPath);
732
+ }
733
+ }
734
+ this.log.debug(`Starting WebDriverAgent initialization with the synchronization key '${synchronizationKey}'`);
735
+ if (SHARED_RESOURCES_GUARD.isBusy() && !this.opts.derivedDataPath && !this.opts.bootstrapPath) {
736
+ this.log.debug(`Consider setting a unique 'derivedDataPath' capability value for each parallel driver instance ` +
737
+ `to avoid conflicts and speed up the building process`);
738
+ }
739
+ if (this.opts.usePreinstalledWDA && this.opts.prebuiltWDAPath && !(await support_1.fs.exists(this.opts.prebuiltWDAPath))) {
740
+ throw new Error(`The prebuilt WebDriverAgent app at '${this.opts.prebuiltWDAPath}' provided as 'prebuiltWDAPath' ` +
741
+ `capability value does not exist or is not accessible`);
742
+ }
743
+ return await SHARED_RESOURCES_GUARD.acquire(synchronizationKey, async () => {
744
+ if (this.opts.useNewWDA) {
745
+ this.log.debug(`Capability 'useNewWDA' set to true, so uninstalling WDA before proceeding`);
746
+ await this.wda.quitAndUninstall();
747
+ this.logEvent('wdaUninstalled');
748
+ }
749
+ else if (!support_1.util.hasValue(this.wda.webDriverAgentUrl) && this.isXcodebuildNeeded()) {
750
+ await this.wda.setupCaching();
751
+ }
752
+ // local helper for the two places we need to uninstall wda and re-start it
753
+ const quitAndUninstall = async (msg) => {
754
+ this.log.debug(msg);
755
+ if (!this.isXcodebuildNeeded()) {
756
+ this.log.debug(`Not quitting/uninstalling WebDriverAgent since at least one of ${CAP_NAMES_NO_XCODEBUILD_REQUIRED} capabilities is provided`);
757
+ throw new Error(msg);
758
+ }
759
+ this.log.warn('Quitting and uninstalling WebDriverAgent');
760
+ await this.wda.quitAndUninstall();
761
+ throw new Error(msg);
762
+ };
763
+ // Used in the following WDA build
764
+ if (this.opts.resultBundlePath) {
765
+ this.assertFeatureEnabled(CUSTOMIZE_RESULT_BUNDLE_PATH);
766
+ }
767
+ let startupRetries = this.opts.wdaStartupRetries ||
768
+ (this.isRealDevice() ? WDA_REAL_DEV_STARTUP_RETRIES : WDA_SIM_STARTUP_RETRIES);
769
+ const startupRetryInterval = this.opts.wdaStartupRetryInterval || WDA_STARTUP_RETRY_INTERVAL;
770
+ // These values help only xcodebuild.
771
+ if (this.isXcodebuildNeeded()) {
772
+ this.log.debug(`Trying to start WebDriverAgent ${startupRetries} times with ${startupRetryInterval}ms interval`);
773
+ if (!support_1.util.hasValue(this.opts.wdaStartupRetries) &&
774
+ !support_1.util.hasValue(this.opts.wdaStartupRetryInterval)) {
775
+ this.log.debug(`These values can be customized by changing wdaStartupRetries/wdaStartupRetryInterval capabilities`);
776
+ }
777
+ }
778
+ else {
779
+ // The startup retry will be one time if the session does not need WDA build
780
+ this.log.debug(`Trying to start WebDriverAgent once since at least one of ${CAP_NAMES_NO_XCODEBUILD_REQUIRED} capabilities is provided`);
781
+ startupRetries = 1;
782
+ }
783
+ /** @type {Error|null} */
784
+ let shortCircuitError = null;
785
+ let retryCount = 0;
786
+ await (0, asyncbox_1.retryInterval)(startupRetries, startupRetryInterval, async () => {
787
+ this.logEvent('wdaStartAttempted');
788
+ if (retryCount > 0) {
789
+ this.log.info(`Retrying WDA startup (${retryCount + 1} of ${startupRetries})`);
790
+ }
791
+ try {
792
+ if (this.opts.usePreinstalledWDA) {
793
+ await this.preparePreinstalledWda();
794
+ }
795
+ this.cachedWdaStatus = await this.wda.launch(/** @type {string} */ (this.sessionId));
796
+ }
797
+ catch (err) {
798
+ this.logEvent('wdaStartFailed');
799
+ this.log.debug(err.stack);
800
+ retryCount++;
801
+ let errorMsg = `Unable to launch WebDriverAgent. Original error: ${err.message}`;
802
+ if (this.isRealDevice()) {
803
+ errorMsg += `. Make sure you follow the tutorial at ${WDA_REAL_DEV_TUTORIAL_URL}`;
804
+ }
805
+ if (this.opts.usePreinstalledWDA) {
806
+ try {
807
+ // In case the bundle id process start got failed because of
808
+ // auth popup in the device. Then, the bundle id process itself started. It is safe to stop it here.
809
+ await this.mobileKillApp(this.wda.bundleIdForXctest);
810
+ }
811
+ catch { }
812
+ ;
813
+ // Mostly it failed to start the WDA process as no the bundle id
814
+ // e.g. '<bundle id of WDA> not found on device <udid>'
815
+ errorMsg = `Unable to launch WebDriverAgent. Original error: ${err.message}. ` +
816
+ `Make sure the application ${this.wda.bundleIdForXctest} exists and it is launchable.`;
817
+ if (this.isRealDevice()) {
818
+ errorMsg += ` ${WDA_REAL_DEV_TUTORIAL_URL} may help to complete the preparation.`;
819
+ }
820
+ ;
821
+ throw new Error(errorMsg);
822
+ }
823
+ else {
824
+ await quitAndUninstall(errorMsg);
825
+ }
826
+ }
827
+ this.proxyReqRes = this.wda.proxyReqRes.bind(this.wda);
828
+ this.jwpProxyActive = true;
829
+ try {
830
+ this.logEvent('wdaSessionAttempted');
831
+ this.log.debug('Sending createSession command to WDA');
832
+ this.cachedWdaStatus = this.cachedWdaStatus || (await this.proxyCommand('/status', 'GET'));
833
+ await this.startWdaSession(this.opts.bundleId, this.opts.processArguments);
834
+ this.logEvent('wdaSessionStarted');
835
+ }
836
+ catch (err) {
837
+ this.logEvent('wdaSessionFailed');
838
+ this.log.debug(err.stack);
839
+ if (err instanceof driver_1.errors.TimeoutError) {
840
+ // Session startup timed out. There is no point to retry
841
+ shortCircuitError = err;
842
+ return;
843
+ }
844
+ let errorMsg = `Unable to start WebDriverAgent session. Original error: ${err.message}`;
845
+ if (this.isRealDevice() && lodash_1.default.includes(err.message, 'xcodebuild')) {
846
+ errorMsg += ` Make sure you follow the tutorial at ${WDA_REAL_DEV_TUTORIAL_URL}.`;
847
+ }
848
+ throw new Error(errorMsg);
849
+ }
850
+ if (this.opts.clearSystemFiles && this.isXcodebuildNeeded()) {
851
+ await (0, utils_1.markSystemFilesForCleanup)(this.wda);
852
+ }
853
+ // We don't restrict the version, but show what version of WDA is running on the device for debugging purposes.
854
+ if (this.cachedWdaStatus?.build) {
855
+ this.log.info(`WebDriverAgent version: '${this.cachedWdaStatus.build.version}'`);
856
+ }
857
+ else {
858
+ this.log.warn(`WebDriverAgent does not provide any version information. ` +
859
+ `This might indicate either a custom or an outdated build.`);
860
+ }
861
+ // we expect certain socket errors until this point, but now
862
+ // mark things as fully working
863
+ this.wda.fullyStarted = true;
864
+ this.logEvent('wdaStarted');
865
+ });
866
+ if (shortCircuitError) {
867
+ throw shortCircuitError;
868
+ }
869
+ });
870
+ }
871
+ /**
872
+ *
873
+ * @param {boolean} [enforceSimulatorShutdown=false]
874
+ */
875
+ async runReset(enforceSimulatorShutdown = false) {
876
+ this.logEvent('resetStarted');
877
+ if (this.isRealDevice()) {
878
+ await real_device_management_1.runRealDeviceReset.bind(this)();
879
+ }
880
+ else {
881
+ await simulator_management_1.runSimulatorReset.bind(this)(enforceSimulatorShutdown);
882
+ }
883
+ this.logEvent('resetComplete');
884
+ }
885
+ async deleteSession(sessionId) {
886
+ await utils_1.removeAllSessionWebSocketHandlers.bind(this)();
887
+ for (const recorder of lodash_1.default.compact([
888
+ this._recentScreenRecorder,
889
+ this._audioRecorder,
890
+ this._trafficCapture,
891
+ ])) {
892
+ await recorder.interrupt(true);
893
+ await recorder.cleanup();
894
+ }
895
+ if (!lodash_1.default.isEmpty(this._perfRecorders)) {
896
+ await bluebird_1.default.all(this._perfRecorders.map((x) => x.stop(true)));
897
+ this._perfRecorders = [];
898
+ }
899
+ if (this._conditionInducerService) {
900
+ this.disableConditionInducer();
901
+ }
902
+ await this.stop();
903
+ if (this.wda && this.isXcodebuildNeeded()) {
904
+ if (this.opts.clearSystemFiles) {
905
+ let synchronizationKey = XCUITestDriver.name;
906
+ const derivedDataPath = await this.wda.retrieveDerivedDataPath();
907
+ if (derivedDataPath) {
908
+ synchronizationKey = node_path_1.default.normalize(derivedDataPath);
909
+ }
910
+ await SHARED_RESOURCES_GUARD.acquire(synchronizationKey, async () => {
911
+ await (0, utils_1.clearSystemFiles)(this.wda);
912
+ });
913
+ }
914
+ else {
915
+ this.log.debug('Not clearing log files. Use `clearSystemFiles` capability to turn on.');
916
+ }
917
+ }
918
+ if (this.remote) {
919
+ this.log.debug('Found a remote debugger session. Removing...');
920
+ await this.stopRemote();
921
+ }
922
+ if (this.opts.resetOnSessionStartOnly === false) {
923
+ await this.runReset(true);
924
+ }
925
+ const simulatorDevice = this.isSimulator() ? /** @type {Simulator} */ (this.device) : null;
926
+ if (simulatorDevice && this.lifecycleData.createSim) {
927
+ this.log.debug(`Deleting simulator created for this run (udid: '${simulatorDevice.udid}')`);
928
+ await simulator_management_1.shutdownSimulator.bind(this)();
929
+ await simulatorDevice.delete();
930
+ }
931
+ const shouldResetLocationService = this.isRealDevice() && !!this.opts.resetLocationService;
932
+ if (shouldResetLocationService) {
933
+ try {
934
+ await this.mobileResetLocationService();
935
+ }
936
+ catch {
937
+ /* Ignore this error since mobileResetLocationService already logged the error */
938
+ }
939
+ }
940
+ await this.logs.syslog?.stopCapture();
941
+ lodash_1.default.values(this.logs).forEach((x) => x.removeAllListeners());
942
+ if (this._bidiServerLogListener) {
943
+ this.log.unwrap().off('log', this._bidiServerLogListener);
944
+ }
945
+ this.logs = {};
946
+ if (this.mjpegStream) {
947
+ this.log.info('Closing MJPEG stream');
948
+ this.mjpegStream.stop();
949
+ }
950
+ this.resetIos();
951
+ await super.deleteSession(sessionId);
952
+ }
953
+ async stop() {
954
+ this.jwpProxyActive = false;
955
+ this.proxyReqRes = null;
956
+ if (this.wda?.fullyStarted) {
957
+ if (this.wda.jwproxy) {
958
+ try {
959
+ await this.proxyCommand(`/session/${this.sessionId}`, 'DELETE');
960
+ }
961
+ catch (err) {
962
+ // an error here should not short-circuit the rest of clean up
963
+ this.log.debug(`Unable to DELETE session on WDA: '${err.message}'. Continuing shutdown.`);
964
+ }
965
+ }
966
+ // The former could cache the xcodebuild, so should not quit the process.
967
+ // If the session skipped the xcodebuild (this.wda.canSkipXcodebuild), the this.wda instance
968
+ // should quit properly.
969
+ if ((!this.wda.webDriverAgentUrl && this.opts.useNewWDA) || this.wda.canSkipXcodebuild) {
970
+ await this.wda.quit();
971
+ }
972
+ }
973
+ device_connections_factory_1.DEVICE_CONNECTIONS_FACTORY.releaseConnection(this.opts.udid);
974
+ }
975
+ /**
976
+ *
977
+ * @param {string} cmd
978
+ * @param {...any} args
979
+ * @returns {Promise<any>}
980
+ */
981
+ async executeCommand(cmd, ...args) {
982
+ this.log.debug(`Executing command '${cmd}'`);
983
+ if (cmd === 'receiveAsyncResponse') {
984
+ return await this.receiveAsyncResponse(...args);
985
+ }
986
+ // TODO: once this fix gets into base driver remove from here
987
+ if (cmd === 'getStatus') {
988
+ return await this.getStatus();
989
+ }
990
+ return await super.executeCommand(cmd, ...args);
991
+ }
992
+ async configureApp() {
993
+ function appIsPackageOrBundle(app) {
994
+ return /^([a-zA-Z0-9\-_]+\.[a-zA-Z0-9\-_]+)+$/.test(app);
995
+ }
996
+ // the app name is a bundleId assign it to the bundleId property
997
+ if (!this.opts.bundleId && appIsPackageOrBundle(this.opts.app)) {
998
+ this.opts.bundleId = this.opts.app;
999
+ this.opts.app = '';
1000
+ }
1001
+ // we have a bundle ID, but no app, or app is also a bundle
1002
+ if (this.opts.bundleId &&
1003
+ appIsPackageOrBundle(this.opts.bundleId) &&
1004
+ (this.opts.app === '' || appIsPackageOrBundle(this.opts.app))) {
1005
+ this.log.debug('App is an iOS bundle, will attempt to run as pre-existing');
1006
+ return;
1007
+ }
1008
+ // check for supported build-in apps
1009
+ switch (lodash_1.default.toLower(this.opts.app)) {
1010
+ case 'settings':
1011
+ this.opts.bundleId = 'com.apple.Preferences';
1012
+ this.opts.app = null;
1013
+ return;
1014
+ case 'calendar':
1015
+ this.opts.bundleId = 'com.apple.mobilecal';
1016
+ this.opts.app = null;
1017
+ return;
1018
+ }
1019
+ this.opts.app = await this.helpers.configureApp(this.opts.app, {
1020
+ onPostProcess: app_utils_1.onPostConfigureApp.bind(this),
1021
+ onDownload: app_utils_1.onDownloadApp.bind(this),
1022
+ supportedExtensions: app_utils_1.SUPPORTED_EXTENSIONS,
1023
+ });
1024
+ }
1025
+ async determineDevice() {
1026
+ // in the one case where we create a sim, we will set this state
1027
+ this.lifecycleData.createSim = false;
1028
+ // if we get generic names, translate them
1029
+ this.opts.deviceName = (0, utils_1.translateDeviceName)(this.opts.platformVersion ?? '', this.opts.deviceName);
1030
+ const setupVersionCaps = async () => {
1031
+ this._iosSdkVersion = await (0, utils_1.getAndCheckIosSdkVersion)();
1032
+ this.log.info(`iOS SDK Version set to '${this._iosSdkVersion}'`);
1033
+ if (!this.opts.platformVersion && this._iosSdkVersion) {
1034
+ this.log.info(`No platformVersion specified. Using the latest version Xcode supports: '${this._iosSdkVersion}'. ` +
1035
+ `This may cause problems if a simulator does not exist for this platform version.`);
1036
+ this.opts.platformVersion = (0, utils_1.normalizePlatformVersion)(this._iosSdkVersion);
1037
+ }
1038
+ };
1039
+ if (this.opts.udid) {
1040
+ if (this.opts.udid.toLowerCase() === utils_1.UDID_AUTO) {
1041
+ try {
1042
+ this.opts.udid = await real_device_management_1.detectUdid.bind(this)();
1043
+ }
1044
+ catch (err) {
1045
+ // Trying to find matching UDID for Simulator
1046
+ this.log.warn(`Cannot detect any connected real devices. Falling back to Simulator. Original error: ${err.message}`);
1047
+ await setupVersionCaps();
1048
+ const device = await simulator_management_1.getExistingSim.bind(this)();
1049
+ if (!device) {
1050
+ // No matching Simulator is found. Throw an error
1051
+ throw this.log.errorWithException(`Cannot detect udid for ${this.opts.deviceName} Simulator running iOS ${this.opts.platformVersion}`);
1052
+ }
1053
+ this.opts.udid = device.udid;
1054
+ return { device, realDevice: false, udid: device.udid };
1055
+ }
1056
+ }
1057
+ else {
1058
+ // If the session specified this.opts.webDriverAgentUrl with a real device,
1059
+ // we can assume the user prepared the device properly already.
1060
+ let isRealDeviceUdid = false;
1061
+ const shouldCheckAvailableRealDevices = !this.opts.webDriverAgentUrl;
1062
+ if (shouldCheckAvailableRealDevices) {
1063
+ const devices = await (0, real_device_1.getConnectedDevices)();
1064
+ this.log.debug(`Available real devices: ${devices.join(', ')}`);
1065
+ isRealDeviceUdid = devices.includes(this.opts.udid);
1066
+ }
1067
+ if (!isRealDeviceUdid) {
1068
+ try {
1069
+ const device = await (0, appium_ios_simulator_1.getSimulator)(this.opts.udid, {
1070
+ devicesSetPath: this.opts.simulatorDevicesSetPath,
1071
+ // @ts-ignore This is ok
1072
+ logger: this.log,
1073
+ });
1074
+ return { device, realDevice: false, udid: this.opts.udid };
1075
+ }
1076
+ catch {
1077
+ if (shouldCheckAvailableRealDevices) {
1078
+ throw new Error(`Unknown device or simulator UDID: '${this.opts.udid}'`);
1079
+ }
1080
+ this.log.debug('Skipping checking of the real devices availability since the session specifies appium:webDriverAgentUrl');
1081
+ }
1082
+ }
1083
+ }
1084
+ this.log.debug(`Creating iDevice object with udid '${this.opts.udid}'`);
1085
+ const device = new real_device_1.RealDevice(this.opts.udid, this.log);
1086
+ return { device, realDevice: true, udid: this.opts.udid };
1087
+ }
1088
+ this.log.info(`No real device udid has been provided in capabilities. ` +
1089
+ `Will select a matching simulator to run the test.`);
1090
+ await setupVersionCaps();
1091
+ if (this.opts.enforceFreshSimulatorCreation) {
1092
+ this.log.debug(`New simulator is requested. If this is not wanted, set 'enforceFreshSimulatorCreation' capability to false`);
1093
+ }
1094
+ else {
1095
+ // figure out the correct simulator to use, given the desired capabilities
1096
+ const device = await simulator_management_1.getExistingSim.bind(this)();
1097
+ // check for an existing simulator
1098
+ if (device) {
1099
+ return { device, realDevice: false, udid: device.udid };
1100
+ }
1101
+ }
1102
+ // no device of this type exists, or they request new sim, so create one
1103
+ this.log.info('Using desired caps to create a new simulator');
1104
+ const device = await this.createSim();
1105
+ return { device, realDevice: false, udid: device.udid };
1106
+ }
1107
+ async startSim() {
1108
+ /** @type {import('@limrun/appium-ios-simulator').DevicePreferences} */
1109
+ const devicePreferences = {};
1110
+ /** @type {import('@limrun/appium-ios-simulator').RunOptions} */
1111
+ const runOpts = {
1112
+ scaleFactor: this.opts.scaleFactor,
1113
+ connectHardwareKeyboard: !!this.opts.connectHardwareKeyboard,
1114
+ pasteboardAutomaticSync: this.opts.simulatorPasteboardAutomaticSync ?? 'off',
1115
+ isHeadless: !!this.opts.isHeadless,
1116
+ tracePointer: this.opts.simulatorTracePointer,
1117
+ devicePreferences,
1118
+ };
1119
+ // add the window center, if it is specified
1120
+ if (this.opts.simulatorWindowCenter) {
1121
+ devicePreferences.SimulatorWindowCenter = this.opts.simulatorWindowCenter;
1122
+ }
1123
+ if (lodash_1.default.isInteger(this.opts.simulatorStartupTimeout)) {
1124
+ runOpts.startupTimeout = this.opts.simulatorStartupTimeout;
1125
+ }
1126
+ // This is to workaround XCTest bug about changing Simulator
1127
+ // orientation is not synchronized to the actual window orientation
1128
+ const orientation = lodash_1.default.isString(this.opts.orientation) && this.opts.orientation.toUpperCase();
1129
+ switch (orientation) {
1130
+ case 'LANDSCAPE':
1131
+ devicePreferences.SimulatorWindowOrientation = 'LandscapeLeft';
1132
+ devicePreferences.SimulatorWindowRotationAngle = 90;
1133
+ break;
1134
+ case 'PORTRAIT':
1135
+ devicePreferences.SimulatorWindowOrientation = 'Portrait';
1136
+ devicePreferences.SimulatorWindowRotationAngle = 0;
1137
+ break;
1138
+ }
1139
+ await /** @type {Simulator} */ (this.device).run(runOpts);
1140
+ }
1141
+ async createSim() {
1142
+ this.lifecycleData.createSim = true;
1143
+ // create sim for caps
1144
+ const sim = await simulator_management_1.createSim.bind(this)();
1145
+ this.log.info(`Created simulator with udid '${sim.udid}'.`);
1146
+ return sim;
1147
+ }
1148
+ async startWdaSession(bundleId, processArguments) {
1149
+ const args = processArguments ? lodash_1.default.cloneDeep(processArguments.args) || [] : [];
1150
+ if (!lodash_1.default.isArray(args)) {
1151
+ throw new Error(`processArguments.args capability is expected to be an array. ` +
1152
+ `${JSON.stringify(args)} is given instead`);
1153
+ }
1154
+ const env = processArguments ? lodash_1.default.cloneDeep(processArguments.env) || {} : {};
1155
+ if (!lodash_1.default.isPlainObject(env)) {
1156
+ throw new Error(`processArguments.env capability is expected to be a dictionary. ` +
1157
+ `${JSON.stringify(env)} is given instead`);
1158
+ }
1159
+ if (support_1.util.hasValue(this.opts.language)) {
1160
+ args.push('-AppleLanguages', `(${this.opts.language})`);
1161
+ args.push('-NSLanguages', `(${this.opts.language})`);
1162
+ }
1163
+ if (support_1.util.hasValue(this.opts.locale)) {
1164
+ args.push('-AppleLocale', this.opts.locale);
1165
+ }
1166
+ if (this.opts.noReset) {
1167
+ if (lodash_1.default.isNil(this.opts.shouldTerminateApp)) {
1168
+ this.opts.shouldTerminateApp = false;
1169
+ }
1170
+ if (lodash_1.default.isNil(this.opts.forceAppLaunch)) {
1171
+ this.opts.forceAppLaunch = false;
1172
+ }
1173
+ }
1174
+ if (support_1.util.hasValue(this.opts.appTimeZone)) {
1175
+ // https://developer.apple.com/forums/thread/86951?answerId=263395022#263395022
1176
+ env.TZ = this.opts.appTimeZone;
1177
+ }
1178
+ /** @type {import('appium-webdriveragent').WDACapabilities} */
1179
+ const wdaCaps = {
1180
+ bundleId: this.opts.autoLaunch === false ? undefined : bundleId,
1181
+ arguments: args,
1182
+ environment: env,
1183
+ eventloopIdleDelaySec: this.opts.wdaEventloopIdleDelay ?? 0,
1184
+ shouldWaitForQuiescence: this.opts.waitForQuiescence ?? true,
1185
+ shouldUseTestManagerForVisibilityDetection: this.opts.simpleIsVisibleCheck ?? false,
1186
+ maxTypingFrequency: this.opts.maxTypingFrequency ?? 60,
1187
+ shouldUseSingletonTestManager: this.opts.shouldUseSingletonTestManager ?? true,
1188
+ waitForIdleTimeout: this.opts.waitForIdleTimeout,
1189
+ // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1190
+ shouldUseCompactResponses: this.opts.shouldUseCompactResponses,
1191
+ // @ts-expect-error - do not assign arbitrary properties to `this.opts`
1192
+ elementResponseFields: this.opts.elementResponseFields,
1193
+ disableAutomaticScreenshots: this.opts.disableAutomaticScreenshots,
1194
+ shouldTerminateApp: this.opts.shouldTerminateApp ?? true,
1195
+ forceAppLaunch: this.opts.forceAppLaunch ?? true,
1196
+ appLaunchStateTimeoutSec: this.opts.appLaunchStateTimeoutSec,
1197
+ useNativeCachingStrategy: this.opts.useNativeCachingStrategy ?? true,
1198
+ forceSimulatorSoftwareKeyboardPresence: this.opts.forceSimulatorSoftwareKeyboardPresence ??
1199
+ (this.opts.connectHardwareKeyboard === true ? false : true),
1200
+ };
1201
+ if (this.opts.autoAcceptAlerts) {
1202
+ wdaCaps.defaultAlertAction = 'accept';
1203
+ }
1204
+ else if (this.opts.autoDismissAlerts) {
1205
+ wdaCaps.defaultAlertAction = 'dismiss';
1206
+ }
1207
+ if (this.opts.initialDeeplinkUrl) {
1208
+ this.log.info(`The deeplink URL will be set to ${this.opts.initialDeeplinkUrl}`);
1209
+ wdaCaps.initialUrl = this.opts.initialDeeplinkUrl;
1210
+ }
1211
+ const timer = new support_1.timing.Timer().start();
1212
+ await this.proxyCommand('/session', 'POST', {
1213
+ capabilities: {
1214
+ firstMatch: [wdaCaps],
1215
+ alwaysMatch: {},
1216
+ },
1217
+ });
1218
+ this.log.info(`WDA session startup took ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`);
1219
+ }
1220
+ // Override Proxy methods from BaseDriver
1221
+ proxyActive() {
1222
+ return Boolean(this.jwpProxyActive);
1223
+ }
1224
+ getProxyAvoidList() {
1225
+ if (this.isWebview()) {
1226
+ return NO_PROXY_WEB_LIST;
1227
+ }
1228
+ return NO_PROXY_NATIVE_LIST;
1229
+ }
1230
+ canProxy() {
1231
+ return true;
1232
+ }
1233
+ /**
1234
+ * @returns {boolean}
1235
+ */
1236
+ isSafari() {
1237
+ return !!this.safari;
1238
+ }
1239
+ /**
1240
+ * @returns {boolean}
1241
+ */
1242
+ isRealDevice() {
1243
+ return 'devicectl' in (this.device ?? {});
1244
+ }
1245
+ /**
1246
+ * @returns {boolean}
1247
+ */
1248
+ isSimulator() {
1249
+ return 'simctl' in (this.device ?? {});
1250
+ }
1251
+ /**
1252
+ * @param {string} strategy
1253
+ */
1254
+ validateLocatorStrategy(strategy) {
1255
+ super.validateLocatorStrategy(strategy, this.isWebContext());
1256
+ }
1257
+ /**
1258
+ * @param {any} caps
1259
+ * @returns {caps is import('@appium/types').DriverCaps<XCUITestDriverConstraints>}
1260
+ */
1261
+ validateDesiredCaps(caps) {
1262
+ if (!super.validateDesiredCaps(caps)) {
1263
+ return false;
1264
+ }
1265
+ // make sure that the capabilities have one of `app` or `bundleId`
1266
+ if (lodash_1.default.toLower(caps.browserName) !== 'safari' && !caps.app && !caps.bundleId) {
1267
+ this.log.info('The desired capabilities include neither an app nor a bundleId. ' +
1268
+ 'WebDriverAgent will be started without the default app');
1269
+ }
1270
+ if (!support_1.util.coerceVersion(String(caps.platformVersion), false)) {
1271
+ this.log.warn(`'platformVersion' capability ('${caps.platformVersion}') is not a valid version number. ` +
1272
+ `Consider fixing it or be ready to experience an inconsistent driver behavior.`);
1273
+ }
1274
+ let verifyProcessArgument = (processArguments) => {
1275
+ const { args, env } = processArguments;
1276
+ if (!lodash_1.default.isNil(args) && !lodash_1.default.isArray(args)) {
1277
+ throw this.log.errorWithException('processArguments.args must be an array of strings');
1278
+ }
1279
+ if (!lodash_1.default.isNil(env) && !lodash_1.default.isPlainObject(env)) {
1280
+ throw this.log.errorWithException('processArguments.env must be an object <key,value> pair {a:b, c:d}');
1281
+ }
1282
+ };
1283
+ // `processArguments` should be JSON string or an object with arguments and/ environment details
1284
+ if (caps.processArguments) {
1285
+ if (lodash_1.default.isString(caps.processArguments)) {
1286
+ try {
1287
+ // try to parse the string as JSON
1288
+ caps.processArguments = JSON.parse(caps.processArguments);
1289
+ verifyProcessArgument(caps.processArguments);
1290
+ }
1291
+ catch (err) {
1292
+ throw this.log.errorWithException(`processArguments must be a JSON format or an object with format {args : [], env : {a:b, c:d}}. ` +
1293
+ `Both environment and argument can be null. Error: ${err}`);
1294
+ }
1295
+ }
1296
+ else if (lodash_1.default.isPlainObject(caps.processArguments)) {
1297
+ verifyProcessArgument(caps.processArguments);
1298
+ }
1299
+ else {
1300
+ throw this.log.errorWithException(`'processArguments must be an object, or a string JSON object with format {args : [], env : {a:b, c:d}}. ` +
1301
+ `Both environment and argument can be null.`);
1302
+ }
1303
+ }
1304
+ // there is no point in having `keychainPath` without `keychainPassword`
1305
+ if ((caps.keychainPath && !caps.keychainPassword) ||
1306
+ (!caps.keychainPath && caps.keychainPassword)) {
1307
+ throw this.log.errorWithException(`If 'keychainPath' is set, 'keychainPassword' must also be set (and vice versa).`);
1308
+ }
1309
+ // `resetOnSessionStartOnly` should be set to true by default
1310
+ this.opts.resetOnSessionStartOnly =
1311
+ !support_1.util.hasValue(this.opts.resetOnSessionStartOnly) || this.opts.resetOnSessionStartOnly;
1312
+ this.opts.useNewWDA = support_1.util.hasValue(this.opts.useNewWDA) ? this.opts.useNewWDA : false;
1313
+ if (caps.commandTimeouts) {
1314
+ caps.commandTimeouts = (0, utils_1.normalizeCommandTimeouts)(caps.commandTimeouts);
1315
+ }
1316
+ if (lodash_1.default.isString(caps.webDriverAgentUrl)) {
1317
+ const { protocol, host } = node_url_1.default.parse(caps.webDriverAgentUrl);
1318
+ if (lodash_1.default.isEmpty(protocol) || lodash_1.default.isEmpty(host)) {
1319
+ throw this.log.errorWithException(`'webDriverAgentUrl' capability is expected to contain a valid WebDriverAgent server URL. ` +
1320
+ `'${caps.webDriverAgentUrl}' is given instead`);
1321
+ }
1322
+ }
1323
+ if (caps.browserName) {
1324
+ if (caps.bundleId) {
1325
+ throw this.log.errorWithException(`'browserName' cannot be set together with 'bundleId' capability`);
1326
+ }
1327
+ // warn if the capabilities have both `app` and `browser, although this
1328
+ // is common with selenium grid
1329
+ if (caps.app) {
1330
+ this.log.warn(`The capabilities should generally not include both an 'app' and a 'browserName'`);
1331
+ }
1332
+ }
1333
+ if (caps.permissions) {
1334
+ try {
1335
+ for (const [bundleId, perms] of lodash_1.default.toPairs(JSON.parse(caps.permissions))) {
1336
+ if (!lodash_1.default.isString(bundleId)) {
1337
+ throw new Error(`'${JSON.stringify(bundleId)}' must be a string`);
1338
+ }
1339
+ if (!lodash_1.default.isPlainObject(perms)) {
1340
+ throw new Error(`'${JSON.stringify(perms)}' must be a JSON object`);
1341
+ }
1342
+ }
1343
+ }
1344
+ catch (e) {
1345
+ throw this.log.errorWithException(`'${caps.permissions}' is expected to be a valid object with format ` +
1346
+ `{"<bundleId1>": {"<serviceName1>": "<serviceStatus1>", ...}, ...}. Original error: ${e.message}`);
1347
+ }
1348
+ }
1349
+ if (caps.platformVersion && !support_1.util.coerceVersion(caps.platformVersion, false)) {
1350
+ throw this.log.errorWithException(`'platformVersion' must be a valid version number. ` +
1351
+ `'${caps.platformVersion}' is given instead.`);
1352
+ }
1353
+ // additionalWebviewBundleIds is an array, JSON array, or string
1354
+ if (caps.additionalWebviewBundleIds) {
1355
+ caps.additionalWebviewBundleIds = this.helpers.parseCapsArray(caps.additionalWebviewBundleIds);
1356
+ }
1357
+ // finally, return true since the superclass check passed, as did this
1358
+ return true;
1359
+ }
1360
+ /**
1361
+ * Check if the given app can be installed, or should uninstall before installing it.
1362
+ *
1363
+ * @param {AutInstallationStateOptions} [opts]
1364
+ * @returns {Promise<AutInstallationState>}
1365
+ */
1366
+ async checkAutInstallationState(opts) {
1367
+ const { enforceAppInstall, fullReset, noReset, bundleId, app } = opts ?? this.opts;
1368
+ const wasAppInstalled = await this.device.isAppInstalled(bundleId);
1369
+ if (wasAppInstalled) {
1370
+ this.log.info(`App '${bundleId}' is already installed`);
1371
+ if (noReset) {
1372
+ this.log.info('noReset is requested. The app will not be be (re)installed');
1373
+ return {
1374
+ install: false,
1375
+ skipUninstall: true,
1376
+ };
1377
+ }
1378
+ }
1379
+ else {
1380
+ this.log.info(`App '${bundleId}' is not installed yet or it has an offload and ` +
1381
+ 'cannot be detected, which might keep the local data.');
1382
+ }
1383
+ if (enforceAppInstall !== false || fullReset || !wasAppInstalled) {
1384
+ return {
1385
+ install: true,
1386
+ skipUninstall: !wasAppInstalled,
1387
+ };
1388
+ }
1389
+ const candidateBundleVersion = await this.appInfosCache.extractBundleVersion(app);
1390
+ this.log.debug(`CFBundleVersion from Info.plist: ${candidateBundleVersion}`);
1391
+ if (!candidateBundleVersion) {
1392
+ return {
1393
+ install: true,
1394
+ skipUninstall: false,
1395
+ };
1396
+ }
1397
+ const appBundleVersion = this.isRealDevice()
1398
+ ? (await /** @type {RealDevice} */ (this.device).fetchAppInfo(bundleId))?.CFBundleVersion
1399
+ : BUNDLE_VERSION_PATTERN.exec(await /** @type {Simulator} */ (this.device).simctl.appInfo(bundleId))?.[1];
1400
+ this.log.debug(`CFBundleVersion from installed app info: ${appBundleVersion}`);
1401
+ if (!appBundleVersion) {
1402
+ return {
1403
+ install: true,
1404
+ skipUninstall: false,
1405
+ };
1406
+ }
1407
+ let shouldUpgrade;
1408
+ try {
1409
+ shouldUpgrade = support_1.util.compareVersions(candidateBundleVersion, '>', appBundleVersion);
1410
+ }
1411
+ catch (err) {
1412
+ this.log.warn(`App versions comparison is not possible: ${err.message}`);
1413
+ return {
1414
+ install: true,
1415
+ skipUninstall: false,
1416
+ };
1417
+ }
1418
+ if (shouldUpgrade) {
1419
+ this.log.info(`The installed version of ${bundleId} is lower than the candidate one ` +
1420
+ `(${candidateBundleVersion} > ${appBundleVersion}). The app will be upgraded.`);
1421
+ }
1422
+ else {
1423
+ this.log.info(`The candidate version of ${bundleId} is lower than the installed one ` +
1424
+ `(${candidateBundleVersion} <= ${appBundleVersion}). The app won't be reinstalled.`);
1425
+ }
1426
+ return {
1427
+ install: shouldUpgrade,
1428
+ skipUninstall: true,
1429
+ };
1430
+ }
1431
+ async installAUT() {
1432
+ // install any other apps
1433
+ if (this.opts.otherApps) {
1434
+ await this.installOtherApps(this.opts.otherApps);
1435
+ }
1436
+ if (this.isSafari() || !this.opts.app) {
1437
+ return;
1438
+ }
1439
+ await app_utils_1.verifyApplicationPlatform.bind(this)();
1440
+ const { install, skipUninstall } = await this.checkAutInstallationState();
1441
+ if (install) {
1442
+ if (this.isRealDevice()) {
1443
+ await real_device_management_1.installToRealDevice.bind(this)(this.opts.app, this.opts.bundleId, {
1444
+ skipUninstall,
1445
+ timeout: this.opts.appPushTimeout,
1446
+ });
1447
+ }
1448
+ else {
1449
+ await simulator_management_1.installToSimulator.bind(this)(this.opts.app, this.opts.bundleId, {
1450
+ skipUninstall,
1451
+ newSimulator: this.lifecycleData?.createSim,
1452
+ });
1453
+ }
1454
+ if (support_1.util.hasValue(this.opts.iosInstallPause)) {
1455
+ // https://github.com/appium/appium/issues/6889
1456
+ const pauseMs = parseInt(this.opts.iosInstallPause, 10);
1457
+ this.log.debug(`iosInstallPause set. Pausing ${pauseMs} ms before continuing`);
1458
+ await bluebird_1.default.delay(pauseMs);
1459
+ }
1460
+ this.logEvent('appInstalled');
1461
+ }
1462
+ }
1463
+ /**
1464
+ * @param {string|string[]} otherApps
1465
+ * @returns {Promise<void>}
1466
+ */
1467
+ async installOtherApps(otherApps) {
1468
+ /** @type {string[]|undefined} */
1469
+ let appsList;
1470
+ try {
1471
+ appsList = this.helpers.parseCapsArray(otherApps);
1472
+ }
1473
+ catch (e) {
1474
+ throw this.log.errorWithException(`Could not parse "otherApps" capability: ${e.message}`);
1475
+ }
1476
+ if (!appsList?.length) {
1477
+ this.log.info(`Got zero apps from 'otherApps' capability value. Doing nothing`);
1478
+ return;
1479
+ }
1480
+ /** @type {string[]} */
1481
+ const appPaths = await bluebird_1.default.all(appsList.map((app) => this.helpers.configureApp(app, {
1482
+ onPostProcess: app_utils_1.onPostConfigureApp.bind(this),
1483
+ onDownload: app_utils_1.onDownloadApp.bind(this),
1484
+ supportedExtensions: app_utils_1.SUPPORTED_EXTENSIONS,
1485
+ })));
1486
+ /** @type {string[]} */
1487
+ const appIds = await bluebird_1.default.all(appPaths.map((appPath) => this.appInfosCache.extractBundleId(appPath)));
1488
+ for (const [appId, appPath] of lodash_1.default.zip(appIds, appPaths)) {
1489
+ if (this.isRealDevice()) {
1490
+ await real_device_management_1.installToRealDevice.bind(this)(appPath, appId, {
1491
+ skipUninstall: true, // to make the behavior as same as UIA2
1492
+ timeout: this.opts.appPushTimeout,
1493
+ });
1494
+ }
1495
+ else {
1496
+ await simulator_management_1.installToSimulator.bind(this)(appPath, appId, {
1497
+ newSimulator: this.lifecycleData.createSim,
1498
+ });
1499
+ }
1500
+ }
1501
+ }
1502
+ /**
1503
+ * @param {string} orientation
1504
+ * @returns {Promise<void>}
1505
+ */
1506
+ async setInitialOrientation(orientation) {
1507
+ const dstOrientation = lodash_1.default.toUpper(orientation);
1508
+ if (!SUPPORTED_ORIENATIONS.includes(dstOrientation)) {
1509
+ this.log.debug(`The initial orientation value '${orientation}' is unknown. ` +
1510
+ `Only ${JSON.stringify(SUPPORTED_ORIENATIONS)} are supported.`);
1511
+ return;
1512
+ }
1513
+ this.log.debug(`Setting initial orientation to '${dstOrientation}'`);
1514
+ try {
1515
+ await this.proxyCommand('/orientation', 'POST', { orientation: dstOrientation });
1516
+ }
1517
+ catch (err) {
1518
+ this.log.warn(`Setting initial orientation failed with: ${err.message}`);
1519
+ }
1520
+ }
1521
+ /**
1522
+ * @param {string} [cmdName]
1523
+ * @returns {number|undefined}
1524
+ */
1525
+ _getCommandTimeout(cmdName) {
1526
+ if (this.opts.commandTimeouts) {
1527
+ if (cmdName && lodash_1.default.has(this.opts.commandTimeouts, cmdName)) {
1528
+ return this.opts.commandTimeouts[cmdName];
1529
+ }
1530
+ return this.opts.commandTimeouts[utils_1.DEFAULT_TIMEOUT_KEY];
1531
+ }
1532
+ }
1533
+ /**
1534
+ * Reset the current session (run the delete session and create session subroutines)
1535
+ */
1536
+ async reset() {
1537
+ throw new Error(`The reset API has been deprecated and is not supported anymore. ` +
1538
+ `Consider using corresponding 'mobile:' extensions to manage the state of the app under test.`);
1539
+ }
1540
+ async preparePreinstalledWda() {
1541
+ if (this.isRealDevice()) {
1542
+ // Stop the existing process before starting a new one to start a fresh WDA process every session.
1543
+ await this.mobileKillApp(this.wda.bundleIdForXctest);
1544
+ }
1545
+ if (!this.opts.prebuiltWDAPath) {
1546
+ return;
1547
+ }
1548
+ const candidateBundleId = await this.appInfosCache.extractBundleId(this.opts.prebuiltWDAPath);
1549
+ this.wda.updatedWDABundleId = candidateBundleId.replace('.xctrunner', '');
1550
+ this.log.info(`Installing prebuilt WDA at '${this.opts.prebuiltWDAPath}'. ` +
1551
+ `Bundle identifier: ${candidateBundleId}.`);
1552
+ // Note: The CFBundleVersion in the test bundle was always 1.
1553
+ // It may not be able to compare with the installed version.
1554
+ if (this.isRealDevice()) {
1555
+ await real_device_management_1.installToRealDevice.bind(this)(this.opts.prebuiltWDAPath, candidateBundleId, {
1556
+ skipUninstall: true,
1557
+ timeout: this.opts.appPushTimeout,
1558
+ });
1559
+ }
1560
+ else {
1561
+ await simulator_management_1.installToSimulator.bind(this)(this.opts.prebuiltWDAPath, candidateBundleId);
1562
+ }
1563
+ }
1564
+ /*---------------+
1565
+ | ACTIVEAPPINFO |
1566
+ +---------------+*/
1567
+ mobileGetActiveAppInfo = activeAppInfoCommands.mobileGetActiveAppInfo;
1568
+ /*-------+
1569
+ | ALERT |
1570
+ +-------+*/
1571
+ getAlertText = alertCommands.getAlertText;
1572
+ setAlertText = alertCommands.setAlertText;
1573
+ postAcceptAlert = alertCommands.postAcceptAlert;
1574
+ postDismissAlert = alertCommands.postDismissAlert;
1575
+ getAlertButtons = alertCommands.getAlertButtons;
1576
+ mobileHandleAlert = alertCommands.mobileHandleAlert;
1577
+ /*---------------+
1578
+ | APPMANAGEMENT |
1579
+ +---------------+*/
1580
+ mobileInstallApp = appManagementCommands.mobileInstallApp;
1581
+ mobileIsAppInstalled = appManagementCommands.mobileIsAppInstalled;
1582
+ mobileRemoveApp = appManagementCommands.mobileRemoveApp;
1583
+ mobileLaunchApp = appManagementCommands.mobileLaunchApp;
1584
+ mobileTerminateApp = appManagementCommands.mobileTerminateApp;
1585
+ mobileActivateApp = appManagementCommands.mobileActivateApp;
1586
+ mobileKillApp = appManagementCommands.mobileKillApp;
1587
+ mobileQueryAppState = appManagementCommands.mobileQueryAppState;
1588
+ installApp = appManagementCommands.installApp;
1589
+ activateApp = appManagementCommands.activateApp;
1590
+ isAppInstalled = appManagementCommands.isAppInstalled;
1591
+ // @ts-ignore it must return boolean
1592
+ terminateApp = appManagementCommands.terminateApp;
1593
+ queryAppState = appManagementCommands.queryAppState;
1594
+ mobileListApps = appManagementCommands.mobileListApps;
1595
+ mobileClearApp = appManagementCommands.mobileClearApp;
1596
+ /*------------+
1597
+ | APPEARANCE |
1598
+ +------------+*/
1599
+ mobileSetAppearance = appearanceCommands.mobileSetAppearance;
1600
+ mobileGetAppearance = appearanceCommands.mobileGetAppearance;
1601
+ /*------------+
1602
+ | INCREASE CONTRAST |
1603
+ +------------+*/
1604
+ mobileSetIncreaseContrast = increaseContrastCommands.mobileSetIncreaseContrast;
1605
+ mobileGetIncreaseContrast = increaseContrastCommands.mobileGetIncreaseContrast;
1606
+ /*------------+
1607
+ | CONTENT SIZE |
1608
+ +------------+*/
1609
+ mobileSetContentSize = contentSizeCommands.mobileSetContentSize;
1610
+ mobileGetContentSize = contentSizeCommands.mobileGetContentSize;
1611
+ /*------------+
1612
+ | AUDIT |
1613
+ +------------+*/
1614
+ mobilePerformAccessibilityAudit = auditCommands.mobilePerformAccessibilityAudit;
1615
+ /*---------+
1616
+ | BATTERY |
1617
+ +---------+*/
1618
+ mobileGetBatteryInfo = batteryCommands.mobileGetBatteryInfo;
1619
+ /*-----------+
1620
+ | BIOMETRIC |
1621
+ +-----------+*/
1622
+ mobileEnrollBiometric = biometricCommands.mobileEnrollBiometric;
1623
+ mobileSendBiometricMatch = biometricCommands.mobileSendBiometricMatch;
1624
+ mobileIsBiometricEnrolled = biometricCommands.mobileIsBiometricEnrolled;
1625
+ /*-------------+
1626
+ | CERTIFICATE |
1627
+ +-------------+*/
1628
+ mobileInstallCertificate = certificateCommands.mobileInstallCertificate;
1629
+ mobileListCertificates = certificateCommands.mobileListCertificates;
1630
+ mobileRemoveCertificate = certificateCommands.mobileRemoveCertificate;
1631
+ /*-----------+
1632
+ | CLIPBOARD |
1633
+ +-----------+*/
1634
+ setClipboard = clipboardCommands.setClipboard;
1635
+ getClipboard = clipboardCommands.getClipboard;
1636
+ /*-----------+
1637
+ | CONDITION |
1638
+ +-----------+*/
1639
+ listConditionInducers = conditionCommands.listConditionInducers;
1640
+ enableConditionInducer = conditionCommands.enableConditionInducer;
1641
+ disableConditionInducer = conditionCommands.disableConditionInducer;
1642
+ /*---------+
1643
+ | CONTEXT |
1644
+ +---------+*/
1645
+ getContexts = contextCommands.getContexts;
1646
+ getCurrentContext = contextCommands.getCurrentContext;
1647
+ // @ts-ignore This is OK
1648
+ getWindowHandle = contextCommands.getWindowHandle;
1649
+ getWindowHandles = contextCommands.getWindowHandles;
1650
+ // @ts-ignore Type mismatch: function type vs method signature
1651
+ setContext = contextCommands.setContext;
1652
+ // @ts-ignore This is OK
1653
+ setWindow = contextCommands.setWindow;
1654
+ activateRecentWebview = contextCommands.activateRecentWebview;
1655
+ connectToRemoteDebugger = contextCommands.connectToRemoteDebugger;
1656
+ getContextsAndViews = contextCommands.getContextsAndViews;
1657
+ listWebFrames = contextCommands.listWebFrames;
1658
+ mobileGetContexts = contextCommands.mobileGetContexts;
1659
+ onPageChange = contextCommands.onPageChange;
1660
+ useNewSafari = contextCommands.useNewSafari;
1661
+ getCurrentUrl = contextCommands.getCurrentUrl;
1662
+ getNewRemoteDebugger = contextCommands.getNewRemoteDebugger;
1663
+ getRecentWebviewContextId = contextCommands.getRecentWebviewContextId;
1664
+ isWebContext = contextCommands.isWebContext;
1665
+ isWebview = contextCommands.isWebview;
1666
+ setCurrentUrl = contextCommands.setCurrentUrl;
1667
+ stopRemote = contextCommands.stopRemote;
1668
+ /*------------+
1669
+ | DEVICEINFO |
1670
+ +------------+*/
1671
+ mobileGetDeviceInfo = deviceInfoCommands.mobileGetDeviceInfo;
1672
+ /*---------+
1673
+ | ELEMENT |
1674
+ +---------+*/
1675
+ elementDisplayed = elementCommands.elementDisplayed;
1676
+ elementEnabled = elementCommands.elementEnabled;
1677
+ elementSelected = elementCommands.elementSelected;
1678
+ getName = elementCommands.getName;
1679
+ getNativeAttribute = elementCommands.getNativeAttribute;
1680
+ getAttribute = elementCommands.getAttribute;
1681
+ getProperty = elementCommands.getProperty;
1682
+ getText = elementCommands.getText;
1683
+ getElementRect = elementCommands.getElementRect;
1684
+ getLocation = elementCommands.getLocation;
1685
+ getLocationInView = elementCommands.getLocationInView;
1686
+ getSize = elementCommands.getSize;
1687
+ /** @deprecated */
1688
+ setValueImmediate = elementCommands.setValueImmediate;
1689
+ setValue = elementCommands.setValue;
1690
+ setValueWithWebAtom = elementCommands.setValueWithWebAtom;
1691
+ keys = elementCommands.keys;
1692
+ clear = elementCommands.clear;
1693
+ getContentSize = elementCommands.getContentSize;
1694
+ getNativeRect = elementCommands.getNativeRect;
1695
+ /*---------+
1696
+ | EXECUTE |
1697
+ +---------+*/
1698
+ receiveAsyncResponse = executeCommands.receiveAsyncResponse;
1699
+ execute = executeCommands.execute;
1700
+ // @ts-ignore Type mismatch: function type vs method signature
1701
+ executeAsync = executeCommands.executeAsync;
1702
+ // Note: executeMobile is handled internally via execute method
1703
+ mobileSimctl = simctlCommands.mobileSimctl;
1704
+ /*--------------+
1705
+ | FILEMOVEMENT |
1706
+ +--------------+*/
1707
+ pushFile = fileMovementCommands.pushFile;
1708
+ mobilePushFile = fileMovementCommands.mobilePushFile;
1709
+ pullFile = fileMovementCommands.pullFile;
1710
+ mobilePullFile = fileMovementCommands.mobilePullFile;
1711
+ mobileDeleteFolder = fileMovementCommands.mobileDeleteFolder;
1712
+ mobileDeleteFile = fileMovementCommands.mobileDeleteFile;
1713
+ pullFolder = fileMovementCommands.pullFolder;
1714
+ mobilePullFolder = fileMovementCommands.mobilePullFolder;
1715
+ /*--------+
1716
+ | MEMORY |
1717
+ +--------+*/
1718
+ mobileSendMemoryWarning = memoryCommands.mobileSendMemoryWarning;
1719
+ /*------+
1720
+ | FIND |
1721
+ +------+*/
1722
+ findElOrEls = findCommands.findElOrEls;
1723
+ findNativeElementOrElements = findCommands.findNativeElementOrElements;
1724
+ doNativeFind = findCommands.doNativeFind;
1725
+ getFirstVisibleChild = findCommands.getFirstVisibleChild;
1726
+ /*---------+
1727
+ | GENERAL |
1728
+ +---------+*/
1729
+ active = generalCommands.active;
1730
+ background = appManagementCommands.background;
1731
+ touchId = generalCommands.touchId;
1732
+ toggleEnrollTouchId = generalCommands.toggleEnrollTouchId;
1733
+ getWindowSize = generalCommands.getWindowSize;
1734
+ getDeviceTime = generalCommands.getDeviceTime;
1735
+ mobileGetDeviceTime = generalCommands.mobileGetDeviceTime;
1736
+ getWindowRect = generalCommands.getWindowRect;
1737
+ getStrings = appStringsCommands.getStrings;
1738
+ removeApp = generalCommands.removeApp;
1739
+ launchApp = generalCommands.launchApp;
1740
+ closeApp = generalCommands.closeApp;
1741
+ // @ts-ignore Type mismatch: function type vs method signature
1742
+ setUrl = generalCommands.setUrl;
1743
+ getViewportRect = generalCommands.getViewportRect;
1744
+ getScreenInfo = generalCommands.getScreenInfo;
1745
+ getStatusBarHeight = generalCommands.getStatusBarHeight;
1746
+ getDevicePixelRatio = generalCommands.getDevicePixelRatio;
1747
+ mobilePressButton = generalCommands.mobilePressButton;
1748
+ mobileSiriCommand = generalCommands.mobileSiriCommand;
1749
+ /*-------------+
1750
+ | GEOLOCATION |
1751
+ +-------------+*/
1752
+ mobileGetSimulatedLocation = geolocationCommands.mobileGetSimulatedLocation;
1753
+ mobileSetSimulatedLocation = geolocationCommands.mobileSetSimulatedLocation;
1754
+ mobileResetSimulatedLocation = geolocationCommands.mobileResetSimulatedLocation;
1755
+ /*---------+
1756
+ | GESTURE |
1757
+ +---------+*/
1758
+ mobileShake = gestureCommands.mobileShake;
1759
+ click = gestureCommands.click;
1760
+ releaseActions = gestureCommands.releaseActions;
1761
+ performActions = gestureCommands.performActions;
1762
+ nativeClick = gestureCommands.nativeClick;
1763
+ mobileScrollToElement = gestureCommands.mobileScrollToElement;
1764
+ mobileScroll = gestureCommands.mobileScroll;
1765
+ mobileSwipe = gestureCommands.mobileSwipe;
1766
+ mobilePinch = gestureCommands.mobilePinch;
1767
+ mobileDoubleTap = gestureCommands.mobileDoubleTap;
1768
+ mobileTwoFingerTap = gestureCommands.mobileTwoFingerTap;
1769
+ mobileTouchAndHold = gestureCommands.mobileTouchAndHold;
1770
+ mobileTap = gestureCommands.mobileTap;
1771
+ mobileDragFromToForDuration = gestureCommands.mobileDragFromToForDuration;
1772
+ mobileDragFromToWithVelocity = gestureCommands.mobileDragFromToWithVelocity;
1773
+ mobileTapWithNumberOfTaps = gestureCommands.mobileTapWithNumberOfTaps;
1774
+ mobileForcePress = gestureCommands.mobileForcePress;
1775
+ mobileSelectPickerWheelValue = gestureCommands.mobileSelectPickerWheelValue;
1776
+ mobileRotateElement = gestureCommands.mobileRotateElement;
1777
+ /*-------+
1778
+ | IOHID |
1779
+ +-------+*/
1780
+ mobilePerformIoHidEvent = iohidCommands.mobilePerformIoHidEvent;
1781
+ /*-----------+
1782
+ | KEYCHAINS |
1783
+ +-----------+*/
1784
+ mobileClearKeychains = keychainsCommands.mobileClearKeychains;
1785
+ /*----------+
1786
+ | KEYBOARD |
1787
+ +----------+*/
1788
+ hideKeyboard = keyboardCommands.hideKeyboard;
1789
+ mobileHideKeyboard = keyboardCommands.mobileHideKeyboard;
1790
+ isKeyboardShown = keyboardCommands.isKeyboardShown;
1791
+ mobileKeys = keyboardCommands.mobileKeys;
1792
+ /*--------------+
1793
+ | LOCALIZATION |
1794
+ +--------------+*/
1795
+ mobileConfigureLocalization = localizationCommands.mobileConfigureLocalization;
1796
+ /*----------+
1797
+ | LOCATION |
1798
+ +----------+*/
1799
+ getGeoLocation = locationCommands.getGeoLocation;
1800
+ setGeoLocation = locationCommands.setGeoLocation;
1801
+ mobileResetLocationService = locationCommands.mobileResetLocationService;
1802
+ /*------+
1803
+ | LOCK |
1804
+ +------+*/
1805
+ lock = lockCommands.lock;
1806
+ unlock = lockCommands.unlock;
1807
+ isLocked = lockCommands.isLocked;
1808
+ /*-----+
1809
+ | LOG |
1810
+ +-----+*/
1811
+ extractLogs = logCommands.extractLogs;
1812
+ supportedLogTypes = logCommands.supportedLogTypes;
1813
+ startLogCapture = logCommands.startLogCapture;
1814
+ mobileStartLogsBroadcast = logCommands.mobileStartLogsBroadcast;
1815
+ mobileStopLogsBroadcast = logCommands.mobileStopLogsBroadcast;
1816
+ /*------------+
1817
+ | NAVIGATION |
1818
+ +------------+*/
1819
+ back = navigationCommands.back;
1820
+ forward = navigationCommands.forward;
1821
+ closeWindow = navigationCommands.closeWindow;
1822
+ nativeBack = navigationCommands.nativeBack;
1823
+ mobileDeepLink = navigationCommands.mobileDeepLink;
1824
+ /*---------------+
1825
+ | NOTIFICATIONS |
1826
+ +---------------+*/
1827
+ mobilePushNotification = notificationsCommands.mobilePushNotification;
1828
+ mobileExpectNotification = notificationsCommands.mobileExpectNotification;
1829
+ /*------------+
1830
+ | PASTEBOARD |
1831
+ +------------+*/
1832
+ mobileSetPasteboard = pasteboardCommands.mobileSetPasteboard;
1833
+ mobileGetPasteboard = pasteboardCommands.mobileGetPasteboard;
1834
+ /*------+
1835
+ | PCAP |
1836
+ +------+*/
1837
+ mobileStartPcap = pcapCommands.mobileStartPcap;
1838
+ mobileStopPcap = pcapCommands.mobileStopPcap;
1839
+ /*-------------+
1840
+ | PERFORMANCE |
1841
+ +-------------+*/
1842
+ mobileStartPerfRecord = performanceCommands.mobileStartPerfRecord;
1843
+ mobileStopPerfRecord = performanceCommands.mobileStopPerfRecord;
1844
+ /*-------------+
1845
+ | PERMISSIONS |
1846
+ +-------------+*/
1847
+ mobileResetPermission = permissionsCommands.mobileResetPermission;
1848
+ mobileGetPermission = permissionsCommands.mobileGetPermission;
1849
+ mobileSetPermissions = permissionsCommands.mobileSetPermissions;
1850
+ /*-------------+
1851
+ | PROXYHELPER |
1852
+ +-------------+*/
1853
+ proxyCommand = proxyHelperCommands.proxyCommand;
1854
+ /*-------------+
1855
+ | RECORDAUDIO |
1856
+ +-------------+*/
1857
+ startAudioRecording = recordAudioCommands.startAudioRecording;
1858
+ stopAudioRecording = recordAudioCommands.stopAudioRecording;
1859
+ /*--------------+
1860
+ | RECORDSCREEN |
1861
+ +--------------+*/
1862
+ // Note: _recentScreenRecorder is a property, not a function, so it's handled internally in recordscreen.js
1863
+ startRecordingScreen = recordScreenCommands.startRecordingScreen;
1864
+ stopRecordingScreen = recordScreenCommands.stopRecordingScreen;
1865
+ /*-------------+
1866
+ | SCREENSHOTS |
1867
+ +-------------+*/
1868
+ getScreenshot = screenshotCommands.getScreenshot;
1869
+ getElementScreenshot = screenshotCommands.getElementScreenshot;
1870
+ getViewportScreenshot = screenshotCommands.getViewportScreenshot;
1871
+ /*--------+
1872
+ | SOURCE |
1873
+ +--------+*/
1874
+ getPageSource = sourceCommands.getPageSource;
1875
+ mobileGetSource = sourceCommands.mobileGetSource;
1876
+ /*----------+
1877
+ | TIMEOUTS |
1878
+ +----------+*/
1879
+ pageLoadTimeoutW3C = timeoutCommands.pageLoadTimeoutW3C;
1880
+ pageLoadTimeoutMJSONWP = timeoutCommands.pageLoadTimeoutMJSONWP;
1881
+ scriptTimeoutW3C = timeoutCommands.scriptTimeoutW3C;
1882
+ scriptTimeoutMJSONWP = timeoutCommands.scriptTimeoutMJSONWP;
1883
+ asyncScriptTimeout = timeoutCommands.asyncScriptTimeout;
1884
+ setPageLoadTimeout = timeoutCommands.setPageLoadTimeout;
1885
+ setAsyncScriptTimeout = timeoutCommands.setAsyncScriptTimeout;
1886
+ /*-----+
1887
+ | WEB |
1888
+ +-----+*/
1889
+ // @ts-ignore Type mismatch: function type vs method signature
1890
+ setFrame = webCommands.setFrame;
1891
+ getCssProperty = webCommands.getCssProperty;
1892
+ submit = webCommands.submit;
1893
+ refresh = webCommands.refresh;
1894
+ getUrl = webCommands.getUrl;
1895
+ title = webCommands.title;
1896
+ getCookies = webCommands.getCookies;
1897
+ setCookie = webCommands.setCookie;
1898
+ deleteCookie = webCommands.deleteCookie;
1899
+ deleteCookies = webCommands.deleteCookies;
1900
+ cacheWebElement = webCommands.cacheWebElement;
1901
+ cacheWebElements = webCommands.cacheWebElements;
1902
+ executeAtom = webCommands.executeAtom;
1903
+ executeAtomAsync = webCommands.executeAtomAsync;
1904
+ getAtomsElement = webCommands.getAtomsElement;
1905
+ convertElementsForAtoms = webCommands.convertElementsForAtoms;
1906
+ getElementId = webCommands.getElementId;
1907
+ hasElementId = webCommands.hasElementId;
1908
+ findWebElementOrElements = webCommands.findWebElementOrElements;
1909
+ clickWebCoords = webCommands.clickWebCoords;
1910
+ getSafariIsIphone = webCommands.getSafariIsIphone;
1911
+ getSafariDeviceSize = webCommands.getSafariDeviceSize;
1912
+ getSafariIsNotched = webCommands.getSafariIsNotched;
1913
+ getExtraTranslateWebCoordsOffset = webCommands.getExtraTranslateWebCoordsOffset;
1914
+ getExtraNativeWebTapOffset = webCommands.getExtraNativeWebTapOffset;
1915
+ nativeWebTap = webCommands.nativeWebTap;
1916
+ translateWebCoords = webCommands.translateWebCoords;
1917
+ checkForAlert = webCommands.checkForAlert;
1918
+ waitForAtom = webCommands.waitForAtom;
1919
+ mobileWebNav = webCommands.mobileWebNav;
1920
+ getWdaLocalhostRoot = webCommands.getWdaLocalhostRoot;
1921
+ mobileCalibrateWebToRealCoordinatesTranslation = webCommands.mobileCalibrateWebToRealCoordinatesTranslation;
1922
+ mobileUpdateSafariPreferences = webCommands.mobileUpdateSafariPreferences;
1923
+ /*--------+
1924
+ | XCTEST |
1925
+ +--------+*/
1926
+ mobileRunXCTest = xctestCommands.mobileRunXCTest;
1927
+ mobileInstallXCTestBundle = xctestCommands.mobileInstallXCTestBundle;
1928
+ mobileListXCTestBundles = xctestCommands.mobileListXCTestBundles;
1929
+ mobileListXCTestsInTestBundle = xctestCommands.mobileListXCTestsInTestBundle;
1930
+ /*----------------------+
1931
+ | XCTEST SCREEN RECORD |
1932
+ +---------------------+*/
1933
+ mobileStartXctestScreenRecording = xctestRecordScreenCommands.mobileStartXctestScreenRecording;
1934
+ mobileGetXctestScreenRecordingInfo = xctestRecordScreenCommands.mobileGetXctestScreenRecordingInfo;
1935
+ mobileStopXctestScreenRecording = xctestRecordScreenCommands.mobileStopXctestScreenRecording;
1936
+ }
1937
+ exports.XCUITestDriver = XCUITestDriver;
1938
+ exports.default = XCUITestDriver;
1939
+ /**
1940
+ * @template {import('@appium/types').Constraints} C
1941
+ * @template [Ctx=string]
1942
+ * @typedef {import('@appium/types').ExternalDriver<C, Ctx>} ExternalDriver
1943
+ */
1944
+ /**
1945
+ * @typedef {Pick<XCUITestDriverOpts, 'enforceAppInstall' | 'fullReset' | 'noReset' | 'bundleId' | 'app'>} AutInstallationStateOptions
1946
+ */
1947
+ /**
1948
+ * @typedef {Object} AutInstallationState
1949
+ * @property {boolean} install - If the given app should install, or not need to install.
1950
+ * @property {boolean} skipUninstall - If the installed app should be uninstalled, or not.
1951
+ */
1952
+ /**
1953
+ * @typedef {typeof desiredCapConstraints} XCUITestDriverConstraints
1954
+ * @typedef {import('@appium/types').DriverOpts<XCUITestDriverConstraints>} XCUITestDriverOpts
1955
+ * @typedef {import('./commands/types').FullContext} FullContext
1956
+ * @typedef {import('@limrun/appium-xcode').XcodeVersion} XcodeVersion
1957
+ * @typedef {import('@limrun/appium-ios-simulator').Simulator} Simulator
1958
+ */
1959
+ /**
1960
+ * @typedef {Object} DriverLogs
1961
+ * @property {import('./device-log/ios-device-log').IOSDeviceLog|import('./device-log/ios-simulator-log').IOSSimulatorLog} [syslog]
1962
+ * @property {import('./device-log/ios-crash-log').IOSCrashLog} [crashlog]
1963
+ * @property {import('./device-log/safari-console-log').SafariConsoleLog} [safariConsole]
1964
+ * @property {import('./device-log/safari-network-log').SafariNetworkLog} [safariNetwork]
1965
+ * @property {import('./device-log/ios-performance-log').IOSPerformanceLog} [performance]
1966
+ */
1967
+ //# sourceMappingURL=driver.js.map