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
package/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ ## [4.5.1](https://github.com/appium/appium-mac2-driver/compare/v4.5.0...v4.5.1) (2026-10-27)
2
+
3
+ ### Bug Fixes
4
+
5
+ * **wda:** check opts.reqBasePath instead of caps.reqBasePath in startSession ([#434](https://github.com/appium/appium-mac2-driver/issues/434)) ([8d0d827](https://github.com/appium/appium-mac2-driver/commit/8d0d827325f544c9a7093878fdf704e00ebb5a4f))
6
+
7
+ ### Code Refactoring
8
+
9
+ * use AsyncLock from asyncbox instead of async-lock ([#430](https://github.com/appium/appium-mac2-driver/issues/430)) ([a795822](https://github.com/appium/appium-mac2-driver/commit/a795822013578cfbe2390a58d4967779ed50cf0e))
10
+
11
+ ## [4.5.0](https://github.com/appium/appium-mac2-driver/compare/v4.4.0...v4.5.0) (2026-10-19)
12
+
13
+ ### Features
14
+
15
+ * add window listing and adjustment extension methods ([#428](https://github.com/appium/appium-mac2-driver/issues/428)) ([42759b6](https://github.com/appium/appium-mac2-driver/commit/42759b603ade35832369b22f790ebe083bff2f3d))
16
+
1
17
  ## [4.4.0](https://github.com/appium/appium-mac2-driver/compare/v4.3.6...v4.4.0) (2026-10-11)
2
18
 
3
19
  ### Features
@@ -0,0 +1,427 @@
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 <XCTest/XCTest.h>
18
+
19
+ #import "AMIntegrationTestCase.h"
20
+ #import "AMScreenUtils.h"
21
+ #import "AMSnapshotUtils.h"
22
+ #import "AMWindowUtils.h"
23
+ #import "AMXCTAccessibility.h"
24
+ #import "FBTestMacros.h"
25
+
26
+ static const CGFloat AM_GEOMETRY_ACCURACY = 1.0;
27
+
28
+ /**
29
+ The windows are inspected and changed through the XCTest accessibility interface, which does not
30
+ need the Accessibility permission, except for the window geometry. AMWindowAccessibilityApiTests
31
+ runs the same tests using the Accessibility API only.
32
+ */
33
+ @interface AMWindowTests : AMIntegrationTestCase
34
+ - (BOOL)usesUnprivilegedRoutes;
35
+ @end
36
+
37
+ @implementation AMWindowTests
38
+
39
+ - (BOOL)usesUnprivilegedRoutes
40
+ {
41
+ return YES;
42
+ }
43
+
44
+ - (void)setUp
45
+ {
46
+ [super setUp];
47
+ AMWindowUtils.usesUnprivilegedRoutes = [self usesUnprivilegedRoutes];
48
+ [self launchApplication];
49
+ }
50
+
51
+ - (void)tearDown
52
+ {
53
+ // Leave the window in a regular state for the other tests
54
+ NSDictionary *normal = @{@"state": AMWindowStateNormal};
55
+ [AMWindowUtils adjustMinimizedWindowOfApplication:self.testedApplication withArguments:normal error:nil];
56
+ XCUIElement *window = [AMWindowUtils mainWindowOfApplication:self.testedApplication];
57
+ if (nil != window) {
58
+ [AMWindowUtils adjustWindow:window inApplication:self.testedApplication withArguments:normal error:nil];
59
+ }
60
+ AMWindowUtils.usesUnprivilegedRoutes = YES;
61
+ [super tearDown];
62
+ }
63
+
64
+ // Changing states needs the XCTest accessibility interface, or the Accessibility permission if it is not used
65
+ - (void)skipUnlessStateRoutesAvailable
66
+ {
67
+ if ([self usesUnprivilegedRoutes]) {
68
+ XCTSkipUnless(AMXCTAccessibility.isAvailable, @"The XCTest accessibility interface is not available");
69
+ } else {
70
+ [self skipUnlessAccessibilityTrusted];
71
+ }
72
+ }
73
+
74
+ #pragma mark - Helpers
75
+
76
+ - (XCUIElement *)mainWindow
77
+ {
78
+ XCUIElement *window = [AMWindowUtils mainWindowOfApplication:self.testedApplication];
79
+ XCTAssertNotNil(window);
80
+ return window;
81
+ }
82
+
83
+ - (AMScreenProperties *)mainDisplay
84
+ {
85
+ for (AMScreenProperties *screen in AMListScreens()) {
86
+ if (screen.isMain) {
87
+ return screen;
88
+ }
89
+ }
90
+ XCTFail(@"No main display is reported");
91
+ return nil;
92
+ }
93
+
94
+ - (NSDictionary<NSString *, id> *)adjustWindow:(XCUIElement *)window arguments:(NSDictionary<NSString *, id> *)arguments
95
+ {
96
+ NSError *error = nil;
97
+ NSDictionary *result = [AMWindowUtils adjustWindow:window inApplication:self.testedApplication withArguments:arguments error:&error];
98
+ XCTAssertNotNil(result, @"The call has failed: %@", error);
99
+ return result;
100
+ }
101
+
102
+ - (NSDictionary<NSString *, id> *)adjustMainWindowWithArguments:(NSDictionary<NSString *, id> *)arguments
103
+ {
104
+ return [self adjustWindow:[self mainWindow] arguments:arguments];
105
+ }
106
+
107
+ - (void)assertInvalidArgumentWithMessage:(NSString *)fragment forArguments:(NSDictionary<NSString *, id> *)arguments
108
+ {
109
+ [self assertInvalidArgumentWithMessage:fragment forArguments:arguments window:[self mainWindow]];
110
+ }
111
+
112
+ - (void)assertInvalidArgumentWithMessage:(NSString *)fragment
113
+ forArguments:(NSDictionary<NSString *, id> *)arguments
114
+ window:(XCUIElement *)window
115
+ {
116
+ NSError *error = nil;
117
+ XCTAssertNil([AMWindowUtils adjustWindow:window inApplication:self.testedApplication withArguments:arguments error:&error]);
118
+ XCTAssertEqualObjects(error.domain, AMWindowErrorDomain);
119
+ XCTAssertEqual(error.code, AMWindowErrorInvalidArgument);
120
+ XCTAssertTrue([error.localizedDescription containsString:fragment], @"Unexpected message: %@", error.localizedDescription);
121
+ }
122
+
123
+ - (CGRect)rectFromInfo:(NSDictionary<NSString *, id> *)info
124
+ {
125
+ NSDictionary<NSString *, NSNumber *> *rect = info[@"rect"];
126
+ return CGRectMake(rect[@"x"].doubleValue, rect[@"y"].doubleValue, rect[@"width"].doubleValue, rect[@"height"].doubleValue);
127
+ }
128
+
129
+ - (void)assertRect:(CGRect)actual equalsRect:(CGRect)expected
130
+ {
131
+ XCTAssertEqualWithAccuracy(actual.origin.x, expected.origin.x, AM_GEOMETRY_ACCURACY);
132
+ XCTAssertEqualWithAccuracy(actual.origin.y, expected.origin.y, AM_GEOMETRY_ACCURACY);
133
+ XCTAssertEqualWithAccuracy(actual.size.width, expected.size.width, AM_GEOMETRY_ACCURACY);
134
+ XCTAssertEqualWithAccuracy(actual.size.height, expected.size.height, AM_GEOMETRY_ACCURACY);
135
+ }
136
+
137
+ - (void)assertRect:(CGRect)rect isWithinRect:(CGRect)container
138
+ {
139
+ XCTAssertTrue(CGRectContainsRect(CGRectInset(container, -AM_GEOMETRY_ACCURACY, -AM_GEOMETRY_ACCURACY), rect),
140
+ @"%@ is not within %@", NSStringFromRect(rect), NSStringFromRect(container));
141
+ }
142
+
143
+ #pragma mark - Displays
144
+
145
+ - (void)testDisplaysReportTheirBounds
146
+ {
147
+ AMScreenProperties *display = [self mainDisplay];
148
+ XCTAssertTrue(display.bounds.size.width > 0 && display.bounds.size.height > 0);
149
+ // The main display is the origin of the global coordinate space
150
+ XCTAssertEqualWithAccuracy(display.bounds.origin.x, 0, AM_GEOMETRY_ACCURACY);
151
+ XCTAssertEqualWithAccuracy(display.bounds.origin.y, 0, AM_GEOMETRY_ACCURACY);
152
+ // The menu bar and the Dock are excluded
153
+ [self assertRect:display.visibleBounds isWithinRect:display.bounds];
154
+ }
155
+
156
+ #pragma mark - Listing
157
+
158
+ - (void)testWindowsAreListed
159
+ {
160
+ NSArray<XCUIElement *> *windows = [AMWindowUtils windowsOfApplication:self.testedApplication];
161
+ XCTAssertTrue(windows.count > 0);
162
+ NSDictionary *info = [AMWindowUtils infoForWindow:windows.firstObject];
163
+ XCTAssertNotNil(info[@"title"]);
164
+ CGRect rect = [self rectFromInfo:info];
165
+ XCTAssertTrue(rect.size.width > 0 && rect.size.height > 0);
166
+ XCTAssertEqualObjects(info[@"displayId"], @([self mainDisplay].identifier));
167
+ }
168
+
169
+ - (void)testWindowTraitsAreListed
170
+ {
171
+ [self skipUnlessStateRoutesAvailable];
172
+
173
+ NSDictionary *info = [AMWindowUtils infoForWindow:[self mainWindow]];
174
+ for (NSString *trait in @[@"isMain", @"isFocused", @"isMinimized", @"isFullscreen"]) {
175
+ XCTAssertTrue([info[trait] isKindOfClass:NSNumber.class], @"'%@' must be a boolean: %@", trait, info);
176
+ }
177
+ XCTAssertTrue([info[@"isMain"] boolValue]);
178
+ XCTAssertFalse([info[@"isMinimized"] boolValue]);
179
+ XCTAssertFalse([info[@"isFullscreen"] boolValue]);
180
+ // These can only be asked through the Accessibility API
181
+ if (AMSnapshotUtils.isAccessibilityTrusted) {
182
+ XCTAssertTrue([info[@"isMovable"] boolValue]);
183
+ XCTAssertTrue([info[@"isResizable"] boolValue]);
184
+ } else {
185
+ XCTAssertEqualObjects(info[@"isMovable"], NSNull.null);
186
+ XCTAssertEqualObjects(info[@"isResizable"], NSNull.null);
187
+ }
188
+ }
189
+
190
+ #pragma mark - Argument validation
191
+
192
+ - (void)testAdjustingRequiresAtLeastOneArgument
193
+ {
194
+ [self assertInvalidArgumentWithMessage:@"At least one of" forArguments:@{}];
195
+ [self assertInvalidArgumentWithMessage:@"At least one of" forArguments:@{@"windowId": @"foo"}];
196
+ }
197
+
198
+ - (void)testAdjustingRejectsUnknownState
199
+ {
200
+ [self assertInvalidArgumentWithMessage:@"'state' must be one of" forArguments:@{@"state": @"foo"}];
201
+ }
202
+
203
+ - (void)testAdjustingRejectsInvalidGeometry
204
+ {
205
+ [self assertInvalidArgumentWithMessage:@"'width'" forArguments:@{@"width": @0}];
206
+ [self assertInvalidArgumentWithMessage:@"'height'" forArguments:@{@"height": @(-10)}];
207
+ [self assertInvalidArgumentWithMessage:@"'x'" forArguments:@{@"x": @"foo"}];
208
+ }
209
+
210
+ - (void)testAdjustingRejectsStateCombinedWithGeometry
211
+ {
212
+ [self assertInvalidArgumentWithMessage:@"cannot be combined"
213
+ forArguments:@{@"state": AMWindowStateMinimized, @"x": @10}];
214
+ [self assertInvalidArgumentWithMessage:@"cannot be combined"
215
+ forArguments:@{@"state": AMWindowStateFullscreen, @"displayId": @([self mainDisplay].identifier)}];
216
+ [self assertInvalidArgumentWithMessage:@"cannot be combined"
217
+ forArguments:@{@"state": AMWindowStateMaximized, @"width": @500}];
218
+ }
219
+
220
+ - (void)testAdjustingRejectsUnknownDisplay
221
+ {
222
+ [self assertInvalidArgumentWithMessage:@"is unknown" forArguments:@{@"displayId": @999999}];
223
+ }
224
+
225
+ - (void)testAdjustingRejectsMalformedDisplayId
226
+ {
227
+ [self assertInvalidArgumentWithMessage:@"'displayId' must be a number" forArguments:@{@"displayId": @{}}];
228
+ [self assertInvalidArgumentWithMessage:@"'displayId' must be a number" forArguments:@{@"displayId": @"foo"}];
229
+ }
230
+
231
+ - (void)testAdjustingRejectsNonWindowElements
232
+ {
233
+ XCUIElement *button = self.testedApplication.buttons.firstMatch;
234
+ XCTAssertTrue([button waitForExistenceWithTimeout:5.0]);
235
+ [self assertInvalidArgumentWithMessage:@"is not a window" forArguments:@{@"x": @10} window:button];
236
+ }
237
+
238
+ #pragma mark - Adjusting (requires the Accessibility permission)
239
+
240
+ - (void)testWindowCanBeResizedAndMoved
241
+ {
242
+ [self skipUnlessAccessibilityTrusted];
243
+
244
+ XCUIElement *window = [self mainWindow];
245
+ CGRect original = [self rectFromInfo:[AMWindowUtils infoForWindow:window]];
246
+ CGRect expected = CGRectMake(original.origin.x + 30, original.origin.y + 30,
247
+ original.size.width + 20, original.size.height + 20);
248
+ NSDictionary *result = [self adjustWindow:window arguments:@{
249
+ @"x": @(expected.origin.x),
250
+ @"y": @(expected.origin.y),
251
+ @"width": @(expected.size.width),
252
+ @"height": @(expected.size.height),
253
+ }];
254
+ [self assertRect:[self rectFromInfo:result] equalsRect:expected];
255
+ // The change is observable from the outside
256
+ [self assertRect:[self rectFromInfo:[AMWindowUtils infoForWindow:window]] equalsRect:expected];
257
+ [self assertRect:window.frame equalsRect:expected];
258
+ }
259
+
260
+ - (void)testOmittedGeometryIsKept
261
+ {
262
+ [self skipUnlessAccessibilityTrusted];
263
+
264
+ XCUIElement *window = [self mainWindow];
265
+ CGRect original = [self rectFromInfo:[AMWindowUtils infoForWindow:window]];
266
+ NSDictionary *result = [self adjustWindow:window arguments:@{@"width": @(original.size.width + 20)}];
267
+ [self assertRect:[self rectFromInfo:result]
268
+ equalsRect:CGRectMake(original.origin.x, original.origin.y, original.size.width + 20, original.size.height)];
269
+ }
270
+
271
+ - (void)testWindowCanBeMovedToDisplay
272
+ {
273
+ [self skipUnlessAccessibilityTrusted];
274
+
275
+ AMScreenProperties *display = [self mainDisplay];
276
+ NSDictionary *result = [self adjustMainWindowWithArguments:@{
277
+ @"displayId": @(display.identifier),
278
+ @"x": @80,
279
+ @"y": @120,
280
+ }];
281
+ CGRect rect = [self rectFromInfo:result];
282
+ // Coordinates are relative to the display
283
+ XCTAssertEqualWithAccuracy(rect.origin.x, display.bounds.origin.x + 80, AM_GEOMETRY_ACCURACY);
284
+ XCTAssertEqualWithAccuracy(rect.origin.y, display.bounds.origin.y + 120, AM_GEOMETRY_ACCURACY);
285
+ XCTAssertEqualObjects(result[@"displayId"], @(display.identifier));
286
+ }
287
+
288
+ - (void)testWindowIsKeptWithinDisplay
289
+ {
290
+ [self skipUnlessAccessibilityTrusted];
291
+
292
+ AMScreenProperties *display = [self mainDisplay];
293
+ NSDictionary *result = [self adjustMainWindowWithArguments:@{
294
+ @"displayId": @(display.identifier),
295
+ @"x": @(display.bounds.size.width * 10),
296
+ @"y": @(display.bounds.size.height * 10),
297
+ }];
298
+ [self assertRect:[self rectFromInfo:result] isWithinRect:display.bounds];
299
+ }
300
+
301
+ - (void)testWindowCanBeMaximized
302
+ {
303
+ [self skipUnlessAccessibilityTrusted];
304
+
305
+ AMScreenProperties *display = [self mainDisplay];
306
+ CGRect original = [self rectFromInfo:[AMWindowUtils infoForWindow:[self mainWindow]]];
307
+ CGRect rect = [self rectFromInfo:[self adjustMainWindowWithArguments:@{@"state": AMWindowStateMaximized}]];
308
+ XCTAssertTrue(rect.size.width * rect.size.height >= original.size.width * original.size.height,
309
+ @"%@ must not be smaller than %@", NSStringFromRect(rect), NSStringFromRect(original));
310
+ // Fills the display, except the menu bar and the Dock
311
+ [self assertRect:rect isWithinRect:display.bounds];
312
+ XCTAssertTrue(rect.size.width >= display.visibleBounds.size.width - AM_GEOMETRY_ACCURACY);
313
+
314
+ // Maximizing is idempotent
315
+ NSDictionary *repeated = [self adjustMainWindowWithArguments:@{@"state": AMWindowStateMaximized}];
316
+ [self assertRect:[self rectFromInfo:repeated] equalsRect:rect];
317
+ }
318
+
319
+ - (void)testWindowCanBeMinimizedAndRestored
320
+ {
321
+ [self skipUnlessStateRoutesAvailable];
322
+
323
+ XCUIApplication *application = self.testedApplication;
324
+ CGRect original = [self rectFromInfo:[AMWindowUtils infoForWindow:[self mainWindow]]];
325
+ NSDictionary *minimized = [self adjustMainWindowWithArguments:@{@"state": AMWindowStateMinimized}];
326
+ XCTAssertEqualObjects(minimized[@"isMinimized"], @YES);
327
+ FBAssertWaitTillBecomesTrue(1 == [AMWindowUtils minimizedWindowsCountOfApplication:application]);
328
+
329
+ // Minimized windows are not a part of the element hierarchy
330
+ NSError *error = nil;
331
+ NSDictionary *restored = [AMWindowUtils adjustMinimizedWindowOfApplication:application
332
+ withArguments:@{@"state": AMWindowStateNormal}
333
+ error:&error];
334
+ XCTAssertNotNil(restored, @"The call has failed: %@", error);
335
+ XCTAssertEqualObjects(restored[@"isMinimized"], @NO);
336
+ [self assertRect:[self rectFromInfo:restored] equalsRect:original];
337
+ FBAssertWaitTillBecomesTrue(0 == [AMWindowUtils minimizedWindowsCountOfApplication:application]);
338
+ FBAssertWaitTillBecomesTrue(nil != [AMWindowUtils mainWindowOfApplication:application]);
339
+ }
340
+
341
+ - (void)testMinimizedWindowIsRestoredByGeometryChange
342
+ {
343
+ [self skipUnlessAccessibilityTrusted];
344
+
345
+ XCUIApplication *application = self.testedApplication;
346
+ CGRect original = [self rectFromInfo:[AMWindowUtils infoForWindow:[self mainWindow]]];
347
+ [self adjustMainWindowWithArguments:@{@"state": AMWindowStateMinimized}];
348
+ FBAssertWaitTillBecomesTrue(1 == [AMWindowUtils minimizedWindowsCountOfApplication:application]);
349
+
350
+ NSError *error = nil;
351
+ NSDictionary *result = [AMWindowUtils adjustMinimizedWindowOfApplication:application
352
+ withArguments:@{@"width": @(original.size.width + 10)}
353
+ error:&error];
354
+ XCTAssertNotNil(result, @"The call has failed: %@", error);
355
+ XCTAssertEqualObjects(result[@"isMinimized"], @NO);
356
+ XCTAssertEqualWithAccuracy([self rectFromInfo:result].size.width, original.size.width + 10, AM_GEOMETRY_ACCURACY);
357
+ }
358
+
359
+ - (void)testRestoringRequiresMinimizedWindow
360
+ {
361
+ [self skipUnlessStateRoutesAvailable];
362
+
363
+ NSError *error = nil;
364
+ XCTAssertNil([AMWindowUtils adjustMinimizedWindowOfApplication:self.testedApplication
365
+ withArguments:@{@"state": AMWindowStateNormal}
366
+ error:&error]);
367
+ XCTAssertEqual(error.code, AMWindowErrorNotFound);
368
+ }
369
+
370
+ - (void)testGeometryRequiresAccessibilityPermission
371
+ {
372
+ XCTSkipIf(AMSnapshotUtils.isAccessibilityTrusted, @"The process is trusted for the Accessibility API");
373
+
374
+ NSError *error = nil;
375
+ XCTAssertNil([AMWindowUtils adjustWindow:[self mainWindow]
376
+ inApplication:self.testedApplication
377
+ withArguments:@{@"width": @600}
378
+ error:&error]);
379
+ XCTAssertEqual(error.code, AMWindowErrorFailure);
380
+ XCTAssertTrue([error.localizedDescription containsString:@"Accessibility"], @"%@", error.localizedDescription);
381
+ }
382
+
383
+ - (void)testWindowCanEnterAndLeaveFullscreen
384
+ {
385
+ [self skipUnlessStateRoutesAvailable];
386
+
387
+ XCUIElement *window = [self mainWindow];
388
+ NSDictionary *fullscreen = [self adjustWindow:window arguments:@{@"state": AMWindowStateFullscreen}];
389
+ XCTAssertEqualObjects(fullscreen[@"isFullscreen"], @YES);
390
+
391
+ NSDictionary *restored = [self adjustWindow:window arguments:@{@"state": AMWindowStateNormal}];
392
+ XCTAssertEqualObjects(restored[@"isFullscreen"], @NO);
393
+ }
394
+
395
+ - (void)testFullscreenWindowCanBeMinimized
396
+ {
397
+ [self skipUnlessStateRoutesAvailable];
398
+
399
+ XCUIApplication *application = self.testedApplication;
400
+ XCUIElement *window = [self mainWindow];
401
+ NSDictionary *fullscreen = [self adjustWindow:window arguments:@{@"state": AMWindowStateFullscreen}];
402
+ XCTAssertEqualObjects(fullscreen[@"isFullscreen"], @YES);
403
+
404
+ NSDictionary *minimized = [self adjustWindow:window arguments:@{@"state": AMWindowStateMinimized}];
405
+ XCTAssertEqualObjects(minimized[@"isMinimized"], @YES);
406
+ XCTAssertEqualObjects(minimized[@"isFullscreen"], @NO);
407
+
408
+ NSError *error = nil;
409
+ XCTAssertNotNil([AMWindowUtils adjustMinimizedWindowOfApplication:application
410
+ withArguments:@{@"state": AMWindowStateNormal}
411
+ error:&error], @"The call has failed: %@", error);
412
+ FBAssertWaitTillBecomesTrue(nil != [AMWindowUtils mainWindowOfApplication:application]);
413
+ }
414
+
415
+ @end
416
+
417
+ @interface AMWindowAccessibilityApiTests : AMWindowTests
418
+ @end
419
+
420
+ @implementation AMWindowAccessibilityApiTests
421
+
422
+ - (BOOL)usesUnprivilegedRoutes
423
+ {
424
+ return NO;
425
+ }
426
+
427
+ @end
@@ -9,6 +9,8 @@
9
9
 
10
10
  #import "AMWindowCommands.h"
11
11
 
12
+ #import "AMWindowUtils.h"
13
+ #import "FBElementCache.h"
12
14
  #import "FBRoute.h"
13
15
  #import "FBRouteRequest.h"
14
16
  #import "FBSession.h"
@@ -23,6 +25,8 @@
23
25
  [[FBRoute POST:@"/window/maximize"] respondWithTarget:self action:@selector(handleMaximizeWindow:)],
24
26
  [[FBRoute POST:@"/window/fullscreen"] respondWithTarget:self action:@selector(handleFullscreenWindow:)],
25
27
  [[FBRoute POST:@"/window/minimize"] respondWithTarget:self action:@selector(handleMinimizeWindow:)],
28
+ [[FBRoute GET:@"/wda/windows"] respondWithTarget:self action:@selector(handleListWindows:)],
29
+ [[FBRoute POST:@"/wda/window/adjust"] respondWithTarget:self action:@selector(handleAdjustWindow:)],
26
30
  ];
27
31
  }
28
32
 
@@ -49,6 +53,65 @@
49
53
  errorMessage:[NSString stringWithFormat:@"%@ window cannot be minimized because the corresponding button is not available", request.session.currentApplication.description]];
50
54
  }
51
55
 
56
+ + (id<FBResponsePayload>)handleListWindows:(FBRouteRequest *)request
57
+ {
58
+ FBElementCache *cache = request.session.elementCache;
59
+ NSMutableArray *result = [NSMutableArray array];
60
+ for (XCUIElement *window in [AMWindowUtils windowsOfApplication:request.session.currentApplication]) {
61
+ NSDictionary *info = [AMWindowUtils infoForWindow:window];
62
+ if (nil != info) {
63
+ [result addObject:[self info:info withWindowId:[cache storeElement:window]]];
64
+ }
65
+ }
66
+ return FBResponseWithObject(result.copy);
67
+ }
68
+
69
+ + (id<FBResponsePayload>)handleAdjustWindow:(FBRouteRequest *)request
70
+ {
71
+ FBElementCache *cache = request.session.elementCache;
72
+ XCUIApplication *application = request.session.currentApplication;
73
+ id rawWindowId = request.arguments[@"windowId"];
74
+ if (nil != rawWindowId && ![rawWindowId isKindOfClass:NSNull.class] && ![rawWindowId isKindOfClass:NSString.class]) {
75
+ return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:
76
+ [NSString stringWithFormat:@"'windowId' must be a string, got '%@'", rawWindowId]
77
+ traceback:nil]);
78
+ }
79
+ NSString *windowId = [rawWindowId isKindOfClass:NSString.class] ? rawWindowId : nil;
80
+ XCUIElement *window = nil != windowId
81
+ ? [cache elementForUUID:windowId]
82
+ : [AMWindowUtils mainWindowOfApplication:application];
83
+ NSError *error = nil;
84
+ NSDictionary *info = nil;
85
+ if (nil != window) {
86
+ info = [AMWindowUtils adjustWindow:window inApplication:application withArguments:request.arguments error:&error];
87
+ } else if (nil == windowId) {
88
+ // There are no visible windows, so a minimized one could be restored
89
+ info = [AMWindowUtils adjustMinimizedWindowOfApplication:application withArguments:request.arguments error:&error];
90
+ }
91
+ NSString *resultWindowId = nil != info && nil != window ? (windowId ?: [cache storeElement:window]) : nil;
92
+ if (nil == info) {
93
+ NSString *message = error.localizedDescription;
94
+ switch (error.code) {
95
+ case AMWindowErrorInvalidArgument:
96
+ return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:message traceback:nil]);
97
+ case AMWindowErrorNotFound:
98
+ return FBResponseWithStatus([FBCommandStatus noSuchWindowErrorWithMessage:message traceback:nil]);
99
+ default:
100
+ return FBResponseWithStatus([FBCommandStatus unknownErrorWithMessage:message traceback:nil]);
101
+ }
102
+ }
103
+ return FBResponseWithObject([self info:info withWindowId:resultWindowId]);
104
+ }
105
+
106
+ #pragma mark - Helpers
107
+
108
+ + (NSDictionary<NSString *, id> *)info:(NSDictionary<NSString *, id> *)info withWindowId:(nullable NSString *)windowId
109
+ {
110
+ NSMutableDictionary *result = [info mutableCopy];
111
+ result[@"windowId"] = windowId ?: NSNull.null;
112
+ return result.copy;
113
+ }
114
+
52
115
  + (id<FBResponsePayload>)performClickWithButtonId:(NSString *)buttonId
