appium-mac2-driver 4.4.0 → 4.5.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 (350) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/WebDriverAgentMac/IntegrationTests/AMWindowTests.m +427 -0
  3. package/WebDriverAgentMac/WebDriverAgentLib/Commands/AMWindowCommands.m +63 -0
  4. package/WebDriverAgentMac/WebDriverAgentLib/Commands/FBDebugCommands.m +2 -0
  5. package/WebDriverAgentMac/WebDriverAgentLib/Routing/FBCommandStatus.h +3 -0
  6. package/WebDriverAgentMac/WebDriverAgentLib/Routing/FBCommandStatus.m +13 -0
  7. package/WebDriverAgentMac/WebDriverAgentLib/Utilities/AMScreenUtils.h +4 -0
  8. package/WebDriverAgentMac/WebDriverAgentLib/Utilities/AMScreenUtils.m +23 -0
  9. package/WebDriverAgentMac/WebDriverAgentLib/Utilities/AMSnapshotUtils.h +18 -0
  10. package/WebDriverAgentMac/WebDriverAgentLib/Utilities/AMSnapshotUtils.m +43 -28
  11. package/WebDriverAgentMac/WebDriverAgentLib/Utilities/AMWindowUtils.h +111 -0
  12. package/WebDriverAgentMac/WebDriverAgentLib/Utilities/AMWindowUtils.m +780 -0
  13. package/WebDriverAgentMac/WebDriverAgentLib/Utilities/AMXCTAccessibility.h +61 -0
  14. package/WebDriverAgentMac/WebDriverAgentLib/Utilities/AMXCTAccessibility.m +108 -0
  15. package/WebDriverAgentMac/WebDriverAgentMac.xcodeproj/project.pbxproj +20 -0
  16. package/build/lib/commands/native-record-screen.d.ts +2 -0
  17. package/build/lib/commands/native-record-screen.d.ts.map +1 -1
  18. package/build/lib/commands/native-record-screen.js.map +1 -1
  19. package/build/lib/commands/windows.d.ts +22 -0
  20. package/build/lib/commands/windows.d.ts.map +1 -0
  21. package/build/lib/commands/windows.js +32 -0
  22. package/build/lib/commands/windows.js.map +1 -0
  23. package/build/lib/driver.d.ts +12 -0
  24. package/build/lib/driver.d.ts.map +1 -1
  25. package/build/lib/driver.js +3 -0
  26. package/build/lib/driver.js.map +1 -1
  27. package/build/lib/execute-method-map.d.ts +9 -0
  28. package/build/lib/execute-method-map.d.ts.map +1 -1
  29. package/build/lib/execute-method-map.js +9 -0
  30. package/build/lib/execute-method-map.js.map +1 -1
  31. package/build/lib/session-claim-handler.d.ts.map +1 -1
  32. package/build/lib/session-claim-handler.js +1 -2
  33. package/build/lib/session-claim-handler.js.map +1 -1
  34. package/build/lib/types.d.ts +26 -0
  35. package/build/lib/types.d.ts.map +1 -1
  36. package/build/lib/wda-mac.d.ts +0 -1
  37. package/build/lib/wda-mac.d.ts.map +1 -1
  38. package/build/lib/wda-mac.js +1 -1
  39. package/lib/commands/native-record-screen.ts +2 -0
  40. package/lib/commands/windows.ts +44 -0
  41. package/lib/driver.ts +4 -0
  42. package/lib/execute-method-map.ts +9 -0
  43. package/lib/session-claim-handler.ts +1 -2
  44. package/lib/types.ts +28 -0
  45. package/lib/wda-mac.ts +1 -2
  46. package/node_modules/@appium/support/build/lib/npm.d.ts.map +1 -1
  47. package/node_modules/@appium/support/build/lib/npm.js +2 -1
  48. package/node_modules/@appium/support/build/lib/npm.js.map +1 -1
  49. package/node_modules/@appium/support/build/lib/util.d.ts.map +1 -1
  50. package/node_modules/@appium/support/build/lib/util.js +13 -1
  51. package/node_modules/@appium/support/build/lib/util.js.map +1 -1
  52. package/node_modules/@appium/support/build/lib/zip.d.ts +2 -1
  53. package/node_modules/@appium/support/build/lib/zip.d.ts.map +1 -1
  54. package/node_modules/@appium/support/build/lib/zip.js +193 -64
  55. package/node_modules/@appium/support/build/lib/zip.js.map +1 -1
  56. package/node_modules/@appium/support/lib/npm.ts +2 -1
  57. package/node_modules/@appium/support/lib/util.ts +13 -1
  58. package/node_modules/@appium/support/lib/zip.ts +231 -71
  59. package/node_modules/@appium/support/node_modules/axios/CHANGELOG.md +1934 -0
  60. package/node_modules/@appium/support/node_modules/axios/LICENSE +7 -0
  61. package/node_modules/@appium/support/node_modules/axios/MIGRATION_GUIDE.md +877 -0
  62. package/node_modules/@appium/support/node_modules/axios/README.md +2851 -0
  63. package/node_modules/@appium/support/node_modules/axios/dist/axios.js +5807 -0
  64. package/node_modules/@appium/support/node_modules/axios/dist/axios.min.js +5 -0
  65. package/node_modules/@appium/support/node_modules/axios/dist/axios.min.js.map +1 -0
  66. package/node_modules/@appium/support/node_modules/axios/dist/browser/axios.cjs +5829 -0
  67. package/node_modules/@appium/support/node_modules/axios/dist/esm/axios.js +5850 -0
  68. package/node_modules/@appium/support/node_modules/axios/dist/esm/axios.min.js +3 -0
  69. package/node_modules/@appium/support/node_modules/axios/dist/esm/axios.min.js.map +1 -0
  70. package/node_modules/@appium/support/node_modules/axios/dist/node/axios.cjs +6808 -0
  71. package/node_modules/@appium/support/node_modules/axios/index.d.cts +766 -0
  72. package/node_modules/@appium/support/node_modules/axios/index.d.ts +787 -0
  73. package/node_modules/@appium/support/node_modules/axios/index.js +45 -0
  74. package/node_modules/@appium/support/node_modules/axios/lib/adapters/README.md +36 -0
  75. package/node_modules/@appium/support/node_modules/axios/lib/adapters/adapters.js +132 -0
  76. package/node_modules/@appium/support/node_modules/axios/lib/adapters/fetch.js +696 -0
  77. package/node_modules/@appium/support/node_modules/axios/lib/adapters/http.js +1490 -0
  78. package/node_modules/@appium/support/node_modules/axios/lib/adapters/xhr.js +277 -0
  79. package/node_modules/@appium/support/node_modules/axios/lib/axios.js +89 -0
  80. package/node_modules/@appium/support/node_modules/axios/lib/cancel/CancelToken.js +135 -0
  81. package/node_modules/@appium/support/node_modules/axios/lib/cancel/CanceledError.js +22 -0
  82. package/node_modules/@appium/support/node_modules/axios/lib/cancel/isCancel.js +5 -0
  83. package/node_modules/@appium/support/node_modules/axios/lib/core/Axios.js +306 -0
  84. package/node_modules/@appium/support/node_modules/axios/lib/core/AxiosError.js +219 -0
  85. package/node_modules/@appium/support/node_modules/axios/lib/core/AxiosHeaders.js +474 -0
  86. package/node_modules/@appium/support/node_modules/axios/lib/core/InterceptorManager.js +171 -0
  87. package/node_modules/@appium/support/node_modules/axios/lib/core/README.md +8 -0
  88. package/node_modules/@appium/support/node_modules/axios/lib/core/buildFullPath.js +76 -0
  89. package/node_modules/@appium/support/node_modules/axios/lib/core/dispatchRequest.js +95 -0
  90. package/node_modules/@appium/support/node_modules/axios/lib/core/mergeConfig.js +174 -0
  91. package/node_modules/@appium/support/node_modules/axios/lib/core/methodList.js +17 -0
  92. package/node_modules/@appium/support/node_modules/axios/lib/core/setFormDataHeaders.js +27 -0
  93. package/node_modules/@appium/support/node_modules/axios/lib/core/settle.js +27 -0
  94. package/node_modules/@appium/support/node_modules/axios/lib/core/transformData.js +28 -0
  95. package/node_modules/@appium/support/node_modules/axios/lib/defaults/index.js +178 -0
  96. package/node_modules/@appium/support/node_modules/axios/lib/defaults/transitional.js +10 -0
  97. package/node_modules/@appium/support/node_modules/axios/lib/env/README.md +3 -0
  98. package/node_modules/@appium/support/node_modules/axios/lib/env/classes/FormData.js +2 -0
  99. package/node_modules/@appium/support/node_modules/axios/lib/env/data.js +1 -0
  100. package/node_modules/@appium/support/node_modules/axios/lib/helpers/AxiosTransformStream.js +156 -0
  101. package/node_modules/@appium/support/node_modules/axios/lib/helpers/AxiosURLSearchParams.js +59 -0
  102. package/node_modules/@appium/support/node_modules/axios/lib/helpers/Http2Sessions.js +121 -0
  103. package/node_modules/@appium/support/node_modules/axios/lib/helpers/HttpStatusCode.js +88 -0
  104. package/node_modules/@appium/support/node_modules/axios/lib/helpers/README.md +7 -0
  105. package/node_modules/@appium/support/node_modules/axios/lib/helpers/ZlibHeaderTransformStream.js +29 -0
  106. package/node_modules/@appium/support/node_modules/axios/lib/helpers/bind.js +14 -0
  107. package/node_modules/@appium/support/node_modules/axios/lib/helpers/buildURL.js +69 -0
  108. package/node_modules/@appium/support/node_modules/axios/lib/helpers/callbackify.js +18 -0
  109. package/node_modules/@appium/support/node_modules/axios/lib/helpers/combineURLs.js +23 -0
  110. package/node_modules/@appium/support/node_modules/axios/lib/helpers/composeSignals.js +68 -0
  111. package/node_modules/@appium/support/node_modules/axios/lib/helpers/cookies.js +64 -0
  112. package/node_modules/@appium/support/node_modules/axios/lib/helpers/deprecatedMethod.js +31 -0
  113. package/node_modules/@appium/support/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js +166 -0
  114. package/node_modules/@appium/support/node_modules/axios/lib/helpers/formDataToJSON.js +125 -0
  115. package/node_modules/@appium/support/node_modules/axios/lib/helpers/formDataToStream.js +119 -0
  116. package/node_modules/@appium/support/node_modules/axios/lib/helpers/fromDataURI.js +69 -0
  117. package/node_modules/@appium/support/node_modules/axios/lib/helpers/isAbsoluteURL.js +19 -0
  118. package/node_modules/@appium/support/node_modules/axios/lib/helpers/isAxiosError.js +14 -0
  119. package/node_modules/@appium/support/node_modules/axios/lib/helpers/isURLSameOrigin.js +16 -0
  120. package/node_modules/@appium/support/node_modules/axios/lib/helpers/normalizeURLForProtocolCheck.js +24 -0
  121. package/node_modules/@appium/support/node_modules/axios/lib/helpers/null.js +2 -0
  122. package/node_modules/@appium/support/node_modules/axios/lib/helpers/parseHeaders.js +71 -0
  123. package/node_modules/@appium/support/node_modules/axios/lib/helpers/parseProtocol.js +6 -0
  124. package/node_modules/@appium/support/node_modules/axios/lib/helpers/progressEventReducer.js +54 -0
  125. package/node_modules/@appium/support/node_modules/axios/lib/helpers/readBlob.js +15 -0
  126. package/node_modules/@appium/support/node_modules/axios/lib/helpers/resolveConfig.js +107 -0
  127. package/node_modules/@appium/support/node_modules/axios/lib/helpers/sanitizeHeaderValue.js +60 -0
  128. package/node_modules/@appium/support/node_modules/axios/lib/helpers/shouldBypassProxy.js +505 -0
  129. package/node_modules/@appium/support/node_modules/axios/lib/helpers/speedometer.js +55 -0
  130. package/node_modules/@appium/support/node_modules/axios/lib/helpers/spread.js +28 -0
  131. package/node_modules/@appium/support/node_modules/axios/lib/helpers/throttle.js +45 -0
  132. package/node_modules/@appium/support/node_modules/axios/lib/helpers/toFormData.js +279 -0
  133. package/node_modules/@appium/support/node_modules/axios/lib/helpers/toURLEncodedForm.js +19 -0
  134. package/node_modules/@appium/support/node_modules/axios/lib/helpers/trackStream.js +89 -0
  135. package/node_modules/@appium/support/node_modules/axios/lib/helpers/validator.js +112 -0
  136. package/node_modules/@appium/support/node_modules/axios/lib/platform/browser/classes/Blob.js +3 -0
  137. package/node_modules/@appium/support/node_modules/axios/lib/platform/browser/classes/FormData.js +3 -0
  138. package/node_modules/@appium/support/node_modules/axios/lib/platform/browser/classes/URLSearchParams.js +4 -0
  139. package/node_modules/@appium/support/node_modules/axios/lib/platform/browser/index.js +13 -0
  140. package/node_modules/@appium/support/node_modules/axios/lib/platform/common/utils.js +52 -0
  141. package/node_modules/@appium/support/node_modules/axios/lib/platform/index.js +7 -0
  142. package/node_modules/@appium/support/node_modules/axios/lib/platform/node/classes/Buffer.js +11 -0
  143. package/node_modules/@appium/support/node_modules/axios/lib/platform/node/classes/FormData.js +3 -0
  144. package/node_modules/@appium/support/node_modules/axios/lib/platform/node/classes/URLSearchParams.js +4 -0
  145. package/node_modules/@appium/support/node_modules/axios/lib/platform/node/index.js +37 -0
  146. package/node_modules/@appium/support/node_modules/axios/lib/utils.js +1150 -0
  147. package/node_modules/@appium/support/node_modules/axios/package.json +203 -0
  148. package/node_modules/@appium/support/package.json +6 -6
  149. package/node_modules/@appium/types/build/lib/commands/basedriver.d.ts +6 -4
  150. package/node_modules/@appium/types/build/lib/commands/basedriver.d.ts.map +1 -1
  151. package/node_modules/@appium/types/lib/commands/basedriver.ts +4 -4
  152. package/node_modules/@appium/types/package.json +2 -2
  153. package/node_modules/appium-xcode/CHANGELOG.md +7 -0
  154. package/node_modules/appium-xcode/package.json +4 -4
  155. package/node_modules/asyncbox/README.md +43 -0
  156. package/node_modules/asyncbox/build/cjs/lib/asyncfilter.d.ts +9 -0
  157. package/node_modules/asyncbox/build/cjs/lib/asyncfilter.d.ts.map +1 -0
  158. package/node_modules/asyncbox/build/cjs/lib/asyncfilter.js +35 -0
  159. package/node_modules/asyncbox/build/cjs/lib/asyncfilter.js.map +1 -0
  160. package/node_modules/asyncbox/build/cjs/lib/asyncmap.d.ts +9 -0
  161. package/node_modules/asyncbox/build/cjs/lib/asyncmap.d.ts.map +1 -0
  162. package/node_modules/asyncbox/build/cjs/lib/asyncmap.js +23 -0
  163. package/node_modules/asyncbox/build/cjs/lib/asyncmap.js.map +1 -0
  164. package/node_modules/asyncbox/build/cjs/lib/errors.d.ts +9 -0
  165. package/node_modules/asyncbox/build/cjs/lib/errors.d.ts.map +1 -0
  166. package/node_modules/asyncbox/build/cjs/lib/errors.js +20 -0
  167. package/node_modules/asyncbox/build/cjs/lib/errors.js.map +1 -0
  168. package/node_modules/asyncbox/build/cjs/lib/index.d.ts +12 -0
  169. package/node_modules/asyncbox/build/cjs/lib/index.d.ts.map +1 -0
  170. package/node_modules/asyncbox/build/cjs/lib/index.js +24 -0
  171. package/node_modules/asyncbox/build/cjs/lib/index.js.map +1 -0
  172. package/node_modules/asyncbox/build/cjs/lib/limit-function.d.ts +3 -0
  173. package/node_modules/asyncbox/build/cjs/lib/limit-function.d.ts.map +1 -0
  174. package/node_modules/asyncbox/build/cjs/lib/limit-function.js +15 -0
  175. package/node_modules/asyncbox/build/cjs/lib/limit-function.js.map +1 -0
  176. package/node_modules/asyncbox/build/cjs/lib/lock.d.ts +74 -0
  177. package/node_modules/asyncbox/build/cjs/lib/lock.d.ts.map +1 -0
  178. package/node_modules/asyncbox/build/cjs/lib/lock.js +295 -0
  179. package/node_modules/asyncbox/build/cjs/lib/lock.js.map +1 -0
  180. package/node_modules/asyncbox/build/cjs/lib/long-sleep.d.ts +15 -0
  181. package/node_modules/asyncbox/build/cjs/lib/long-sleep.d.ts.map +1 -0
  182. package/node_modules/asyncbox/build/cjs/lib/long-sleep.js +36 -0
  183. package/node_modules/asyncbox/build/cjs/lib/long-sleep.js.map +1 -0
  184. package/node_modules/asyncbox/build/cjs/lib/retry.d.ts +17 -0
  185. package/node_modules/asyncbox/build/cjs/lib/retry.d.ts.map +1 -0
  186. package/node_modules/asyncbox/build/cjs/lib/retry.js +57 -0
  187. package/node_modules/asyncbox/build/cjs/lib/retry.js.map +1 -0
  188. package/node_modules/asyncbox/build/cjs/lib/sleep.d.ts +20 -0
  189. package/node_modules/asyncbox/build/cjs/lib/sleep.d.ts.map +1 -0
  190. package/node_modules/asyncbox/build/cjs/lib/sleep.js +61 -0
  191. package/node_modules/asyncbox/build/cjs/lib/sleep.js.map +1 -0
  192. package/node_modules/asyncbox/build/cjs/lib/wait-for-condition.d.ts +18 -0
  193. package/node_modules/asyncbox/build/cjs/lib/wait-for-condition.d.ts.map +1 -0
  194. package/node_modules/asyncbox/build/cjs/lib/wait-for-condition.js +51 -0
  195. package/node_modules/asyncbox/build/cjs/lib/wait-for-condition.js.map +1 -0
  196. package/node_modules/asyncbox/build/cjs/lib/with-timeout.d.ts +16 -0
  197. package/node_modules/asyncbox/build/cjs/lib/with-timeout.d.ts.map +1 -0
  198. package/node_modules/asyncbox/build/cjs/lib/with-timeout.js +45 -0
  199. package/node_modules/asyncbox/build/cjs/lib/with-timeout.js.map +1 -0
  200. package/node_modules/asyncbox/build/esm/lib/asyncfilter.d.ts +9 -0
  201. package/node_modules/asyncbox/build/esm/lib/asyncfilter.d.ts.map +1 -0
  202. package/node_modules/asyncbox/build/esm/lib/asyncfilter.js +32 -0
  203. package/node_modules/asyncbox/build/esm/lib/asyncfilter.js.map +1 -0
  204. package/node_modules/asyncbox/build/esm/lib/asyncmap.d.ts +9 -0
  205. package/node_modules/asyncbox/build/esm/lib/asyncmap.d.ts.map +1 -0
  206. package/node_modules/asyncbox/build/esm/lib/asyncmap.js +20 -0
  207. package/node_modules/asyncbox/build/esm/lib/asyncmap.js.map +1 -0
  208. package/node_modules/asyncbox/build/esm/lib/errors.d.ts +9 -0
  209. package/node_modules/asyncbox/build/esm/lib/errors.d.ts.map +1 -0
  210. package/node_modules/asyncbox/build/esm/lib/errors.js +15 -0
  211. package/node_modules/asyncbox/build/esm/lib/errors.js.map +1 -0
  212. package/node_modules/asyncbox/build/esm/lib/index.d.ts +12 -0
  213. package/node_modules/asyncbox/build/esm/lib/index.d.ts.map +1 -0
  214. package/node_modules/asyncbox/build/esm/lib/index.js +10 -0
  215. package/node_modules/asyncbox/build/esm/lib/index.js.map +1 -0
  216. package/node_modules/asyncbox/build/esm/lib/limit-function.d.ts +3 -0
  217. package/node_modules/asyncbox/build/esm/lib/limit-function.d.ts.map +1 -0
  218. package/node_modules/asyncbox/build/esm/lib/limit-function.js +12 -0
  219. package/node_modules/asyncbox/build/esm/lib/limit-function.js.map +1 -0
  220. package/node_modules/asyncbox/build/esm/lib/lock.d.ts +74 -0
  221. package/node_modules/asyncbox/build/esm/lib/lock.d.ts.map +1 -0
  222. package/node_modules/asyncbox/build/esm/lib/lock.js +291 -0
  223. package/node_modules/asyncbox/build/esm/lib/lock.js.map +1 -0
  224. package/node_modules/asyncbox/build/esm/lib/long-sleep.d.ts +15 -0
  225. package/node_modules/asyncbox/build/esm/lib/long-sleep.d.ts.map +1 -0
  226. package/node_modules/asyncbox/build/esm/lib/long-sleep.js +33 -0
  227. package/node_modules/asyncbox/build/esm/lib/long-sleep.js.map +1 -0
  228. package/node_modules/asyncbox/build/esm/lib/retry.d.ts +17 -0
  229. package/node_modules/asyncbox/build/esm/lib/retry.d.ts.map +1 -0
  230. package/node_modules/asyncbox/build/esm/lib/retry.js +53 -0
  231. package/node_modules/asyncbox/build/esm/lib/retry.js.map +1 -0
  232. package/node_modules/asyncbox/build/esm/lib/sleep.d.ts +20 -0
  233. package/node_modules/asyncbox/build/esm/lib/sleep.d.ts.map +1 -0
  234. package/node_modules/asyncbox/build/esm/lib/sleep.js +58 -0
  235. package/node_modules/asyncbox/build/esm/lib/sleep.js.map +1 -0
  236. package/node_modules/asyncbox/build/esm/lib/wait-for-condition.d.ts +18 -0
  237. package/node_modules/asyncbox/build/esm/lib/wait-for-condition.d.ts.map +1 -0
  238. package/node_modules/asyncbox/build/esm/lib/wait-for-condition.js +48 -0
  239. package/node_modules/asyncbox/build/esm/lib/wait-for-condition.js.map +1 -0
  240. package/node_modules/asyncbox/build/esm/lib/with-timeout.d.ts +16 -0
  241. package/node_modules/asyncbox/build/esm/lib/with-timeout.d.ts.map +1 -0
  242. package/node_modules/asyncbox/build/esm/lib/with-timeout.js +42 -0
  243. package/node_modules/asyncbox/build/esm/lib/with-timeout.js.map +1 -0
  244. package/node_modules/asyncbox/lib/asyncfilter.ts +38 -0
  245. package/node_modules/asyncbox/lib/asyncmap.ts +29 -0
  246. package/node_modules/asyncbox/lib/errors.ts +15 -0
  247. package/node_modules/asyncbox/lib/index.ts +21 -0
  248. package/node_modules/asyncbox/lib/limit-function.ts +18 -0
  249. package/node_modules/asyncbox/lib/lock.ts +360 -0
  250. package/node_modules/asyncbox/lib/long-sleep.ts +38 -0
  251. package/node_modules/asyncbox/lib/retry.ts +61 -0
  252. package/node_modules/asyncbox/lib/sleep.ts +79 -0
  253. package/node_modules/asyncbox/lib/wait-for-condition.ts +52 -0
  254. package/node_modules/asyncbox/lib/with-timeout.ts +43 -0
  255. package/node_modules/asyncbox/package.json +8 -8
  256. package/node_modules/axios/README.md +41 -106
  257. package/node_modules/axios/dist/axios.js +931 -278
  258. package/node_modules/axios/dist/axios.min.js +2 -2
  259. package/node_modules/axios/dist/axios.min.js.map +1 -1
  260. package/node_modules/axios/dist/browser/axios.cjs +948 -268
  261. package/node_modules/axios/dist/esm/axios.js +948 -268
  262. package/node_modules/axios/dist/esm/axios.min.js +2 -2
  263. package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
  264. package/node_modules/axios/dist/node/axios.cjs +925 -242
  265. package/node_modules/axios/index.d.cts +20 -1
  266. package/node_modules/axios/index.d.ts +18 -1
  267. package/node_modules/axios/lib/adapters/fetch.js +73 -20
  268. package/node_modules/axios/lib/adapters/http.js +145 -26
  269. package/node_modules/axios/lib/adapters/xhr.js +120 -13
  270. package/node_modules/axios/lib/core/Axios.js +67 -12
  271. package/node_modules/axios/lib/core/AxiosError.js +59 -0
  272. package/node_modules/axios/lib/core/AxiosHeaders.js +17 -4
  273. package/node_modules/axios/lib/core/InterceptorManager.js +13 -2
  274. package/node_modules/axios/lib/core/assertParamsAcyclic.js +49 -0
  275. package/node_modules/axios/lib/core/createMultipartBody.js +37 -0
  276. package/node_modules/axios/lib/core/dispatchRequest.js +20 -0
  277. package/node_modules/axios/lib/core/mergeConfig.js +183 -120
  278. package/node_modules/axios/lib/defaults/transitional.js +1 -0
  279. package/node_modules/axios/lib/env/data.js +1 -1
  280. package/node_modules/axios/lib/helpers/AxiosTransformStream.js +11 -2
  281. package/node_modules/axios/lib/helpers/Http2Sessions.js +2 -1
  282. package/node_modules/axios/lib/helpers/composeSignals.js +6 -3
  283. package/node_modules/axios/lib/helpers/cookies.js +30 -6
  284. package/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js +34 -7
  285. package/node_modules/axios/lib/helpers/formDataToBlob.js +113 -0
  286. package/node_modules/axios/lib/helpers/formDataToJSON.js +25 -1
  287. package/node_modules/axios/lib/helpers/fromDataURI.js +8 -2
  288. package/node_modules/axios/lib/helpers/isURLSameOrigin.js +4 -9
  289. package/node_modules/axios/lib/helpers/parseHeaders.js +2 -1
  290. package/node_modules/axios/lib/helpers/parseProtocol.js +1 -1
  291. package/node_modules/axios/lib/helpers/resolveConfig.js +16 -3
  292. package/node_modules/axios/lib/helpers/shouldBypassProxy.js +16 -1
  293. package/node_modules/axios/lib/utils.js +61 -10
  294. package/node_modules/axios/package.json +1 -2
  295. package/node_modules/bare-url/README.md +4 -0
  296. package/node_modules/bare-url/index.d.ts +3 -0
  297. package/node_modules/bare-url/index.js +42 -18
  298. package/node_modules/bare-url/lib/errors.js +4 -0
  299. package/node_modules/bare-url/package.json +1 -1
  300. package/node_modules/bare-url/prebuilds/android-arm/bare-url.bare +0 -0
  301. package/node_modules/bare-url/prebuilds/android-arm64/bare-url.bare +0 -0
  302. package/node_modules/bare-url/prebuilds/android-ia32/bare-url.bare +0 -0
  303. package/node_modules/bare-url/prebuilds/android-x64/bare-url.bare +0 -0
  304. package/node_modules/bare-url/prebuilds/darwin-arm64/bare-url.bare +0 -0
  305. package/node_modules/bare-url/prebuilds/darwin-x64/bare-url.bare +0 -0
  306. package/node_modules/bare-url/prebuilds/ios-arm64/bare-url.bare +0 -0
  307. package/node_modules/bare-url/prebuilds/ios-arm64-simulator/bare-url.bare +0 -0
  308. package/node_modules/bare-url/prebuilds/ios-x64-simulator/bare-url.bare +0 -0
  309. package/node_modules/bare-url/prebuilds/linux-arm64/bare-url.bare +0 -0
  310. package/node_modules/bare-url/prebuilds/linux-x64/bare-url.bare +0 -0
  311. package/node_modules/bare-url/prebuilds/win32-arm64/bare-url.bare +0 -0
  312. package/node_modules/bare-url/prebuilds/win32-x64/bare-url.bare +0 -0
  313. package/node_modules/follow-redirects/README.md +27 -1
  314. package/node_modules/follow-redirects/index.js +1 -5
  315. package/node_modules/follow-redirects/package.json +1 -1
  316. package/node_modules/shell-quote/README.md +37 -4
  317. package/node_modules/shell-quote/package.json +10 -6
  318. package/node_modules/shell-quote/parse.d.ts +1 -1
  319. package/node_modules/shell-quote/parse.js +63 -11
  320. package/node_modules/shell-quote/quote.d.ts +2 -1
  321. package/node_modules/shell-quote/quote.js +23 -3
  322. package/node_modules/uuid/package.json +17 -17
  323. package/package.json +6 -7
  324. package/scripts/setup-accessibility.mjs +175 -0
  325. package/node_modules/async-lock/AUTHORS +0 -21
  326. package/node_modules/async-lock/History.md +0 -132
  327. package/node_modules/async-lock/LICENSE +0 -22
  328. package/node_modules/async-lock/README.md +0 -177
  329. package/node_modules/async-lock/index.js +0 -2
  330. package/node_modules/async-lock/lib/index.js +0 -312
  331. package/node_modules/async-lock/package.json +0 -48
  332. package/node_modules/asyncbox/build/cjs/lib/asyncbox.d.ts +0 -103
  333. package/node_modules/asyncbox/build/cjs/lib/asyncbox.d.ts.map +0 -1
  334. package/node_modules/asyncbox/build/cjs/lib/asyncbox.js +0 -311
  335. package/node_modules/asyncbox/build/cjs/lib/asyncbox.js.map +0 -1
  336. package/node_modules/asyncbox/build/esm/lib/asyncbox.d.ts +0 -103
  337. package/node_modules/asyncbox/build/esm/lib/asyncbox.d.ts.map +0 -1
  338. package/node_modules/asyncbox/build/esm/lib/asyncbox.js +0 -298
  339. package/node_modules/asyncbox/build/esm/lib/asyncbox.js.map +0 -1
  340. package/node_modules/asyncbox/lib/asyncbox.ts +0 -382
  341. package/node_modules/shell-quote/.nycrc +0 -14
  342. package/node_modules/shell-quote/eslint.config.mjs +0 -29
  343. package/node_modules/shell-quote/security.md +0 -11
  344. package/node_modules/shell-quote/test/comment.js +0 -16
  345. package/node_modules/shell-quote/test/env.js +0 -52
  346. package/node_modules/shell-quote/test/env_fn.js +0 -21
  347. package/node_modules/shell-quote/test/op.js +0 -102
  348. package/node_modules/shell-quote/test/parse.js +0 -149
  349. package/node_modules/shell-quote/test/quote.js +0 -145
  350. package/node_modules/shell-quote/test/set.js +0 -31
