@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,1029 @@
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.setFrame = setFrame;
40
+ exports.getCssProperty = getCssProperty;
41
+ exports.submit = submit;
42
+ exports.refresh = refresh;
43
+ exports.getUrl = getUrl;
44
+ exports.title = title;
45
+ exports.getCookies = getCookies;
46
+ exports.setCookie = setCookie;
47
+ exports.deleteCookie = deleteCookie;
48
+ exports.deleteCookies = deleteCookies;
49
+ exports.cacheWebElement = cacheWebElement;
50
+ exports.cacheWebElements = cacheWebElements;
51
+ exports.executeAtom = executeAtom;
52
+ exports.executeAtomAsync = executeAtomAsync;
53
+ exports.getAtomsElement = getAtomsElement;
54
+ exports.convertElementsForAtoms = convertElementsForAtoms;
55
+ exports.getElementId = getElementId;
56
+ exports.hasElementId = hasElementId;
57
+ exports.findWebElementOrElements = findWebElementOrElements;
58
+ exports.clickWebCoords = clickWebCoords;
59
+ exports.getSafariIsIphone = getSafariIsIphone;
60
+ exports.getSafariDeviceSize = getSafariDeviceSize;
61
+ exports.getSafariIsNotched = getSafariIsNotched;
62
+ exports.getExtraTranslateWebCoordsOffset = getExtraTranslateWebCoordsOffset;
63
+ exports.getExtraNativeWebTapOffset = getExtraNativeWebTapOffset;
64
+ exports.nativeWebTap = nativeWebTap;
65
+ exports.translateWebCoords = translateWebCoords;
66
+ exports.checkForAlert = checkForAlert;
67
+ exports.waitForAtom = waitForAtom;
68
+ exports.mobileWebNav = mobileWebNav;
69
+ exports.getWdaLocalhostRoot = getWdaLocalhostRoot;
70
+ exports.mobileCalibrateWebToRealCoordinatesTranslation = mobileCalibrateWebToRealCoordinatesTranslation;
71
+ exports.mobileUpdateSafariPreferences = mobileUpdateSafariPreferences;
72
+ const driver_1 = require("appium/driver");
73
+ const support_1 = require("appium/support");
74
+ const asyncbox_1 = require("asyncbox");
75
+ const bluebird_1 = __importStar(require("bluebird"));
76
+ const lodash_1 = __importDefault(require("lodash"));
77
+ const IPHONE_TOP_BAR_HEIGHT = 71;
78
+ const IPHONE_SCROLLED_TOP_BAR_HEIGHT = 41;
79
+ const IPHONE_X_SCROLLED_OFFSET = 55;
80
+ const IPHONE_X_NOTCH_OFFSET_IOS = 24;
81
+ const IPHONE_X_NOTCH_OFFSET_IOS_13 = 20;
82
+ const IPHONE_LANDSCAPE_TOP_BAR_HEIGHT = 51;
83
+ const IPHONE_BOTTOM_BAR_OFFSET = 49;
84
+ const TAB_BAR_OFFSET = 33;
85
+ const IPHONE_WEB_COORD_SMART_APP_BANNER_OFFSET = 84;
86
+ const IPAD_WEB_COORD_SMART_APP_BANNER_OFFSET = 95;
87
+ const CALIBRATION_TAP_DELTA_PX = 7;
88
+ const NOTCHED_DEVICE_SIZES = [
89
+ { w: 1125, h: 2436 }, // 11 Pro, X, Xs
90
+ { w: 828, h: 1792 }, // 11, Xr
91
+ { w: 1242, h: 2688 }, // 11 Pro Max, Xs Max
92
+ { w: 1080, h: 2340 }, // 13 mini, 12 mini
93
+ { w: 1170, h: 2532 }, // 14, 13, 13 Pro, 12, 12 Pro
94
+ { w: 1284, h: 2778 }, // 14 Plus, 13 Pro Max, 12 Pro Max
95
+ { w: 1179, h: 2556 }, // 14 Pro
96
+ { w: 1290, h: 2796 }, // 14 Pro Max
97
+ ];
98
+ const { W3C_WEB_ELEMENT_IDENTIFIER } = support_1.util;
99
+ const ATOM_WAIT_TIMEOUT_MS = 2 * 60000;
100
+ // This value must be greater than the alerts check interval in WDA:
101
+ // https://github.com/appium/WebDriverAgent/blob/8bc3135f021b529d916846477544f4b8ca890f59/WebDriverAgentLib/Utilities/FBAlertsMonitor.m#L17
102
+ const ATOM_INITIAL_WAIT_MS = 2100;
103
+ const OBSTRUCTING_ALERT_PRESENCE_CHECK_INTERVAL_MS = 500;
104
+ const ON_OBSTRUCTING_ALERT_EVENT = 'alert';
105
+ const ON_APP_CRASH_EVENT = 'app_crash';
106
+ const VISIBLE = 'visible';
107
+ const INVISIBLE = 'invisible';
108
+ const DETECT = 'detect';
109
+ const VISIBILITIES = [VISIBLE, INVISIBLE, DETECT];
110
+ // The position of Safari's tab (search bar).
111
+ // Since iOS 15, the bar is the bottom by default.
112
+ const TAB_BAR_POSITION_TOP = 'top';
113
+ const TAB_BAR_POSITION_BOTTOM = 'bottom';
114
+ const TAB_BAR_POSSITIONS = [TAB_BAR_POSITION_TOP, TAB_BAR_POSITION_BOTTOM];
115
+ /**
116
+ * @this {XCUITestDriver}
117
+ * @group Mobile Web Only
118
+ * @param {number|string|null} frame
119
+ * @returns {Promise<void>}
120
+ */
121
+ async function setFrame(frame) {
122
+ if (!this.isWebContext()) {
123
+ throw new driver_1.errors.NotImplementedError();
124
+ }
125
+ if (lodash_1.default.isNull(frame)) {
126
+ this.curWebFrames = [];
127
+ this.log.debug('Leaving web frame and going back to default content');
128
+ return;
129
+ }
130
+ if (hasElementId(frame)) {
131
+ const atomsElement = this.getAtomsElement(frame);
132
+ const value = await this.executeAtom('get_frame_window', [atomsElement]);
133
+ this.log.debug(`Entering new web frame: '${value.WINDOW}'`);
134
+ this.curWebFrames.unshift(value.WINDOW);
135
+ }
136
+ else {
137
+ const atom = lodash_1.default.isNumber(frame) ? 'frame_by_index' : 'frame_by_id_or_name';
138
+ const value = await this.executeAtom(atom, [frame]);
139
+ if (lodash_1.default.isNull(value) || lodash_1.default.isUndefined(value.WINDOW)) {
140
+ throw new driver_1.errors.NoSuchFrameError();
141
+ }
142
+ this.log.debug(`Entering new web frame: '${value.WINDOW}'`);
143
+ this.curWebFrames.unshift(value.WINDOW);
144
+ }
145
+ }
146
+ /**
147
+ * @this {XCUITestDriver}
148
+ * @group Mobile Web Only
149
+ * @param {string} propertyName
150
+ * @param {Element | string} el
151
+ * @returns {Promise<string>}
152
+ */
153
+ async function getCssProperty(propertyName, el) {
154
+ if (!this.isWebContext()) {
155
+ throw new driver_1.errors.NotImplementedError();
156
+ }
157
+ const atomsElement = this.getAtomsElement(el);
158
+ return await this.executeAtom('get_value_of_css_property', [atomsElement, propertyName]);
159
+ }
160
+ /**
161
+ * Submit the form an element is in
162
+ *
163
+ * @param {string|Element} el - the element ID
164
+ * @group Mobile Web Only
165
+ * @this {XCUITestDriver}
166
+ */
167
+ async function submit(el) {
168
+ if (!this.isWebContext()) {
169
+ throw new driver_1.errors.NotImplementedError();
170
+ }
171
+ const atomsElement = this.getAtomsElement(el);
172
+ await this.executeAtom('submit', [atomsElement]);
173
+ }
174
+ /**
175
+ * @this {XCUITestDriver}
176
+ * @group Mobile Web Only
177
+ */
178
+ async function refresh() {
179
+ if (!this.isWebContext()) {
180
+ throw new driver_1.errors.NotImplementedError();
181
+ }
182
+ await ( /** @type {RemoteDebugger} */(this.remote)).execute('window.location.reload()');
183
+ }
184
+ /**
185
+ * @this {XCUITestDriver}
186
+ * @group Mobile Web Only
187
+ * @returns {Promise<string>}
188
+ */
189
+ async function getUrl() {
190
+ if (!this.isWebContext()) {
191
+ throw new driver_1.errors.NotImplementedError();
192
+ }
193
+ return await ( /** @type {RemoteDebugger} */(this.remote)).execute('window.location.href');
194
+ }
195
+ /**
196
+ * @this {XCUITestDriver}
197
+ * @group Mobile Web Only
198
+ * @returns {Promise<string>}
199
+ */
200
+ async function title() {
201
+ if (!this.isWebContext()) {
202
+ throw new driver_1.errors.NotImplementedError();
203
+ }
204
+ return await ( /** @type {RemoteDebugger} */(this.remote)).execute('window.document.title');
205
+ }
206
+ /**
207
+ * @this {XCUITestDriver}
208
+ * @group Mobile Web Only
209
+ * @returns {Promise<import('@appium/types').Cookie[]>}
210
+ */
211
+ async function getCookies() {
212
+ if (!this.isWebContext()) {
213
+ throw new driver_1.errors.NotImplementedError();
214
+ }
215
+ // get the cookies from the remote debugger, or an empty object
216
+ const { cookies } = await ( /** @type {RemoteDebugger} */(this.remote)).getCookies();
217
+ // the value is URI encoded, so decode it safely
218
+ return cookies.map((cookie) => {
219
+ if (!lodash_1.default.isEmpty(cookie.value)) {
220
+ try {
221
+ cookie.value = decodeURI(cookie.value);
222
+ }
223
+ catch (error) {
224
+ this.log.debug(`Cookie ${cookie.name} was not decoded successfully. Cookie value: ${cookie.value}`);
225
+ this.log.warn(error);
226
+ // Keep the original value
227
+ }
228
+ }
229
+ return cookie;
230
+ });
231
+ }
232
+ /**
233
+ * @this {XCUITestDriver}
234
+ * @group Mobile Web Only
235
+ * @param {import('@appium/types').Cookie} cookie
236
+ * @returns {Promise<void>}
237
+ */
238
+ async function setCookie(cookie) {
239
+ if (!this.isWebContext()) {
240
+ throw new driver_1.errors.NotImplementedError();
241
+ }
242
+ const clonedCookie = lodash_1.default.clone(cookie);
243
+ // if `path` field is not specified, Safari will not update cookies as expected; eg issue #1708
244
+ if (!clonedCookie.path) {
245
+ clonedCookie.path = '/';
246
+ }
247
+ const jsCookie = createJSCookie(clonedCookie.name, clonedCookie.value, {
248
+ expires: lodash_1.default.isNumber(clonedCookie.expiry)
249
+ ? new Date(clonedCookie.expiry * 1000).toUTCString()
250
+ : clonedCookie.expiry,
251
+ path: clonedCookie.path,
252
+ domain: clonedCookie.domain,
253
+ httpOnly: clonedCookie.httpOnly,
254
+ secure: clonedCookie.secure,
255
+ });
256
+ const script = `document.cookie = ${JSON.stringify(jsCookie)}`;
257
+ await this.executeAtom('execute_script', [script, []]);
258
+ }
259
+ /**
260
+ * @this {XCUITestDriver}
261
+ * @param {string} cookieName
262
+ * @returns {Promise<void>}
263
+ * @group Mobile Web Only
264
+ */
265
+ async function deleteCookie(cookieName) {
266
+ if (!this.isWebContext()) {
267
+ throw new driver_1.errors.NotImplementedError();
268
+ }
269
+ const cookies = await this.getCookies();
270
+ const cookie = cookies.find(({ name }) => name === cookieName);
271
+ if (!cookie) {
272
+ this.log.debug(`Cookie '${cookieName}' not found. Ignoring.`);
273
+ return;
274
+ }
275
+ await _deleteCookie.bind(this)(cookie);
276
+ }
277
+ /**
278
+ * @this {XCUITestDriver}
279
+ * @group Mobile Web Only
280
+ * @returns {Promise<void>}
281
+ */
282
+ async function deleteCookies() {
283
+ if (!this.isWebContext()) {
284
+ throw new driver_1.errors.NotImplementedError();
285
+ }
286
+ const cookies = await this.getCookies();
287
+ await bluebird_1.default.all(cookies.map((cookie) => _deleteCookie.bind(this)(cookie)));
288
+ }
289
+ /**
290
+ * @this {XCUITestDriver}
291
+ * @param {Element | string} el
292
+ * @returns {Element | string}
293
+ */
294
+ function cacheWebElement(el) {
295
+ if (!lodash_1.default.isPlainObject(el)) {
296
+ return el;
297
+ }
298
+ const elId = support_1.util.unwrapElement(el);
299
+ if (!isValidElementIdentifier(elId)) {
300
+ return el;
301
+ }
302
+ // In newer debugger releases element identifiers look like `:wdc:1628151649325`
303
+ // We assume it is safe to use these to identify cached elements
304
+ const cacheId = lodash_1.default.includes(elId, ':') ? elId : support_1.util.uuidV4();
305
+ this.webElementsCache.set(cacheId, elId);
306
+ return support_1.util.wrapElement(cacheId);
307
+ }
308
+ /**
309
+ * @this {XCUITestDriver}
310
+ * @param {any} response
311
+ * @returns {any}
312
+ */
313
+ function cacheWebElements(response) {
314
+ const toCached = (/** @type {any} */ v) => (lodash_1.default.isArray(v) || lodash_1.default.isPlainObject(v)) ? this.cacheWebElements(v) : v;
315
+ if (lodash_1.default.isArray(response)) {
316
+ return response.map(toCached);
317
+ }
318
+ else if (lodash_1.default.isPlainObject(response)) {
319
+ const result = { ...response, ...( /** @type {Element} */(this.cacheWebElement(response))) };
320
+ return lodash_1.default.toPairs(result).reduce((acc, [key, value]) => {
321
+ acc[key] = toCached(value);
322
+ return acc;
323
+ }, {});
324
+ }
325
+ return response;
326
+ }
327
+ /**
328
+ * @param {string} atom
329
+ * @param {unknown[]} args
330
+ * @returns {Promise<any>}
331
+ * @privateRemarks This should return `Promise<T>` where `T` extends `unknown`, but that's going to cause a lot of things to break.
332
+ * @this {XCUITestDriver}
333
+ */
334
+ async function executeAtom(atom, args, alwaysDefaultFrame = false) {
335
+ let frames = alwaysDefaultFrame === true ? [] : this.curWebFrames;
336
+ let promise = ( /** @type {RemoteDebugger} */(this.remote)).executeAtom(atom, args, frames);
337
+ return await this.waitForAtom(promise);
338
+ }
339
+ /**
340
+ * @this {XCUITestDriver}
341
+ * @param {string} atom
342
+ * @param {any[]} args
343
+ */
344
+ async function executeAtomAsync(atom, args) {
345
+ // save the resolve and reject methods of the promise to be waited for
346
+ let promise = new bluebird_1.default((resolve, reject) => {
347
+ this.asyncPromise = { resolve, reject };
348
+ });
349
+ await ( /** @type {RemoteDebugger} */(this.remote)).executeAtomAsync(atom, args, this.curWebFrames);
350
+ return await this.waitForAtom(promise);
351
+ }
352
+ /**
353
+ * @template {string} S
354
+ * @param {S|Element<S>} elOrId
355
+ * @returns {import('./types').AtomsElement<S>}
356
+ * @this {XCUITestDriver}
357
+ */
358
+ function getAtomsElement(elOrId) {
359
+ const elId = support_1.util.unwrapElement(elOrId);
360
+ if (!this.webElementsCache?.has(elId)) {
361
+ throw new driver_1.errors.StaleElementReferenceError();
362
+ }
363
+ return { ELEMENT: this.webElementsCache.get(elId) };
364
+ }
365
+ /**
366
+ * @param {readonly any[]} [args]
367
+ * @this {XCUITestDriver}
368
+ */
369
+ function convertElementsForAtoms(args = []) {
370
+ return args.map((arg) => {
371
+ if (hasElementId(arg)) {
372
+ try {
373
+ return this.getAtomsElement(arg);
374
+ }
375
+ catch (err) {
376
+ if (!(0, driver_1.isErrorType)(err, driver_1.errors.StaleElementReferenceError)) {
377
+ throw err;
378
+ }
379
+ }
380
+ return arg;
381
+ }
382
+ return lodash_1.default.isArray(arg) ? this.convertElementsForAtoms(arg) : arg;
383
+ });
384
+ }
385
+ /**
386
+ *
387
+ * @param {any} element
388
+ * @returns {string | undefined}
389
+ */
390
+ function getElementId(element) {
391
+ return element?.ELEMENT || element?.[W3C_WEB_ELEMENT_IDENTIFIER];
392
+ }
393
+ /**
394
+ * @param {any} element
395
+ * @returns {element is Element}
396
+ */
397
+ function hasElementId(element) {
398
+ return (support_1.util.hasValue(element) &&
399
+ (support_1.util.hasValue(element.ELEMENT) || support_1.util.hasValue(element[W3C_WEB_ELEMENT_IDENTIFIER])));
400
+ }
401
+ /**
402
+ * @this {XCUITestDriver}
403
+ * @param {string} strategy
404
+ * @param {string} selector
405
+ * @param {boolean} [many]
406
+ * @param {Element | string | null} [ctx]
407
+ * @returns {Promise<Element | Element[]>}
408
+ */
409
+ async function findWebElementOrElements(strategy, selector, many, ctx) {
410
+ const contextElement = lodash_1.default.isNil(ctx) ? null : this.getAtomsElement(ctx);
411
+ const atomName = many ? 'find_elements' : 'find_element_fragment';
412
+ let element;
413
+ const doFind = async () => {
414
+ element = await this.executeAtom(atomName, [strategy, selector, contextElement]);
415
+ return !lodash_1.default.isNull(element);
416
+ };
417
+ try {
418
+ await this.implicitWaitForCondition(doFind);
419
+ }
420
+ catch (err) {
421
+ if (err.message && lodash_1.default.isFunction(err.message.match) && err.message.match(/Condition unmet/)) {
422
+ // condition was not met setting res to empty array
423
+ element = [];
424
+ }
425
+ else {
426
+ throw err;
427
+ }
428
+ }
429
+ if (many) {
430
+ return this.cacheWebElements(element);
431
+ }
432
+ if (lodash_1.default.isEmpty(element)) {
433
+ throw new driver_1.errors.NoSuchElementError();
434
+ }
435
+ return this.cacheWebElements(element);
436
+ }
437
+ /**
438
+ * @this {XCUITestDriver}
439
+ * @param {number} x
440
+ * @param {number} y
441
+ */
442
+ async function clickWebCoords(x, y) {
443
+ const { x: translatedX, y: translatedY } = await this.translateWebCoords(x, y);
444
+ await this.mobileTap(translatedX, translatedY);
445
+ }
446
+ /**
447
+ * @this {XCUITestDriver}
448
+ * @returns {Promise<boolean>}
449
+ */
450
+ async function getSafariIsIphone() {
451
+ if (lodash_1.default.isBoolean(this._isSafariIphone)) {
452
+ return this._isSafariIphone;
453
+ }
454
+ try {
455
+ const userAgent = /** @type {string} */ (await this.execute('return navigator.userAgent'));
456
+ this._isSafariIphone = userAgent.toLowerCase().includes('iphone');
457
+ }
458
+ catch (err) {
459
+ this.log.warn(`Unable to find device type from useragent. Assuming iPhone`);
460
+ this.log.debug(`Error: ${err.message}`);
461
+ }
462
+ return this._isSafariIphone ?? true;
463
+ }
464
+ /**
465
+ * @this {XCUITestDriver}
466
+ * @returns {Promise<import('@appium/types').Size>}
467
+ */
468
+ async function getSafariDeviceSize() {
469
+ const script = 'return {height: window.screen.availHeight * window.devicePixelRatio, width: window.screen.availWidth * window.devicePixelRatio};';
470
+ const { width, height } = /** @type {import('@appium/types').Size} */ (await this.execute(script));
471
+ const [normHeight, normWidth] = height > width ? [height, width] : [width, height];
472
+ return {
473
+ width: normWidth,
474
+ height: normHeight,
475
+ };
476
+ }
477
+ /**
478
+ * @this {XCUITestDriver}
479
+ * @returns {Promise<boolean>}
480
+ */
481
+ async function getSafariIsNotched() {
482
+ if (lodash_1.default.isBoolean(this._isSafariNotched)) {
483
+ return this._isSafariNotched;
484
+ }
485
+ try {
486
+ const { width, height } = await this.getSafariDeviceSize();
487
+ for (const device of NOTCHED_DEVICE_SIZES) {
488
+ if (device.w === width && device.h === height) {
489
+ this._isSafariNotched = true;
490
+ }
491
+ }
492
+ }
493
+ catch (err) {
494
+ this.log.warn(`Unable to find device type from dimensions. Assuming the device is not notched`);
495
+ this.log.debug(`Error: ${err.message}`);
496
+ }
497
+ return this._isSafariNotched ?? false;
498
+ }
499
+ /**
500
+ * @this {XCUITestDriver}
501
+ */
502
+ async function getExtraTranslateWebCoordsOffset(wvPos, realDims) {
503
+ let topOffset = 0;
504
+ let bottomOffset = 0;
505
+ const isIphone = await this.getSafariIsIphone();
506
+ // No need to check whether the Smart App Banner or Tab Bar is visible or not
507
+ // if already defined by nativeWebTapTabBarVisibility or nativeWebTapSmartAppBannerVisibility in settings.
508
+ const { nativeWebTapTabBarVisibility, nativeWebTapSmartAppBannerVisibility, safariTabBarPosition = support_1.util.compareVersions(/** @type {string} */ (this.opts.platformVersion), '>=', '15.0') &&
509
+ isIphone
510
+ ? TAB_BAR_POSITION_BOTTOM
511
+ : TAB_BAR_POSITION_TOP, } = this.settings.getSettings();
512
+ let tabBarVisibility = lodash_1.default.lowerCase(String(nativeWebTapTabBarVisibility));
513
+ let bannerVisibility = lodash_1.default.lowerCase(String(nativeWebTapSmartAppBannerVisibility));
514
+ const tabBarPosition = lodash_1.default.lowerCase(String(safariTabBarPosition));
515
+ if (!VISIBILITIES.includes(tabBarVisibility)) {
516
+ tabBarVisibility = DETECT;
517
+ }
518
+ if (!VISIBILITIES.includes(bannerVisibility)) {
519
+ bannerVisibility = DETECT;
520
+ }
521
+ if (!TAB_BAR_POSSITIONS.includes(tabBarPosition)) {
522
+ throw new driver_1.errors.InvalidArgumentError(`${safariTabBarPosition} is invalid as Safari tab bar position. Available positions are ${TAB_BAR_POSSITIONS}.`);
523
+ }
524
+ const isNotched = isIphone && (await this.getSafariIsNotched());
525
+ const orientation = realDims.h > realDims.w ? 'PORTRAIT' : 'LANDSCAPE';
526
+ const notchOffset = isNotched
527
+ ? support_1.util.compareVersions(/** @type {string} */ (this.opts.platformVersion), '=', '13.0')
528
+ ? IPHONE_X_NOTCH_OFFSET_IOS_13
529
+ : IPHONE_X_NOTCH_OFFSET_IOS
530
+ : 0;
531
+ const isScrolled = await this.execute('return document.documentElement.scrollTop > 0');
532
+ if (isScrolled) {
533
+ topOffset = IPHONE_SCROLLED_TOP_BAR_HEIGHT + notchOffset;
534
+ if (isNotched) {
535
+ topOffset -= IPHONE_X_SCROLLED_OFFSET;
536
+ }
537
+ // If the iPhone is landscape then there is no top bar
538
+ if (orientation === 'LANDSCAPE' && isIphone) {
539
+ topOffset = 0;
540
+ }
541
+ }
542
+ else {
543
+ topOffset = tabBarPosition === TAB_BAR_POSITION_BOTTOM ? 0 : IPHONE_TOP_BAR_HEIGHT;
544
+ topOffset += notchOffset;
545
+ this.log.debug(`tabBarPosition and topOffset: ${tabBarPosition}, ${topOffset}`);
546
+ if (isIphone) {
547
+ if (orientation === 'PORTRAIT') {
548
+ // The bottom bar is only visible when portrait
549
+ bottomOffset = IPHONE_BOTTOM_BAR_OFFSET;
550
+ }
551
+ else {
552
+ topOffset = IPHONE_LANDSCAPE_TOP_BAR_HEIGHT;
553
+ }
554
+ }
555
+ if (orientation === 'LANDSCAPE' || !isIphone) {
556
+ if (tabBarVisibility === VISIBLE) {
557
+ topOffset += TAB_BAR_OFFSET;
558
+ }
559
+ else if (tabBarVisibility === DETECT) {
560
+ // Tabs only appear if the device is landscape or if it's an iPad so we only check visibility in this case
561
+ // Assume that each tab bar is a WebView
562
+ const contextsAndViews = await this.getContextsAndViews();
563
+ const tabs = contextsAndViews.filter((ctx) => ctx.id.startsWith('WEBVIEW_'));
564
+ if (tabs.length > 1) {
565
+ this.log.debug(`Found ${tabs.length} tabs. Assuming the tab bar is visible`);
566
+ topOffset += TAB_BAR_OFFSET;
567
+ }
568
+ }
569
+ }
570
+ }
571
+ topOffset += await this.getExtraNativeWebTapOffset(isIphone, bannerVisibility);
572
+ wvPos.y += topOffset;
573
+ realDims.h -= topOffset + bottomOffset;
574
+ }
575
+ /**
576
+ * @this {XCUITestDriver}
577
+ * @param {boolean} isIphone
578
+ * @param {string} bannerVisibility
579
+ * @returns {Promise<number>}
580
+ */
581
+ async function getExtraNativeWebTapOffset(isIphone, bannerVisibility) {
582
+ let offset = 0;
583
+ if (bannerVisibility === VISIBLE) {
584
+ offset += isIphone
585
+ ? IPHONE_WEB_COORD_SMART_APP_BANNER_OFFSET
586
+ : IPAD_WEB_COORD_SMART_APP_BANNER_OFFSET;
587
+ }
588
+ else if (bannerVisibility === DETECT) {
589
+ // try to see if there is an Smart App Banner
590
+ const banners = /** @type {import('@appium/types').Element[]} */ (await this.findNativeElementOrElements('accessibility id', 'Close app download offer', true));
591
+ if (banners?.length) {
592
+ offset += isIphone
593
+ ? IPHONE_WEB_COORD_SMART_APP_BANNER_OFFSET
594
+ : IPAD_WEB_COORD_SMART_APP_BANNER_OFFSET;
595
+ }
596
+ }
597
+ this.log.debug(`Additional native web tap offset computed: ${offset}`);
598
+ return offset;
599
+ }
600
+ /**
601
+ * @this {XCUITestDriver}
602
+ * @param {any} el
603
+ * @returns {Promise<void>}
604
+ */
605
+ async function nativeWebTap(el) {
606
+ const atomsElement = this.getAtomsElement(el);
607
+ // if strict native tap, do not try to do it with WDA directly
608
+ if (!(this.settings.getSettings()).nativeWebTapStrict &&
609
+ (await tapWebElementNatively.bind(this)(atomsElement))) {
610
+ return;
611
+ }
612
+ this.log.warn('Unable to do simple native web tap. Attempting to convert coordinates');
613
+ const [size, coordinates] =
614
+ /** @type {[import('@appium/types').Size, import('@appium/types').Position]} */ (await bluebird_1.default.Promise.all([
615
+ this.executeAtom('get_size', [atomsElement]),
616
+ this.executeAtom('get_top_left_coordinates', [atomsElement]),
617
+ ]));
618
+ const { width, height } = size;
619
+ const { x, y } = coordinates;
620
+ await this.clickWebCoords(x + width / 2, y + height / 2);
621
+ }
622
+ /**
623
+ * @this {XCUITestDriver}
624
+ * @param {number} x
625
+ * @param {number} y
626
+ * @returns {Promise<import('@appium/types').Position>}
627
+ */
628
+ async function translateWebCoords(x, y) {
629
+ this.log.debug(`Translating web coordinates (${JSON.stringify({ x, y })}) to native coordinates`);
630
+ if (this.webviewCalibrationResult) {
631
+ this.log.debug(`Will use the recent calibration result: ${JSON.stringify(this.webviewCalibrationResult)}`);
632
+ const { offsetX, offsetY, pixelRatioX, pixelRatioY } = this.webviewCalibrationResult;
633
+ const cmd = '(function () {return {innerWidth: window.innerWidth, innerHeight: window.innerHeight, ' +
634
+ 'outerWidth: window.outerWidth, outerHeight: window.outerHeight}; })()';
635
+ const wvDims = await ( /** @type {RemoteDebugger} */(this.remote)).execute(cmd);
636
+ // https://tripleodeon.com/2011/12/first-understand-your-screen/
637
+ const shouldApplyPixelRatio = wvDims.innerWidth > wvDims.outerWidth
638
+ || wvDims.innerHeight > wvDims.outerHeight;
639
+ return {
640
+ x: offsetX + x * (shouldApplyPixelRatio ? pixelRatioX : 1),
641
+ y: offsetY + y * (shouldApplyPixelRatio ? pixelRatioY : 1),
642
+ };
643
+ }
644
+ else {
645
+ this.log.debug(`Using the legacy algorithm for coordinates translation. ` +
646
+ `Invoke 'mobile: calibrateWebToRealCoordinatesTranslation' to change that.`);
647
+ }
648
+ // absolutize web coords
649
+ /** @type {import('@appium/types').Element|undefined|string} */
650
+ let webview;
651
+ try {
652
+ webview = /** @type {import('@appium/types').Element|undefined} */ (await (0, asyncbox_1.retryInterval)(5, 100, async () => await this.findNativeElementOrElements('class name', 'XCUIElementTypeWebView', false)));
653
+ }
654
+ catch { }
655
+ if (!webview) {
656
+ throw new Error(`No WebView found. Unable to translate web coordinates for native web tap.`);
657
+ }
658
+ webview = support_1.util.unwrapElement(webview);
659
+ const rect = /** @type {Rect} */ (await this.proxyCommand(`/element/${webview}/rect`, 'GET'));
660
+ const wvPos = { x: rect.x, y: rect.y };
661
+ const realDims = { w: rect.width, h: rect.height };
662
+ const cmd = '(function () { return {w: window.innerWidth, h: window.innerHeight}; })()';
663
+ const wvDims = await ( /** @type {RemoteDebugger} */(this.remote)).execute(cmd);
664
+ // keep track of implicit wait, and set locally to 0
665
+ // https://github.com/appium/appium/issues/14988
666
+ const implicitWaitMs = this.implicitWaitMs;
667
+ this.setImplicitWait(0);
668
+ try {
669
+ await this.getExtraTranslateWebCoordsOffset(wvPos, realDims);
670
+ }
671
+ finally {
672
+ this.setImplicitWait(implicitWaitMs);
673
+ }
674
+ if (!wvDims || !realDims || !wvPos) {
675
+ throw new Error(`Web coordinates ${JSON.stringify({ x, y })} cannot be translated into real coordinates. ` +
676
+ `Try to invoke 'mobile: calibrateWebToRealCoordinatesTranslation' or consider translating the ` +
677
+ `coordinates from the client code.`);
678
+ }
679
+ const xRatio = realDims.w / wvDims.w;
680
+ const yRatio = realDims.h / wvDims.h;
681
+ const newCoords = {
682
+ x: wvPos.x + Math.round(xRatio * x),
683
+ y: wvPos.y + Math.round(yRatio * y),
684
+ };
685
+ // additional logging for coordinates, since it is sometimes broken
686
+ // see https://github.com/appium/appium/issues/9159
687
+ this.log.debug(`Converted coordinates: ${JSON.stringify(newCoords)}`);
688
+ this.log.debug(` rect: ${JSON.stringify(rect)}`);
689
+ this.log.debug(` wvPos: ${JSON.stringify(wvPos)}`);
690
+ this.log.debug(` realDims: ${JSON.stringify(realDims)}`);
691
+ this.log.debug(` wvDims: ${JSON.stringify(wvDims)}`);
692
+ this.log.debug(` xRatio: ${JSON.stringify(xRatio)}`);
693
+ this.log.debug(` yRatio: ${JSON.stringify(yRatio)}`);
694
+ this.log.debug(`Converted web coords ${JSON.stringify({ x, y })} into real coords ${JSON.stringify(newCoords)}`);
695
+ return newCoords;
696
+ }
697
+ /**
698
+ * @this {XCUITestDriver}
699
+ * @returns {Promise<boolean>}
700
+ */
701
+ async function checkForAlert() {
702
+ return lodash_1.default.isString(await this.getAlertText());
703
+ }
704
+ /**
705
+ * @param {Promise<any>} promise
706
+ * @this {XCUITestDriver}
707
+ */
708
+ async function waitForAtom(promise) {
709
+ const timer = new support_1.timing.Timer().start();
710
+ const atomWaitTimeoutMs = lodash_1.default.isNumber(this.opts.webviewAtomWaitTimeout) && this.opts.webviewAtomWaitTimeout > 0
711
+ ? this.opts.webviewAtomWaitTimeout
712
+ : ATOM_WAIT_TIMEOUT_MS;
713
+ // need to check for alert while the atom is being executed.
714
+ // so notify ourselves when it happens
715
+ const timedAtomPromise = bluebird_1.default.resolve(promise).timeout(atomWaitTimeoutMs);
716
+ const handlePromiseError = async (p) => {
717
+ try {
718
+ return await p;
719
+ }
720
+ catch (err) {
721
+ const originalError = err instanceof bluebird_1.AggregateError ? err[0] : err;
722
+ this.log.debug(`Error received while executing atom: ${originalError.message}`);
723
+ throw (originalError instanceof bluebird_1.TimeoutError
724
+ ? (await generateAtomTimeoutError.bind(this)(timer))
725
+ : originalError);
726
+ }
727
+ };
728
+ // if the atom promise is fulfilled within ATOM_INITIAL_WAIT_MS
729
+ // then we don't need to check for an alert presence
730
+ await handlePromiseError(bluebird_1.default.any([bluebird_1.default.delay(ATOM_INITIAL_WAIT_MS), timedAtomPromise]));
731
+ if (timedAtomPromise.isFulfilled()) {
732
+ return await timedAtomPromise;
733
+ }
734
+ // ...otherwise make sure there is no unexpected alert covering the element
735
+ this._waitingAtoms.count++;
736
+ let onAlertCallback;
737
+ let onAppCrashCallback;
738
+ try {
739
+ // only restart the monitor if it is not running already
740
+ if (this._waitingAtoms.alertMonitor.isResolved()) {
741
+ this._waitingAtoms.alertMonitor = bluebird_1.default.resolve((async () => {
742
+ while (this._waitingAtoms.count > 0) {
743
+ try {
744
+ if (await this.checkForAlert()) {
745
+ this._waitingAtoms.alertNotifier.emit(ON_OBSTRUCTING_ALERT_EVENT);
746
+ }
747
+ }
748
+ catch (err) {
749
+ if ((0, driver_1.isErrorType)(err, driver_1.errors.InvalidElementStateError)) {
750
+ this._waitingAtoms.alertNotifier.emit(ON_APP_CRASH_EVENT, err);
751
+ }
752
+ }
753
+ await bluebird_1.default.delay(OBSTRUCTING_ALERT_PRESENCE_CHECK_INTERVAL_MS);
754
+ }
755
+ })());
756
+ }
757
+ return await new bluebird_1.default((resolve, reject) => {
758
+ onAlertCallback = () => reject(new driver_1.errors.UnexpectedAlertOpenError());
759
+ onAppCrashCallback = reject;
760
+ this._waitingAtoms.alertNotifier.once(ON_OBSTRUCTING_ALERT_EVENT, onAlertCallback);
761
+ this._waitingAtoms.alertNotifier.once(ON_APP_CRASH_EVENT, onAppCrashCallback);
762
+ handlePromiseError(timedAtomPromise)
763
+ .then(resolve)
764
+ .catch(reject);
765
+ });
766
+ }
767
+ finally {
768
+ if (onAlertCallback) {
769
+ this._waitingAtoms.alertNotifier.removeListener(ON_OBSTRUCTING_ALERT_EVENT, onAlertCallback);
770
+ }
771
+ if (onAppCrashCallback) {
772
+ this._waitingAtoms.alertNotifier.removeListener(ON_APP_CRASH_EVENT, onAppCrashCallback);
773
+ }
774
+ this._waitingAtoms.count--;
775
+ }
776
+ }
777
+ /**
778
+ * @param {string} navType
779
+ * @this {XCUITestDriver}
780
+ */
781
+ async function mobileWebNav(navType) {
782
+ ( /** @type {RemoteDebugger} */(this.remote)).allowNavigationWithoutReload = true;
783
+ try {
784
+ await this.executeAtom('execute_script', [`history.${navType}();`, null]);
785
+ }
786
+ finally {
787
+ ( /** @type {RemoteDebugger} */(this.remote)).allowNavigationWithoutReload = false;
788
+ }
789
+ }
790
+ /**
791
+ * @this {XCUITestDriver}
792
+ * @returns {string} The base url which could be used to access WDA HTTP endpoints.
793
+ */
794
+ function getWdaLocalhostRoot() {
795
+ const remotePort = ((this.isRealDevice() ? this.opts.wdaRemotePort : null)
796
+ ?? this.wda?.url?.port
797
+ ?? this.opts.wdaLocalPort)
798
+ || 8100;
799
+ const remoteIp = this.opts.wdaBindingIP ?? '127.0.0.1';
800
+ return `http://${remoteIp}:${remotePort}`;
801
+ }
802
+ /**
803
+ * Calibrates web to real coordinates translation.
804
+ * This API can only be called from Safari web context.
805
+ * It must load a custom page to the browser, and then restore
806
+ * the original one, so don't call it if you can potentially
807
+ * lose the current web app state.
808
+ * The outcome of this API is then used in nativeWebTap mode.
809
+ * The returned value could also be used to manually transform web coordinates
810
+ * to real devices ones in client scripts.
811
+ *
812
+ * @this {XCUITestDriver}
813
+ * @returns {Promise<import('../types').CalibrationData>}
814
+ */
815
+ async function mobileCalibrateWebToRealCoordinatesTranslation() {
816
+ if (!this.isWebContext()) {
817
+ throw new driver_1.errors.NotImplementedError('This API can only be called from a web context');
818
+ }
819
+ const currentUrl = await this.getUrl();
820
+ await this.setUrl(`${this.getWdaLocalhostRoot()}/calibrate`);
821
+ const { width, height } = /** @type {import('@appium/types').Rect} */ (await this.proxyCommand('/window/rect', 'GET'));
822
+ const [centerX, centerY] = [width / 2, height / 2];
823
+ const errorPrefix = 'Cannot determine web view coordinates offset. Are you in Safari context?';
824
+ const performCalibrationTap = async (/** @type {number} */ tapX, /** @type {number} */ tapY) => {
825
+ await this.mobileTap(tapX, tapY);
826
+ /** @type {import('@appium/types').Position} */
827
+ let result;
828
+ try {
829
+ const title = await this.title();
830
+ this.log.debug(JSON.stringify(title));
831
+ result = lodash_1.default.isPlainObject(title) ? title : JSON.parse(title);
832
+ }
833
+ catch (e) {
834
+ throw new Error(`${errorPrefix} Original error: ${e.message}`);
835
+ }
836
+ const { x, y } = result;
837
+ if (!lodash_1.default.isInteger(x) || !lodash_1.default.isInteger(y)) {
838
+ throw new Error(errorPrefix);
839
+ }
840
+ return result;
841
+ };
842
+ await (0, asyncbox_1.retryInterval)(6, 500, async () => {
843
+ const { x: x0, y: y0 } = await performCalibrationTap(centerX - CALIBRATION_TAP_DELTA_PX, centerY - CALIBRATION_TAP_DELTA_PX);
844
+ const { x: x1, y: y1 } = await performCalibrationTap(centerX + CALIBRATION_TAP_DELTA_PX, centerY + CALIBRATION_TAP_DELTA_PX);
845
+ const pixelRatioX = CALIBRATION_TAP_DELTA_PX * 2 / (x1 - x0);
846
+ const pixelRatioY = CALIBRATION_TAP_DELTA_PX * 2 / (y1 - y0);
847
+ this.webviewCalibrationResult = {
848
+ offsetX: centerX - CALIBRATION_TAP_DELTA_PX - x0 * pixelRatioX,
849
+ offsetY: centerY - CALIBRATION_TAP_DELTA_PX - y0 * pixelRatioY,
850
+ pixelRatioX,
851
+ pixelRatioY,
852
+ };
853
+ });
854
+ if (currentUrl) {
855
+ // restore the previous url
856
+ await this.setUrl(currentUrl);
857
+ }
858
+ const result = /** @type {import('../types').CalibrationData} */ (this.webviewCalibrationResult);
859
+ return {
860
+ ...result,
861
+ offsetX: Math.round(result.offsetX),
862
+ offsetY: Math.round(result.offsetY),
863
+ };
864
+ }
865
+ /**
866
+ * @typedef {Object} SafariOpts
867
+ * @property {object} preferences An object containing Safari settings to be updated.
868
+ * The list of available setting names and their values could be retrieved by
869
+ * changing the corresponding Safari settings in the UI and then inspecting
870
+ * 'Library/Preferences/com.apple.mobilesafari.plist' file inside of
871
+ * com.apple.mobilesafari app container.
872
+ * The full path to the Mobile Safari's container could be retrieved from
873
+ * `xcrun simctl get_app_container <sim_udid> com.apple.mobilesafari data`
874
+ * command output.
875
+ * Use the `xcrun simctl spawn <sim_udid> defaults read <path_to_plist>` command
876
+ * to print the plist content to the Terminal.
877
+ */
878
+ /**
879
+ * Updates Mobile Safari preferences on an iOS Simulator
880
+ *
881
+ * @param {import('@appium/types').StringRecord} preferences - An object containing Safari settings to be updated.
882
+ * The list of available setting names and their values can be retrieved by changing the
883
+ * corresponding Safari settings in the UI and then inspecting
884
+ * `Library/Preferences/com.apple.mobilesafari.plist` file inside of the `com.apple.mobilesafari`
885
+ * app container within the simulator filesystem. The full path to Mobile Safari's container can
886
+ * be retrieved by running `xcrun simctl get_app_container <sim_udid> com.apple.mobilesafari
887
+ * data`. Use the `xcrun simctl spawn <sim_udid> defaults read <path_to_plist>` command to print
888
+ * the plist content to the Terminal.
889
+ *
890
+ * @group Simulator Only
891
+ * @returns {Promise<void>}
892
+ * @throws {Error} if run on a real device or if the preferences argument is invalid
893
+ * @this {XCUITestDriver}
894
+ */
895
+ async function mobileUpdateSafariPreferences(preferences) {
896
+ if (!this.isSimulator()) {
897
+ throw new Error('This extension is only available for Simulator');
898
+ }
899
+ if (!lodash_1.default.isPlainObject(preferences)) {
900
+ throw new driver_1.errors.InvalidArgumentError('"preferences" argument must be a valid object');
901
+ }
902
+ this.log.debug(`About to update Safari preferences: ${JSON.stringify(preferences)}`);
903
+ await /** @type {import('../driver').Simulator} */ (this.device).updateSafariSettings(preferences);
904
+ }
905
+ /**
906
+ * @this {XCUITestDriver}
907
+ * @param {timing.Timer} timer
908
+ * @returns {Promise<InstanceType<typeof errors.TimeoutError>>}
909
+ */
910
+ async function generateAtomTimeoutError(timer) {
911
+ let message = (`The remote Safari debugger did not respond to the requested ` +
912
+ `command after ${timer.getDuration().asMilliSeconds}ms. `);
913
+ message += (await this.remote?.isJavascriptExecutionBlocked()) ? (`It appears that JavaScript execution is blocked, ` +
914
+ `which could be caused by either a modal dialog obstructing the current page, ` +
915
+ `or a JavaScript routine monopolizing the event loop.`) : (`However, the debugger still responds to JavaScript commands, ` +
916
+ `which suggests that the provided atom script is taking too long to execute.`);
917
+ if (lodash_1.default.isUndefined(this.opts.webviewAtomWaitTimeout)) {
918
+ message += (` You may also consider adjusting the timeout by setting the ` +
919
+ `'webviewAtomWaitTimeout' driver capability.`);
920
+ }
921
+ return new driver_1.errors.TimeoutError(message);
922
+ }
923
+ /**
924
+ * @this {XCUITestDriver}
925
+ * @param {any} atomsElement
926
+ * @returns {Promise<boolean>}
927
+ */
928
+ async function tapWebElementNatively(atomsElement) {
929
+ // try to get the text of the element, which will be accessible in the
930
+ // native context
931
+ try {
932
+ const [text1, text2] = await bluebird_1.default.all([
933
+ this.executeAtom('get_text', [atomsElement]),
934
+ this.executeAtom('get_attribute_value', [atomsElement, 'value'])
935
+ ]);
936
+ const text = text1 || text2;
937
+ if (!text) {
938
+ return false;
939
+ }
940
+ const els = await this.findNativeElementOrElements('accessibility id', text, true);
941
+ if (![1, 2].includes(els.length)) {
942
+ return false;
943
+ }
944
+ const el = els[0];
945
+ // use tap because on iOS 11.2 and below `nativeClick` crashes WDA
946
+ const rect = /** @type {import('@appium/types').Rect} */ (await this.proxyCommand(`/element/${support_1.util.unwrapElement(el)}/rect`, 'GET'));
947
+ if (els.length > 1) {
948
+ const el2 = els[1];
949
+ const rect2 = /** @type {import('@appium/types').Rect} */ (await this.proxyCommand(`/element/${support_1.util.unwrapElement(el2)}/rect`, 'GET'));
950
+ if (rect.x !== rect2.x || rect.y !== rect2.y
951
+ || rect.width !== rect2.width || rect.height !== rect2.height) {
952
+ // These 2 native elements are not referring to the same web element
953
+ return false;
954
+ }
955
+ }
956
+ await this.mobileTap(rect.x + rect.width / 2, rect.y + rect.height / 2);
957
+ return true;
958
+ }
959
+ catch (err) {
960
+ // any failure should fall through and trigger the more elaborate
961
+ // method of clicking
962
+ this.log.warn(`Error attempting to click: ${err.message}`);
963
+ }
964
+ return false;
965
+ }
966
+ /**
967
+ * @param {any} id
968
+ * @returns {boolean}
969
+ */
970
+ function isValidElementIdentifier(id) {
971
+ if (!lodash_1.default.isString(id) && !lodash_1.default.isNumber(id)) {
972
+ return false;
973
+ }
974
+ if (lodash_1.default.isString(id) && lodash_1.default.isEmpty(id)) {
975
+ return false;
976
+ }
977
+ if (lodash_1.default.isNumber(id) && isNaN(id)) {
978
+ return false;
979
+ }
980
+ return true;
981
+ }
982
+ /**
983
+ * Creates a JavaScript Cookie
984
+ *
985
+ * @param {string} key
986
+ * @param {string} value
987
+ * @param {CookieOptions} [options={}]
988
+ * @returns {string}
989
+ */
990
+ function createJSCookie(key, value, options = {}) {
991
+ return [
992
+ encodeURIComponent(key),
993
+ '=',
994
+ value,
995
+ options.expires ? `; expires=${options.expires}` : '',
996
+ options.path ? `; path=${options.path}` : '',
997
+ options.domain ? `; domain=${options.domain}` : '',
998
+ options.secure ? '; secure' : '',
999
+ ].join('');
1000
+ }
1001
+ /**
1002
+ * @this {XCUITestDriver}
1003
+ * @param {import('@appium/types').Cookie} cookie
1004
+ * @returns {Promise<any>}
1005
+ */
1006
+ async function _deleteCookie(cookie) {
1007
+ const url = `http${cookie.secure ? 's' : ''}://${cookie.domain}${cookie.path}`;
1008
+ return await ( /** @type {RemoteDebugger} */(this.remote)).deleteCookie(cookie.name, url);
1009
+ }
1010
+ /**
1011
+ * @typedef {Object} CookieOptions
1012
+ * @property {string} [expires]
1013
+ * @property {string} [path]
1014
+ * @property {string} [domain]
1015
+ * @property {boolean} [secure]
1016
+ * @property {boolean} [httpOnly]
1017
+ */
1018
+ /**
1019
+ * @typedef {import('../driver').XCUITestDriver} XCUITestDriver
1020
+ * @typedef {import('@appium/types').Rect} Rect
1021
+ */
1022
+ /**
1023
+ * @template {string} [S=string]
1024
+ * @typedef {import('@appium/types').Element<S>} Element
1025
+ */
1026
+ /**
1027
+ * @typedef {import('appium-remote-debugger').RemoteDebugger} RemoteDebugger
1028
+ */
1029
+ //# sourceMappingURL=web.js.map