53
116
  request:(FBRouteRequest *)request
54
117
  errorMessage:(NSString *)errorMessage
@@ -9,6 +9,7 @@
9
9
 
10
10
  #import "FBDebugCommands.h"
11
11
 
12
+ #import "AMGeometryUtils.h"
12
13
  #import "AMScreenUtils.h"
13
14
  #import "FBRouteRequest.h"
14
15
  #import "FBSession.h"
@@ -65,6 +66,7 @@ static NSString *const SOURCE_FORMAT_DESCRIPTION = @"description";
65
66
  result[[NSString stringWithFormat:@"%lld", screenInfo.identifier]] = @{
66
67
  @"id": @(screenInfo.identifier),
67
68
  @"isMain": @(screenInfo.isMain),
69
+ @"rect": AMCGRectToDict(screenInfo.bounds),
68
70
  };
69
71
  }
70
72
  return FBResponseWithObject(result.copy);
@@ -37,6 +37,9 @@ NS_ASSUME_NONNULL_BEGIN
37
37
  + (instancetype)noSuchElementErrorWithMessage:(nullable NSString *)message
38
38
  traceback:(nullable NSString *)traceback;
39
39
 
40
+ + (instancetype)noSuchWindowErrorWithMessage:(nullable NSString *)message
41
+ traceback:(nullable NSString *)traceback;
42
+
40
43
  + (instancetype)invalidElementStateErrorWithMessage:(nullable NSString *)message