@@ -0,0 +1,780 @@
1
+ /*
2
+ * Licensed under the Apache License, Version 2.0 (the "License");
3
+ * you may not use this file except in compliance with the License.
4
+ * See the NOTICE file distributed with this work for additional
5
+ * information regarding copyright ownership.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ #import "AMWindowUtils.h"
18
+
19
+ #import <AppKit/AppKit.h>
20
+ #import <ApplicationServices/ApplicationServices.h>
21
+
22
+ #import "AMGeometryUtils.h"
23
+ #import "AMScreenUtils.h"
24
+ #import "AMSnapshotUtils.h"
25
+ #import "AMXCTAccessibility.h"
26
+ #import "XCUIApplication+AMHelpers.h"
27
+ #import "XCUIElementQuery+AMHelpers.h"
28
+
29
+ NSString *const AMWindowErrorDomain = @"AMWindowErrorDomain";
30
+ NSString *const AMWindowStateNormal = @"normal";
31
+ NSString *const AMWindowStateMinimized = @"minimized";
32
+ NSString *const AMWindowStateMaximized = @"maximized";
33
+ NSString *const AMWindowStateFullscreen = @"fullscreen";
34
+
35
+ static const NSTimeInterval AM_WINDOW_STATE_TIMEOUT = 3.0;
36
+ static NSString *const AM_GEOMETRY_ACCESS_DENIED_MESSAGE = @"Changing the window geometry requires the Accessibility API. "
37
+ @"Grant the Accessibility permission to the WebDriverAgentRunner app and restart it";
38
+ static NSString *const AM_MINIMIZE_BUTTON_ID = @"_XCUI:MinimizeWindow";
39
+ static NSString *const AM_FULLSCREEN_BUTTON_ID = @"_XCUI:FullScreenWindow";
40
+ static NSString *const AM_DOCK_BUNDLE_ID = @"com.apple.dock";
41
+ static NSString *const AM_MINIMIZED_DOCK_ITEM_SUBROLE = @"AXMinimizedWindowDockItem";
42
+
43
+ static NSString *const AM_KEY_TITLE = @"title";
44
+ static NSString *const AM_KEY_RECT = @"rect";
45
+ static NSString *const AM_KEY_MAIN = @"main";
46
+ static NSString *const AM_KEY_FOCUSED = @"focused";
47
+ static NSString *const AM_KEY_MINIMIZED = @"minimized";
48
+ static NSString *const AM_KEY_FULLSCREEN = @"fullscreen";
49
+
50
+ static BOOL gUsesUnprivilegedRoutes = YES;
51
+
52
+ static void AMAssignError(NSError **error, NSError *value)
53
+ {
54
+ if (NULL != error) {
55
+ *error = value;
56
+ }
57
+ }
58
+
59
+ // The display with the biggest intersection with the rect. Falls back to the main one
60
+ static AMScreenProperties *_Nullable AMDisplayForRect(CGRect rect)
61
+ {
62
+ AMScreenProperties *result = nil;
63
+ CGFloat maxArea = 0;
64
+ for (AMScreenProperties *screen in AMListScreens()) {
65
+ CGRect intersection = CGRectIntersection(screen.bounds, rect);
66
+ CGFloat area = CGRectIsNull(intersection) ? 0 : intersection.size.width * intersection.size.height;
67
+ if (area > maxArea) {
68
+ maxArea = area;
69
+ result = screen;
70
+ }
71
+ }
72
+ if (nil == result) {
73
+ for (AMScreenProperties *screen in AMListScreens()) {
74
+ if (screen.isMain) {
75
+ return screen;
76
+ }
77
+ }
78
+ }
79
+ return result;
80
+ }
81
+
82
+ static id _Nullable AMCopyAXAttribute(AXUIElementRef element, CFStringRef name)
83
+ {
84
+ CFTypeRef value = NULL;
85
+ if (kAXErrorSuccess != AXUIElementCopyAttributeValue(element, name, &value) || NULL == value) {
86
+ return nil;
87
+ }
88
+ return CFBridgingRelease(value);
89
+ }
90
+
91
+ static NSNumber *_Nullable AMAXBool(AXUIElementRef element, CFStringRef name)
92
+ {
93
+ id value = AMCopyAXAttribute(element, name);
94
+ return [value isKindOfClass:NSNumber.class] ? value : nil;
95
+ }
96
+
97
+ static BOOL AMAXSetBool(AXUIElementRef element, CFStringRef name, BOOL value)
98
+ {
99
+ return kAXErrorSuccess == AXUIElementSetAttributeValue(element, name, value ? kCFBooleanTrue : kCFBooleanFalse);
100
+ }
101
+
102
+ static BOOL AMAXIsSettable(AXUIElementRef element, CFStringRef name)
103
+ {
104
+ Boolean settable = false;
105
+ return kAXErrorSuccess == AXUIElementIsAttributeSettable(element, name, &settable) && settable;
106
+ }
107
+
108
+ static BOOL AMAXSetGeometry(AXUIElementRef element, CFStringRef name, AXValueType type, const void *geometry)
109
+ {
110
+ AXValueRef value = AXValueCreate(type, geometry);
111
+ if (NULL == value) {
112
+ return NO;
113
+ }
114
+ AXError err = AXUIElementSetAttributeValue(element, name, value);
115
+ CFRelease(value);
116
+ return kAXErrorSuccess == err;
117
+ }
118
+
119
+ static BOOL AMAXReadRect(AXUIElementRef element, CGRect *rect)
120
+ {
121
+ CGPoint origin = CGPointZero;
122
+ CGSize size = CGSizeZero;
123
+ id position = AMCopyAXAttribute(element, kAXPositionAttribute);
124
+ id dimensions = AMCopyAXAttribute(element, kAXSizeAttribute);
125
+ if (nil == position || nil == dimensions
126
+ || !AXValueGetValue((__bridge AXValueRef)position, kAXValueTypeCGPoint, &origin)
127
+ || !AXValueGetValue((__bridge AXValueRef)dimensions, kAXValueTypeCGSize, &size)) {
128
+ return NO;
129
+ }
130
+ *rect = CGRectMake(origin.x, origin.y, size.width, size.height);
131
+ return YES;
132
+ }
133
+
134
+ static BOOL AMWaitUntil(BOOL (^condition)(void))
135
+ {
136
+ NSDate *deadline = [NSDate dateWithTimeIntervalSinceNow:AM_WINDOW_STATE_TIMEOUT];
137
+ while (!condition()) {
138
+ if ([deadline timeIntervalSinceNow] <= 0) {
139
+ return NO;
140
+ }
141
+ [NSThread sleepForTimeInterval:0.1];
142
+ }
143
+ return YES;
144
+ }
145
+
146
+ static CGPoint AMPointFromAXDict(NSDictionary *dict)
147
+ {
148
+ return CGPointMake([dict[@"X"] doubleValue], [dict[@"Y"] doubleValue]);
149
+ }
150
+
151
+ static CGSize AMSizeFromAXDict(NSDictionary *dict)
152
+ {
153
+ return CGSizeMake([dict[@"Width"] doubleValue], [dict[@"Height"] doubleValue]);
154
+ }
155
+
156
+ /**
157
+ Identifies a window by its XCTest accessibility element. Minimized windows have no
158
+ XCUIElement, because they are not a part of the element hierarchy.
159
+ */
160
+ @interface AMWindowHandle : NSObject
161
+ @property (nonatomic, nullable) XCUIElement *element;
162
+ @property (nonatomic, nullable) id accessibilityElement;
163
+ @property (nonatomic, copy, nullable) NSString *fallbackTitle;
164
+ @property (nonatomic) CGRect fallbackFrame;
165
+
166
+ /** Takes the ownership of the AX element. Used if XCTest accessibility elements are not available */
167
+ - (void)adoptAXElement:(AXUIElementRef CF_RELEASES_ARGUMENT)ref;
168
+ /** The AX element is owned by the handle. NULL if the Accessibility permission is not granted */
169
+ - (nullable AXUIElementRef)axElement;
170
+ @end
171
+
172
+ @implementation AMWindowHandle {
173
+ AXUIElementRef _axElement;
174
+ }
175
+
176
+ - (void)adoptAXElement:(AXUIElementRef CF_RELEASES_ARGUMENT)ref
177
+ {
178
+ if (NULL != _axElement) {
179
+ CFRelease(_axElement);
180
+ }
181
+ _axElement = ref;
182
+ }
183
+
184
+ - (nullable AXUIElementRef)axElement
185
+ {
186
+ if (NULL == _axElement && nil != self.accessibilityElement) {
187
+ _axElement = [AMSnapshotUtils createAXElementWithAccessibilityElement:self.accessibilityElement];
188
+ }
189
+ return _axElement;
190
+ }
191
+
192
+ - (void)dealloc
193
+ {
194
+ if (NULL != _axElement) {
195
+ CFRelease(_axElement);
196
+ }
197
+ }
198
+
199
+ @end
200
+
201
+ /**
202
+ Reads the window attributes (title, rect, main, focused, minimized, fullscreen). XCTest accessibility
203
+ is used first, because it does not need the Accessibility permission. Returns nil if the window cannot be read.
204
+ */
205
+ static NSDictionary<NSString *, id> *_Nullable AMReadWindow(AMWindowHandle *handle)
206
+ {
207
+ NSMutableDictionary<NSString *, id> *result = [NSMutableDictionary dictionary];
208
+ if (gUsesUnprivilegedRoutes && nil != handle.accessibilityElement) {
209
+ NSDictionary *attrs = [AMXCTAccessibility attributes:@[@"AXTitle", @"AXPosition", @"AXSize", @"AXMinimized",
210
+ @"AXFullScreen", @"AXMain", @"AXFocused"]
211
+ ofElement:handle.accessibilityElement];
212
+ if (attrs.count > 0) {
213
+ if ([attrs[@"AXTitle"] isKindOfClass:NSString.class]) {
214
+ result[AM_KEY_TITLE] = attrs[@"AXTitle"];
215
+ }
216
+ if ([attrs[@"AXPosition"] isKindOfClass:NSDictionary.class] && [attrs[@"AXSize"] isKindOfClass:NSDictionary.class]) {
217
+ CGPoint origin = AMPointFromAXDict(attrs[@"AXPosition"]);
218
+ CGSize size = AMSizeFromAXDict(attrs[@"AXSize"]);
219
+ result[AM_KEY_RECT] = [NSValue valueWithRect:CGRectMake(origin.x, origin.y, size.width, size.height)];
220
+ }
221
+ NSDictionary *keys = @{AM_KEY_MINIMIZED: @"AXMinimized", AM_KEY_FULLSCREEN: @"AXFullScreen",
222
+ AM_KEY_MAIN: @"AXMain", AM_KEY_FOCUSED: @"AXFocused"};
223
+ for (NSString *key in keys) {
224
+ if ([attrs[keys[key]] isKindOfClass:NSNumber.class]) {
225
+ result[key] = attrs[keys[key]];
226
+ }
227
+ }
228
+ return result.copy;
229
+ }
230
+ }
231
+ AXUIElementRef ref = [handle axElement];
232
+ if (NULL == ref) {
233
+ return nil;
234
+ }
235
+ id title = AMCopyAXAttribute(ref, kAXTitleAttribute);
236
+ if ([title isKindOfClass:NSString.class]) {
237
+ result[AM_KEY_TITLE] = title;
238
+ }
239
+ CGRect rect;
240
+ if (AMAXReadRect(ref, &rect)) {
241
+ result[AM_KEY_RECT] = [NSValue valueWithRect:rect];
242
+ }
243
+ NSDictionary *keys = @{AM_KEY_MINIMIZED: (__bridge NSString *)kAXMinimizedAttribute, AM_KEY_FULLSCREEN: @"AXFullScreen",
244
+ AM_KEY_MAIN: (__bridge NSString *)kAXMainAttribute, AM_KEY_FOCUSED: (__bridge NSString *)kAXFocusedAttribute};
245
+ for (NSString *key in keys) {
246
+ NSNumber *value = AMAXBool(ref, (__bridge CFStringRef)keys[key]);
247
+ if (nil != value) {
248
+ result[key] = value;
249
+ }
250
+ }
251
+ return result.copy;
252
+ }
253
+
254
+ static BOOL AMWindowFlag(AMWindowHandle *handle, NSString *key)
255
+ {
256
+ return [AMReadWindow(handle)[key] boolValue];
257
+ }
258
+
259
+ static BOOL AMWaitForWindowFlag(AMWindowHandle *handle, NSString *key, BOOL expected)
260
+ {
261
+ return AMWaitUntil(^BOOL{ return AMWindowFlag(handle, key) == expected; });
262
+ }
263
+
264
+ @implementation AMWindowUtils
265
+
266
+ + (BOOL)usesUnprivilegedRoutes
267
+ {
268
+ return gUsesUnprivilegedRoutes;
269
+ }
270
+
271
+ + (void)setUsesUnprivilegedRoutes:(BOOL)value
272
+ {
273
+ gUsesUnprivilegedRoutes = value;
274
+ }
275
+
276
+ + (NSArray<XCUIElement *> *)windowsOfApplication:(XCUIApplication *)application
277
+ {
278
+ return [application.windows am_allMatches];
279
+ }
280
+
281
+ + (nullable AMWindowHandle *)handleWithWindow:(XCUIElement *)window
282
+ {
283
+ id<XCUIElementSnapshot> snapshot = [window snapshotWithError:nil];
284
+ if (nil == snapshot) {
285
+ return nil;
286
+ }
287
+ AMWindowHandle *handle = [AMWindowHandle new];
288
+ handle.element = window;
289
+ handle.accessibilityElement = [AMXCTAccessibility accessibilityElementWithSnapshot:snapshot];
290
+ handle.fallbackTitle = snapshot.title;
291
+ handle.fallbackFrame = snapshot.frame;
292
+ if (nil == handle.accessibilityElement) {
293
+ // XCTest accessibility elements are not available, so AX has to be used
294
+ [handle adoptAXElement:[AMSnapshotUtils createAXElementWithSnapshot:snapshot]];
295
+ }
296
+ return handle;
297
+ }
298
+
299
+ + (nullable XCUIElement *)mainWindowOfApplication:(XCUIApplication *)application
300
+ {
301
+ NSArray<XCUIElement *> *windows = [self windowsOfApplication:application];
302
+ XCUIElement *focused = nil;
303
+ for (XCUIElement *window in windows) {
304
+ AMWindowHandle *handle = [self handleWithWindow:window];
305
+ NSDictionary *attrs = nil == handle ? nil : AMReadWindow(handle);
306
+ if (nil == attrs) {
307
+ break;
308
+ }
309
+ if ([attrs[AM_KEY_MAIN] boolValue]) {
310
+ return window;
311
+ }
312
+ if ([attrs[AM_KEY_FOCUSED] boolValue] && nil == focused) {
313
+ focused = window;
314
+ }
315
+ }
316
+ return focused ?: windows.firstObject;
317
+ }
318
+
319
+ + (nullable NSDictionary<NSString *, id> *)infoForWindow:(XCUIElement *)window
320
+ {
321
+ AMWindowHandle *handle = [self handleWithWindow:window];
322
+ return nil == handle ? nil : [self infoForHandle:handle];
323
+ }
324
+
325
+ + (NSDictionary<NSString *, id> *)infoForHandle:(AMWindowHandle *)handle
326
+ {
327
+ NSDictionary *attrs = AMReadWindow(handle);
328
+ NSString *title = attrs[AM_KEY_TITLE] ?: handle.fallbackTitle;
329
+ CGRect frame = nil != attrs[AM_KEY_RECT] ? [attrs[AM_KEY_RECT] rectValue] : handle.fallbackFrame;
330
+ NSNumber *null = (NSNumber *)NSNull.null;
331
+ // Whether the window is movable/resizable can only be asked through the Accessibility API
332
+ AXUIElementRef ref = [handle axElement];
333
+ NSMutableDictionary<NSString *, id> *info = [NSMutableDictionary dictionaryWithDictionary:@{
334
+ @"title": title ?: @"",
335
+ @"isMain": attrs[AM_KEY_MAIN] ?: null,
336
+ @"isFocused": attrs[AM_KEY_FOCUSED] ?: null,
337
+ @"isMinimized": attrs[AM_KEY_MINIMIZED] ?: null,
338
+ @"isFullscreen": attrs[AM_KEY_FULLSCREEN] ?: null,
339
+ @"isMovable": NULL == ref ? null : @(AMAXIsSettable(ref, kAXPositionAttribute)),
340
+ @"isResizable": NULL == ref ? null : @(AMAXIsSettable(ref, kAXSizeAttribute)),
341
+ @"rect": AMCGRectToDict(frame),
342
+ }];
343
+ AMScreenProperties *display = AMDisplayForRect(frame);
344
+ info[@"displayId"] = nil == display ? NSNull.null : @(display.identifier);
345
+ return info.copy;
346
+ }
347
+
348
+ + (nullable NSDictionary<NSString *, id> *)adjustWindow:(XCUIElement *)window
349
+ inApplication:(XCUIApplication *)application
350
+ withArguments:(NSDictionary<NSString *, id> *)arguments
351
+ error:(NSError **)error
352
+ {
353
+ NSString *state = nil;
354
+ NSDictionary<NSString *, NSNumber *> *rect = nil;
355
+ AMScreenProperties *display = nil;
356
+ if (![self parseArguments:arguments state:&state rect:&rect display:&display error:error]) {
357
+ return nil;
358
+ }
359
+ id<XCUIElementSnapshot> snapshot = [window snapshotWithError:nil];
360
+ if (nil == snapshot) {
361
+ AMAssignError(error, [self windowErrorWithCode:AMWindowErrorNotFound
362
+ format:@"The window is not available anymore. It might have been closed or minimized"]);
363
+ return nil;
364
+ }
365
+ if (XCUIElementTypeWindow != snapshot.elementType) {
366
+ AMAssignError(error, [self windowErrorWithCode:AMWindowErrorInvalidArgument format:@"The element is not a window"]);
367
+ return nil;
368
+ }
369
+ AMWindowHandle *handle = [self handleWithWindow:window];
370
+ return [self adjustHandle:handle application:application state:state rect:rect display:display error:error];
371
+ }
372
+
373
+ + (nullable NSDictionary<NSString *, id> *)adjustMinimizedWindowOfApplication:(XCUIApplication *)application
374
+ withArguments:(NSDictionary<NSString *, id> *)arguments
375
+ error:(NSError **)error
376
+ {
377
+ NSString *state = nil;
378
+ NSDictionary<NSString *, NSNumber *> *rect = nil;
379
+ AMScreenProperties *display = nil;
380
+ if (![self parseArguments:arguments state:&state rect:&rect display:&display error:error]) {
381
+ return nil;
382
+ }
383
+ AMWindowHandle *handle = [self minimizedWindowsOfApplication:application].firstObject;
384
+ if (nil == handle) {
385
+ AMAssignError(error, [self windowErrorWithCode:AMWindowErrorNotFound format:@"The application has no minimized windows"]);
386
+ return nil;
387
+ }
388
+ return [self adjustHandle:handle application:application state:state rect:rect display:display error:error];
389
+ }
390
+
391
+ + (NSUInteger)minimizedWindowsCountOfApplication:(XCUIApplication *)application
392
+ {
393
+ return [self minimizedWindowsOfApplication:application].count;
394
+ }
395
+
396
+ #pragma mark - Private
397
+
398
+ + (NSError *)windowErrorWithCode:(AMWindowErrorCode)code format:(NSString *)format, ... NS_FORMAT_FUNCTION(2,3)
399
+ {
400
+ va_list args;
401
+ va_start(args, format);
402
+ NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
403
+ va_end(args);
404
+ return [NSError errorWithDomain:AMWindowErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey: message}];
405
+ }
406
+
407
+ // Validates the arguments and extracts the geometry, the state and the target display
408
+ + (BOOL)parseArguments:(NSDictionary<NSString *, id> *)arguments
409
+ state:(NSString * _Nullable *)outState
410
+ rect:(NSDictionary<NSString *, NSNumber *> * _Nullable *)outRect
411
+ display:(AMScreenProperties * _Nullable *)outDisplay
412
+ error:(NSError **)error
413
+ {
414
+ NSMutableDictionary<NSString *, NSNumber *> *rect = [NSMutableDictionary dictionary];
415
+ for (NSString *key in @[@"x", @"y", @"width", @"height"]) {
416
+ id value = arguments[key];
417
+ if (nil == value || [value isKindOfClass:NSNull.class]) {
418
+ continue;
419
+ }
420
+ if (![value isKindOfClass:NSNumber.class]
421
+ || (([key hasPrefix:@"w"] || [key hasPrefix:@"h"]) && [value doubleValue] <= 0)) {
422
+ AMAssignError(error, [self windowErrorWithCode:AMWindowErrorInvalidArgument
423
+ format:@"'%@' must be a valid number, got '%@'", key, value]);
424
+ return NO;
425
+ }
426
+ rect[key] = value;
427
+ }
428
+ id rawDisplayId = arguments[@"displayId"];
429
+ if (nil != rawDisplayId && ![rawDisplayId isKindOfClass:NSNull.class] && ![rawDisplayId isKindOfClass:NSNumber.class]) {
430
+ AMAssignError(error, [self windowErrorWithCode:AMWindowErrorInvalidArgument
431
+ format:@"'displayId' must be a number, got '%@'", rawDisplayId]);
432
+ return NO;
433
+ }
434
+ NSNumber *displayId = [rawDisplayId isKindOfClass:NSNumber.class] ? rawDisplayId : nil;
435
+ NSString *state = arguments[@"state"];
436
+ if ([state isKindOfClass:NSNull.class]) {
437
+ state = nil;
438
+ }
439
+ NSArray<NSString *> *states = @[AMWindowStateNormal, AMWindowStateMinimized, AMWindowStateMaximized, AMWindowStateFullscreen];
440
+ if (nil != state && ![states containsObject:state]) {
441
+ AMAssignError(error, [self windowErrorWithCode:AMWindowErrorInvalidArgument
442
+ format:@"'state' must be one of: %@. Got '%@'", [states componentsJoinedByString:@", "], state]);
443
+ return NO;
444
+ }
445
+ if (nil == state && 0 == rect.count && nil == displayId) {
446
+ AMAssignError(error, [self windowErrorWithCode:AMWindowErrorInvalidArgument
447
+ format:@"At least one of 'state', 'x', 'y', 'width', 'height' or 'displayId' must be provided"]);
448
+ return NO;
449
+ }
450
+ BOOL isGeometryFree = [state isEqualToString:AMWindowStateMinimized] || [state isEqualToString:AMWindowStateFullscreen];
451
+ if ((isGeometryFree && (rect.count > 0 || nil != displayId))
452
+ || ([state isEqualToString:AMWindowStateMaximized] && rect.count > 0)) {
453
+ AMAssignError(error, [self windowErrorWithCode:AMWindowErrorInvalidArgument
454
+ format:@"The '%@' state cannot be combined with the explicit window geometry", state]);
455
+ return NO;
456
+ }
457
+ AMScreenProperties *targetDisplay = nil;
458
+ if (nil != displayId) {
459
+ NSMutableArray<NSNumber *> *available = [NSMutableArray array];
460
+ for (AMScreenProperties *screen in AMListScreens()) {
461
+ [available addObject:@(screen.identifier)];
462
+ if (screen.identifier == displayId.longLongValue) {
463
+ targetDisplay = screen;
464
+ }
465
+ }
466
+ if (nil == targetDisplay) {
467
+ AMAssignError(error, [self windowErrorWithCode:AMWindowErrorInvalidArgument
468
+ format:@"The display '%@' is unknown. Available identifiers: %@",
469
+ displayId, [available componentsJoinedByString:@","]]);
470
+ return NO;
471
+ }
472
+ }
473
+ *outState = state;
474
+ *outRect = rect.copy;
475
+ *outDisplay = targetDisplay;
476
+ return YES;
477
+ }
478
+
479
+ // Minimized windows are not in the XCUIElement hierarchy, but the accessibility application keeps them
480
+ + (NSArray<AMWindowHandle *> *)minimizedWindowsOfApplication:(XCUIApplication *)application
481
+ {
482
+ NSMutableArray<AMWindowHandle *> *result = [NSMutableArray array];
483
+ if (gUsesUnprivilegedRoutes) {
484
+ id appElement = [AMXCTAccessibility accessibilityElementWithApplication:application];
485
+ NSArray *windows = [AMXCTAccessibility attributes:@[@"AXWindows"] ofElement:appElement][@"AXWindows"];
486
+ if ([windows isKindOfClass:NSArray.class]) {
487
+ for (id element in windows) {
488
+ AMWindowHandle *handle = [AMWindowHandle new];
489
+ handle.accessibilityElement = element;
490
+ if (AMWindowFlag(handle, AM_KEY_MINIMIZED)) {
491
+ [result addObject:handle];
492
+ }
493
+ }
494
+ return result.copy;
495
+ }
496
+ }
497
+ if (!AMSnapshotUtils.isAccessibilityTrusted) {
498
+ return @[];
499
+ }
500
+ NSRunningApplication *runningApp = [NSRunningApplication runningApplicationsWithBundleIdentifier:application.am_bundleID].firstObject;
501
+ if (nil == runningApp) {
502
+ return @[];
503
+ }
504
+ AXUIElementRef appRef = AXUIElementCreateApplication(runningApp.processIdentifier);
505
+ id windows = AMCopyAXAttribute(appRef, kAXWindowsAttribute);
506
+ CFRelease(appRef);
507
+ for (id window in [windows isKindOfClass:NSArray.class] ? windows : @[]) {
508
+ AMWindowHandle *handle = [AMWindowHandle new];
509
+ [handle adoptAXElement:(AXUIElementRef)CFRetain((__bridge CFTypeRef)window)];
510
+ if (AMWindowFlag(handle, AM_KEY_MINIMIZED)) {
511
+ [result addObject:handle];
512
+ }
513
+ }
514
+ return result.copy;
515
+ }
516
+
517
+ // The XCUIElement of the window, which is not available while the window is minimized
518
+ + (nullable XCUIElement *)elementOfHandle:(AMWindowHandle *)handle application:(XCUIApplication *)application
519
+ {
520
+ if (nil != handle.element && nil != [handle.element snapshotWithError:nil]) {
521
+ return handle.element;
522
+ }
523
+ if (nil == handle.accessibilityElement) {
524
+ return nil;
525
+ }
526
+ for (XCUIElement *window in [self windowsOfApplication:application]) {
527
+ id element = [AMXCTAccessibility accessibilityElementWithSnapshot:[window snapshotWithError:nil]];
528
+ if ([element isEqual:handle.accessibilityElement]) {
529
+ handle.element = window;
530
+ return window;
531
+ }
532
+ }
533
+ return nil;
534
+ }
535
+
536
+ // Presses the button of the window without moving the mouse
537
+ + (BOOL)pressButton:(NSString *)identifier ofHandle:(AMWindowHandle *)handle application:(XCUIApplication *)application
538
+ {
539
+ XCUIElement *window = [self elementOfHandle:handle application:application];
540
+ XCUIElement *button = [[window descendantsMatchingType:XCUIElementTypeButton] matchingIdentifier:identifier].firstMatch;
541
+ id element = nil == window || !button.exists
542
+ ? nil
543
+ : [AMXCTAccessibility accessibilityElementWithSnapshot:[button snapshotWithError:nil]];
544
+ return nil != element && [AMXCTAccessibility pressElement:element error:nil];
545
+ }
546
+
547
+ // Restores the window by its Dock item. It is only done if the item can be identified unambiguously
548
+ + (BOOL)restoreHandleThroughDock:(AMWindowHandle *)handle
549
+ {
550
+ NSString *title = AMReadWindow(handle)[AM_KEY_TITLE] ?: handle.fallbackTitle;
551
+ if (0 == title.length) {
552
+ return NO;
553
+ }
554
+ XCUIApplication *dock = [[XCUIApplication alloc] initWithBundleIdentifier:AM_DOCK_BUNDLE_ID];
555
+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"title == %@", title];
556
+ NSMutableArray<XCUIElement *> *candidates = [NSMutableArray array];
557
+ NSMutableArray *elements = [NSMutableArray array];
558
+ for (XCUIElement *item in [[dock descendantsMatchingType:XCUIElementTypeDockItem] matchingPredicate:predicate].allElementsBoundByIndex) {
559
+ id element = [AMXCTAccessibility accessibilityElementWithSnapshot:[item snapshotWithError:nil]];
560
+ NSDictionary *attrs = [AMXCTAccessibility attributes:@[@"AXSubrole"] ofElement:element];
561
+ if (nil != element && [attrs[@"AXSubrole"] isEqual:AM_MINIMIZED_DOCK_ITEM_SUBROLE]) {
562
+ [candidates addObject:item];
563
+ [elements addObject:element];
564
+ }
565
+ }
566
+ if (1 != candidates.count) {
567
+ // Another minimized window with the same title could be restored by mistake
568
+ return NO;
569
+ }
570
+ // An auto-hidden Dock item is not hittable, so it is pressed without the mouse
571
+ if (![AMXCTAccessibility pressElement:elements.firstObject error:nil]) {
572
+ if (!candidates.firstObject.hittable) {
573
+ return NO;
574
+ }
575
+ [candidates.firstObject click];
576
+ }
577
+ return AMWaitForWindowFlag(handle, AM_KEY_MINIMIZED, NO);
578
+ }
579
+
580
+ + (BOOL)minimizeHandle:(AMWindowHandle *)handle application:(XCUIApplication *)application
581
+ {
582
+ if (gUsesUnprivilegedRoutes
583
+ && [self pressButton:AM_MINIMIZE_BUTTON_ID ofHandle:handle application:application]
584
+ && AMWaitForWindowFlag(handle, AM_KEY_MINIMIZED, YES)) {
585
+ return YES;
586
+ }
587
+ AXUIElementRef ref = [handle axElement];
588
+ return NULL != ref
589
+ && AMAXSetBool(ref, kAXMinimizedAttribute, YES)
590
+ && AMWaitForWindowFlag(handle, AM_KEY_MINIMIZED, YES);
591
+ }
592
+
593
+ + (BOOL)restoreHandle:(AMWindowHandle *)handle
594
+ {
595
+ if (gUsesUnprivilegedRoutes && [self restoreHandleThroughDock:handle]) {
596
+ return YES;
597
+ }
598
+ AXUIElementRef ref = [handle axElement];
599
+ return NULL != ref
600
+ && AMAXSetBool(ref, kAXMinimizedAttribute, NO)
601
+ && AMWaitForWindowFlag(handle, AM_KEY_MINIMIZED, NO);
602
+ }
603
+
604
+ + (BOOL)enterFullscreenHandle:(AMWindowHandle *)handle application:(XCUIApplication *)application
605
+ {
606
+ if (gUsesUnprivilegedRoutes
607
+ && [self pressButton:AM_FULLSCREEN_BUTTON_ID ofHandle:handle application:application]
608
+ && AMWaitForWindowFlag(handle, AM_KEY_FULLSCREEN, YES)) {
609
+ return YES;
610
+ }
611
+ AXUIElementRef ref = [handle axElement];
612
+ return NULL != ref
613
+ && AMAXSetBool(ref, CFSTR("AXFullScreen"), YES)
614
+ && AMWaitForWindowFlag(handle, AM_KEY_FULLSCREEN, YES);
615
+ }
616
+
617
+ + (BOOL)focusHandle:(AMWindowHandle *)handle application:(XCUIApplication *)application
618
+ {
619
+ [application activate];
620
+ if (AMWaitForWindowFlag(handle, AM_KEY_FOCUSED, YES)) {
621
+ return YES;
622
+ }
623
+ AXUIElementRef ref = [handle axElement];
624
+ if (NULL == ref) {
625
+ return NO;
626
+ }
627
+ AXUIElementPerformAction(ref, kAXRaiseAction);
628
+ return AMWaitForWindowFlag(handle, AM_KEY_FOCUSED, YES);
629
+ }
630
+
631
+ + (BOOL)leaveFullscreenHandle:(AMWindowHandle *)handle application:(XCUIApplication *)application
632
+ {
633
+ if (gUsesUnprivilegedRoutes) {
634
+ // The window buttons are hidden in the fullscreen mode, so the standard shortcut is used.
635
+ // It toggles the focused window, so the shortcut is skipped if the target cannot be focused
636
+ if ([self focusHandle:handle application:application]) {
637
+ [application typeKey:@"f" modifierFlags:XCUIKeyModifierControl | XCUIKeyModifierCommand];
638
+ if (AMWaitForWindowFlag(handle, AM_KEY_FULLSCREEN, NO)) {
639
+ return YES;
640
+ }
641
+ }
642
+ }
643
+ AXUIElementRef ref = [handle axElement];
644
+ return NULL != ref
645
+ && AMAXSetBool(ref, CFSTR("AXFullScreen"), NO)
646
+ && AMWaitForWindowFlag(handle, AM_KEY_FULLSCREEN, NO);
647
+ }
648
+
649
+ // Applies the change and describes the result
650
+ + (nullable NSDictionary<NSString *, id> *)adjustHandle:(AMWindowHandle *)handle
651
+ application:(XCUIApplication *)application
652
+ state:(nullable NSString *)state
653
+ rect:(NSDictionary<NSString *, NSNumber *> *)rect
654
+ display:(nullable AMScreenProperties *)targetDisplay
655
+ error:(NSError **)error
656
+ {
657
+ NSDictionary *attrs = AMReadWindow(handle);
658
+ if (nil == attrs) {
659
+ AMAssignError(error, [self windowErrorWithCode:AMWindowErrorFailure
660
+ format:@"Cannot read the window state. The XCTest accessibility interface is not available. "
661
+ @"Grant the Accessibility permission to the WebDriverAgentRunner app and restart it"]);
662
+ return nil;
663
+ }
664
+
665
+ BOOL wantsMinimized = [state isEqualToString:AMWindowStateMinimized];
666
+ BOOL isMinimized = [attrs[AM_KEY_MINIMIZED] boolValue];
667
+ if (isMinimized && wantsMinimized) {
668
+ return [self infoForHandle:handle];
669
+ }
670
+ // Every other change needs a regular window
671
+ if (isMinimized && ![self restoreHandle:handle]) {
672
+ AMAssignError(error, [self windowErrorWithCode:AMWindowErrorFailure
673
+ format:@"The minimized window cannot be restored. Make sure there are no other minimized windows "
674
+ @"with the same title or grant the Accessibility permission to the WebDriverAgentRunner app"]);
675
+ return nil;
676
+ }
677
+ BOOL isFullscreen = [AMReadWindow(handle)[AM_KEY_FULLSCREEN] boolValue];
678
+ BOOL wantsFullscreen = [state isEqualToString:AMWindowStateFullscreen];
679
+ if (isFullscreen && !wantsFullscreen && ![self leaveFullscreenHandle:handle application:application]) {
680
+ AMAssignError(error, [self windowErrorWithCode:AMWindowErrorFailure
681
+ format:@"The window did not leave the fullscreen mode in %.0f seconds", AM_WINDOW_STATE_TIMEOUT]);
682
+ return nil;
683
+ }
684
+ if (wantsMinimized) {
685
+ if (![self minimizeHandle:handle application:application]) {
686
+ AMAssignError(error, [self windowErrorWithCode:AMWindowErrorFailure format:@"The window cannot be minimized"]);
687
+ return nil;
688
+ }
689
+ return [self infoForHandle:handle];
690
+ }
691
+ if (wantsFullscreen) {
692
+ if (!isFullscreen && ![self enterFullscreenHandle:handle application:application]) {
693
+ AMAssignError(error, [self windowErrorWithCode:AMWindowErrorFailure format:@"The window cannot be put into the fullscreen mode"]);
694
+ return nil;
695
+ }
696
+ return [self infoForHandle:handle];
697
+ }
698
+
699
+ if ([state isEqualToString:AMWindowStateMaximized] || rect.count > 0 || nil != targetDisplay) {
700
+ AXUIElementRef ref = [handle axElement];
701
+ if (NULL == ref) {
702
+ AMAssignError(error, [self windowErrorWithCode:AMWindowErrorFailure format:@"%@", AM_GEOMETRY_ACCESS_DENIED_MESSAGE]);
703
+ return nil;
704
+ }
705
+ if (![self applyGeometryToAXWindow:ref state:state rect:rect display:targetDisplay error:error]) {
706
+ return nil;
707
+ }
708
+ }
709
+ return [self infoForHandle:handle];
710
+ }
711
+
712
+ + (BOOL)applyGeometryToAXWindow:(AXUIElementRef)ref
713
+ state:(nullable NSString *)state
714
+ rect:(NSDictionary<NSString *, NSNumber *> *)rect
715
+ display:(nullable AMScreenProperties *)targetDisplay
716
+ error:(NSError **)error
717
+ {
718
+ CGRect current;
719
+ if (!AMAXReadRect(ref, &current)) {
720
+ AMAssignError(error, [self windowErrorWithCode:AMWindowErrorFailure format:@"Cannot read the current window rect"]);
721
+ return NO;
722
+ }
723
+ if ([state isEqualToString:AMWindowStateMaximized]) {
724
+ // Fills the visible area of the display, which is also deterministic when repeated
725
+ AMScreenProperties *display = targetDisplay ?: AMDisplayForRect(current);
726
+ if (nil == display) {
727
+ AMAssignError(error, [self windowErrorWithCode:AMWindowErrorFailure format:@"Cannot determine the display to maximize the window on"]);
728
+ return NO;
729
+ }
730
+ CGRect visible = display.visibleBounds;
731
+ return [self applyRect:@{@"x": @(visible.origin.x), @"y": @(visible.origin.y),
732
+ @"width": @(visible.size.width), @"height": @(visible.size.height)}
733
+ current:current ref:ref display:nil error:error];
734
+ }
735
+ return [self applyRect:rect current:current ref:ref display:targetDisplay error:error];
736
+ }
737
+
738
+ // Coordinates are global unless a display is given
739
+ + (BOOL)applyRect:(NSDictionary<NSString *, NSNumber *> *)rect
740
+ current:(CGRect)current
741
+ ref:(AXUIElementRef)ref
742
+ display:(nullable AMScreenProperties *)targetDisplay
743
+ error:(NSError **)error
744
+ {
745
+ CGSize size = CGSizeMake(nil != rect[@"width"] ? rect[@"width"].doubleValue : current.size.width,
746
+ nil != rect[@"height"] ? rect[@"height"].doubleValue : current.size.height);
747
+ CGPoint origin = current.origin;
748
+ if (nil != targetDisplay) {
749
+ CGRect bounds = targetDisplay.bounds;
750
+ AMScreenProperties *sourceDisplay = AMDisplayForRect(current);
751
+ CGPoint sourceOrigin = nil == sourceDisplay ? CGPointZero : sourceDisplay.bounds.origin;
752
+ // x/y are relative to the target display; the relative position is kept if they are omitted
753
+ origin.x = bounds.origin.x + (nil != rect[@"x"] ? rect[@"x"].doubleValue : current.origin.x - sourceOrigin.x);
754
+ origin.y = bounds.origin.y + (nil != rect[@"y"] ? rect[@"y"].doubleValue : current.origin.y - sourceOrigin.y);
755
+ // Keep the window within the display
756
+ origin.x = MAX(bounds.origin.x, MIN(origin.x, CGRectGetMaxX(bounds) - size.width));
757
+ origin.y = MAX(bounds.origin.y, MIN(origin.y, CGRectGetMaxY(bounds) - size.height));
758
+ } else {
759
+ origin.x = nil != rect[@"x"] ? rect[@"x"].doubleValue : origin.x;
760
+ origin.y = nil != rect[@"y"] ? rect[@"y"].doubleValue : origin.y;
761
+ }
762
+
763
+ BOOL moves = !CGPointEqualToPoint(origin, current.origin);
764
+ BOOL resizes = !CGSizeEqualToSize(size, current.size);
765
+ if (moves && !AMAXSetGeometry(ref, kAXPositionAttribute, kAXValueTypeCGPoint, &origin)) {
766
+ AMAssignError(error, [self windowErrorWithCode:AMWindowErrorFailure format:@"The window cannot be moved"]);
767
+ return NO;
768
+ }
769
+ if (resizes && !AMAXSetGeometry(ref, kAXSizeAttribute, kAXValueTypeCGSize, &size)) {
770
+ AMAssignError(error, [self windowErrorWithCode:AMWindowErrorFailure format:@"The window cannot be resized"]);
771
+ return NO;
772
+ }
773
+ // The size may have been adjusted for the new display, which can shift the window
774
+ if (moves && resizes) {
775
+ AMAXSetGeometry(ref, kAXPositionAttribute, kAXValueTypeCGPoint, &origin);
776
+ }
777
+ return YES;
778
+ }
779
+
780
+ @end