41
44
  traceback:(nullable NSString *)traceback;
42
45
 
@@ -21,6 +21,10 @@ static NSString *const FB_NO_SUCH_ELEMENT_ERROR = @"no such element";
21
21
  static const HTTPStatusCode FB_NO_SUCH_ELEMENT_ERROR_CODE = kHTTPStatusCodeNotFound;
22
22
  static NSString *const FB_NO_SUCH_ELEMENT_MSG = @"An element could not be located on the page using the given search parameters";
23
23
 
24
+ static NSString *const FB_NO_SUCH_WINDOW_ERROR = @"no such window";
25
+ static const HTTPStatusCode FB_NO_SUCH_WINDOW_ERROR_CODE = kHTTPStatusCodeNotFound;
26
+ static NSString *const FB_NO_SUCH_WINDOW_MSG = @"A window could not be found. It might have been closed";
27
+
24
28
  static NSString *const FB_INVALID_ELEMENT_STATE_ERROR = @"invalid element state";
25
29
  static const HTTPStatusCode FB_INVALID_ELEMENT_STATE_ERROR_CODE = kHTTPStatusCodeBadRequest;
26
30
  static NSString *const FB_INVALID_ELEMENT_STATE_MSG = @"An element command could not be completed because the element is in an invalid state (e.g. attempting to click a disabled element)";
@@ -155,6 +159,15 @@ static NSString *const FB_NO_SUCH_DRIVER_MSG = @"A session is either terminated
155
159
  traceback:traceback];
156
160
  }
157
161
 
162
+ + (instancetype)noSuchWindowErrorWithMessage:(NSString *)message
163
+ traceback:(NSString *)traceback
164
+ {
165
+ return [[FBCommandStatus alloc] initWithError:FB_NO_SUCH_WINDOW_ERROR
166
+ statusCode:FB_NO_SUCH_WINDOW_ERROR_CODE
167
+ message:message ?: FB_NO_SUCH_WINDOW_MSG
168
+ traceback:traceback];
169
+ }
170
+
158
171
  + (instancetype)invalidElementStateErrorWithMessage:(NSString *)message
159
172
  traceback:(NSString *)traceback
160
173
  {
@@ -24,6 +24,10 @@ NS_ASSUME_NONNULL_BEGIN
24
24
  @property (readonly, nonatomic) BOOL isMain;
25
25
  /** The integer identifier of a screen */
26
26
  @property (readonly, nonatomic) long long identifier;
27
+ /** The display bounds in the global coordinate space with the top-left origin (same as XCUIElement frames) */
28
+ @property (readonly, nonatomic) CGRect bounds;
29
+ /** Same as bounds, but without the menu bar and the Dock */
30
+ @property (readonly, nonatomic) CGRect visibleBounds;
27
31
 
28
32
  @end
29
33
 
@@ -18,6 +18,29 @@
18
18
 
19
19
  @implementation AMScreenProperties
20
20
 
21
+ - (CGRect)bounds
22
+ {
23
+ return CGDisplayBounds((CGDirectDisplayID)self.identifier);
24
+ }
25
+
26
+ - (CGRect)visibleBounds
27
+ {
28
+ CGRect bounds = self.bounds;
29
+ for (NSScreen *screen in NSScreen.screens) {
30
+ if ([screen.deviceDescription[@"NSScreenNumber"] longLongValue] != self.identifier) {
31
+ continue;
32
+ }
33
+ // NSScreen uses the bottom-left origin of the primary screen, which is the first one
34
+ CGFloat primaryHeight = NSScreen.screens.firstObject.frame.size.height;
35
+ CGRect visible = screen.visibleFrame;
36
+ return CGRectMake(visible.origin.x,
37
+ primaryHeight - CGRectGetMaxY(visible),
38
+ visible.size.width,
39
+ visible.size.height);
40
+ }
41
+ return bounds;
42
+ }
43
+
21
44
  - (instancetype)initWithIdentifier:(long long)identifier
22
45
  isMain:(BOOL)isMain
23
46
  {
@@ -14,6 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
+ #import <ApplicationServices/ApplicationServices.h>
17
18
  #import <XCTest/XCTest.h>
18
19
 
19
20
  NS_ASSUME_NONNULL_BEGIN
@@ -79,6 +80,23 @@ NS_ASSUME_NONNULL_BEGIN
79
80
  */
80
81
  + (nullable NSString *)domIdentifierWithSnapshot:(nullable id)snapshot;
81
82
 
83
+ /**
84
+ Creates an AX element for the given snapshot. The caller owns the result and must CFRelease it.
85
+
86
+ @param snapshot snapshot instance to create the AX element for
87
+ @return The AX element or NULL if this process lacks Accessibility permission or the element is unavailable
88
+ */
89
+ + (nullable AXUIElementRef)createAXElementWithSnapshot:(nullable id)snapshot CF_RETURNS_RETAINED;
90
+
91
+ /**
92
+ Creates an AX element for the XCTest accessibility element (XCAccessibilityElement).
93
+ The caller owns the result and must CFRelease it.
94
+
95
+ @param element XCTest accessibility element
96
+ @return The AX element or NULL if this process lacks Accessibility permission or the element is unavailable
97
+ */
98
+ + (nullable AXUIElementRef)createAXElementWithAccessibilityElement:(nullable id)element CF_RETURNS_RETAINED;
99
+
82
100
  @end
83
101
 
84
102
  NS_ASSUME_NONNULL_END