appium-mcp 0.0.1 → 1.1.4

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 (585) hide show
  1. package/.github/workflows/ci.yml +37 -0
  2. package/.github/workflows/pr-title.yml +15 -0
  3. package/.github/workflows/publish.yml +31 -0
  4. package/.gitmodules +9 -0
  5. package/.prettierignore +29 -0
  6. package/.prettierrc +10 -0
  7. package/.releaserc +37 -0
  8. package/CHANGELOG.md +37 -0
  9. package/LICENSE +21 -0
  10. package/README.md +153 -0
  11. package/dist/devicemanager/adb-manager.d.ts +71 -0
  12. package/dist/devicemanager/adb-manager.js +140 -0
  13. package/dist/devicemanager/adb-manager.js.map +1 -0
  14. package/dist/devicemanager/ios-manager.d.ts +58 -0
  15. package/dist/devicemanager/ios-manager.js +122 -0
  16. package/dist/devicemanager/ios-manager.js.map +1 -0
  17. package/dist/index.d.ts +2 -0
  18. package/dist/index.js +40 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/locators/element-filter.d.ts +13 -0
  21. package/dist/locators/element-filter.js +79 -0
  22. package/dist/locators/element-filter.js.map +1 -0
  23. package/dist/locators/generate-all-locators.d.ts +21 -0
  24. package/dist/locators/generate-all-locators.js +72 -0
  25. package/dist/locators/generate-all-locators.js.map +1 -0
  26. package/dist/locators/locator-generation.d.ts +36 -0
  27. package/dist/locators/locator-generation.js +501 -0
  28. package/dist/locators/locator-generation.js.map +1 -0
  29. package/dist/locators/logger.d.ts +5 -0
  30. package/dist/locators/logger.js +9 -0
  31. package/dist/locators/logger.js.map +1 -0
  32. package/dist/locators/source-parsing.d.ts +43 -0
  33. package/dist/locators/source-parsing.js +100 -0
  34. package/dist/locators/source-parsing.js.map +1 -0
  35. package/dist/resources/index.d.ts +1 -0
  36. package/dist/resources/index.js +7 -0
  37. package/dist/resources/index.js.map +1 -0
  38. package/dist/resources/java/template.d.ts +4 -0
  39. package/dist/resources/java/template.js +82 -0
  40. package/dist/resources/java/template.js.map +1 -0
  41. package/dist/schema.d.ts +2 -0
  42. package/dist/schema.js +5 -0
  43. package/dist/schema.js.map +1 -0
  44. package/dist/scripts/simple-index-documentation.d.ts +20 -0
  45. package/dist/scripts/simple-index-documentation.js +77 -0
  46. package/dist/scripts/simple-index-documentation.js.map +1 -0
  47. package/dist/scripts/simple-query-documentation.d.ts +12 -0
  48. package/dist/scripts/simple-query-documentation.js +52 -0
  49. package/dist/scripts/simple-query-documentation.js.map +1 -0
  50. package/dist/server.d.ts +3 -0
  51. package/dist/server.js +37 -0
  52. package/dist/server.js.map +1 -0
  53. package/dist/tests/__mocks__/@appium/support.d.ts +21 -0
  54. package/dist/tests/__mocks__/@appium/support.js +30 -0
  55. package/dist/tests/__mocks__/@appium/support.js.map +1 -0
  56. package/dist/tests/generate-all-locators.test.d.ts +1 -0
  57. package/dist/tests/generate-all-locators.test.js +140 -0
  58. package/dist/tests/generate-all-locators.test.js.map +1 -0
  59. package/dist/tests/test-setup-wda.d.ts +1 -0
  60. package/dist/tests/test-setup-wda.js +202 -0
  61. package/dist/tests/test-setup-wda.js.map +1 -0
  62. package/dist/tools/answer-appium.d.ts +1 -0
  63. package/dist/tools/answer-appium.js +71 -0
  64. package/dist/tools/answer-appium.js.map +1 -0
  65. package/dist/tools/boot-simulator.d.ts +1 -0
  66. package/dist/tools/boot-simulator.js +71 -0
  67. package/dist/tools/boot-simulator.js.map +1 -0
  68. package/dist/tools/create-session.d.ts +1 -0
  69. package/dist/tools/create-session.js +192 -0
  70. package/dist/tools/create-session.js.map +1 -0
  71. package/dist/tools/delete-session.d.ts +1 -0
  72. package/dist/tools/delete-session.js +47 -0
  73. package/dist/tools/delete-session.js.map +1 -0
  74. package/dist/tools/documentation/index.d.ts +28 -0
  75. package/dist/tools/documentation/index.js +63 -0
  76. package/dist/tools/documentation/index.js.map +1 -0
  77. package/dist/tools/documentation/reasoning-rag.d.ts +88 -0
  78. package/dist/tools/documentation/reasoning-rag.js +281 -0
  79. package/dist/tools/documentation/reasoning-rag.js.map +1 -0
  80. package/dist/tools/documentation/sentence-transformers-embeddings.d.ts +34 -0
  81. package/dist/tools/documentation/sentence-transformers-embeddings.js +111 -0
  82. package/dist/tools/documentation/sentence-transformers-embeddings.js.map +1 -0
  83. package/dist/tools/documentation/simple-pdf-indexer.d.ts +45 -0
  84. package/dist/tools/documentation/simple-pdf-indexer.js +402 -0
  85. package/dist/tools/documentation/simple-pdf-indexer.js.map +1 -0
  86. package/dist/tools/documentation/uploads/documents.json +1 -0
  87. package/dist/tools/generate-tests.d.ts +2 -0
  88. package/dist/tools/generate-tests.js +46 -0
  89. package/dist/tools/generate-tests.js.map +1 -0
  90. package/dist/tools/index.d.ts +16 -0
  91. package/dist/tools/index.js +112 -0
  92. package/dist/tools/index.js.map +1 -0
  93. package/dist/tools/install-wda.d.ts +1 -0
  94. package/dist/tools/install-wda.js +219 -0
  95. package/dist/tools/install-wda.js.map +1 -0
  96. package/dist/tools/interactions/activate-app.d.ts +2 -0
  97. package/dist/tools/interactions/activate-app.js +44 -0
  98. package/dist/tools/interactions/activate-app.js.map +1 -0
  99. package/dist/tools/interactions/click.d.ts +2 -0
  100. package/dist/tools/interactions/click.js +45 -0
  101. package/dist/tools/interactions/click.js.map +1 -0
  102. package/dist/tools/interactions/double-tap.d.ts +2 -0
  103. package/dist/tools/interactions/double-tap.js +81 -0
  104. package/dist/tools/interactions/double-tap.js.map +1 -0
  105. package/dist/tools/interactions/find.d.ts +13 -0
  106. package/dist/tools/interactions/find.js +55 -0
  107. package/dist/tools/interactions/find.js.map +1 -0
  108. package/dist/tools/interactions/get-text.d.ts +2 -0
  109. package/dist/tools/interactions/get-text.js +45 -0
  110. package/dist/tools/interactions/get-text.js.map +1 -0
  111. package/dist/tools/interactions/install-app.d.ts +2 -0
  112. package/dist/tools/interactions/install-app.js +43 -0
  113. package/dist/tools/interactions/install-app.js.map +1 -0
  114. package/dist/tools/interactions/list-apps.d.ts +2 -0
  115. package/dist/tools/interactions/list-apps.js +59 -0
  116. package/dist/tools/interactions/list-apps.js.map +1 -0
  117. package/dist/tools/interactions/screenshot.d.ts +2 -0
  118. package/dist/tools/interactions/screenshot.js +49 -0
  119. package/dist/tools/interactions/screenshot.js.map +1 -0
  120. package/dist/tools/interactions/set-value.d.ts +2 -0
  121. package/dist/tools/interactions/set-value.js +46 -0
  122. package/dist/tools/interactions/set-value.js.map +1 -0
  123. package/dist/tools/interactions/terminate-app.d.ts +2 -0
  124. package/dist/tools/interactions/terminate-app.js +45 -0
  125. package/dist/tools/interactions/terminate-app.js.map +1 -0
  126. package/dist/tools/interactions/uninstall-app.d.ts +2 -0
  127. package/dist/tools/interactions/uninstall-app.js +45 -0
  128. package/dist/tools/interactions/uninstall-app.js.map +1 -0
  129. package/dist/tools/locators.d.ts +1 -0
  130. package/dist/tools/locators.js +71 -0
  131. package/dist/tools/locators.js.map +1 -0
  132. package/dist/tools/scroll-to-element.d.ts +1 -0
  133. package/dist/tools/scroll-to-element.js +155 -0
  134. package/dist/tools/scroll-to-element.js.map +1 -0
  135. package/dist/tools/scroll.d.ts +1 -0
  136. package/dist/tools/scroll.js +91 -0
  137. package/dist/tools/scroll.js.map +1 -0
  138. package/dist/tools/select-device.d.ts +5 -0
  139. package/dist/tools/select-device.js +222 -0
  140. package/dist/tools/select-device.js.map +1 -0
  141. package/dist/tools/select-platform.d.ts +1 -0
  142. package/dist/tools/select-platform.js +195 -0
  143. package/dist/tools/select-platform.js.map +1 -0
  144. package/dist/tools/session-store.d.ts +7 -0
  145. package/dist/tools/session-store.js +64 -0
  146. package/dist/tools/session-store.js.map +1 -0
  147. package/dist/tools/setup-wda.d.ts +1 -0
  148. package/dist/tools/setup-wda.js +177 -0
  149. package/dist/tools/setup-wda.js.map +1 -0
  150. package/docs/CONTRIBUTING.md +424 -0
  151. package/eslint.config.js +49 -0
  152. package/examples/android-gmail.md +7 -0
  153. package/examples/android-todo-app.md +9 -0
  154. package/jest.config.js +23 -0
  155. package/package.json +71 -6
  156. package/scripts/setup-submodules-sparse.sh +53 -0
  157. package/scripts/update-submodules.sh +14 -0
  158. package/src/devicemanager/adb-manager.ts +164 -0
  159. package/src/devicemanager/ios-manager.ts +145 -0
  160. package/src/index.ts +47 -0
  161. package/src/locators/element-filter.ts +134 -0
  162. package/src/locators/generate-all-locators.ts +149 -0
  163. package/src/locators/locator-generation.ts +657 -0
  164. package/src/locators/logger.ts +11 -0
  165. package/src/locators/source-parsing.ts +149 -0
  166. package/src/resources/caps.json +697 -0
  167. package/src/resources/index.ts +7 -0
  168. package/src/resources/java/template.ts +83 -0
  169. package/src/resources/submodules/appium/.github/PULL_REQUEST_TEMPLATE.md +28 -0
  170. package/src/resources/submodules/appium/CHANGELOG.md +45 -0
  171. package/src/resources/submodules/appium/CONDUCT.md +48 -0
  172. package/src/resources/submodules/appium/GOVERNANCE.md +185 -0
  173. package/src/resources/submodules/appium/IDEAS.md +16 -0
  174. package/src/resources/submodules/appium/README.md +221 -0
  175. package/src/resources/submodules/appium/ROADMAP.md +30 -0
  176. package/src/resources/submodules/appium/SPONSORS.md +3 -0
  177. package/src/resources/submodules/appium/docs/README.md +6 -0
  178. package/src/resources/submodules/appium/docs/payout.md +35 -0
  179. package/src/resources/submodules/appium/packages/appium/CHANGELOG.md +1437 -0
  180. package/src/resources/submodules/appium/packages/appium/README.md +221 -0
  181. package/src/resources/submodules/appium/packages/appium/docs/en/blog/index.md +2 -0
  182. package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/announcing-appiumconf2024.md +45 -0
  183. package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/announcing-browserstack-as-strategic-partner.md +46 -0
  184. package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/announcing-headspin-as-development-partner.md +47 -0
  185. package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/announcing-lambdatest-as-strategic-partner.md +42 -0
  186. package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/announcing-sauce-labs-as-strategic-partner.md +36 -0
  187. package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/announcing-sponsorship-program.md +48 -0
  188. package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/appium3.md +40 -0
  189. package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/hello-world.md +15 -0
  190. package/src/resources/submodules/appium/packages/appium/docs/en/contributing/index.md +150 -0
  191. package/src/resources/submodules/appium/packages/appium/docs/en/developing/build-docs.md +86 -0
  192. package/src/resources/submodules/appium/packages/appium/docs/en/developing/build-doctor-checks.md +141 -0
  193. package/src/resources/submodules/appium/packages/appium/docs/en/developing/build-drivers.md +860 -0
  194. package/src/resources/submodules/appium/packages/appium/docs/en/developing/build-plugins.md +514 -0
  195. package/src/resources/submodules/appium/packages/appium/docs/en/developing/config-system.md +451 -0
  196. package/src/resources/submodules/appium/packages/appium/docs/en/developing/index.md +18 -0
  197. package/src/resources/submodules/appium/packages/appium/docs/en/developing/sensitive.md +49 -0
  198. package/src/resources/submodules/appium/packages/appium/docs/en/ecosystem/clients.md +132 -0
  199. package/src/resources/submodules/appium/packages/appium/docs/en/ecosystem/drivers.md +207 -0
  200. package/src/resources/submodules/appium/packages/appium/docs/en/ecosystem/index.md +45 -0
  201. package/src/resources/submodules/appium/packages/appium/docs/en/ecosystem/plugins.md +138 -0
  202. package/src/resources/submodules/appium/packages/appium/docs/en/ecosystem/tools.md +83 -0
  203. package/src/resources/submodules/appium/packages/appium/docs/en/guides/branch-testing.md +57 -0
  204. package/src/resources/submodules/appium/packages/appium/docs/en/guides/caching.md +76 -0
  205. package/src/resources/submodules/appium/packages/appium/docs/en/guides/caps.md +275 -0
  206. package/src/resources/submodules/appium/packages/appium/docs/en/guides/config.md +98 -0
  207. package/src/resources/submodules/appium/packages/appium/docs/en/guides/context.md +44 -0
  208. package/src/resources/submodules/appium/packages/appium/docs/en/guides/event-timing.md +73 -0
  209. package/src/resources/submodules/appium/packages/appium/docs/en/guides/execute-methods.md +122 -0
  210. package/src/resources/submodules/appium/packages/appium/docs/en/guides/grid.md +166 -0
  211. package/src/resources/submodules/appium/packages/appium/docs/en/guides/headers.md +17 -0
  212. package/src/resources/submodules/appium/packages/appium/docs/en/guides/log-filters.md +86 -0
  213. package/src/resources/submodules/appium/packages/appium/docs/en/guides/managing-exts.md +87 -0
  214. package/src/resources/submodules/appium/packages/appium/docs/en/guides/migrating-1-to-2.md +368 -0
  215. package/src/resources/submodules/appium/packages/appium/docs/en/guides/migrating-2-to-3.md +464 -0
  216. package/src/resources/submodules/appium/packages/appium/docs/en/guides/security.md +89 -0
  217. package/src/resources/submodules/appium/packages/appium/docs/en/guides/settings.md +68 -0
  218. package/src/resources/submodules/appium/packages/appium/docs/en/guides/tls.md +42 -0
  219. package/src/resources/submodules/appium/packages/appium/docs/en/index.md +59 -0
  220. package/src/resources/submodules/appium/packages/appium/docs/en/intro/appium.md +202 -0
  221. package/src/resources/submodules/appium/packages/appium/docs/en/intro/clients.md +127 -0
  222. package/src/resources/submodules/appium/packages/appium/docs/en/intro/drivers.md +188 -0
  223. package/src/resources/submodules/appium/packages/appium/docs/en/intro/history.md +196 -0
  224. package/src/resources/submodules/appium/packages/appium/docs/en/intro/index.md +39 -0
  225. package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/index.md +29 -0
  226. package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/install.md +50 -0
  227. package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/next-steps.md +23 -0
  228. package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/requirements.md +29 -0
  229. package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/test-dotnet.md +105 -0
  230. package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/test-java.md +23 -0
  231. package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/test-js.md +75 -0
  232. package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/test-py.md +60 -0
  233. package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/test-rb.md +83 -0
  234. package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/uiauto2-driver.md +144 -0
  235. package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/appium.md +394 -0
  236. package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/bidi.md +70 -0
  237. package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/index.md +30 -0
  238. package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/jsonwp.md +214 -0
  239. package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/mjsonwp.md +151 -0
  240. package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/others.md +671 -0
  241. package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/plugins.md +289 -0
  242. package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/webdriver.md +1114 -0
  243. package/src/resources/submodules/appium/packages/appium/docs/en/reference/cli/env-vars.md +31 -0
  244. package/src/resources/submodules/appium/packages/appium/docs/en/reference/cli/extensions.md +239 -0
  245. package/src/resources/submodules/appium/packages/appium/docs/en/reference/cli/index.md +35 -0
  246. package/src/resources/submodules/appium/packages/appium/docs/en/reference/cli/server.md +76 -0
  247. package/src/resources/submodules/appium/packages/appium/docs/en/reference/cli/setup.md +76 -0
  248. package/src/resources/submodules/appium/packages/appium/docs/en/reference/index.md +25 -0
  249. package/src/resources/submodules/appium/packages/appium/docs/en/resources/index.md +28 -0
  250. package/src/resources/submodules/appium/packages/appium/docs/en/sponsors/index.md +64 -0
  251. package/src/resources/submodules/appium/packages/appium/docs/ja/blog/index.md +2 -0
  252. package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/announcing-appiumconf2024.md +45 -0
  253. package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/announcing-browserstack-as-strategic-partner.md +46 -0
  254. package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/announcing-headspin-as-development-partner.md +47 -0
  255. package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/announcing-lambdatest-as-strategic-partner.md +41 -0
  256. package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/announcing-sauce-labs-as-strategic-partner.md +36 -0
  257. package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/announcing-sponsorship-program.md +48 -0
  258. package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/appium3.md +40 -0
  259. package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/hello-world.md +15 -0
  260. package/src/resources/submodules/appium/packages/appium/docs/ja/contributing/index.md +158 -0
  261. package/src/resources/submodules/appium/packages/appium/docs/ja/developing/build-docs.md +86 -0
  262. package/src/resources/submodules/appium/packages/appium/docs/ja/developing/build-doctor-checks.md +141 -0
  263. package/src/resources/submodules/appium/packages/appium/docs/ja/developing/build-drivers.md +866 -0
  264. package/src/resources/submodules/appium/packages/appium/docs/ja/developing/build-plugins.md +520 -0
  265. package/src/resources/submodules/appium/packages/appium/docs/ja/developing/config-system.md +468 -0
  266. package/src/resources/submodules/appium/packages/appium/docs/ja/developing/index.md +18 -0
  267. package/src/resources/submodules/appium/packages/appium/docs/ja/developing/sensitive.md +49 -0
  268. package/src/resources/submodules/appium/packages/appium/docs/ja/ecosystem/clients.md +143 -0
  269. package/src/resources/submodules/appium/packages/appium/docs/ja/ecosystem/drivers.md +219 -0
  270. package/src/resources/submodules/appium/packages/appium/docs/ja/ecosystem/index.md +45 -0
  271. package/src/resources/submodules/appium/packages/appium/docs/ja/ecosystem/plugins.md +140 -0
  272. package/src/resources/submodules/appium/packages/appium/docs/ja/ecosystem/tools.md +87 -0
  273. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/branch-testing.md +57 -0
  274. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/caching.md +78 -0
  275. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/caps.md +259 -0
  276. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/config.md +102 -0
  277. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/context.md +44 -0
  278. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/event-timing.md +75 -0
  279. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/execute-methods.md +142 -0
  280. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/grid.md +166 -0
  281. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/headers.md +17 -0
  282. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/log-filters.md +86 -0
  283. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/managing-exts.md +89 -0
  284. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/migrating-1-to-2.md +402 -0
  285. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/migrating-2-to-3.md +458 -0
  286. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/security.md +89 -0
  287. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/settings.md +70 -0
  288. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/tls.md +43 -0
  289. package/src/resources/submodules/appium/packages/appium/docs/ja/index.md +55 -0
  290. package/src/resources/submodules/appium/packages/appium/docs/ja/intro/appium.md +191 -0
  291. package/src/resources/submodules/appium/packages/appium/docs/ja/intro/clients.md +139 -0
  292. package/src/resources/submodules/appium/packages/appium/docs/ja/intro/drivers.md +188 -0
  293. package/src/resources/submodules/appium/packages/appium/docs/ja/intro/history.md +196 -0
  294. package/src/resources/submodules/appium/packages/appium/docs/ja/intro/index.md +39 -0
  295. package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/index.md +23 -0
  296. package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/install.md +47 -0
  297. package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/next-steps.md +19 -0
  298. package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/requirements.md +29 -0
  299. package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/test-dotnet.md +107 -0
  300. package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/test-java.md +23 -0
  301. package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/test-js.md +77 -0
  302. package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/test-py.md +63 -0
  303. package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/test-rb.md +85 -0
  304. package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/uiauto2-driver.md +148 -0
  305. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/appium.md +395 -0
  306. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/bidi.md +71 -0
  307. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/index.md +30 -0
  308. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/jsonwp.md +215 -0
  309. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/mjsonwp.md +152 -0
  310. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/others.md +672 -0
  311. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/plugins.md +291 -0
  312. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/webdriver.md +1114 -0
  313. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/cli/env-vars.md +31 -0
  314. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/cli/extensions.md +240 -0
  315. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/cli/index.md +35 -0
  316. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/cli/server.md +76 -0
  317. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/cli/setup.md +78 -0
  318. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/index.md +25 -0
  319. package/src/resources/submodules/appium/packages/appium/docs/ja/resources/index.md +28 -0
  320. package/src/resources/submodules/appium/packages/appium/docs/ja/sponsors/index.md +61 -0
  321. package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/appium-logo-horiz-white.png +0 -0
  322. package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/appium-logo-horiz.png +0 -0
  323. package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/appium-logo-white.png +0 -0
  324. package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/appium-logo.png +0 -0
  325. package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/sponsor-logo-browserstack-dark.png +0 -0
  326. package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/sponsor-logo-browserstack-light.png +0 -0
  327. package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/sponsor-logo-lambdatest-dark.png +0 -0
  328. package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/sponsor-logo-lambdatest-light.png +0 -0
  329. package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/sponsor-logo-sauce.png +0 -0
  330. package/src/resources/submodules/appium/packages/appium/docs/zh/blog/index.md +2 -0
  331. package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/announcing-appiumconf2024.md +45 -0
  332. package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/announcing-browserstack-as-strategic-partner.md +46 -0
  333. package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/announcing-headspin-as-development-partner.md +47 -0
  334. package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/announcing-lambdatest-as-strategic-partner.md +41 -0
  335. package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/announcing-sauce-labs-as-strategic-partner.md +36 -0
  336. package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/announcing-sponsorship-program.md +48 -0
  337. package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/appium3.md +40 -0
  338. package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/hello-world.md +15 -0
  339. package/src/resources/submodules/appium/packages/appium/docs/zh/contributing/index.md +132 -0
  340. package/src/resources/submodules/appium/packages/appium/docs/zh/developing/build-docs.md +86 -0
  341. package/src/resources/submodules/appium/packages/appium/docs/zh/developing/build-doctor-checks.md +141 -0
  342. package/src/resources/submodules/appium/packages/appium/docs/zh/developing/build-drivers.md +866 -0
  343. package/src/resources/submodules/appium/packages/appium/docs/zh/developing/build-plugins.md +520 -0
  344. package/src/resources/submodules/appium/packages/appium/docs/zh/developing/config-system.md +468 -0
  345. package/src/resources/submodules/appium/packages/appium/docs/zh/developing/index.md +18 -0
  346. package/src/resources/submodules/appium/packages/appium/docs/zh/developing/sensitive.md +49 -0
  347. package/src/resources/submodules/appium/packages/appium/docs/zh/ecosystem/clients.md +143 -0
  348. package/src/resources/submodules/appium/packages/appium/docs/zh/ecosystem/drivers.md +219 -0
  349. package/src/resources/submodules/appium/packages/appium/docs/zh/ecosystem/index.md +45 -0
  350. package/src/resources/submodules/appium/packages/appium/docs/zh/ecosystem/plugins.md +140 -0
  351. package/src/resources/submodules/appium/packages/appium/docs/zh/ecosystem/tools.md +87 -0
  352. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/branch-testing.md +57 -0
  353. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/caching.md +78 -0
  354. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/caps.md +284 -0
  355. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/config.md +102 -0
  356. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/context.md +44 -0
  357. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/event-timing.md +75 -0
  358. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/execute-methods.md +142 -0
  359. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/grid.md +166 -0
  360. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/headers.md +17 -0
  361. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/log-filters.md +86 -0
  362. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/managing-exts.md +89 -0
  363. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/migrating-1-to-2.md +410 -0
  364. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/migrating-2-to-3.md +459 -0
  365. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/security.md +89 -0
  366. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/settings.md +70 -0
  367. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/tls.md +43 -0
  368. package/src/resources/submodules/appium/packages/appium/docs/zh/index.md +54 -0
  369. package/src/resources/submodules/appium/packages/appium/docs/zh/intro/appium.md +200 -0
  370. package/src/resources/submodules/appium/packages/appium/docs/zh/intro/clients.md +139 -0
  371. package/src/resources/submodules/appium/packages/appium/docs/zh/intro/drivers.md +188 -0
  372. package/src/resources/submodules/appium/packages/appium/docs/zh/intro/history.md +196 -0
  373. package/src/resources/submodules/appium/packages/appium/docs/zh/intro/index.md +39 -0
  374. package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/index.md +23 -0
  375. package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/install.md +47 -0
  376. package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/next-steps.md +19 -0
  377. package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/requirements.md +21 -0
  378. package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/test-dotnet.md +99 -0
  379. package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/test-java.md +20 -0
  380. package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/test-js.md +62 -0
  381. package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/test-py.md +57 -0
  382. package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/test-rb.md +80 -0
  383. package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/uiauto2-driver.md +148 -0
  384. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/appium.md +395 -0
  385. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/bidi.md +71 -0
  386. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/index.md +30 -0
  387. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/jsonwp.md +215 -0
  388. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/mjsonwp.md +152 -0
  389. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/others.md +672 -0
  390. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/plugins.md +291 -0
  391. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/webdriver.md +1114 -0
  392. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/cli/env-vars.md +31 -0
  393. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/cli/extensions.md +240 -0
  394. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/cli/index.md +35 -0
  395. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/cli/server.md +76 -0
  396. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/cli/setup.md +78 -0
  397. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/index.md +25 -0
  398. package/src/resources/submodules/appium/packages/appium/docs/zh/resources/index.md +28 -0
  399. package/src/resources/submodules/appium/packages/appium/docs/zh/sponsors/index.md +61 -0
  400. package/src/resources/submodules/appium/packages/appium/types/manifest/README.md +30 -0
  401. package/src/resources/submodules/appium/packages/base-driver/CHANGELOG.md +1131 -0
  402. package/src/resources/submodules/appium/packages/base-driver/README.md +15 -0
  403. package/src/resources/submodules/appium/packages/base-driver/docs/mjsonwp/errors.md +82 -0
  404. package/src/resources/submodules/appium/packages/base-driver/docs/mjsonwp/protocol-methods.md +182 -0
  405. package/src/resources/submodules/appium/packages/base-driver/static/appium.png +0 -0
  406. package/src/resources/submodules/appium/packages/base-plugin/CHANGELOG.md +672 -0
  407. package/src/resources/submodules/appium/packages/base-plugin/README.md +15 -0
  408. package/src/resources/submodules/appium/packages/docutils/CHANGELOG.md +948 -0
  409. package/src/resources/submodules/appium/packages/docutils/README.md +27 -0
  410. package/src/resources/submodules/appium/packages/driver-test-support/CHANGELOG.md +717 -0
  411. package/src/resources/submodules/appium/packages/driver-test-support/README.md +112 -0
  412. package/src/resources/submodules/appium/packages/eslint-config-appium-ts/CHANGELOG.md +168 -0
  413. package/src/resources/submodules/appium/packages/eslint-config-appium-ts/README.md +33 -0
  414. package/src/resources/submodules/appium/packages/execute-driver-plugin/CHANGELOG.md +603 -0
  415. package/src/resources/submodules/appium/packages/execute-driver-plugin/README.md +42 -0
  416. package/src/resources/submodules/appium/packages/fake-driver/CHANGELOG.md +545 -0
  417. package/src/resources/submodules/appium/packages/fake-driver/README.md +7 -0
  418. package/src/resources/submodules/appium/packages/fake-driver/lib/screen.png +0 -0
  419. package/src/resources/submodules/appium/packages/fake-plugin/CHANGELOG.md +683 -0
  420. package/src/resources/submodules/appium/packages/fake-plugin/README.md +7 -0
  421. package/src/resources/submodules/appium/packages/images-plugin/CHANGELOG.md +602 -0
  422. package/src/resources/submodules/appium/packages/images-plugin/README.md +27 -0
  423. package/src/resources/submodules/appium/packages/images-plugin/docs/find-by-image.md +65 -0
  424. package/src/resources/submodules/appium/packages/images-plugin/docs/image-comparison.md +203 -0
  425. package/src/resources/submodules/appium/packages/images-plugin/test/fixtures/appstore.png +0 -0
  426. package/src/resources/submodules/appium/packages/images-plugin/test/fixtures/img1.png +0 -0
  427. package/src/resources/submodules/appium/packages/images-plugin/test/fixtures/img2.png +0 -0
  428. package/src/resources/submodules/appium/packages/images-plugin/test/fixtures/img2_part.png +0 -0
  429. package/src/resources/submodules/appium/packages/logger/CHANGELOG.md +162 -0
  430. package/src/resources/submodules/appium/packages/logger/README.md +31 -0
  431. package/src/resources/submodules/appium/packages/opencv/CHANGELOG.md +384 -0
  432. package/src/resources/submodules/appium/packages/opencv/README.md +68 -0
  433. package/src/resources/submodules/appium/packages/opencv/test/e2e/images/appium-diagram.jpg +0 -0
  434. package/src/resources/submodules/appium/packages/opencv/test/e2e/images/cc1.png +0 -0
  435. package/src/resources/submodules/appium/packages/opencv/test/e2e/images/cc2.png +0 -0
  436. package/src/resources/submodules/appium/packages/opencv/test/e2e/images/cc_rotated.png +0 -0
  437. package/src/resources/submodules/appium/packages/opencv/test/e2e/images/findwaldo.jpg +0 -0
  438. package/src/resources/submodules/appium/packages/opencv/test/e2e/images/number5.png +0 -0
  439. package/src/resources/submodules/appium/packages/opencv/test/e2e/images/waldo.jpg +0 -0
  440. package/src/resources/submodules/appium/packages/plugin-test-support/CHANGELOG.md +539 -0
  441. package/src/resources/submodules/appium/packages/plugin-test-support/README.md +49 -0
  442. package/src/resources/submodules/appium/packages/relaxed-caps-plugin/CHANGELOG.md +154 -0
  443. package/src/resources/submodules/appium/packages/relaxed-caps-plugin/README.md +35 -0
  444. package/src/resources/submodules/appium/packages/schema/CHANGELOG.md +271 -0
  445. package/src/resources/submodules/appium/packages/schema/README.md +50 -0
  446. package/src/resources/submodules/appium/packages/storage-plugin/CHANGELOG.md +73 -0
  447. package/src/resources/submodules/appium/packages/storage-plugin/README.md +83 -0
  448. package/src/resources/submodules/appium/packages/strongbox/CHANGELOG.md +94 -0
  449. package/src/resources/submodules/appium/packages/strongbox/README.md +96 -0
  450. package/src/resources/submodules/appium/packages/support/CHANGELOG.md +1054 -0
  451. package/src/resources/submodules/appium/packages/support/README.md +161 -0
  452. package/src/resources/submodules/appium/packages/test-support/CHANGELOG.md +712 -0
  453. package/src/resources/submodules/appium/packages/test-support/README.md +61 -0
  454. package/src/resources/submodules/appium/packages/tsconfig/CHANGELOG.md +131 -0
  455. package/src/resources/submodules/appium/packages/tsconfig/README.md +19 -0
  456. package/src/resources/submodules/appium/packages/types/CHANGELOG.md +793 -0
  457. package/src/resources/submodules/appium/packages/types/README.md +21 -0
  458. package/src/resources/submodules/appium/packages/universal-xml-plugin/CHANGELOG.md +435 -0
  459. package/src/resources/submodules/appium/packages/universal-xml-plugin/README.md +53 -0
  460. package/src/resources/submodules/appium/renovate/README.md +63 -0
  461. package/src/resources/submodules/appium-uiautomator2-driver/CHANGELOG.md +1204 -0
  462. package/src/resources/submodules/appium-uiautomator2-driver/README.md +2077 -0
  463. package/src/resources/submodules/appium-uiautomator2-driver/docs/actions.md +72 -0
  464. package/src/resources/submodules/appium-uiautomator2-driver/docs/activity-startup.md +47 -0
  465. package/src/resources/submodules/appium-uiautomator2-driver/docs/android-appbundle.md +69 -0
  466. package/src/resources/submodules/appium-uiautomator2-driver/docs/android-mobile-gestures.md +352 -0
  467. package/src/resources/submodules/appium-uiautomator2-driver/docs/bidi.md +50 -0
  468. package/src/resources/submodules/appium-uiautomator2-driver/docs/capability-sets.md +136 -0
  469. package/src/resources/submodules/appium-uiautomator2-driver/docs/scheduled-actions.md +155 -0
  470. package/src/resources/submodules/appium-uiautomator2-driver/docs/uiautomator-uiselector.md +51 -0
  471. package/src/resources/submodules/appium-uiautomator2-driver/docs/unlock/main.md +95 -0
  472. package/src/resources/submodules/appium-uiautomator2-driver/docs/unlock/screen1.png +0 -0
  473. package/src/resources/submodules/appium-uiautomator2-driver/docs/unlock/screen2.png +0 -0
  474. package/src/resources/submodules/appium-uiautomator2-driver/test/functional/assets/checkered-squares.png +0 -0
  475. package/src/resources/submodules/appium-uiautomator2-driver/test/functional/assets/start-button.png +0 -0
  476. package/src/resources/submodules/appium-uiautomator2-driver/test/functional/assets/stop-button.png +0 -0
  477. package/src/resources/submodules/appium-xcuitest-driver/.github/ISSUE_TEMPLATE.md +4 -0
  478. package/src/resources/submodules/appium-xcuitest-driver/CHANGELOG.md +2594 -0
  479. package/src/resources/submodules/appium-xcuitest-driver/README.md +55 -0
  480. package/src/resources/submodules/appium-xcuitest-driver/docs/assets/images/appium-logo-white.png +0 -0
  481. package/src/resources/submodules/appium-xcuitest-driver/docs/assets/images/appium-logo.png +0 -0
  482. package/src/resources/submodules/appium-xcuitest-driver/docs/assets/images/appium-plus-xctest.png +0 -0
  483. package/src/resources/submodules/appium-xcuitest-driver/docs/contributing.md +45 -0
  484. package/src/resources/submodules/appium-xcuitest-driver/docs/endpoints-wda.md +61 -0
  485. package/src/resources/submodules/appium-xcuitest-driver/docs/endpoints.md +98 -0
  486. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/assets/images/ios-xctest-file-movement/keynote.png +0 -0
  487. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/assets/images/ios-xctest-file-movement/on_my_iphone.png +0 -0
  488. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/assets/images/ios-xctest-file-movement/top_files.png +0 -0
  489. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/attach-to-running-wda.md +43 -0
  490. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/audio-capture.md +78 -0
  491. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/capability-sets.md +169 -0
  492. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/ci-setup.md +47 -0
  493. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/clipboard.md +47 -0
  494. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/elements-lookup-troubleshooting.md +158 -0
  495. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/file-transfer.md +147 -0
  496. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/gestures.md +52 -0
  497. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/hybrid.md +137 -0
  498. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/input-events.md +67 -0
  499. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/install-certificate.md +19 -0
  500. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/multiple-xcode-versions.md +37 -0
  501. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/parallel-tests.md +39 -0
  502. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/run-prebuilt-wda.md +135 -0
  503. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/run-preinstalled-wda.md +178 -0
  504. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/touch-id.md +33 -0
  505. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/troubleshooting.md +191 -0
  506. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/tvos.md +114 -0
  507. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/wda-custom-server.md +283 -0
  508. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/wda-slowness.md +231 -0
  509. package/src/resources/submodules/appium-xcuitest-driver/docs/index.md +36 -0
  510. package/src/resources/submodules/appium-xcuitest-driver/docs/installation/index.md +137 -0
  511. package/src/resources/submodules/appium-xcuitest-driver/docs/overview.md +19 -0
  512. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/check-prov-prof.png +0 -0
  513. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/create-new-project.png +0 -0
  514. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/create-single-page.png +0 -0
  515. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/no-prov-prof.png +0 -0
  516. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/project-prov-prof.png +0 -0
  517. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/set-up-bundle.png +0 -0
  518. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/untrusted-dev.png +0 -0
  519. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/xcode-bundle-id.png +0 -0
  520. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/xcode-config.png +0 -0
  521. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/xcode-facebook-fail.png +0 -0
  522. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/xcode-facebook-succeed.png +0 -0
  523. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/index.md +51 -0
  524. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/prov-profile-basic-auto.md +49 -0
  525. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/prov-profile-basic-manual.md +40 -0
  526. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/prov-profile-full-manual.md +50 -0
  527. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/prov-profile-generic-manual.md +49 -0
  528. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/real-device-config.md +100 -0
  529. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/assets/images/useXctestrunFile.png +0 -0
  530. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/bidi.md +75 -0
  531. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/capabilities.md +165 -0
  532. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/commands.md +490 -0
  533. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/element-attributes.md +27 -0
  534. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/execute-methods.md +2206 -0
  535. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/ios-predicate.md +196 -0
  536. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/locator-strategies.md +19 -0
  537. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/scripts.md +29 -0
  538. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/security-flags.md +22 -0
  539. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/server-args.md +16 -0
  540. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/settings.md +49 -0
  541. package/src/resources/submodules/appium-xcuitest-driver/test/assets/TestApp-iphonesimulator.app/Default-568h@2x.png +0 -0
  542. package/src/resources/submodules/appium-xcuitest-driver/test/assets/test.png +0 -0
  543. package/src/schema.ts +5 -0
  544. package/src/scripts/simple-index-documentation.ts +93 -0
  545. package/src/scripts/simple-query-documentation.ts +61 -0
  546. package/src/server.ts +40 -0
  547. package/src/tests/README.md +83 -0
  548. package/src/tests/__mocks__/@appium/support.ts +31 -0
  549. package/src/tests/generate-all-locators.test.ts +179 -0
  550. package/src/tests/test-setup-wda.ts +247 -0
  551. package/src/tools/README.md +170 -0
  552. package/src/tools/answer-appium.ts +75 -0
  553. package/src/tools/boot-simulator.ts +87 -0
  554. package/src/tools/create-session.ts +270 -0
  555. package/src/tools/delete-session.ts +46 -0
  556. package/src/tools/documentation/index.ts +97 -0
  557. package/src/tools/documentation/reasoning-rag.ts +434 -0
  558. package/src/tools/documentation/sentence-transformers-embeddings.ts +142 -0
  559. package/src/tools/documentation/simple-pdf-indexer.ts +509 -0
  560. package/src/tools/documentation/uploads/documents.json +1 -0
  561. package/src/tools/generate-tests.ts +50 -0
  562. package/src/tools/index.ts +133 -0
  563. package/src/tools/install-wda.ts +277 -0
  564. package/src/tools/interactions/activate-app.ts +46 -0
  565. package/src/tools/interactions/click.ts +47 -0
  566. package/src/tools/interactions/double-tap.ts +87 -0
  567. package/src/tools/interactions/find.ts +58 -0
  568. package/src/tools/interactions/get-text.ts +47 -0
  569. package/src/tools/interactions/install-app.ts +45 -0
  570. package/src/tools/interactions/list-apps.ts +65 -0
  571. package/src/tools/interactions/screenshot.ts +56 -0
  572. package/src/tools/interactions/set-value.ts +48 -0
  573. package/src/tools/interactions/terminate-app.ts +47 -0
  574. package/src/tools/interactions/uninstall-app.ts +47 -0
  575. package/src/tools/locators.ts +83 -0
  576. package/src/tools/scroll-to-element.ts +188 -0
  577. package/src/tools/scroll.ts +97 -0
  578. package/src/tools/select-device.ts +298 -0
  579. package/src/tools/select-platform.ts +243 -0
  580. package/src/tools/session-store.ts +72 -0
  581. package/src/tools/setup-wda.ts +218 -0
  582. package/src/types/appium-ios-device.d.ts +8 -0
  583. package/src/types/appium-xcuitest-driver.d.ts +5 -0
  584. package/tsconfig.json +23 -0
  585. package/index.js +0 -0
@@ -0,0 +1 @@
1
+ [{"pageContent":"---\nhide:\n - toc\n\ntitle: Server Command-Line Arguments\n---\n\nTo start the Appium server, you may either run `appium` or `appium server`. The `server` subcommand\nis considered to be the default, so if you omit it, Appium will interpret this as your request to\nrun the Appium server.\n\nThe invocation of `appium` (or `appium server`) can take a number of arguments, which are detailed\nbelow.\n\n!!! note\n\n All of these arguments can be set via a [Configuration File](../guides/config.md) instead if\n you want. Any arguments set on the command line will override any arguments found in\n a configuration file.","metadata":{"loc":{"lines":{"from":1,"to":19}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/args.md","filename":"args.md","relativePath":"appium/cli/args.md"}},{"pageContent":"|<div style=\"width:12em\">Argument</div>|Description|Type|<div style=\"width:8em\">Default</div>|Aliases|\n|--|--|--|--|--|\n|`--address`|IP address to listen on|string|`0.0.0.0`|`-a`|\n|`--allow-cors`|Whether the Appium server should allow web browser connections from any host|boolean|`false`||\n|`--allow-insecure`|Set which [insecure features](../guides/security.md) are allowed to run in this server's sessions. Most features are defined on a driver level; see driver documentation for more details. Individual features can be overridden by `--deny-insecure`. Has no effect in combination with `--relaxed-security`.|array<string>|`[]`||\n|`--base-path`|Base path to use as the prefix for all webdriver routes running on the server|string|`\"\"`|`-pa`|\n|`--callback-address`|Callback IP address (default: same as `--address`)|string||`-ca`|\n|`--callback-port`|Callback port (default: same as `--port`) (Value must be between `1` and `65535`)|integer|`4723`|`-cp`|","metadata":{"loc":{"lines":{"from":22,"to":29}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/args.md","filename":"args.md","relativePath":"appium/cli/args.md"}},{"pageContent":"|`--callback-port`|Callback port (default: same as `--port`) (Value must be between `1` and `65535`)|integer|`4723`|`-cp`|\n|`--config`|Path to an [Appium configuration JSON file](../guides/config.md)|string|||\n|`--debug-log-spacing`|Add exaggerated spacing in logs to help with visual inspection|boolean|`false`||\n|`--default-capabilities`|Set the default desired capabilities, which will be set on each session unless overridden by received capabilities. If a string, a path to a JSON file containing the capabilities, or raw JSON.|object||`-dc`|\n|`--deny-insecure`|Set which [insecure features](../guides/security.md) are not allowed to run in this server's sessions. Most features are defined on a driver level; see driver documentation for more details. Since all insecure features are disabled by default, this argument has no effect without either `--allow-insecure` or `--relaxed-security`, and is applied after both.|array<string>|`[]`||","metadata":{"loc":{"lines":{"from":29,"to":33}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/args.md","filename":"args.md","relativePath":"appium/cli/args.md"}},{"pageContent":"|`--driver`|Driver-specific configuration. Keys should correspond to driver package names|object|||\n|`--drivers-import-chunk-size`|The maximum amount of drivers that could be imported in parallel on server startup|number|`3`||\n|`--keep-alive-timeout`|Number of seconds the Appium server should apply as both the keep-alive timeout and the connection timeout for all requests. Setting this to `0` disables the timeout.|integer|`600`|`-ka`|\n|`--request-timeout`|Number of seconds the Appium server should apply for receiving the entire HTTP request from the client. A value of 0 disables the timeout. Set it to a non-zero value to protect against potential Denial-of-Service attacks in case the server is deployed without a reverse proxy in front. HTTP requests that are running longer than allowed by this timeout would be rejected with the status code 408.|integer|`3600`||\n|`--local-timezone`|Use local timezone for timestamps|boolean|`false`||","metadata":{"loc":{"lines":{"from":34,"to":38}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/args.md","filename":"args.md","relativePath":"appium/cli/args.md"}},{"pageContent":"|`--local-timezone`|Use local timezone for timestamps|boolean|`false`||\n|`--log`|Also send log output to this file|string||`-g`|\n|`--log-filters`|One or more log filtering rules|array|||\n|`--log-level`|Log level (console[:file]) (Value must be one of: `info`, `info:debug`, `info:info`, `info:warn`, `info:error`, `warn`, `warn:debug`, `warn:info`, `warn:warn`, `warn:error`, `error`, `error:debug`, `error:info`, `error:warn`, `error:error`, `debug`, `debug:debug`, `debug:info`, `debug:warn`, `debug:error`)|string|`debug`||\n|`--log-format`|Log format (Value must be to one of: `text`, `json`, `pretty_json`). If logs are printed as JSON then the text coloring is always disabled.|string|`text`||\n|`--log-no-colors`|Do not use color in console output|boolean|`false`||\n|`--log-timestamp`|Show timestamps in console output|boolean|`false`||\n|`--long-stacktrace`|Add long stack traces to log entries. Recommended for debugging only.|boolean|`false`||","metadata":{"loc":{"lines":{"from":38,"to":45}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/args.md","filename":"args.md","relativePath":"appium/cli/args.md"}},{"pageContent":"|`--log-timestamp`|Show timestamps in console output|boolean|`false`||\n|`--long-stacktrace`|Add long stack traces to log entries. Recommended for debugging only.|boolean|`false`||\n|`--no-perms-check`|Skip various permission checks on the server startup|boolean|`false`||\n|`--nodeconfig`|Path to configuration JSON file to register Appium as a node with Selenium Grid 3; otherwise the configuration itself|string|||\n|`--plugin`|Plugin-specific configuration. Keys should correspond to plugin package names|object|||\n|`--plugins-import-chunk-size`|The maximum amount of plugins that could be imported in parallel on server startup|number|`7`||\n|`--port`|Port to listen on (Value must be between `1` and `65535`)|integer|`4723`|`-p`|","metadata":{"loc":{"lines":{"from":44,"to":50}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/args.md","filename":"args.md","relativePath":"appium/cli/args.md"}},{"pageContent":"|`--port`|Port to listen on (Value must be between `1` and `65535`)|integer|`4723`|`-p`|\n|`--relaxed-security`|Allow all [insecure features](../guides/security.md). Only use this if all clients are in a trusted network and could not potentially break out of the session sandbox. Specific features can be overridden by using `--deny-insecure`.|boolean|`false`||\n|`--session-override`|Enables session override (clobbering)|boolean|`false`||\n|`--ssl-cert-path`|Absolute path to the `.cert` file if TLS is used. Must be provided together with `--ssl-key-path`. See the [SSL/TLS/SPDY Support guide](../guides/tls.md) for details|string|||\n|`--ssl-key-path`|Absolute path to the `.key` file if TLS is used. Must be provided together with `--ssl-cert-path`. See the [SSL/TLS/SPDY Support guide](../guides/tls.md) for details|string|||\n|`--strict-caps`|Cause sessions to fail if desired caps are sent in that Appium does not recognize as valid for the selected device|boolean|`false`||","metadata":{"loc":{"lines":{"from":50,"to":55}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/args.md","filename":"args.md","relativePath":"appium/cli/args.md"}},{"pageContent":"|`--strict-caps`|Cause sessions to fail if desired caps are sent in that Appium does not recognize as valid for the selected device|boolean|`false`||\n|`--tmp`|Absolute path to directory Appium can use to manage temp files|string|Windows: `C:\\Windows\\Temp`<br>Others: `/tmp`||\n|`--trace-dir`|Absolute path to directory Appium can use to save iOS instrument traces|string|`<tmp>/appium-instruments`||\n|`--use-drivers`|A list of drivers to activate. By default, all installed drivers will be activated.|array<string>|`[]`||\n|`--use-plugins`|A list of plugins to activate. To activate all plugins, the value should be an array with a single item `\"all\"`.|array<string>|`[]`||\n|`--webhook`|Also send log output to this http listener|string||`-G`|","metadata":{"loc":{"lines":{"from":55,"to":60}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/args.md","filename":"args.md","relativePath":"appium/cli/args.md"}},{"pageContent":"The following arguments are used for information retrieval, after which the server will automatically exit. They are therefore meant for reference or debug purposes.\n\n|<div style=\"width:10em\">Argument</div>|Description|Alias|\n|--|--|--|\n|`--help`|Print instructions on using the Appium command-line. This argument can also be used for any Appium subcommands.|`-h`|\n|`--show-build-info`|Print detailed information on the Appium server version||\n|`--show-config`|Print the current Appium server configuration details||\n|`--show-debug-info`|Print information on the current environment: details about the operating system, Node.js, and Appium itself||\n|`--version`|Print the Appium server version|`-v`|","metadata":{"loc":{"lines":{"from":62,"to":70}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/args.md","filename":"args.md","relativePath":"appium/cli/args.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Server Environment Variables\n---\n\nThe primary way of configuring the Appium server is via [Command-Line Arguments](./args.md). However, some more\nadvanced features are toggled or configured via environment variables. To set environment\nvariables, refer to the documentation for your operating system and terminal. These are the\nenvironment variables that the Appium server understands:","metadata":{"loc":{"lines":{"from":1,"to":11}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/env-vars.md","filename":"env-vars.md","relativePath":"appium/cli/env-vars.md"}},{"pageContent":"|Variable&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|Description|\n|--------|-----------|\n|`APPIUM_HOME`|By default, Appium creates a directory called `.appium` in the home directory for your system user. You can adjust the directory with this variable, as detailed in the [Managing Extensions](../guides/managing-exts.md) guide.|\n|`APPIUM_TMP_DIR`|By default, Appium uses a random temporary directory for many of its operations. If you wish to use a specific directory, you may do so by including an absolute path as the value of this variable. The behaviour is equivalent to using the `--tmp` CLI arg.|","metadata":{"loc":{"lines":{"from":13,"to":16}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/env-vars.md","filename":"env-vars.md","relativePath":"appium/cli/env-vars.md"}},{"pageContent":"|`APPIUM_PREFER_SYSTEM_UNZIP`|Set to `0` or `false` to request that Appium not use the `unzip` binary included on your system for unzipping downloaded apps or other artifacts. Instead it will use a JS-based unzip library. This could help on some systems with non-existent or non-standard `unzip` commands. Note that if unzipping fails using the system library, the fallback library will be attempted in any case, so setting this env var merely saves time in the event you know the system unzip will fail.|\n|`APPIUM_HOST`|Same as the `--address` CLI arg|\n|`APPIUM_PORT`|Same as the `--port` CLI arg|\n|`APPIUM_RELOAD_EXTENSIONS`|Set to `1` to cause Appium to re-require extensions when new sessions are created. This is mostly useful for [building extensions](../developing/build-drivers.md)|\n|`APPIUM_OMIT_PEER_DEPS`|Adds `--omit=peer` to all the NPM commands run internally by Appium. Mostly an internal feature.|","metadata":{"loc":{"lines":{"from":17,"to":21}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/env-vars.md","filename":"env-vars.md","relativePath":"appium/cli/env-vars.md"}},{"pageContent":"|`APPIUM_OMIT_PEER_DEPS`|Adds `--omit=peer` to all the NPM commands run internally by Appium. Mostly an internal feature.|\n|`APPIUM_APPS_CACHE_MAX_AGE`|Allows to set the maximum age (in minutes) for [cached applications](../guides/caching.md). The default value is `60 * 24` (24 hours). Do not set it to a lower number than the duration of a single session startup.|\n|`APPIUM_APPS_CACHE_MAX_ITEMS`|Allows to set the maximum amount of [cached applications](../guides/caching.md). The default value is `1024`. Do not set it to a lower number than the amount of apps in all parallel sessions per process.|\n|`APPIUM_APPS_CACHE_IGNORE_URL_QUERY`| If the above option is enabled then the 'search' part of the app URL will be cut off from cache keys. See the corresponding [feature request](https://discuss.appium.io/t/regarding-app-caching-when-using-aws-s3-presigned-urls/42713) for more details. Disabled by default.|","metadata":{"loc":{"lines":{"from":21,"to":24}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/env-vars.md","filename":"env-vars.md","relativePath":"appium/cli/env-vars.md"}},{"pageContent":"---\ntitle: Extension Command-Line Usage\n---\n\nAppium allows for the flexible installation and management of various _extensions_, such as _drivers_\n(which provide Appium with the capability to automate a given platform) and _plugins_ (which can\naugment or alter the way individual Appium commands work). For a conceptual understanding of these\nentities, please review the [Introduction](../intro/index.md).\n\nManagement of drivers and plugins is handled by Appium's Extension CLI (command-line interface).\n\n!!! note\n\n This reference uses placeholders to refer to various options. Anywhere you see one of these\n placeholders in the reference, ensure you replace it with the correct type of actual content.","metadata":{"loc":{"lines":{"from":1,"to":15}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/extensions.md","filename":"extensions.md","relativePath":"appium/cli/extensions.md"}},{"pageContent":"This reference uses placeholders to refer to various options. Anywhere you see one of these\n placeholders in the reference, ensure you replace it with the correct type of actual content.\n\n|Placeholder|Meaning|\n|--|--|\n|`<ext-type>`|\"Extension type\". It should be either `driver` or `plugin`. All the Extension CLI commands can be used with either drivers or plugins, so you must specify which type of extension will be used|\n|`<ext-name>`|\"Extension name\". This is the short name of the extension found in a call to `appium <ext-type> list`. This is distinct from the NPM package name of the extension or, in general, the \"install spec\" of the extension.|\n|`<install-spec>`|\"Install specification\". This refers to the string used to indicate what extension Appium should install.|\n|`<install-source>`|This refers to the method that Appium should use to install an extension.|\n\n## Commands","metadata":{"loc":{"lines":{"from":14,"to":24}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/extensions.md","filename":"extensions.md","relativePath":"appium/cli/extensions.md"}},{"pageContent":"## Commands\n\nAll Extension CLI commands begin with `appium <ext-type>`, i.e., either `appium driver` or `appium\nplugin`.\n\nAll Extension CLI commands can take an optional `--json` argument, which will return the result of\nthe command as a machine-readable JSON string rather than the standard output, which is colourized\nand tuned for human consumption.\n\n### `doctor`\n\nRun doctor checks for the given extension, which validate whether the extension has its prerequisites\nconfigured correctly. Note that not all extensions include doctor checks. See the\n[Building Doctor Checks](../developing/build-doctor-checks.md) tutorial for more details on\nhow to create them.\n\nUsage:\n\n```\nappium <ext-type> doctor <ext-name>\n```\n\nRequired arguments:\n\n- `<ext-type>`: must be `driver` or `plugin`\n- `<ext-name>`: the name of the extension whose doctor checks you want to run\n\nOptional arguments:\n\n- `--json`: return the result in JSON format\n\nExample (run doctor checks for the UiAutomator2 driver):","metadata":{"loc":{"lines":{"from":24,"to":55}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/extensions.md","filename":"extensions.md","relativePath":"appium/cli/extensions.md"}},{"pageContent":"Optional arguments:\n\n- `--json`: return the result in JSON format\n\nExample (run doctor checks for the UiAutomator2 driver):\n\n```\nappium driver doctor uiautomator2\n```\n\n### `install`\n\nInstall an extension. If successful, respond with the short name of the extension which can be used\nin other invocations of the Extension CLI. If the extension is a driver, also note which platforms\nmay be used with the driver.\n\nUsage:\n\n```\nappium <ext-type> install <install-spec> [--source=<install-source>] [--package=<package-name>] [--json]\n```\n\nRequired arguments:\n\n- `<ext-type>`: must be `driver` or `plugin`\n- `<install-spec>`: this is the name, location, and/or version of the extension you want to\n install. Its possible values are dependent on the `<install-source>` (see below).\n\nOptional arguments:","metadata":{"loc":{"lines":{"from":51,"to":79}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/extensions.md","filename":"extensions.md","relativePath":"appium/cli/extensions.md"}},{"pageContent":"Optional arguments:\n\n- `--source`: this directs Appium where to find your extension. See below for a table of possible\n source types and corresponding install specification.\n- `--package`: when `<install-source>` is `git` or `github`, `--package` is required. It should be\n the Node.js package name of the extension. Without this information, Appium will not be able to\n find the installed package.\n- `--json`: return the result in JSON format","metadata":{"loc":{"lines":{"from":79,"to":86}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/extensions.md","filename":"extensions.md","relativePath":"appium/cli/extensions.md"}},{"pageContent":"|Install source type|Behaviour|\n|--|--|\n|None|This is the default behaviour when no `--source` is used. In this case, Appium will look at `<install-spec>` and match it against the name of extensions available when running `appium <ext-type> list`, i.e., against the officially recognized extension names. If found, it will install that extension at the latest version via NPM|\n|`npm`|Install an extension based on its NPM package name. Here, `<install-spec>` must be the NPM package name with any additional NPM installation modifiers, like version (see below)|\n|`github`|Install an extension via a GitHub spec of the form `<org>/<repo>`|\n|`git`|Install an extension via a Git URL (e.g., `git+ssh://git-host.com/repo.git`)|\n|`local`|Install an extension via a local path. This must be a path to the directory where the Node.js package information for the driver is located.|\n\n#### NPM-based `<install-spec>`","metadata":{"loc":{"lines":{"from":88,"to":96}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/extensions.md","filename":"extensions.md","relativePath":"appium/cli/extensions.md"}},{"pageContent":"#### NPM-based `<install-spec>`\n\nWhen Appium is installing an extension via NPM (as is the case when `--source` is either omitted or\nset to `npm`), the `<install-spec>` can be complex, and can include any kind of information allowed\nby `npm install`:\n\n- `[@scope]/<name>`\n- `[@scope]/<name>@<version>`\n- `[@scope]/<name>@<tag>`\n- `[@scope]/<name>@<version range>`\n\n#### Examples\n\n- Install the latest XCUITest driver:\n\n ```\n appium driver install xcuitest\n ```\n\n- Install the XCUITest driver at version 4.11.1:\n\n ```\n appium driver install xcuitest@4.11.1\n ```\n\n- Install the `beta` version of the `@appium/fake-driver` from NPM:\n\n ```\n appium driver install --source=npm @appium/fake-driver@beta\n ```\n\n- Install a locally-developed plugin:\n\n ```\n appium plugin install --source=local /path/to/my/plugin\n ```\n\n### `list`","metadata":{"loc":{"lines":{"from":96,"to":133}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/extensions.md","filename":"extensions.md","relativePath":"appium/cli/extensions.md"}},{"pageContent":"- Install a locally-developed plugin:\n\n ```\n appium plugin install --source=local /path/to/my/plugin\n ```\n\n### `list`\n\nList installed and available extensions. \"Available\" extensions include those which are officially\nrecognized by the Appium team, but you are not limited to installing only the extensions displayed\nin this list.\n\nUsage:\n\n```\nappium <ext-type> list [--installed] [--updates] [--json]\n```\n\nRequired arguments:\n\n- `<ext-type>`: must be `driver` or `plugin`\n\nOptional arguments:\n\n- `--installed`: show only installed extensions, not installed plus available extensions\n- `--updates`: for extensions installed via NPM, display a message if there are any updates\n- `--json`: return the result in JSON format\n\n### `run`","metadata":{"loc":{"lines":{"from":127,"to":155}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/extensions.md","filename":"extensions.md","relativePath":"appium/cli/extensions.md"}},{"pageContent":"### `run`\n\nRun a script included in an extension package. Extension authors can include runnable scripts that\nassist with setup or perform other tasks. These scripts are given names (called the `<script-name>`\nin this reference) by extension authors and will generally be documented in extension\ndocumentation.\n\nUsage:\n\n```\nappium <ext-type> run <ext-name> [--json] <script-name> [script-args]\n```\n\nRequired arguments:\n\n- `<ext-type>`: must be `driver` or `plugin`\n- `<ext-name>`: the name of the extension whose script you want to run\n- `<script-name>`: the name of the script the extension has published\n\nOptional arguments:\n\n- `script-args`: any arguments that Appium does not interpret as belonging to its own set of\n arguments will be passed along to the extension script\n- `--json`: return the result in JSON format\n\nExample (run the `reset` script included with the UiAutomator2 driver):\n\n```\nappium driver run uiautomator2 reset\n```\n\n### `update`","metadata":{"loc":{"lines":{"from":155,"to":186}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/extensions.md","filename":"extensions.md","relativePath":"appium/cli/extensions.md"}},{"pageContent":"Example (run the `reset` script included with the UiAutomator2 driver):\n\n```\nappium driver run uiautomator2 reset\n```\n\n### `update`\n\nUpdate one or more extensions that have been installed via NPM. By default, Appium will not\nautomatically update any extension past a major version boundary, so as to prevent\nunintended breaking changes.\n\nUsage:\n\n```\nappium <ext-type> update <ext-name> [--unsafe] [--json]\n```\n\nRequired arguments:\n\n- `<ext-type>`: must be `driver` or `plugin`\n- `<ext-name>`: the name of the extension to update, or the string `installed` (which will update\n all installed extensions)\n\nOptional arguments:\n\n- `--unsafe`: direct Appium to go ahead and update past a major version boundary\n- `--json`: return the result in JSON format\n\n### `uninstall`\n\nRemove an installed extension.\n\nUsage:\n\n```\nappium <ext-type> uninstall <ext-name> [--json]\n```\n\nRequired arguments:\n\n- `<ext-type>`: must be `driver` or `plugin`\n- `<ext-name>`: the name of the extension to uninstall","metadata":{"loc":{"lines":{"from":180,"to":222}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/extensions.md","filename":"extensions.md","relativePath":"appium/cli/extensions.md"}},{"pageContent":"Usage:\n\n```\nappium <ext-type> uninstall <ext-name> [--json]\n```\n\nRequired arguments:\n\n- `<ext-type>`: must be `driver` or `plugin`\n- `<ext-name>`: the name of the extension to uninstall\n\nOptional arguments:\n\n- `--json`: return the result in JSON format","metadata":{"loc":{"lines":{"from":213,"to":226}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/extensions.md","filename":"extensions.md","relativePath":"appium/cli/extensions.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Command-Line Overview\n---\n\nAppium provides a command-line executable (`appium`), which will likely be your main way of interacting with\nthe Appium server. This section of the Appium documentation describes how to use this executable.\n\nTo start off, you can run `appium -v` or `appium --version` to return the installed version, \nor run `appium -h` or `appium --help` to return the help message.\n\nThe main `appium` executable provides the following subcommands:\n\n1. `appium server` (or simply `appium`) - launch an Appium server\n - [See here for accepted arguments](./args.md)\n - For advanced features, [see here for accepted environment variables](./env-vars.md)\n2. `appium driver` - manage Appium drivers\n - [See here for details](./extensions.md)\n3. `appium plugin` - manage Appium plugins\n - [See here for details](./extensions.md)\n4. `appium setup` - batch install a preset of drivers and plugins\n - [See here for details](./setup.md)","metadata":{"loc":{"lines":{"from":1,"to":24}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/index.md","filename":"index.md","relativePath":"appium/cli/index.md"}},{"pageContent":"Like the main command, you can also run each subcommand with the `-h` or `--help` flag to learn more about it.","metadata":{"loc":{"lines":{"from":26,"to":26}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/index.md","filename":"index.md","relativePath":"appium/cli/index.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Setup Command-Line Usage\n---\n\nThe `setup` command aims to simplify the initial procedure of setting up Appium. It allows to install\nmultiple extensions (drivers/plugins) in one go, without the need to run\n`appium <ext-name> install <ext-name>` multiple times.\n\nThe command has several presets that can be used to install different sets of extensions.\nThe presets are as follows:\n\n|Preset|Installation Command|Included Drivers|Included Plugins|\n|--|--|--|--|\n|Mobile|`appium setup mobile` or `appium setup`|`uiautomator2`, `xcuitest`[^1], `espresso`|`images`|\n|Desktop application|`appium setup desktop`|`mac2`[^1], `windows`[^2]|`images`|\n|Desktop browser|`appium setup browser`|`safari`[^1], `gecko`, `chromium`|`images`|\n\nAttempting to install a preset while already having one or more of its included extensions installed\nwill only install the missing extensions.","metadata":{"loc":{"lines":{"from":1,"to":22}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/setup.md","filename":"setup.md","relativePath":"appium/cli/setup.md"}},{"pageContent":"Attempting to install a preset while already having one or more of its included extensions installed\nwill only install the missing extensions.\n\nRefer to the [Ecosystem documentation](../ecosystem/index.md) to learn more about the extensions\nlisted above.\n\nThis commands also supports the functionality that allows to fully reset your Appium server\ndeployment if you experience various configuration issues,\nfor example, due to a failed upgrade attempt from an older Appium version, on server startup.\nBy running `appium setup reset` the server would uninstall all installed drivers, plugins and their related manifest files from the currently used Appium home folder.\n\n[^1]: Only installed if the host machine is running macOS.\n[^2]: Only installed if the host machine is running Windows.","metadata":{"loc":{"lines":{"from":21,"to":33}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/cli/setup.md","filename":"setup.md","relativePath":"appium/cli/setup.md"}},{"pageContent":"# Driver: base-driver\n\n### `createSession`\n\n`POST` **`/session`**\n\nHistorically the first two arguments were reserved for JSONWP capabilities.\nAppium 2 has dropped the support of these, so now we only accept capability\nobjects in W3C format and thus allow any of the three arguments to represent\nthe latter.\n\n**`See`**\n\n[https://w3c.github.io/webdriver/#new-session](https://w3c.github.io/webdriver/#new-session)\n\n<!-- comment source: multiple -->\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `desiredCapabilities?` | `W3CDriverCaps`<`C`\\> | the new session capabilities |\n| `requiredCapabilities?` | `W3CDriverCaps`<`C`\\> | another place the new session capabilities could be sent (typically left undefined) |\n| `capabilities?` | `W3CDriverCaps`<`C`\\> | another place the new session capabilities could be sent (typically left undefined) |\n\n#### Response\n\n`CreateResult`\n\nThe capabilities object representing the created session\n\n### `deleteSession`","metadata":{"loc":{"lines":{"from":1,"to":32}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/base-driver.md","filename":"base-driver.md","relativePath":"appium/commands/base-driver.md"}},{"pageContent":"#### Response\n\n`CreateResult`\n\nThe capabilities object representing the created session\n\n### `deleteSession`\n\n`DELETE` **`/session/:sessionId`**\n\nReturns capabilities for the session and event history (if applicable)\n\n<!-- comment source: method-signature -->\n\n#### Response\n\n`SingularSessionData`<`C`, `SessionData`\\>\n\nA session data object\n\n### `getSession`\n\n`GET` **`/session/:sessionId`**\n\nReturns capabilities for the session and event history (if applicable).\n\n!!! warning \"Deprecated\"\n\n Please use `getAppiumSessionCapabilities` to get the session capabilities.\n Please use `getLogEvents` to get event history.\n\n\n<!-- comment source: multiple -->\n\n#### Response\n\n`SingularSessionData`<`C`, `SessionData`\\>\n\nA session data object\n\n### `getAppiumSessionCapabilities`\n\n`GET` **`/session/:sessionId/appium/capabilities`**\n\nReturns capabilities for the session.\n\n<!-- comment source: multiple -->\n\n#### Response\n\n`AppiumSessionCapabilities`\n\nA session data object\n\n### `findElement`","metadata":{"loc":{"lines":{"from":26,"to":80}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/base-driver.md","filename":"base-driver.md","relativePath":"appium/commands/base-driver.md"}},{"pageContent":"Returns capabilities for the session.\n\n<!-- comment source: multiple -->\n\n#### Response\n\n`AppiumSessionCapabilities`\n\nA session data object\n\n### `findElement`\n\n`POST` **`/session/:sessionId/element`**\n\nFind a UI element given a locator strategy and a selector, erroring if it can't be found\n\n**`See`**\n\n[https://w3c.github.io/webdriver/#find-element](https://w3c.github.io/webdriver/#find-element)\n\n<!-- comment source: method-signature -->\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `using` | `string` | the locator strategy |\n| `value` | `string` | the selector to combine with the strategy to find the specific element |\n\n#### Response\n\n`Element`<`string`\\>\n\nThe element object encoding the element id which can be used in element-related\ncommands\n\n### `findElementFromElement`\n\n`POST` **`/session/:sessionId/element/:elementId/element`**","metadata":{"loc":{"lines":{"from":70,"to":108}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/base-driver.md","filename":"base-driver.md","relativePath":"appium/commands/base-driver.md"}},{"pageContent":"The element object encoding the element id which can be used in element-related\ncommands\n\n### `findElementFromElement`\n\n`POST` **`/session/:sessionId/element/:elementId/element`**\n\nFind a UI element given a locator strategy and a selector, erroring if it can't be found. Only\nlook for elements among the set of descendants of a given element\n\n**`See`**\n\n[https://w3c.github.io/webdriver/#find-element-from-element](https://w3c.github.io/webdriver/#find-element-from-element)\n\n<!-- comment source: method-signature -->\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `using` | `string` | the locator strategy |\n| `value` | `string` | the selector to combine with the strategy to find the specific element |\n\n#### Response\n\n`Element`<`string`\\>\n\nThe element object encoding the element id which can be used in element-related\ncommands\n\n### `findElementFromShadowRoot`\n\n`POST` **`/session/:sessionId/shadow/:shadowId/element`**\n\nFind an element from a shadow root","metadata":{"loc":{"lines":{"from":103,"to":137}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/base-driver.md","filename":"base-driver.md","relativePath":"appium/commands/base-driver.md"}},{"pageContent":"### `findElementFromShadowRoot`\n\n`POST` **`/session/:sessionId/shadow/:shadowId/element`**\n\nFind an element from a shadow root\n\n**`See`**\n\n[https://w3c.github.io/webdriver/#find-element-from-shadow-root](https://w3c.github.io/webdriver/#find-element-from-shadow-root)\n\n<!-- comment source: method-signature -->\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `using` | `string` | the locator strategy |\n| `value` | `string` | the selector to combine with the strategy to find the specific elements |\n\n#### Response\n\n`Element`<`string`\\>\n\nThe element inside the shadow root matching the selector\n\n### `findElements`\n\n`POST` **`/session/:sessionId/elements`**\n\nFind a a list of all UI elements matching a given a locator strategy and a selector\n\n**`See`**\n\n[https://w3c.github.io/webdriver/#find-elements](https://w3c.github.io/webdriver/#find-elements)\n\n<!-- comment source: method-signature -->\n\n#### Parameters","metadata":{"loc":{"lines":{"from":133,"to":170}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/base-driver.md","filename":"base-driver.md","relativePath":"appium/commands/base-driver.md"}},{"pageContent":"**`See`**\n\n[https://w3c.github.io/webdriver/#find-elements](https://w3c.github.io/webdriver/#find-elements)\n\n<!-- comment source: method-signature -->\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `using` | `string` | the locator strategy |\n| `value` | `string` | the selector to combine with the strategy to find the specific elements |\n\n#### Response\n\n`Element`<`string`\\>[]\n\nA possibly-empty list of element objects\n\n### `findElementsFromElement`\n\n`POST` **`/session/:sessionId/element/:elementId/elements`**\n\nFind a a list of all UI elements matching a given a locator strategy and a selector. Only\nlook for elements among the set of descendants of a given element\n\n**`See`**\n\n[https://w3c.github.io/webdriver/#find-elements-from-element](https://w3c.github.io/webdriver/#find-elements-from-element)\n\n<!-- comment source: method-signature -->\n\n#### Parameters","metadata":{"loc":{"lines":{"from":164,"to":196}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/base-driver.md","filename":"base-driver.md","relativePath":"appium/commands/base-driver.md"}},{"pageContent":"**`See`**\n\n[https://w3c.github.io/webdriver/#find-elements-from-element](https://w3c.github.io/webdriver/#find-elements-from-element)\n\n<!-- comment source: method-signature -->\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `using` | `string` | the locator strategy |\n| `value` | `string` | the selector to combine with the strategy to find the specific elements |\n\n#### Response\n\n`Element`<`string`\\>[]\n\nA possibly-empty list of element objects\n\n### `findElementsFromShadowRoot`\n\n`POST` **`/session/:sessionId/shadow/:shadowId/elements`**\n\nFind elements from a shadow root\n\n**`See`**\n\n[https://w3c.github.io/webdriver/#find-element-from-shadow-root](https://w3c.github.io/webdriver/#find-element-from-shadow-root)\n\n<!-- comment source: method-signature -->\n\n#### Parameters","metadata":{"loc":{"lines":{"from":190,"to":221}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/base-driver.md","filename":"base-driver.md","relativePath":"appium/commands/base-driver.md"}},{"pageContent":"[https://w3c.github.io/webdriver/#find-element-from-shadow-root](https://w3c.github.io/webdriver/#find-element-from-shadow-root)\n\n<!-- comment source: method-signature -->\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `using` | `string` | the locator strategy |\n| `value` | `string` | the selector to combine with the strategy to find the specific elements |\n\n#### Response\n\n`Element`<`string`\\>[]\n\nA possibly empty list of elements inside the shadow root matching the selector\n\n### `getLog`\n\n`POST` **`/session/:sessionId/se/log`**\n\nGet the log for a given log type.\n\n<!-- comment source: method-signature -->\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `type` | `string` | Name/key of log type as defined in ILogCommands.supportedLogTypes. |\n\n#### Response\n\n`any`\n\n### `getLogEvents`\n\n`POST` **`/session/:sessionId/appium/events`**\n\nGet a list of events that have occurred in the current session","metadata":{"loc":{"lines":{"from":217,"to":256}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/base-driver.md","filename":"base-driver.md","relativePath":"appium/commands/base-driver.md"}},{"pageContent":"#### Response\n\n`any`\n\n### `getLogEvents`\n\n`POST` **`/session/:sessionId/appium/events`**\n\nGet a list of events that have occurred in the current session\n\n<!-- comment source: method-signature -->\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `type?` | `string` \\| `string`[] | filter the returned events by including one or more types |\n\n#### Response\n\n`EventHistory` \\| `Record`<`string`, `number`\\>\n\nThe event history for the session\n\n### `getLogTypes`\n\n`GET` **`/session/:sessionId/se/log/types`**\n\nGet available log types as a list of strings\n\n<!-- comment source: method-signature -->\n\n#### Response\n\n`string`[]\n\n### `getPageSource`\n\n`GET` **`/session/:sessionId/source`**\n\nGet the current page/app source as HTML/XML\n\n**`See`**\n\n[https://w3c.github.io/webdriver/#get-page-source](https://w3c.github.io/webdriver/#get-page-source)\n\n<!-- comment source: method-signature -->\n\n#### Response\n\n`string`","metadata":{"loc":{"lines":{"from":248,"to":298}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/base-driver.md","filename":"base-driver.md","relativePath":"appium/commands/base-driver.md"}},{"pageContent":"**`See`**\n\n[https://w3c.github.io/webdriver/#get-page-source](https://w3c.github.io/webdriver/#get-page-source)\n\n<!-- comment source: method-signature -->\n\n#### Response\n\n`string`\n\nThe UI hierarchy in a platform-appropriate format (e.g., HTML for a web page)\n\n### `getAppiumSessions`\n\n`GET` **`/appium/sessions`**\n\nGet data for all sessions running on an Appium server\n\n<!-- comment source: method-signature -->\n\n#### Response\n\nA list of session data objects, where each object contains 3 keys:\n\n* `id`: the session ID\n* `created`: the session creation time as a Unix timestamp in milliseconds\n* `capabilities`: the session capabilities\n\nData is only returned if the `session_discovery` [insecure feature](../guides/security.md)\nis enabled on the server.\n\n#### Example","metadata":{"loc":{"lines":{"from":290,"to":321}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/base-driver.md","filename":"base-driver.md","relativePath":"appium/commands/base-driver.md"}},{"pageContent":"Data is only returned if the `session_discovery` [insecure feature](../guides/security.md)\nis enabled on the server.\n\n#### Example\n\n```json\n[\n {\n \"id\":\"ba30c6da-c266-4734-8ddb-c16f5bb53e16\",\n \"created\": 1736092760555,\n \"capabilities\":{ \"platformName\":\"ios\",\"browserName\":\"safari\",\"automationName\":\"xcuitest\",\"platformVersion\":\"17.2\",\"deviceName\":\"iPhone 15\" }\n },\n {\n \"id\":\"1441110c-1ece-4e45-abbf-ebf404f45f0a\",\n \"created\": 1736092760555,\n \"capabilities\":{ \"platformName\":\"ios\",\"browserName\":\"safari\",\"automationName\":\"xcuitest\",\"platformVersion\":\"17.0\",\"deviceName\":\"iPhone 14\" }\n },\n ...\n]\n```\n\n### `getSettings`\n\n`GET` **`/session/:sessionId/appium/settings`**\n\nUpdate the session's settings dictionary with a new settings object\n\n<!-- comment source: method-signature -->\n\n#### Response\n\n``null``\n\n### `updateSettings`\n\n`POST` **`/session/:sessionId/appium/settings`**\n\nUpdate the session's settings dictionary with a new settings object","metadata":{"loc":{"lines":{"from":318,"to":355}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/base-driver.md","filename":"base-driver.md","relativePath":"appium/commands/base-driver.md"}},{"pageContent":"#### Response\n\n``null``\n\n### `updateSettings`\n\n`POST` **`/session/:sessionId/appium/settings`**\n\nUpdate the session's settings dictionary with a new settings object\n\n<!-- comment source: method-signature -->\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `settings` | `Settings` | A key-value map of setting names to values. Settings not named in the map will not have their value adjusted. |\n\n#### Response\n\n``null``\n\n### `getStatus`\n\n`GET` **`/status`**\n\n**`Summary`**\n\nRetrieve the server's current status.\n\n**`Description`**\n\nReturns information about whether a remote end is in a state in which it can create new sessions and can additionally include arbitrary meta information that is specific to the implementation.\n\nThe readiness state is represented by the ready property of the body, which is false if an attempt to create a session at the current time would fail. However, the value true does not guarantee that a New Session command will succeed.","metadata":{"loc":{"lines":{"from":347,"to":381}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/base-driver.md","filename":"base-driver.md","relativePath":"appium/commands/base-driver.md"}},{"pageContent":"Implementations may optionally include additional meta information as part of the body, but the top-level properties ready and message are reserved and must not be overwritten.\n\n<!-- comment source: builtin-interface -->\n\n#### Examples\n\n<!-- BEGIN:EXAMPLES -->\n##### JavaScript\n<!-- BEGIN:EXAMPLE lang=JavaScript -->\n\n```js\n// webdriver.io example\nawait driver.status();\n```\n\n<!-- END:EXAMPLE -->\n##### Python\n<!-- BEGIN:EXAMPLE lang=Python -->\n\n```python\ndriver.get_status()\n```\n\n<!-- END:EXAMPLE -->\n##### Java\n<!-- BEGIN:EXAMPLE lang=Java -->\n\n```java\ndriver.getStatus();\n```\n\n<!-- END:EXAMPLE -->\n##### Ruby\n<!-- BEGIN:EXAMPLE lang=Ruby -->\n\n```ruby\n# ruby_lib example\nremote_status\n\n# ruby_lib_core example\n@driver.remote_status\n```\n\n<!-- END:EXAMPLE -->\n<!-- END:EXAMPLES -->\n\n#### Response\n\n`Object`\n\n### `getTimeouts`\n\n`GET` **`/session/:sessionId/timeouts`**\n\nSet the various timeouts associated with a session\n\n**`See`**","metadata":{"loc":{"lines":{"from":383,"to":439}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/base-driver.md","filename":"base-driver.md","relativePath":"appium/commands/base-driver.md"}},{"pageContent":"<!-- END:EXAMPLE -->\n<!-- END:EXAMPLES -->\n\n#### Response\n\n`Object`\n\n### `getTimeouts`\n\n`GET` **`/session/:sessionId/timeouts`**\n\nSet the various timeouts associated with a session\n\n**`See`**\n\n[https://w3c.github.io/webdriver/#set-timeouts](https://w3c.github.io/webdriver/#set-timeouts)\n\n<!-- comment source: method-signature -->\n\n#### Response\n\n``null``\n\n### `timeouts`\n\n`POST` **`/session/:sessionId/timeouts`**\n\nSet the various timeouts associated with a session\n\n**`See`**\n\n[https://w3c.github.io/webdriver/#set-timeouts](https://w3c.github.io/webdriver/#set-timeouts)\n\n<!-- comment source: method-signature -->\n\n#### Parameters","metadata":{"loc":{"lines":{"from":426,"to":461}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/base-driver.md","filename":"base-driver.md","relativePath":"appium/commands/base-driver.md"}},{"pageContent":"**`See`**\n\n[https://w3c.github.io/webdriver/#set-timeouts](https://w3c.github.io/webdriver/#set-timeouts)\n\n<!-- comment source: method-signature -->\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `type?` | `string` | used only for the old (JSONWP) command, the type of the timeout |\n| `ms?` | `string` \\| `number` | used only for the old (JSONWP) command, the ms for the timeout |\n| `script?` | `number` | the number in ms for the script timeout, used for the W3C command |\n| `pageLoad?` | `number` | the number in ms for the pageLoad timeout, used for the W3C command |\n| `implicit?` | `string` \\| `number` | the number in ms for the implicit wait timeout, used for the W3C command |\n\n#### Response\n\n``null``\n\n### `logCustomEvent`\n\n`POST` **`/session/:sessionId/appium/log_event`**\n\nAdd a custom-named event to the Appium event log\n\n<!-- comment source: method-signature -->\n\n#### Parameters","metadata":{"loc":{"lines":{"from":455,"to":483}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/base-driver.md","filename":"base-driver.md","relativePath":"appium/commands/base-driver.md"}},{"pageContent":"``null``\n\n### `logCustomEvent`\n\n`POST` **`/session/:sessionId/appium/log_event`**\n\nAdd a custom-named event to the Appium event log\n\n<!-- comment source: method-signature -->\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `vendor` | `string` | the name of the vendor or tool the event belongs to, to namespace the event |\n| `event` | `string` | the name of the event itself |\n\n#### Response\n\n``null``","metadata":{"loc":{"lines":{"from":473,"to":492}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/base-driver.md","filename":"base-driver.md","relativePath":"appium/commands/base-driver.md"}},{"pageContent":"# Plugin: execute-driver\n\n### `executeDriverScript`\n\n`POST` **`/session/:sessionId/appium/execute_driver`**\n\nImplementation of a command within a plugin\n\nAt minimum, `D` must be `ExternalDriver`, but a plugin can be more narrow about which drivers it supports.\n\n<!-- comment source: method-signature -->\n\n#### Parameters\n\n| Name | Type |\n| :------ | :------ |\n| `script` | [script: string, scriptType: string, timeoutMs: number] |\n| `type?` | [script: string, scriptType: string, timeoutMs: number] |\n\n#### Response\n\n`unknown`","metadata":{"loc":{"lines":{"from":1,"to":22}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/execute-driver-plugin.md","filename":"execute-driver-plugin.md","relativePath":"appium/commands/execute-driver-plugin.md"}},{"pageContent":"# Plugin: images\n\n### `compareImages`\n\n`POST` **`/session/:sessionId/appium/compare_images`**\n\n#### Parameters\n\n| Name | Type |\n| :------ | :------ |\n| `mode` | `any`[] |\n| `options?` | `any`[] |\n\n#### Response\n\n`ComparisonResult`\n\n### `findElement`\n\n`POST` **`/session/:sessionId/element`**\n\nFind a UI element given a locator strategy and a selector, erroring if it can't be found\n\n**`See`**\n\n[https://w3c.github.io/webdriver/#find-element](https://w3c.github.io/webdriver/#find-element)\n\n<!-- comment source: method-signature -->\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `using` | `any` | the locator strategy |\n| `value` | `any` | the selector to combine with the strategy to find the specific element |\n\n#### Response\n\n`any`\n\nThe element object encoding the element id which can be used in element-related\ncommands\n\n### `findElements`\n\n`POST` **`/session/:sessionId/elements`**","metadata":{"loc":{"lines":{"from":1,"to":46}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/images-plugin.md","filename":"images-plugin.md","relativePath":"appium/commands/images-plugin.md"}},{"pageContent":"#### Response\n\n`any`\n\nThe element object encoding the element id which can be used in element-related\ncommands\n\n### `findElements`\n\n`POST` **`/session/:sessionId/elements`**\n\nFind a a list of all UI elements matching a given a locator strategy and a selector\n\n**`See`**\n\n[https://w3c.github.io/webdriver/#find-elements](https://w3c.github.io/webdriver/#find-elements)\n\n<!-- comment source: method-signature -->\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `using` | `any` | the locator strategy |\n| `value` | `any` | the selector to combine with the strategy to find the specific elements |\n\n#### Response\n\n`any`\n\nA possibly-empty list of element objects\n\n### `performActions`\n\n`POST` **`/session/:sessionId/actions`**\n\nIf the actions contains image elements as origin, convert them to viewport coordinates before sending it to the external driver\n\n**`See`**\n\n[https://w3c.github.io/webdriver/#perform-actions](https://w3c.github.io/webdriver/#perform-actions)","metadata":{"loc":{"lines":{"from":37,"to":77}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/images-plugin.md","filename":"images-plugin.md","relativePath":"appium/commands/images-plugin.md"}},{"pageContent":"**`See`**\n\n[https://w3c.github.io/webdriver/#perform-actions](https://w3c.github.io/webdriver/#perform-actions)\n\n<!-- comment source: method-signature -->\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `actions` | `ActionSequence[]` | an array of action sequences |\n\n#### Response\n\n`null`","metadata":{"loc":{"lines":{"from":75,"to":89}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/images-plugin.md","filename":"images-plugin.md","relativePath":"appium/commands/images-plugin.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Intro to Commands\n---\n\nHere you can find various commands exposed by the main Appium module through its base driver, as\nwell as the commands available in several plugins.\n\n!!! note\n\n The Appium base driver only exposes a few commands, as it is not meant to be used on its own.\n Please refer to the documentation of your [Appium driver](../ecosystem/drivers.md) to learn\n about the commands it exposes, and then check your [Appium client](../ecosystem/clients.md)\n documentation for the exact syntax of that command.\n\nThe command listings can be found here:\n\n* [Base Driver](./base-driver.md)\n* [Execute Driver Plugin](./execute-driver-plugin.md)\n* [Images Plugin](./images-plugin.md)\n* [Inspector](https://github.com/appium/appium-inspector/tree/main/plugins)\n* [Relaxed Caps Plugin](./relaxed-caps-plugin.md)\n* [Storage Plugin](./storage-plugin.md)\n* [Universal XML Plugin](./universal-xml-plugin.md)","metadata":{"loc":{"lines":{"from":1,"to":26}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/index.md","filename":"index.md","relativePath":"appium/commands/index.md"}},{"pageContent":"# Plugin: relaxed-caps\n\n### `createSession`\n\n`POST` **`/session`**\n\nStart a new automation session\n\n**`See`**\n\n[https://w3c.github.io/webdriver/#new-session](https://w3c.github.io/webdriver/#new-session)\n\n<!-- comment source: multiple -->\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `desiredCapabilities?` | `any` | the new session capabilities |\n| `requiredCapabilities?` | `any` | another place the new session capabilities could be sent (typically left undefined) |\n| `capabilities?` | `any` | another place the new session capabilities could be sent (typically left undefined) |\n\n#### Response\n\n`any`\n\nThe capabilities object representing the created session","metadata":{"loc":{"lines":{"from":1,"to":27}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/relaxed-caps-plugin.md","filename":"relaxed-caps-plugin.md","relativePath":"appium/commands/relaxed-caps-plugin.md"}},{"pageContent":"# Plugin: storage\n\n!!! tip\n\n All these commands can be invoked without creating a session, allowing you to\n prepare your test environment in advance.\n\n### `addStorageItem`\n\n`POST` **`/storage/add`**\n\nAdd a new file to the storage\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `name` | `string` | the name used to save the file (must not include path separator characters) |\n| `sha1` | `string` | SHA1 hash of the file to be uploaded |\n\n#### Example\n\n```bash\ncurl -X POST --header \"Content-Type: application/json\" --data '{\"name\":\"app.ipa\",\"sha1\":\"ccc963411b2621335657963322890305ebe96186\"}' http://127.0.0.1:4723/storage/add\n```\n\n#### Response\n\n`AddRequestResult`\n\nA JSON object in the following format:\n```json\n{\n \"ws\": {\n \"stream\": \"/storage/add/ccc963411b2621335657963322890305ebe96186/stream\",\n \"events\": \"/storage/add/ccc963411b2621335657963322890305ebe96186/events\"\n },\n \"ttlMs\": 300000\n}\n```","metadata":{"loc":{"lines":{"from":1,"to":40}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/storage-plugin.md","filename":"storage-plugin.md","relativePath":"appium/commands/storage-plugin.md"}},{"pageContent":"| Name | Type | Description |\n| :------ | :------ | :------ |\n| `ws.stream` | `string` | the pathname of the streaming web socket used to upload the file content |\n| `ws.events` | `string` | the pathname of the events web socket used to notify about upload success or a failure |\n| `ttlMs` | `number` | the amount of milliseconds both web sockets will be kept active before they expire, or a file payload would be successfully uploaded |\n\n\n### `listStorageItems`\n\n`GET` **`/storage/list`**\n\nList all files present in the storage\n\n#### Example\n\n```bash\ncurl http://127.0.0.1:4723/storage/list\n```\n\n#### Response\n\n`List<StorageItem>`\n\nA list of items, where each item has the following properties:\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `name` | `string` | the name of the file in the storage |\n| `path` | `string` | full path to the file on the remote file system |\n| `size` | `number` | file size in bytes |\n\n### `deleteStorageItem`\n\n`POST` **`/storage/delete`**","metadata":{"loc":{"lines":{"from":42,"to":75}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/storage-plugin.md","filename":"storage-plugin.md","relativePath":"appium/commands/storage-plugin.md"}},{"pageContent":"### `deleteStorageItem`\n\n`POST` **`/storage/delete`**\n\nDeletes a file in the storage with the specified name\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `name` | `string` | the name of the file to be deleted |\n\n#### Example\n\n```bash\ncurl -X POST --header \"Content-Type: application/json\" --data '{\"name\":\"app.ipa\"}' http://127.0.0.1:4723/storage/delete\n```\n\n#### Response\n\n`boolean`\n\n`false` if the file does not exist in the storage, or `true` upon successful file deletion \n\n### `resetStorage`\n\n`POST` **`/storage/reset`**\n\nDeletes all uploaded files and stops any incomplete uploads.\nIf the `APPIUM_STORAGE_KEEP_ALL` flag is enabled, all uploaded files will be preserved,\nand only the incomplete uploads will be stopped.\n\n#### Example\n\n```bash\ncurl -X POST http://127.0.0.1:4723/storage/reset\n```\n\n#### Response\n\n`undefined`","metadata":{"loc":{"lines":{"from":73,"to":113}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/storage-plugin.md","filename":"storage-plugin.md","relativePath":"appium/commands/storage-plugin.md"}},{"pageContent":"# Plugin: universal-xml\n\n### `findElement`\n\n`POST` **`/session/:sessionId/element`**\n\nFind a UI element given a locator strategy and a selector, erroring if it can't be found\n\n**`See`**\n\n[https://w3c.github.io/webdriver/#find-element](https://w3c.github.io/webdriver/#find-element)\n\n<!-- comment source: method-signature -->\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `using` | `any`[] | the locator strategy |\n\n#### Response\n\n`any`\n\nThe element object encoding the element id which can be used in element-related\ncommands\n\n### `findElements`\n\n`POST` **`/session/:sessionId/elements`**\n\nFind a a list of all UI elements matching a given a locator strategy and a selector\n\n**`See`**\n\n[https://w3c.github.io/webdriver/#find-elements](https://w3c.github.io/webdriver/#find-elements)\n\n<!-- comment source: method-signature -->\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `using` | `any`[] | the locator strategy |","metadata":{"loc":{"lines":{"from":1,"to":44}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/universal-xml-plugin.md","filename":"universal-xml-plugin.md","relativePath":"appium/commands/universal-xml-plugin.md"}},{"pageContent":"<!-- comment source: method-signature -->\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `using` | `any`[] | the locator strategy |\n\n#### Response\n\n`any`\n\nA possibly-empty list of element objects\n\n### `getPageSource`\n\n`GET` **`/session/:sessionId/source`**\n\nGet the current page/app source as HTML/XML\n\n**`See`**\n\n[https://w3c.github.io/webdriver/#get-page-source](https://w3c.github.io/webdriver/#get-page-source)\n\n<!-- comment source: method-signature -->\n\n#### Response\n\n`string`\n\nThe UI hierarchy in a platform-appropriate format (e.g., HTML for a web page)","metadata":{"loc":{"lines":{"from":38,"to":68}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/commands/universal-xml-plugin.md","filename":"universal-xml-plugin.md","relativePath":"appium/commands/universal-xml-plugin.md"}},{"pageContent":"---\nhide:\n - navigation\n\ntitle: Contributing to Appium\n---\n\nThe Appium project would not exist without the many contributions of code, documentation,\nmaintenance, and support from companies and volunteers. As such, we welcome contributions!\n\nThere are a lot of different ways to help the project - see below for everything you can do and the\nprocesses to follow for each contribution method. Note that no matter how you contribute, your\nparticipation is governed by our [Code of Conduct](https://github.com/appium/appium/blob/master/CONDUCT.md).\n\n## Join the Discussion Forum\n\nYou don't need to know the internals of Appium to be able to contribute! If you have experience with\nusing Appium and feel like sharing your knowledge with others, consider helping out users on the\nAppium forums at [discuss.appium.io](https://discuss.appium.io/). Hop on over and see if there are\nany questions that you can answer.\n\n## Report Bugs or Feature Requests","metadata":{"loc":{"lines":{"from":1,"to":22}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/contributing.md","filename":"contributing.md","relativePath":"appium/contributing.md"}},{"pageContent":"## Report Bugs or Feature Requests\n\nIf you've encountered a bug, or have a cool feature in mind that you think Appium should support,\nmake sure to let us know at our [GitHub issue tracker](https://github.com/appium/appium/issues).\nPlease use the appropriate issue form template when creating your issue.\n\n## Triage Issues\n\nIn addition to creating issues, you can also help us investigate already reported issues. All you\nneed is enough familiarity with Appium to try and reproduce bugs.\n\nYou can get started by checking our [GitHub issue tracker](https://github.com/appium/appium/issues)\nfor issues with labels such as `Needs Triage` or `Needs Info`, and leaving relevant comments:","metadata":{"loc":{"lines":{"from":22,"to":34}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/contributing.md","filename":"contributing.md","relativePath":"appium/contributing.md"}},{"pageContent":"You can get started by checking our [GitHub issue tracker](https://github.com/appium/appium/issues)\nfor issues with labels such as `Needs Triage` or `Needs Info`, and leaving relevant comments:\n\n- If the issue is a duplicate, drop a link to the original issue\n- If the user has not provided enough information (such as Appium logs), ask them for more details\n- If you can reproduce the problem on your own environment, provide all the information that you think\n would help us track down the cause of the issue\n\nFor further information on triaging Appium issues (for any Appium project repository), please contact\nany member of the [Technical Committee](https://github.com/appium/appium/blob/master/GOVERNANCE.md#the-technical-committee).\n\n## Contribute Code\n\nWe are always open to pull requests for improving the Appium code or documentation!\n\n!!! info","metadata":{"loc":{"lines":{"from":33,"to":48}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/contributing.md","filename":"contributing.md","relativePath":"appium/contributing.md"}},{"pageContent":"## Contribute Code\n\nWe are always open to pull requests for improving the Appium code or documentation!\n\n!!! info\n\n Developer information may not be kept up to date as frequently as user-facing information, or\n it may be most relevant in its current form on the online repository, not in this published\n version. Make sure to check the repo or discuss with maintainers. We would be glad to help\n new contributors get started!\n\nStart by cloning the repository (we recommend [forking](https://github.com/appium/appium/fork)\nit first):\n```sh\ngit clone https://github.com/appium/appium.git\ncd appium\n```\n\n!!! info\n\n If you are VS Code user, you can easily check out the project using [Runme](https://runme.dev/api/runme?repository=https%3A%2F%2Fgithub.com%2Fappium%2Fappium.git&fileToOpen=packages%2Fappium%2Fdocs%2Fen%2Fcontributing%2Findex.md).\n\nInstall dependencies:\n```sh\nnpm install\n```\n\nFrom here on there are several things you can do.\n\nBuild the project:\n```sh\nnpm run build\n```","metadata":{"loc":{"lines":{"from":44,"to":76}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/contributing.md","filename":"contributing.md","relativePath":"appium/contributing.md"}},{"pageContent":"Install dependencies:\n```sh\nnpm install\n```\n\nFrom here on there are several things you can do.\n\nBuild the project:\n```sh\nnpm run build\n```\n\nBuild the project and watch for changes:\n```sh\nnpm run dev\n```\n\nStart the locally built Appium server:\n```sh\nnpm start\n```\n\nRun various tests:\n```sh\nnpm run lint\nnpm run test:unit\nnpm run test:types\nnpm run test:smoke\nnpm run test:e2e\nnpm run test:quick # unit and types\nnpm run test:slow # everything\n```\n\nYou can also run tests for specific workspaces, e.g.:\n\n```sh\nexport APPIUM_WORKSPACE=@appium/base-driver\nnpm run test:unit -w $APPIUM_WORKSPACE\n```\n\n### Documentation","metadata":{"loc":{"lines":{"from":66,"to":106}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/contributing.md","filename":"contributing.md","relativePath":"appium/contributing.md"}},{"pageContent":"You can also run tests for specific workspaces, e.g.:\n\n```sh\nexport APPIUM_WORKSPACE=@appium/base-driver\nnpm run test:unit -w $APPIUM_WORKSPACE\n```\n\n### Documentation\n\nThe documentation for this project is [available in the project repository itself](https://github.com/appium/appium/tree/master/packages/appium/docs).\nIt is contained in Markdown files, which are built by our documentation system in the\n`@appium/docutils` module. This module is based on [MkDocs](https://www.mkdocs.org/) and therefore\nrequires [Python](https://www.python.org/) to be installed on your system.\n\nInstall Python dependencies:\n```sh\nnpm run install-docs-deps\n```\n\nAfter making your changes, you can run the documentation server in dev mode:\n```sh\nnpm run dev:docs\n```\n\nYou can then view the documentation at `http://127.0.0.1:8000/docs/en`.\n\n## Translating Appium Documentation","metadata":{"loc":{"lines":{"from":99,"to":125}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/contributing.md","filename":"contributing.md","relativePath":"appium/contributing.md"}},{"pageContent":"You can then view the documentation at `http://127.0.0.1:8000/docs/en`.\n\n## Translating Appium Documentation\n\nThe process of Appium documents localization into languages other than English is automated and is done via\nthe [Crowdin Translations Management System](https://crowdin.com). Do not edit any translated documents\ndirectly in the GitHub Appium repository as they are going to be replaced with ones exported from Crowdin\nduring an upcoming sync.\n\n### Where To Start\n\nIf you would like to contribute to the translation of Appium documents into your language then simply join\nthe translators group for the [Appium Documentation](https://crowdin.com/project/appium-documentation)\nCrowdin project, and start translating documents there. If you see that your language is missing from\nthe list of available Crowdin languages then simply let us know by creating an\n[issue](https://github.com/appium/appium/issues).\n\n### Source Language Updates","metadata":{"loc":{"lines":{"from":123,"to":140}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/contributing.md","filename":"contributing.md","relativePath":"appium/contributing.md"}},{"pageContent":"### Source Language Updates\n\nChanges in documents are synchronized to Crowdin automatically via the `Update Crowdin English Docs` GitHub action.\nThis action is triggered automatically as soon as there are any changes under `packages/appium/docs/en/**.md`\nor `packages/appium/docs/mkdocs-en.yml`.\n\n### Fetching Translated Documents\n\nIn order to fetch translated files from Crowdin to the GitHub repository it is necessary to trigger\nthe `Sync Crowdin Docs Translations` action. This action should also automatically create a PR with\ncorresponding translated resources included.","metadata":{"loc":{"lines":{"from":140,"to":150}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/contributing.md","filename":"contributing.md","relativePath":"appium/contributing.md"}},{"pageContent":"---\ntitle: Building Documentation\n---\n\nOnce you've [built a driver](./build-drivers.md) or [built a plugin](./build-plugins.md) for Appium,\nyou will hopefully want to document how that extension works for your users. The most basic way of\ndoing this is to write up a quick `README.md` and keep it in the root of your project's repository.\nHowever, this can involve a lot of effort.\n\nThe Appium project has built tools to help with this, and we've packaged up these tools so our\necosystem developers building drivers and plugins can _also_ use them. The best way to get going\nwith these tools is probably to look at an existing Appium driver repo to see how it's done, for\nexample the [XCUITest driver repo](https://github.com/appium/appium-xcuitest-driver). But this guide\nwill outline the basic approach.\n\n### Conceptual architecture","metadata":{"loc":{"lines":{"from":1,"to":16}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-docs.md","filename":"build-docs.md","relativePath":"appium/developing/build-docs.md"}},{"pageContent":"### Conceptual architecture\n\nAppium settled on [MkDocs](https://www.mkdocs.org/) as a Markdown-based documentation site\ngenerator. It uses a Python toolchain (and not Node.js), but it turned out to be the best option\nfor our purposes. You can adjust this, but by default Appium's utilities also assume that you'll be\nusing the [mkdocs-material](https://squidfunk.github.io/mkdocs-material/) theme/extension for\nMkDocs.\n\nIn order to make different versions of your docs available (one for each minor release of your\nextension, typically), we also bundle [Mike](https://github.com/jimporter/mike).\n\nFrom here, building a basic docs site is as easy as collecting your Markdown files together and\ndefining how you want them to be organized.\n\n### Prerequisites\n\nTo take advantage of Appium's documentation utilities, you'll need to install:","metadata":{"loc":{"lines":{"from":16,"to":32}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-docs.md","filename":"build-docs.md","relativePath":"appium/developing/build-docs.md"}},{"pageContent":"### Prerequisites\n\nTo take advantage of Appium's documentation utilities, you'll need to install:\n\n- [Python v3+](https://www.python.org/downloads/)\n- [pip](https://pip.pypa.io/en/stable/installation/) (this may be installed automatically with Python)\n- The `@appium/docutils` package:\n\n ```bash\n npm install --save-dev @appium/docutils\n ```\n\n### Initializing an Extension for Building Docs\n\nTo prepare your extension for generating documentation, run the following command:\n\n```bash\nnpx appium-docs init\n```\n\nThis will:\n\n1. Create a `tsconfig.json` if one does not already exist. This is necessary even if your extension\nis not written in TypeScript.\n2. Create a `mkdocs.yml` with the necessary configuration for MkDocs.\n\n### Documenting Your Extension","metadata":{"loc":{"lines":{"from":30,"to":56}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-docs.md","filename":"build-docs.md","relativePath":"appium/developing/build-docs.md"}},{"pageContent":"### Documenting Your Extension\n\nAt this point, you can begin documenting your extension. By default, MkDocs will look for Markdown\nfiles in the `docs` directory. You can therefore create your Markdown documentation files, place\nthem in `docs`, and add links to these files in `mkdocs.yml`.\n\nRefer to the [MkDocs documentation](https://www.mkdocs.org/user-guide/writing-your-docs/) for\ninformation on how to organize and structure your documentation. \n\n### Building the Docs\n\nAt this point, you can use the `appium-docs` CLI tool. Run this tool with no arguments to get the\nfull help output and see all the available subcommands and parameters. Here are a few usage\nexamples:\n\n```bash\n# Generate reference and build the mkdocs site into the site dir\nnpx appium-docs build\n\n# Same as build, but host the docs on a local dev server\n# and watch for changes and rebuild when files change\nnpx appium-docs build --serve","metadata":{"loc":{"lines":{"from":56,"to":77}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-docs.md","filename":"build-docs.md","relativePath":"appium/developing/build-docs.md"}},{"pageContent":"# Same as build, but host the docs on a local dev server\n# and watch for changes and rebuild when files change\nnpx appium-docs build --serve\n\n# Build the docs and deploy them with mike versioning to the docs-site branch\n# using the included commit message.\n# This is particularly useful for pushing content to a GitHub pages branch!\nnpx appium-docs build \\\n --deploy \\\n -b docs-site \\\n -m 'docs: auto-build docs for appium-xcuitest-driver@%s'\n```","metadata":{"loc":{"lines":{"from":75,"to":86}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-docs.md","filename":"build-docs.md","relativePath":"appium/developing/build-docs.md"}},{"pageContent":"---\ntitle: Building Doctor Checks\n---\n\nThe idea of Appium Doctor is to assist users with driver or plugin preconditions setup. Sometimes such\npreconditions might be quite complicated and require non-trivial technical knowledge. Doctor checks,\nwhich are vanilla Node.js class instances written by extension authors, simplify\nthe setup process by automating diagnostics and possible fixes for the found issues. These checks\nmight also be interactive to ensure better usage experience.\n\nThis tutorial is supposed to be used by plugin or driver authors that would like to help their users\nto deal with complicated setup or configuration steps.\n\n## Adding Doctor Checks\n\n### Typing Requirements\n\nThe term `Doctor Check` literally describes a single javascript class instance that implements the\n[IDoctorCheck interface](https://github.com/appium/appium/blob/master/packages/types/lib/doctor.ts).\nThe interface defines the following methods and properties:","metadata":{"loc":{"lines":{"from":1,"to":20}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-doctor-checks.md","filename":"build-doctor-checks.md","relativePath":"appium/developing/build-doctor-checks.md"}},{"pageContent":"- `diagnose(): Promise<DoctorCheckResult>`: Contains the code to diagnose a possible issue\n- `fix(): Promise<string|null>`: Either fixes the actual problem if `hasAutofix()` returns true or\n returns a string description for possible manual fixes. If this method throws an exception named\n `FixSkippedError` and `hasAutofix()` returns true then the result of the method invocation\n is going to be ignored.\n- `hasAutofix(): boolean`: Whether calling `fix()` would resolve the found issue\n- `isOptional(): boolean`: Whether the found issue can be ignored and is not a showstopper\n- `log: AppiumLogger`: May be used for logging. This property may be assigned\n by the instance itself or by the Appium server if it is left unassigned.\n\nThe `DoctorCheckResult` object returned by the `diagnose()` method must contain the following properties:","metadata":{"loc":{"lines":{"from":22,"to":32}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-doctor-checks.md","filename":"build-doctor-checks.md","relativePath":"appium/developing/build-doctor-checks.md"}},{"pageContent":"The `DoctorCheckResult` object returned by the `diagnose()` method must contain the following properties:\n\n- `ok: boolean`: Whether the diagnosis found no issues\n- `optional: boolean`: Whether the diagnosed issue is safe to ignore\n- `message: string`: The text message describing the diagnostic result\n\n### Manifest Requirements\n\nA single extension may export multiple Doctor checks to Appium. In order for these checks to be properly\npicked up by the server CLI after the corresponding extension is installed they might be listed in the\npackage .json manifest under the `appium.doctor.checks` section similar to the definition below:","metadata":{"loc":{"lines":{"from":32,"to":42}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-doctor-checks.md","filename":"build-doctor-checks.md","relativePath":"appium/developing/build-doctor-checks.md"}},{"pageContent":"```json\n // ...\n \"appium\": {\n \"driverName\": \"fake\",\n \"automationName\": \"Fake\",\n \"platformNames\": [\n \"Fake\"\n ],\n \"mainClass\": \"FakeDriver\",\n \"schema\": \"./build/lib/fake-driver-schema.js\",\n \"scripts\": {\n \"fake-error\": \"./build/lib/scripts/fake-error.js\",\n \"fake-success\": \"./build/lib/scripts/fake-success.js\",\n \"fake-stdin\": \"./build/lib/scripts/fake-stdin.js\"\n },\n \"doctor\": {\n \"checks\": [\n \"./doctor/fake1.js\",\n \"./doctor/fake2.js\"\n // ...\n ]\n }\n },\n // ...\n```\n\nAlso, it makes sense to include the [@appium/types](https://www.npmjs.com/package/@appium/types) import\nto the package dev dependencies.\n\n### Implementation Example\n\nThe below example is a \"raw\" Node.JS implementation that does not use any transpilation:\n\n```js\nconst {fs, doctor} = require('@appium/support');","metadata":{"loc":{"lines":{"from":44,"to":78}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-doctor-checks.md","filename":"build-doctor-checks.md","relativePath":"appium/developing/build-doctor-checks.md"}},{"pageContent":"### Implementation Example\n\nThe below example is a \"raw\" Node.JS implementation that does not use any transpilation:\n\n```js\nconst {fs, doctor} = require('@appium/support');\n\n/** @satisfies {import('@appium/types').IDoctorCheck} */\nclass EnvVarAndPathCheck {\n /**\n * @param {string} varName\n */\n constructor(varName) {\n this.varName = varName;\n }\n\n async diagnose() {\n const varValue = process.env[this.varName];\n if (typeof varValue === 'undefined') {\n return doctor.nok(`${this.varName} environment variable is NOT set!`);\n }\n\n if (await fs.exists(varValue)) {\n return doctor.ok(`${this.varName} is set to: ${varValue}`);\n }\n\n return doctor.nok(`${this.varName} is set to '${varValue}' but this is NOT a valid path!`);\n }\n\n async fix() {\n return (\n `Make sure the environment variable ${this.varName} is properly configured for the Appium server process`\n );\n }\n\n hasAutofix() {\n return false;\n }\n\n isOptional() {\n return false;\n }\n}","metadata":{"loc":{"lines":{"from":73,"to":115}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-doctor-checks.md","filename":"build-doctor-checks.md","relativePath":"appium/developing/build-doctor-checks.md"}},{"pageContent":"hasAutofix() {\n return false;\n }\n\n isOptional() {\n return false;\n }\n}\n\nconst androidHomeCheck = new EnvVarAndPathCheck('ANDROID_HOME');\n\nmodule.exports = {androidHomeCheck};\n\n/**\n * @typedef {import('@appium/types').DoctorCheckResult} CheckResult\n */\n```\n\nThis file could be saved as `doctor/android-home-check.js` and then added to the package.json manifest\nas\n\n```json\n // ...\n \"appium\": {\n // ...\n \"doctor\": {\n \"checks\": [\n \"./doctor/android-home-check.js\",\n ]\n }\n // ...\n },\n // ...\n```","metadata":{"loc":{"lines":{"from":108,"to":141}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-doctor-checks.md","filename":"build-doctor-checks.md","relativePath":"appium/developing/build-doctor-checks.md"}},{"pageContent":"---\ntitle: Building Drivers\n---\n\nAppium wants to make it easy for anyone to develop their own automation drivers as part of the\nAppium ecosystem. This guide will explain what's involved and how you can accomplish various driver\ndevelopment tasks using the tools Appium provides. This guide assumes you (1) are a competent user of\nAppium, (2) are a competent Node.js developer, and (3) that you have read and understood the\n[Driver Intro](../intro/drivers.md).\n\nIf that describes you, great! This guide will get you started.\n\n## Before you create your driver\n\nBefore you get to work implementing your driver, it's important to have a few things sorted out.\nFor example, you need to know what your driver will do. Which platform is it trying to expose\nWebDriver automation for?","metadata":{"loc":{"lines":{"from":1,"to":17}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"Appium doesn't magically give you the power to automate any platform. All it does is give you a set\nof convenient tools for implementing the WebDriver Protocol. So if you want to create, for example,\na driver for a new app platform, you'll need to know how to automate apps on that platform *without Appium*.\n\nThis usually means that you need to be very familiar with app development for a given platform. And\nit usually means that you will rely on tools or SDKs provided by the platform vendor.\n\nBasically, if you can't answer the question **\"how would I launch, remotely trigger behaviours, and\nread state from an app on this platform?\" then you're not quite ready to write an Appium driver**.\nMake sure you do the research to feel comfortable that there *is* a path forward. Once there is,\ncoding it up and making it available as an Appium driver should be the easy part!\n\n## Other drivers to reference","metadata":{"loc":{"lines":{"from":19,"to":31}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"## Other drivers to reference\n\nOne of the greatest things about building an Appium driver is that there are already a number of\nopen source Appium drivers which you can look at for reference. There is\na [fake-driver](https://github.com/appium/appium/tree/master/packages/fake-driver) sample driver which\ndoes basically nothing other than showcase some of the things described in this guide.\n\nAnd of course, all of Appium's official drivers are open source and available in repositories at\nthe project's GitHub organization. So if you ever find yourself asking, \"how does a driver do X?\",\nread the code for these drivers! Also don't be afraid to ask questions of the Appium developers if\nyou get stuck; we're always happy to help make sure the driver development experience is a good\none!\n\n## Basic requirements for Appium drivers\n\nThese are the things your driver *must* do (or be), if you want it to be a valid Appium driver.\n\n### Node.js package with Appium extension metadata","metadata":{"loc":{"lines":{"from":31,"to":48}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"## Basic requirements for Appium drivers\n\nThese are the things your driver *must* do (or be), if you want it to be a valid Appium driver.\n\n### Node.js package with Appium extension metadata\n\nAll Appium drivers are fundamentally Node.js packages, and therefore must have a valid\n`package.json`. Your driver is not _limited_ to Node.js, but it must provide an adapter written in Node.js so it can be loaded by Appium.\n\nYour `package.json` must include `appium` as a `peerDependency`. The requirements for the\ndependency versions should be as loose as possible (unless you happen to know your driver will only\nwork with certain versions of Appium). For Appium 2, for example, this would look something like\n`^2.0.0`, declaring that your driver works with any version of Appium that starts with 2.x.\n\nYour `package.json` must contain an `appium` field, like this (we call this the 'Appium extension\nmetadata'):","metadata":{"loc":{"lines":{"from":44,"to":59}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"Your `package.json` must contain an `appium` field, like this (we call this the 'Appium extension\nmetadata'):\n\n```json\n{\n ...,\n \"appium\": {\n \"driverName\": \"fake\",\n \"automationName\": \"Fake\",\n \"platformNames\": [\n \"Fake\"\n ],\n \"mainClass\": \"FakeDriver\"\n },\n ...\n}\n```\n\nThe required subfields are:","metadata":{"loc":{"lines":{"from":58,"to":76}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"The required subfields are:\n\n* `driverName`: this should be a short name for your driver.\n* `automationName`: this should be the string users will use for their `appium:automationName`\n capability to tell Appium to use *your* driver.\n* `platformNames`: this is an array of one or more platform names considered valid for your driver.\n When a user sends in the `platformName` capability to start a session, it must be included in\n this list for your driver to handle the session. Known platform name strings include: `iOS`,\n `tvOS`, `macOS`, `Windows`, `Android`.\n* `mainClass`: this is a named export (in CommonJS style) from your `main` field. It must be a\n class which extends Appium's `BaseDriver` (see below).\n\n### Extend Appium's `BaseDriver` class","metadata":{"loc":{"lines":{"from":76,"to":88}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"### Extend Appium's `BaseDriver` class\n\nUltimately, your driver is much easier to write because most of the hard work of implementing the\nWebDriver protocol and handling certain common logic is taken care of already by Appium. This is\nall encoded up as a class which Appium exports for you to use, called `BaseDriver`. It is exported\nfrom `appium/driver`, so you can use one of these styles to import it and create your *own* class\nthat extends it:\n\n```js\nimport {BaseDriver} from 'appium/driver';\n// or: const {BaseDriver} = require('appium/driver');\n\nexport class MyDriver extends BaseDriver {\n}\n```\n\n### Make your driver available\n\nThat's basically it! With a Node.js package exporting a driver class and with correct Appium\nextension metadata, you've got yourself an Appium driver! Now it doesn't *do* anything, but you can\nload it up in Appium, start and stop sessions with it, etc...","metadata":{"loc":{"lines":{"from":88,"to":108}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"To make it available to users, you could publish it via NPM. When you do so, your driver will be\ninstallable via the Appium CLI:\n\n```\nappium driver install --source=npm <driver-package-on-npm>\n```\n\nIt's a good idea to test your driver first, of course. One way to see how it works within Appium is\nto install it locally first:\n\n```\nappium driver install --source=local /path/to/your/driver\n```\n\n### Developing your driver\n\nHow you develop your driver is up to you. It is convenient, however, to run it from within Appium\nwithout having to do lots of publishing and installing. The most straightforward way to do this is\nto include the most recent version of Appium as a `devDependency`, and then also your own driver,\nlike this:\n\n```json\n{\n \"devDependencies\": {\n ...,\n \"appium\": \"^2.0.0\",\n \"your-driver\": \"file:.\",\n ...\n }\n}\n```","metadata":{"loc":{"lines":{"from":110,"to":140}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"```json\n{\n \"devDependencies\": {\n ...,\n \"appium\": \"^2.0.0\",\n \"your-driver\": \"file:.\",\n ...\n }\n}\n```\n\nNow, you can run Appium locally (`npm exec appium` or `npx appium`), and because your driver is\nlisted as a dependency alongside it, it will be automatically \"installed\" and available. You can\ndesign your e2e tests this way, or if you're writing them in Node.js, you can simply import\nAppium's start server methods to handle starting and stopping the Appium server in Node. (TODO:\nreference an implementation of this in one of the open source drivers when ready).\n\nAnother way to do local development with an existing Appium server install is to simply install\nyour driver locally:\n\n```\nappium driver install --source=local /path/to/your/driver/dev/dir\n```\n\n### Refreshing your driver during development","metadata":{"loc":{"lines":{"from":131,"to":155}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"```\nappium driver install --source=local /path/to/your/driver/dev/dir\n```\n\n### Refreshing your driver during development\n\nWhen the Appium server starts, it loads your driver into memory. Changes to your driver code will\nnot take effect until the next time the Appium server starts. Simply starting a new session is not\nsufficient to cause your driver's code to be reloaded.\n\nHowever, you can set the `APPIUM_RELOAD_EXTENSIONS` environment variable to `1` to request that\nAppium clear its module cache and reload extensions whenever a new session is requested. This may\nobviate the need to restart the server when you make code changes to your driver.\n\n## Standard driver implementation ideas\n\nThese are things you will probably find yourself wanting to do when creating a driver.\n\n### Set up state in a constructor\n\nIf you define your own constructor, you'll need to call `super` to make sure all the standard state\nis set up correctly:","metadata":{"loc":{"lines":{"from":151,"to":172}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"### Set up state in a constructor\n\nIf you define your own constructor, you'll need to call `super` to make sure all the standard state\nis set up correctly:\n\n```js\nconstructor(...args) {\n super(...args);\n // now do your own thing\n}\n```\n\nThe `args` parameter here is the object containing all the CLI args used to start the Appium\nserver.\n\n### Define and validate accepted capabilities\n\nYou can define your own capabilities and basic validation for them. Users will always be able to\nsend in capabilities that you don't define, but if they send in capabilities you have explicitly\ndefined, then Appium will validate that they are of the correct type (and will check for the\npresence of required capabilities).\n\nIf you want to turn capability validation off entirely, set `this.shouldValidateCaps` to `false` in\nyour constructor.","metadata":{"loc":{"lines":{"from":169,"to":192}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"If you want to turn capability validation off entirely, set `this.shouldValidateCaps` to `false` in\nyour constructor.\n\nTo give Appium your validation constraints, set `this.desiredCapConstraints` to a validation object\nin your constructor. Validation objects can be somewhat complex. Here's an example from the\nUiAutomator2 driver:\n\n```js\n{\n app: {\n presence: true,\n isString: true\n },\n automationName: {\n isString: true\n },\n browserName: {\n isString: true\n },\n launchTimeout: {\n isNumber: true\n },\n}\n```\n\n### Start a session and read capabilities\n\nAppium's `BaseDriver` already implements the `createSession` command, so you don't have to. However\nit's very common to need to perform your own startup actions (launching an app, running some\nplatform code, or doing different things based on capabilities you have defined for your driver).\nSo you'll probably end up overriding `createSession`. You can do so by defining the method in your\ndriver:","metadata":{"loc":{"lines":{"from":191,"to":222}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"```js\nasync createSession(jwpCaps, reqCaps, w3cCaps, otherDriverData) {\n const [sessionId, caps] = super.createSession(w3cCaps);\n // do your own stuff here\n return [sessionId, caps];\n}\n```\n\nFor legacy reasons, your function will receive old-style JSON Wire Protocol desired and required\ncaps as the first two arguments. Given that the old protocol isn't supported anymore and clients\nhave all been updated, you can instead only rely on the `w3cCaps` parameter. (For a discussion\nabout what `otherDriverData` is about, see the section below on concurrent drivers).\n\nYou'll want to make sure to call `super.createSession` in order to get the session ID as well as\nthe processed capabilities (note that capabilities are also set on `this.caps`; modifying `caps`\nlocally here would have no effect other than changing what the user sees in the create session\nresponse).\n\nSo that's it! You can fill out the middle section with whatever startup logic your driver requires.\n\n### End a session","metadata":{"loc":{"lines":{"from":224,"to":244}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"So that's it! You can fill out the middle section with whatever startup logic your driver requires.\n\n### End a session\n\nIf your driver requires any cleanup or shutdown logic, it's best to do it as part of overriding the\nimplementation of `deleteSession`:\n\n```js\nasync deleteSession() {\n // do your own cleanup here\n // don't forget to call super!\n await super.deleteSession();\n}\n```\n\nIt's very important not to throw any errors here if possible so that all parts of session cleanup\ncan succeed!\n\n### Access capabilities and CLI args\n\nYou'll often want to read parameters the user has set for the session, whether as CLI args or as\ncapabilities. The easiest way to do this is to access `this.opts`, which is a merge of all options,\nfrom the CLI or from capabilities. So for example to access the `appium:app` capability, you could\nsimply get the value of `this.opts.app`.","metadata":{"loc":{"lines":{"from":242,"to":265}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"If you care about knowing whether something was sent in as a CLI arg *or* a capability, you can\naccess the `this.cliArgs` and `this.caps` objects explicitly.\n\nIn all cases, the `appium:` capability prefix will have been stripped away by the time you are\naccessing values here, for convenience.\n\n### Implement WebDriver classic commands\n\nYou handle WebDriver commands by implementing functions in your driver class. Each member of the\nWebDriver Protocol, plus the various Appium extensions, has a corresponding function that you\nimplement if you want to support that command in your driver. The best way to see which commands\nAppium supports and which method you need to implement for each command is to look at Appium's\n[routes.js](https://github.com/appium/appium/blob/master/packages/base-driver/lib/protocol/routes.js).\nEach route object in this file tells you the command name as well as the parameters you'd expect to\nreceive for that command.","metadata":{"loc":{"lines":{"from":267,"to":281}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"Let's take this block for example:\n```js\n'/session/:sessionId/url': {\n GET: {command: 'getUrl'},\n POST: {command: 'setUrl', payloadParams: {required: ['url']}},\n}\n```\n\nHere we see that the route `/session/:sessionId/url` is mapped to two commands, one for a `GET`\nrequest and one for a `POST` request. If we want to allow our driver to change the \"url\" (or\nwhatever that might mean for our driver), we can therefore implement the `setUrl` command, knowing\nit will take the `url` parameter:\n\n```js\nasync setUrl(url) {\n // your implementation here\n}\n```","metadata":{"loc":{"lines":{"from":283,"to":300}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"```js\nasync setUrl(url) {\n // your implementation here\n}\n```\n\nA few notes:\n- all command methods should be `async` functions or otherwise return a `Promise`\n- you don't need to worry about protocol encoding/decoding. You will get JS objects as params, and\n can return JSON-serializable objects in response. Appium will take care of wrapping it up in the\n WebDriver protocol response format, turning it into JSON, etc...\n- all session-based commands receive the `sessionId` parameter as the last parameter\n- all element-based commands receive the `elementId` parameter as the second-to-last parameter\n- if your driver doesn't implement a command, users can still try to access the command, and will\n get a `501 Not Yet Implemented` response error.\n\n### Implement WebDriver BiDi commands","metadata":{"loc":{"lines":{"from":296,"to":312}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"### Implement WebDriver BiDi commands\n\n[WebDriver BiDi](https://w3c.github.io/webdriver-bidi) is a newer version of the WebDriver spec\nwhich is implemented over Websockets instead of HTTP. As an Appium driver author you can take\nadvantage of Appium's BiDi support without having to know anything about the BiDi protocol or\nWebsockets. Implementing handlers for BiDi commands works just the same as implementing handlers\nfor WebDriver classic commands (described in the previous section). You simply define a method on\nyour driver of the appropriate name, and it will be called when the BiDi command is requested by\nthe client. To see which specific names you should use for BiDi commands, have a look at\n[bidi-commands.js](https://github.com/appium/appium/blob/master/packages/base-driver/lib/protocol/bidi-commands.js)","metadata":{"loc":{"lines":{"from":312,"to":321}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"You are not limited to BiDi commands that are defined in the official BiDi specification. If you\nwish to define new commands, you may do so; you just need to tell Appium about them! See\n[below](#extend-the-existing-protocol-with-new-commands) for more information.\n\n### Implement element finding\n\nElement finding is a special command implementation case. You don't actually want to override\n`findElement` or `findElements`, even though those are what are listed in `routes.js`. Appium does\na lot of work for you if instead you implement this function:\n\n```js\nasync findElOrEls(strategy, selector, mult, context) {\n // find your element here\n}\n```\n\nHere's what gets passed in:","metadata":{"loc":{"lines":{"from":323,"to":339}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"```js\nasync findElOrEls(strategy, selector, mult, context) {\n // find your element here\n}\n```\n\nHere's what gets passed in:\n\n- `strategy` - a string, the locator strategy being used\n- `selector` - a string, the selector\n- `mult` - boolean, whether the user has requested one element or all elements matching the\n selector\n- `context` - (optional) if defined, will be a W3C Element (i.e., a JS object with the W3C element\n identifier as the key and the element ID as the value)\n\nAnd you need to return one of the following:\n\n- a single W3C element (an object as described above)\n- an array of W3C elements\n\nNote that you can import that W3C web element identifier from `appium/support`:\n\n```js\nimport {util} from 'appium/support';\nconst { W3C_WEB_ELEMENT_IDENTIFIER } = util;\n```\n\nWhat you do with elements is up to you! Usually you end up keeping a cache map of IDs to actual\nelement \"objects\" or whatever the equivalent is for your platform.\n\n### Define valid locator strategies","metadata":{"loc":{"lines":{"from":333,"to":363}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"### Define valid locator strategies\n\nYour driver might only support a subset of the standard WebDriver locator strategies, or it might\nadd its own custom locator strategies. To tell Appium which strategies are considered valid for\nyour driver, create an array of strategies and assign it to `this.locatorStrategies`:\n\n```js\nthis.locatorStrategies = ['xpath', 'custom-strategy'];\n```\n\nAppium will throw an error if the user attempts to use any strategies other than the allowed ones,\nwhich enables you to keep your element finding code clean and deal with only the strategies you\nknow about.\n\nBy default, the list of valid strategies is empty, so if your driver isn't simply proxying to\nanother WebDriver endpoint, you'll need to define some. The protocol-standard locator strategies\nare defined [here](https://www.w3.org/TR/webdriver/#locator-strategies).\n\n### Throw WebDriver-specific errors","metadata":{"loc":{"lines":{"from":363,"to":381}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"### Throw WebDriver-specific errors\n\nThe WebDriver spec defines a [set of error\ncodes](https://github.com/jlipps/simple-wd-spec#error-codes) to accompany command responses if an\nerror occurred. Appium has created error classes for each of these codes, so you can throw the\nappropriate error from inside a command, and it will do the right thing in terms of the protocol\nresponse to the user. To get access to these error classes, import them from `appium/driver`:\n\n```\nimport {errors} from 'appium/driver';\n\nthrow new errors.NoSuchElementError();\n```\n\n### Log messages to the Appium log\n\nYou can always use `console.log`, of course, but Appium provides a nice logger for you as\n`this.log` (it has `.info`, `.debug`, `.log`, `.warn`, `.error` methods on it for differing log\nlevels). If you want to create an Appium logger outside of a driver context (say in a script or\nhelper file), you can always construct your own too:","metadata":{"loc":{"lines":{"from":381,"to":400}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"```js\nimport {logging} from 'appium/support';\nconst log = logging.getLogger('MyDriver');\n```\n\n## Further possibilities for Appium drivers\n\nThese are things your driver *can* do to take advantage of extra driver features or do its job more\nconveniently.\n\n### Add a schema for custom command line arguments\n\nYou can add custom CLI args if you want your driver to receive data from the command line when the\nAppium server is started (for example, ports that a server administrator should set that should not\nbe passed in as capabilities.\n\nTo define CLI arguments (or configuration properties) for the Appium server, your extension must provide a _schema_. In\nthe `appium` property of your extension's `package.json`, add a `schema` property. This will either\na) be a schema itself, or b) be a path to a schema file.\n\nThe rules for these schemas:","metadata":{"loc":{"lines":{"from":402,"to":422}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"The rules for these schemas:\n\n- Schemas must conform to [JSON Schema Draft-07](https://ajv.js.org/json-schema.html#draft-07).\n- If the `schema` property is a path to a schema file, the file must be in JSON or JS (CommonJS) format.\n- Custom `$id` values are unsupported. To use `$ref`, provide a value relative to the schema root, e.g., `/properties/foo`.\n- Known values of the `format` keyword are likely supported, but various other keywords may be unsupported. If you find a keyword that is unsupported which you need to use, please [ask for support](https://github.com/appium/appium/issues/new) or send a PR!\n- The schema must be of type `object` (`{\"type\": \"object\"}`), containing the arguments in a `properties` keyword. Nested properties are unsupported.\n\nExample:","metadata":{"loc":{"lines":{"from":422,"to":430}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"Example:\n\n```json\n{\n \"type\": \"object\",\n \"properties\": {\n \"test-web-server-port\": {\n \"type\": \"integer\",\n \"minimum\": 1,\n \"maximum\": 65535,\n \"description\": \"The port to use for the test web server\"\n },\n \"test-web-server-host\": {\n \"type\": \"string\",\n \"description\": \"The host to use for the test web server\",\n \"default\": \"sillyhost\"\n }\n }\n}\n```\n\nThe above schema defines two properties which can be set via CLI argument or configuration file. If\nthis extension is a _driver_ and its name is \"horace\", the CLI args would be\n`--driver-horace-test-web-server-port` and `--driver-horace-test-web-server-host`, respectively.\nAlternatively, a user could provide a configuration file containing:\n\n```json\n{\n \"server\": {\n \"driver\": {\n \"horace\": {\n \"test-web-server-port\": 1234,\n \"test-web-server-host\": \"localhorse\"\n }\n }\n }\n}\n```\n\n### Add driver scripts","metadata":{"loc":{"lines":{"from":430,"to":469}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"```json\n{\n \"server\": {\n \"driver\": {\n \"horace\": {\n \"test-web-server-port\": 1234,\n \"test-web-server-host\": \"localhorse\"\n }\n }\n }\n}\n```\n\n### Add driver scripts\n\nSometimes you might want users of your driver to be able to run scripts outside the context of\na session (for example, to run a script that pre-builds aspects of your driver). To support this,\nyou can add a map of script names and JS files to the `scripts` field within your Appium extension\nmetadata. So let's say you've created a script in your project that lives in a `scripts` directory\nin your project, named `driver-prebuild.js`. Then you could add a `scripts` field like this:\n\n```json\n{\n \"scripts\": {\n \"prebuild\": \"./scripts/driver-prebuild.js\"\n }\n}\n```\n\nNow, assuming your driver is named `mydriver`, users of your driver can run `appium driver run\nmydriver prebuild`, and your script will execute.\n\n### Proxy commands to another WebDriver implementation","metadata":{"loc":{"lines":{"from":456,"to":488}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"### Proxy commands to another WebDriver implementation\n\nA very common design architecture for Appium drivers is to have some kind of platform-specific\nWebDriver implementation that the Appium driver interfaces with. For example, the Appium\nUiAutomator2 driver interfaces with a special (Java-based) server running on the Android device. In\nwebview mode, it also interfaces with Chromedriver.\n\nIf you find yourself in this situation, it is extremely easy to tell Appium that your driver is\njust going to be proxying WebDriver commands straight to another endpoint.\n\nFirst, let Appium know that your driver *can* proxy by implementing the `canProxy` method:\n\n```js\ncanProxy() {\n return true;\n}\n```\n\nNext, tell Appium which WebDriver routes it should *not* attempt to proxy (there often end up being\ncertain routes that you don't want to forward on):\n\n```js\ngetProxyAvoidList() {\n return [\n ['POST', new RegExp('^/session/[^/]+/appium')]\n ];\n}\n```","metadata":{"loc":{"lines":{"from":488,"to":515}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"```js\ngetProxyAvoidList() {\n return [\n ['POST', new RegExp('^/session/[^/]+/appium')]\n ];\n}\n```\n\nThe proxy avoidance list should be an array of arrays, where each inner array has an HTTP method as\nits first member, and a regular expression as its second. If the regular expression matches the\nroute, then the route will not be proxied and instead will be handled by your driver. In this\nexample, we are avoiding proxying all `POST` routes that have the `appium` prefix.\n\nNext, we have to set up the proxying itself. The way to do this is to use a special class from\nAppium called `JWProxy`. (The name means \"JSON Wire Proxy\" and is related to a legacy\nimplementation of the protocol). You'll want to create a `JWProxy` object using the details required to\nconnect to the remote server:\n\n```js\n// import {JWProxy} from 'appium/driver';\n\nconst proxy = new JWProxy({\n server: 'remote.server',\n port: 1234,\n base: '/',\n});","metadata":{"loc":{"lines":{"from":509,"to":534}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"```js\n// import {JWProxy} from 'appium/driver';\n\nconst proxy = new JWProxy({\n server: 'remote.server',\n port: 1234,\n base: '/',\n});\n\nthis.proxyReqRes = proxy.proxyReqRes.bind(proxy);\nthis.proxyCommand = proxy.command.bind(proxy);\n```\n\nHere we are creating a proxy object and assigning some of its methods to `this` under the names\n`proxyReqRes` and `proxyCommand`. This is required for Appium to use the proxy, so don't forget\nthis step! The `JWProxy` has a variety of other options which you can check out in the source code,\nas well. (TODO: publish options as API docs and link here).\n\nFinally, we need a way to tell Appium when the proxy is active. For your driver it might always\nbe active, or it might only be active when in a certain context. You can define the logic as an\nimplementation of `proxyActive`:\n\n```js\nproxyActive() {\n return true; // or use custom logic\n}\n```","metadata":{"loc":{"lines":{"from":527,"to":553}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"```js\nproxyActive() {\n return true; // or use custom logic\n}\n```\n\nWith those pieces in play, you won't have to reimplement anything that's already implemented by the\nremote endpoint you're proxying to. Appium will take care of all the proxying for you.\n\n### Proxy BiDi commands to another BiDi implementation\n\nAll of the above about proxying WebDriver commands is conceptually also valid for proxying BiDi\ncommands specifically. In order to enable BiDi proxying, you need to implement `get bidiProxyUrl`\non your driver. This should return a Websocket URL which is the address of the upstream socket you\nwant BiDi commands to be proxied to.","metadata":{"loc":{"lines":{"from":549,"to":563}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"The intended pattern here is for you to start a session on the upstream implementation, check\nwhether it has an active BiDi socket in the returned capabilities (e.g., the `webSocketUrl`\ncapability), and then to set an internal field to that value, so that it can be returned by `get\nbidiProxyUrl`. Once all this is in place, Appium will proxy BiDi commands from the client straight\nto the upstream connection.\n\n### Extend the existing protocol with new commands\n\nYou may find that the existing commands don't cut it for your driver. If you want to expose\nbehaviours that don't map to any of the existing commands, you can create new commands in one of\nthree ways:","metadata":{"loc":{"lines":{"from":565,"to":575}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"1. Extending the classic WebDriver protocol and creating client-side plugins to access the extensions via the classic HTTP interface\n1. Extending the WebDriver BiDi protocol with new modules and methods, accessed from a client via the BiDi interface\n1. Overloading the Execute Script command by defining [Execute\n Methods](../guides/execute-methods.md)\n\nIf you want to follow the first path, you can direct Appium to recognize new methods and add them\nto its set of allowed HTTP routes and command names. You do this by assigning the `newMethodMap`\nstatic variable in your driver class to an object of the same form as Appium's `routes.js` object.\nFor example, here is the `newMethodMap` for the `FakeDriver` example driver:","metadata":{"loc":{"lines":{"from":577,"to":585}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"```js\nstatic newMethodMap = {\n '/session/:sessionId/fakedriver': {\n GET: {command: 'getFakeThing'},\n POST: {command: 'setFakeThing', payloadParams: {required: ['thing']}},\n },\n '/session/:sessionId/fakedriverargs': {\n GET: {command: 'getFakeDriverArgs'},\n },\n};\n```\n\nIn this example we're adding a few new routes and a total of 3 new commands. For more examples of\nhow to define commands in this way, it's best to have a look through `routes.js`. Now all you need\nto do is implement the command handlers in the same way you'd implement any other Appium command.\n\nThe downside of this way of adding new commands is that people using the standard Appium clients\nwon't have nice client-side functions designed to target these endpoints. So you would need to\ncreate and release client-side plugins for each language you want to support (directions or\nexamples can be found at the relevant client docs).","metadata":{"loc":{"lines":{"from":587,"to":606}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"The second way of adding new commands is adding them as BiDi commands (accessed via the BiDi\nwebsocket interface, rather than the classic HTTP interface). BiDi commands come in two parts:\na \"module\", which is basically a container or namespace, and a \"command\", which is the name of your\nnew command.\n\nAs with the first method, you teach Appium to recognize your new BiDi commands by adding a static\nfield to your driver class, called `newBidiCommands`. It has a format similar to `newMethodMap`.\nBasically it encapsulates information about the BiDi module, BiDi command name, reference to your\ndriver instance method that will handle the command, and required and optional parameters. Here's\nan example of a `newBidiCommands` as implemented on an imaginary driver:","metadata":{"loc":{"lines":{"from":608,"to":617}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"```js\nstatic newBidiCommands = {\n 'appium:video': {\n startFramerateCapture: {\n command: 'startFrameCap',\n params: {\n required: ['videoSource'],\n optional: ['showOnScreen'],\n }\n },\n stopFramerateCapture: {\n command: 'stopFrameCap',\n },\n }\n};\n```","metadata":{"loc":{"lines":{"from":619,"to":634}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"In this imaginary example, we have defined two new BiDi commands:\n`appium:video.startFramerateCapture` and `appium:video.stopFramerateCapture`. Note first of all\nthat, because we are defining a custom BiDi command, we should include a 'vendor prefix' (in this\ncase, `appium:`, though you should pick something that represents your project). The first command\ntakes a required and an optional parameter, and the second does not. When combined with generic\nBiDi support in your driver (see [the section on BiDi](#implement-webdriver-bidi-commands) above),\nand given an implementation of the appropriate methods on your driver (e.g. `startFrameCap` and\n`stopFrameCap` in this example), clients would be able to send these BiDi commands using whatever\nmechanism normally exists for doing so in the client library.","metadata":{"loc":{"lines":{"from":636,"to":644}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"An alternative to these other ways of doing things is to overload a command which all WebDriver clients\nhave access to already: Execute Script. Appium provides some a convenient tool for making this\neasy. Let's say you are building a driver for stereo system called `soundz`, and you wanted to\ncreate a command for playing a song by name. You could expose this to your users in such a way that\nthey call something like:\n\n```js\n// webdriverio example. Calling webdriverio's `executeScript` command is what trigger's Appium's\n// Execute Script command handler\ndriver.executeScript('soundz: playSong', [{song: 'Stairway to Heaven', artist: 'Led Zeppelin'}]);\n```","metadata":{"loc":{"lines":{"from":646,"to":656}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"Then in your driver code you can define the static property `executeMethodMap` as a mapping of\nscript names to methods on your driver. It has the same basic form as `newMethodMap`, described\nabove. Once `executeMethodMap` is defined, you'll also need to implement the Execute Script command\nhandler, which according to Appium's routes mapping is called `execute`. The implementation can\ncall a single helper function, `this.executeMethod`, which takes care of looking at the script and\narguments the user sent in and routing it to the correct custom handler you've defined. Here's an\nexample:\n\n```js\nstatic executeMethodMap = {\n 'soundz: playSong', {\n command: 'soundzPlaySong',\n params: {required: ['song', 'artist'], optional: []},\n }\n}\n\nasync soundzPlaySong(song, artist) {\n // play the song based on song and artist details\n}\n\nasync execute(script, args) {\n return await this.executeMethod(script, args);\n}\n```","metadata":{"loc":{"lines":{"from":658,"to":681}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"A couple notes about this system:\n1. The arguments array sent via the call to Execute Script must contain only zero or one element(s). The\n first item in the list is considered to be the parameters object for your method. These parameters\n will be parsed, validated, and then applied to your overload method in the order specified in\n `executeMethodMap` (the order specified in the `required` parameters list, followed by the\n `optional` parameters list). I.e., this framework assumes only a single actual argument sent in via\n Execute Script (and this argument should be an object with keys/values representing the\n parameters your execute method expects).\n1. Appium does not automatically implement `execute` (the Execute Script handler) for you. You may\n wish, for example, to only call the `executeMethod` helper function when you're not in proxy\n mode!\n1. The `executeMethod` helper will reject with an error if a script name doesn't match one of the","metadata":{"loc":{"lines":{"from":683,"to":694}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"mode!\n1. The `executeMethod` helper will reject with an error if a script name doesn't match one of the\n script names defined as a command in `executeMethodMap`, or if there are missing parameters.","metadata":{"loc":{"lines":{"from":693,"to":695}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"One of the nice things about the Execute Method strategy is that methods implemented in this way\nwill be available via the classic or BiDi interfaces (since they will result in the same Appium\nhandlers being called).\n\n\n### Build Appium Doctor checks\n\nYour users can run `appium driver doctor <driverName>` to run installation and health checks. Visit\nthe [Building Doctor Checks](./build-doctor-checks.md) guide for more information on this\ncapability.\n\n### Implement handling of Appium settings\n\nAppium users can send parameters to your driver via CLI args as well as via capabilities. But these\ncannot change during the course of a test, and sometimes users want to adjust parameters mid-test.\nAppium has a [Settings](../guides/settings.md) API for this purpose.\n\nTo support settings in your own driver, first of all define `this.settings` to be an instance of\nthe appropriate class, in your constructor:\n\n```js\n// import {DeviceSettings} from 'appium/driver';","metadata":{"loc":{"lines":{"from":697,"to":718}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"To support settings in your own driver, first of all define `this.settings` to be an instance of\nthe appropriate class, in your constructor:\n\n```js\n// import {DeviceSettings} from 'appium/driver';\n\nthis.settings = new DeviceSettings();\n```\n\nNow, you can read user settings any time simply by calling `this.settings.getSettings()`. This will\nreturn a JS object where the settings names are keys and have their corresponding values.\n\nIf you want to assign some default settings, or run some code on your end whenever settings are\nupdated, you can do both of these things as well.\n\n```js\nconstructor() {\n const defaults = {setting1: 'value1'};\n this.settings = new DeviceSettings(defaults, this.onSettingsUpdate.bind(this));\n}\n\nasync onSettingsUpdate(key, value) {\n // do anything you want here with key and value\n}\n```\n\n### Emit BiDi events","metadata":{"loc":{"lines":{"from":714,"to":740}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"async onSettingsUpdate(key, value) {\n // do anything you want here with key and value\n}\n```\n\n### Emit BiDi events\n\nWith the WebDriver BiDi protocol, clients can subscribe to arbitrary events which can be sent\nasynchronously to the client over the BiDi socket connection. As an Appium driver author you don't\nneed to worry about event subscription. If you want to emit an event with a certain method name and\npayload, it's as easy as using the built-in event emitter with the `bidiEvent` event.\n\nAs an\nexample, let's say our driver wants to periodically emit CPU load information. We could define an\nevent called `system.cpu`, and a payload that looks like `{load: 0.97}` to signify 97% CPU usage.\nWhenever we want, our driver can simply call the following code (assuming we have the current load\nin `this.currentCpuLoad`):\n\n```js\nthis.eventEmitter.emit('bidiEvent', {\n method: 'appium:system.cpu',\n params: {load: this.currentCpuLoad},\n})\n```","metadata":{"loc":{"lines":{"from":735,"to":758}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"```js\nthis.eventEmitter.emit('bidiEvent', {\n method: 'appium:system.cpu',\n params: {load: this.currentCpuLoad},\n})\n```\n\nNow, if the client has subscribed to the `system.cpu` event, it will be notified with the load\nwhenever the driver emits it.\n\n### Make itself aware of resources other concurrent drivers are using\n\nLet's say your driver uses up some system resources, like ports. There are a few ways to make sure\nthat multiple simultaneous sessions don't use the same resources:\n\n1. Have your users specify resource IDs via capabilities (`appium:driverPort` etc)\n1. Just always use free resources (find a new random port for each session)\n1. Have each driver express what resources it is using, then examine currently-used resources from\n other drivers when a new session begins.\n\nTo support this third strategy, you can implement `get driverData` in your driver to return what\nsorts of resources your driver is currently using, for example:","metadata":{"loc":{"lines":{"from":753,"to":774}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"To support this third strategy, you can implement `get driverData` in your driver to return what\nsorts of resources your driver is currently using, for example:\n\n```js\nget driverData() {\n return {specialPort: 1234, specialFile: /path/to/file}\n}\n```\n\nNow, when a new session is started on your driver, the `driverData` response from any other\nsimultaneously running drivers (of the same type) will also be included, as the last parameter of\nthe `createSession` method:\n\n```js\nasync createSession(jwpCaps, reqCaps, w3cCaps, driverData)\n```\n\nYou can dig into this `driverData` array to see what resources other drivers are using to help\ndetermine which ones you want to use for this particular session.\n\n!!! warning","metadata":{"loc":{"lines":{"from":773,"to":793}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"You can dig into this `driverData` array to see what resources other drivers are using to help\ndetermine which ones you want to use for this particular session.\n\n!!! warning\n\n Be careful here, since `driverData` is only passed between sessions of a single running Appium\n server. There's nothing to stop a user from running multiple Appium servers and requesting your\n driver simultaneously on each of them. In this case, you won't be able to ensure independence\n of resources via `driverData`, so you might consider using file-based locking mechanisms or\n something similar.\n\n!!! warning","metadata":{"loc":{"lines":{"from":790,"to":801}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"!!! warning\n\n It's also important to note you will only receive `driverData` for other instances of *your*\n driver. So unrelated drivers also running may still be using some system resources. In general\n Appium doesn't provide any features for ensuring unrelated drivers don't interfere with one\n another, so it's up to the drivers to allow users to specify resource locations or addresses to\n avoid clashes.\n\n### Log events to the Appium event timeline\n\nAppium has an [Event Timing API](../guides/event-timing.md) which allows users to get timestamps\nfor certain server-side events (like commands, startup milestones, etc...) and display them on\na timeline. The feature basically exists to allow introspection of timing for internal events to\nhelp with debugging or running analysis on Appium driver internals. You can add your own events to\nthe event log:\n\n```js\nthis.logEvent(name);\n```","metadata":{"loc":{"lines":{"from":801,"to":819}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"```js\nthis.logEvent(name);\n```\n\nSimply provide a name for the event and it will be added at the current time, and made accessible\nas part of the event log for users.\n\n### Hide behaviour behind security flags\n\nAppium has a feature-flag based [security model](../guides/security.md) that allows driver authors\nto hide certain features behind security flags. What this means is that if you have a feature you\ndeem insecure and want to require server admins to opt in to it, you can require that they enable\nthe feature by adding it to the `--allow-insecure` list or turning off server security entirely.\n\nTo support the check within your own driver, you can call `this.isFeatureEnabled(featureName)` to\ndetermine whether a feature of the given name has been enabled. Or, if you want to simply\nshort-circuit and throw an error if the feature isn't enabled, you can call\n`this.assertFeatureEnabled(featureName)`.\n\n### Use a temp dir for files","metadata":{"loc":{"lines":{"from":817,"to":836}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"### Use a temp dir for files\n\nIf you want to use a temporary directory for files your driver creates that are not important to\nkeep around between computer or server restarts, you can simply read from `this.opts.tmpDir`. This\nreads the temporary directory location from `@appium/support`, potentially overridden by a CLI\nflag. I.e., it's safer than writing to your own temporary directory because the location here plays\nnicely with possible user configuration. `this.opts.tmpDir` is a string, the path to the dir.\n\n### Deal with unexpected shutdowns or crashes\n\nYour driver might run into a situation where it can't continue operating normally. For example, it\nmight detect that some external service has crashed and nothing will work anymore. In this case, it\ncan call `this.startUnexpectedShutdown(err)` with an error object including any details, and Appium\nwill attempt to gracefully handle any remaining requests before shutting down the session.","metadata":{"loc":{"lines":{"from":836,"to":849}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"If you want to perform some of your own cleanup logic when you encounter this condition, you can\neither do so immediately before calling `this.startUnexpectedShutdown`, or you can attach a handler\nto the unexpected shutdown event and run your cleanup logic \"out of band\" so to speak:\n\n```js\nthis.onUnexpectedShutdown(handler)\n```\n\n`handler` should be a function which receives an error object (representing the reason for the\nunexpected shutdown).","metadata":{"loc":{"lines":{"from":851,"to":860}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-drivers.md","filename":"build-drivers.md","relativePath":"appium/developing/build-drivers.md"}},{"pageContent":"---\ntitle: Building Plugins\n---\n\nThis is a high-level guide for developing Appium plugins, which is not something most Appium users\nneed to know or care about. If you are not familiar with Appium plugins yet from a user\nperspective, check out the [list of plugins](../ecosystem/plugins.md) to play around with some and get\nan idea of the sorts of things that plugins can do. Plugins are a powerful system for augmenting\nAppium's functionality or changing the way Appium works. They can be distributed to other Appium\nusers and can extend Appium's ecosystem in all kinds of interesting ways! (There is also\na significant amount of overlap here with developing Appium drivers, so you may also want to check\nout the [building drivers](./build-drivers.md) guide for further inspiration.)\n\n## Before you create your plugin","metadata":{"loc":{"lines":{"from":1,"to":14}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"## Before you create your plugin\n\nBefore creating your plugin, it's good to have a general idea of what you want your plugin to\naccomplish and whether it will be possible to implement it given the restrictions of the Appium\nplatform. Reading through this guide will help you understand what's possible. In general, Appium's\nplugin system is extremely powerful and no attempts have been made to artificially limit what's\npossible with them (which is a main reason that all plugins are opt-in by the system administrator\nresponsible for starting the Appium server---plugins are powerful and should only be used when\nexplicitly trusted!).\n\n## Other plugins to reference","metadata":{"loc":{"lines":{"from":14,"to":24}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"## Other plugins to reference\n\nThere are a wide variety of open source Appium plugins available for perusal. It's definitely\nrecommended to explore the code for some other plugins before embarking on writing your own. The\nAppium team maintains a set of official plugins in the [Appium GitHub\nrepo](https://github.com/appium/appium). Links to other open source plugins can be found in the\n[Plugin list](../ecosystem/plugins.md)\n\n## Basic requirements for plugins\n\nThese are the things your plugin *must* do (or be), if you want it to be a valid Appium plugin.\n\n### Node.js package with Appium extension metadata\n\nAll Appium plugins are fundamentally Node.js packages, and therefore must have a valid\n`package.json`. Your driver is not _limited_ to Node.js, but it must provide an adapter written in\nNode.js so it can be loaded by Appium.","metadata":{"loc":{"lines":{"from":24,"to":40}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"Your `package.json` must include `appium` as a `peerDependency`. The requirements for the\ndependency versions should be as loose as possible (unless you happen to know your plugin will only\nwork with certain versions of Appium). For Appium 2, for example, this would look something like\n`^2.0.0`, declaring that your plugin works with any version of Appium that starts with 2.x.\n\nYour `package.json` must contain an `appium` field, like this (we call this the 'Appium extension\nmetadata'):\n\n ```json\n {\n ...,\n \"appium\": {\n \"pluginName\": \"fake\",\n \"mainClass\": \"FakePlugin\"\n },\n ...\n }\n ```\n\nThe required subfields are:\n\n* `pluginName`: this should be a short name for your plugin.\n* `mainClass`: this is a named export (in CommonJS style) from your `main` field. It must be a\n class which extends Appium's `BasePlugin` (see below).\n\n### Extend Appium's `BasePlugin` class","metadata":{"loc":{"lines":{"from":42,"to":67}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"### Extend Appium's `BasePlugin` class\n\nUltimately, your plugin is much easier to write because most of the hard work of defining patterns\nfor overriding commands is done for you. This is\nall encoded up as a class which Appium exports for you to use, called `BasePlugin`. It is exported\nfrom `appium/plugin`, so you can use one of these styles to import it and create your *own* class\nthat extends it:\n\n```js\nimport {BasePlugin} from 'appium/plugin';\n// or: const {BasePlugin} = require('appium/plugin');\n\nexport class MyPlugin extends BasePlugin {\n // class methods here\n}\n```\n\n!!! note\n\n In all the code samples below, whenever we reference an example method, it is assumed\n that it is defined _within_ the class, though this is not explicitly written, for the sake of\n clarity and space.\n\n### Make your plugin available","metadata":{"loc":{"lines":{"from":67,"to":90}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"### Make your plugin available\n\nThat's basically it! With a Node.js package exporting a plugin class and with correct Appium\nextension metadata, you've got yourself an Appium plugin! Now it doesn't *do* anything, but you can\nload it up in Appium, activate it, etc...\n\nTo make it available to users, you could publish it via NPM. When you do so, your plugin will be\ninstallable via the Appium CLI:\n\n```\nappium plugin install --source=npm <plugin-package-on-npm>\n```\n\nIt's a good idea to test your plugin first, of course. One way to see how it works within Appium is\nto install it locally first:\n\n```\nappium plugin install --source=local /path/to/your/plugin\n```\n\nAnd of course, plugins must be \"activated\" during Appium server start, so make sure you direct your\nusers to do so:\n\n```\nappium --use-plugins=plugin-name\n```\n\n### Developing your plugin","metadata":{"loc":{"lines":{"from":90,"to":117}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"And of course, plugins must be \"activated\" during Appium server start, so make sure you direct your\nusers to do so:\n\n```\nappium --use-plugins=plugin-name\n```\n\n### Developing your plugin\n\nHow you develop your plugin is up to you. It is convenient, however, to run it from within Appium\nwithout having to do lots of publishing and installing. The most straightforward way to do this is\nto include the most recent version of Appium as a `devDependency` (although its being already\nincluded as a `peerDependency` is sufficient in newer versions of NPM), and then also your own plugin,\nlike this:\n\n```json\n{\n \"devDependencies\": {\n ...,\n \"appium\": \"^2.0.0\",\n \"your-plugin\": \"file:.\",\n ...\n }\n}\n```","metadata":{"loc":{"lines":{"from":110,"to":134}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"```json\n{\n \"devDependencies\": {\n ...,\n \"appium\": \"^2.0.0\",\n \"your-plugin\": \"file:.\",\n ...\n }\n}\n```\n\nNow, you can run Appium locally (`npm exec appium` or `npx appium`), and because your plugin is\nlisted as a dependency alongside it, it will be automatically \"installed\" and available. You can\ndesign your e2e tests this way, or if you're writing them in Node.js, you can simply import\nAppium's start server methods to handle starting and stopping the Appium server in Node.\n\nOf course, you can always install it locally as described above as well.\n\nAnytime you make changes to your plugin code, you'll need to restart the Appium server to make sure\nit picks up the latest code. As with drivers, you can set the `APPIUM_RELOAD_EXTENSIONS`\nenvironment variable if you wish Appium to try to re-require your plugin module when a new session\nstarts.\n\n## Standard plugin implementation ideas","metadata":{"loc":{"lines":{"from":125,"to":148}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"## Standard plugin implementation ideas\n\nThese are things you will probably find yourself wanting to do when creating a plugin.\n\n### Set up state in a constructor\n\nIf you define your own constructor, you'll need to call `super` to make sure all the standard state\nis set up correctly:\n\n```js\nconstructor(...args) {\n super(...args);\n // now do your own thing\n}\n```\n\nThe `args` parameter here is the object containing all the CLI args used to start the Appium\nserver.\n\n### Intercept and handle specific Appium commands","metadata":{"loc":{"lines":{"from":148,"to":167}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"The `args` parameter here is the object containing all the CLI args used to start the Appium\nserver.\n\n### Intercept and handle specific Appium commands\n\nThis is the most normal behavior for Appium plugins -- to modify or replace the execution of one or\nmore commands that would normally be handled by the active driver. To override the default command\nhandling, you need to implement `async` methods in your class with the same name as the Appium\ncommands to be handled (just exactly how [drivers themselves are\nimplemented](./build-drivers.md#implement-webdriver-classic-commands)). Curious what command names there\nare? They are defined in the Appium base driver's\n[routes.js](https://github.com/appium/appium-base-driver/blob/master/lib/protocol/routes.js) file,\nand of course you can add more as defined in the next section.\n\nEach command method is sent the following arguments:","metadata":{"loc":{"lines":{"from":164,"to":178}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"Each command method is sent the following arguments:\n\n1. `next`: This is a reference to an `async` function which encapsulates the chain of behaviors which would take place if this plugin were not handling the command. You can choose to call the next behavior in the chain at any point in your logic (by making sure to include `await next()` somewhere), or not. If you don't, it means the default behavior (or any plugins registered after this one) won't be run.\n1. `driver`: This is the object representing the driver handling the current session. You have access to it for any work you need to do, for example calling other driver methods, checking capabilities or settings, etc...\n1. `...args`: A spread array with any arguments that have been applied to the command by the user.\n\nFor example, if we wanted to override the `setUrl` command to simply add some extra logging on top,\nwe would implement as follows:","metadata":{"loc":{"lines":{"from":178,"to":185}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"For example, if we wanted to override the `setUrl` command to simply add some extra logging on top,\nwe would implement as follows:\n\n```js\nasync setUrl(next, driver, url) {\n this.log(`Let's get the page source for some reason before navigating to '${url}'!`);\n await driver.getPageSource();\n const result = await next();\n this.log(`We can also log after the original behaviour`);\n return result;\n}\n```\n\n### Intercept and handle _all_ Appium commands\n\nYou might find yourself in a position where you want to handle *all* commands, in order to inspect\npayloads to determine whether or not to act in some way. If so, you can implement `async handle`,\nand any command that is not handled by one of your named methods will be handled by this method\ninstead. It takes the following parameters (with all the same semantics as above):\n\n1. `next`\n1. `driver`\n1. `cmdName` - string representing the command being run\n1. `...args`","metadata":{"loc":{"lines":{"from":184,"to":207}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"1. `next`\n1. `driver`\n1. `cmdName` - string representing the command being run\n1. `...args`\n\nFor example, let's say we want to log timing for all Appium commands as part of a plugin. We could\ndo this by implementing `handle` in our plugin class as follows:\n\n```js\nasync handle(next, driver, cmdName, ...args) {\n const start = Date.now();\n try {\n const result = await next();\n } finally {\n const elapsedMs = Date.now() - start;\n this.log(`Command '${cmdName}' took ${elapsedMs}`);\n }\n return result;\n}\n```\n\n### Working with driver proxies","metadata":{"loc":{"lines":{"from":204,"to":225}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"### Working with driver proxies\n\nThere is a bit of a gotcha with handling Appium commands. Appium drivers have the ability to turn\non a special 'proxy' mode, wherein the Appium server process takes a look at incoming URLs, and\ndecides whether to forward them on to some upstream WebDriver server. It could happen that\na command which a plugin wants to handle is designated as a command which is being proxied to an\nupstream server. In this case, we might run into a problem, because the plugin never gets a chance to\nhandle that command! The way Appium handles this is as follows:","metadata":{"loc":{"lines":{"from":225,"to":232}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"1. When a command comes in, before deciding whether to proxy the command, the main protocol handler\n checks to see whether a plugin would handle the command.\n2. If a plugin would *not* handle the command--all proceeds as normal, and the request is either\n proxied or not, based on the driver's proxy mode.\n3. If a plugin *would* handle the command, then the proxy behavior is skipped for the time being,\n and wrapped up as the `next` function sent to the plugin. So if you have a command handler in\n your plugin, and you want to be sure that the default driver proxying *does* take place, then\n simply `await next()` instead of (or in addition to) whatever your plugin handler is doing.\n\n### Throw WebDriver-specific errors","metadata":{"loc":{"lines":{"from":234,"to":243}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"### Throw WebDriver-specific errors\n\nThe WebDriver spec defines a [set of error\ncodes](https://github.com/jlipps/simple-wd-spec#error-codes) to accompany command responses if an\nerror occurred. Appium has created error classes for each of these codes, so you can throw the\nappropriate error from inside a command, and it will do the right thing in terms of the protocol\nresponse to the user. To get access to these error classes, import them from `appium/driver`:\n\n```js\nimport {errors} from 'appium/driver';\n\nthrow new errors.NoSuchElementError();\n```\n\n### Log messages to the Appium log\n\nYou can always use `console.log`, of course, but Appium provides a nice logger for you as\n`this.logger` (it has `.info`, `.debug`, `.log`, `.warn`, `.error` methods on it for differing log\nlevels). If you want to create an Appium logger outside of a plugin context (say in a script or\nhelper file), you can always construct your own too:","metadata":{"loc":{"lines":{"from":243,"to":262}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"```js\nimport {logging} from 'appium/support';\nconst log = logging.getLogger('MyPlugin');\n```\n\n## Further possibilities for Appium plugins\n\nThese are things your plugin *can* do to take advantage of extra plugin features or do its job more\nconveniently.\n\n### Add a schema for custom command line arguments\n\nYou can add custom CLI args if you want your plugin to receive data from the command line when the\nAppium server is started (for example, ports that a server administrator should set that should not\nbe passed in as capabilities).\n\nThis works largely the same for plugins as it does for drivers, so for more details have a look at\n[the equivalent section in the building drivers\ndoc](./build-drivers.md#add-a-schema-for-custom-command-line-arguments).","metadata":{"loc":{"lines":{"from":264,"to":282}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"The only difference is that to construct the CLI argument name, you prefix it with\n`--plugin-<name>`. So for example, if you have a plugin named `pluggo` and a CLI arg defined with\nthe name `electro-port`, you can set it when starting Appium via `--plugin-pluggo-electro-port`.\n\nSetting args via a configuration file is also supported, as it is for drivers, but under the\n`plugin` field instead. For example:\n\n```json\n{\n \"server\": {\n \"plugin\": {\n \"pluggo\": {\n \"electro-port\": 1234\n }\n }\n }\n}\n```\n\n### Add plugin scripts","metadata":{"loc":{"lines":{"from":284,"to":303}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"```json\n{\n \"server\": {\n \"plugin\": {\n \"pluggo\": {\n \"electro-port\": 1234\n }\n }\n }\n}\n```\n\n### Add plugin scripts\n\nSometimes you might want users of your plugin to be able to run scripts outside the context of\na session (for example, to run a script that pre-builds aspects of your plugin). To support this,\nyou can add a map of script names and JS files to the `scripts` field within your Appium extension\nmetadata. So let's say you've created a script in your project that lives in a `scripts` directory\nin your project, named `plugin-prebuild.js`. Then you could add a `scripts` field like this:\n\n```json\n{\n \"scripts\": {\n \"prebuild\": \"./scripts/plugin-prebuild.js\"\n }\n}\n```\n\nNow, assuming your plugin is named `myplugin`, users of your plugin can run `appium plugin run\nmyplugin prebuild`, and your script will execute.\n\n### Add new Appium commands","metadata":{"loc":{"lines":{"from":291,"to":322}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"Now, assuming your plugin is named `myplugin`, users of your plugin can run `appium plugin run\nmyplugin prebuild`, and your script will execute.\n\n### Add new Appium commands\n\nIf you want to offer functionality that doesn't map to any of the existing commands supported by\ndrivers, you can create new commands in one of two ways, just as is possible for drivers:\n\n1. Extending the WebDriver protocol and creating client-side plugins to access the extensions\n1. Extending the WebDriver BiDi protocol with new modules and methods, accessed from a client via the BiDi interface\n1. Overloading the Execute Script command by defining [Execute\n Methods](../guides/execute-methods.md)\n\n#### Extending the HTTP Protocol","metadata":{"loc":{"lines":{"from":319,"to":332}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"#### Extending the HTTP Protocol\n\nIf you want to follow the first path, you can direct Appium to recognize new methods and add them\nto its set of allowed HTTP routes and command names. You do this by assigning the `newMethodMap`\nstatic variable in your driver class to an object of the same form as Appium's `routes.js` object.\nFor example, here is part of the `newMethodMap` for the `FakePlugin` example driver:\n\n```js\nstatic newMethodMap = {\n '/session/:sessionId/fake_data': {\n GET: {command: 'getFakeSessionData', neverProxy: true},\n POST: {\n command: 'setFakeSessionData',\n payloadParams: {required: ['data']},\n neverProxy: true,\n },\n },\n '/session/:sessionId/fakepluginargs': {\n GET: {command: 'getFakePluginArgs', neverProxy: true},\n },\n};\n```\n\n!!! note\n\n If you're using TypeScript, static member objects like these should be defined `as const`.","metadata":{"loc":{"lines":{"from":332,"to":357}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"!!! note\n\n If you're using TypeScript, static member objects like these should be defined `as const`.\n\nIn this example we're adding a few new routes and a total of 3 new commands. For more examples of\nhow to define commands in this way, it's best to have a look through `routes.js`. Now all you need\nto do is implement the command handlers in the same way you'd implement any other Appium command.\n\nNote also the special `neverProxy` key for commands; this is generally a good idea to set to `true`\nfor plugins, since your plugin might be active for a driver that is put into proxy mode but hasn't\nbothered to decline proxying for these (new and therefore unknown) commands. Setting `neverProxy`\nto `true` here will cause Appium to never proxy these routes and therefore ensure your plugin\nhandles them, even if a driver is in proxy mode.","metadata":{"loc":{"lines":{"from":355,"to":367}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"The downside of adding new commands via `newMethodMap` is that people using the standard Appium\nclients won't have nice client-side functions designed to target these endpoints. So you would need\nto create and release client-side plugins for each language you want to support (directions or\nexamples can be found at the relevant client docs).\n\n#### Extending the BiDi Protocol\n\nYou can also make new commands accessible via the WebDriver BiDi (WebSocket-based) protocol. BiDi\ncommands come in two parts: a \"module\", which is basically a container or namespace, and\na \"command\", which is the name of your new command.","metadata":{"loc":{"lines":{"from":369,"to":378}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"As with the first method, you teach Appium to recognize your new BiDi commands by adding a static\nfield to your driver class, called `newBidiCommands`. It has a format similar to `newMethodMap`.\nBasically it encapsulates information about the BiDi module, BiDi command name, reference to your\ndriver instance method that will handle the command, and required and optional parameters. Here's\nan example of a `newBidiCommands` as implemented on an imaginary driver:\n\n```js\nstatic newBidiCommands = {\n 'appium:video': {\n startFramerateCapture: {\n command: 'startFrameCap',\n params: {\n required: ['videoSource'],\n optional: ['showOnScreen'],\n }\n },\n stopFramerateCapture: {\n command: 'stopFrameCap',\n },\n }\n};\n```","metadata":{"loc":{"lines":{"from":380,"to":401}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"In this imaginary example, we have defined two new BiDi commands: `appium:video.startFramerateCapture` and\n`appium:video.stopFramerateCapture`. The first command takes a required and an optional parameter, and the\nsecond does not. When you have implemented the `startFrameCap` and `stopFrameCap` methods on your\nplugin class, they will be called whenever the BiDi commands are triggered by a client. The\nsignatures for these methods would look as follows:\n\n```js\nasync startFrameCap(next: () => Promise<any>, driver: DriverClass, videoSource: string, showOnScreen: boolean): Promise<any>;\nasync stopFrameCap(next: () => Promise<any>, driver: DriverClass): Promise<any>;\n```","metadata":{"loc":{"lines":{"from":403,"to":412}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"As with adding or overriding existing HTTP protocol commands, these methods are injected with\na `next` parameter and a `driver` parameter. The `driver` object represents the driver currently\nowning the session, and calling `await next()` will execute/return the behavior that would execute\nwere the plugin not active (i.e., the driver's own handling of that method, or the chain of\ncommands executed with the same name by other active plugins).\n\nNote that, currently, if a driver has BiDi proxying turned on, plugins will not be able to override\nBiDi methods handled by the proxy. Also note that since these are custom BiDi commands, our module\nname should include a vendor prefix (we chose `appium:`, but you can/should choose something that\nmakes sense for your extension).\n\n#### Overloading Execute Script","metadata":{"loc":{"lines":{"from":414,"to":425}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"#### Overloading Execute Script\n\nAn alternative to these ways of doing things is to overload a command which all WebDriver clients\nhave access to already: Execute Script. Make sure to read the section on [adding new\ncommands](./build-drivers.md#extend-the-existing-protocol-with-new-commands) in\nthe Building Drivers guide to understand the way this works in general. The way it works with\nplugins is only slightly different. Let's look at an example taken from Appium's `fake-plugin`:\n\n```js\nstatic executeMethodMap = {\n 'fake: plugMeIn': {\n command: 'plugMeIn',\n params: {required: ['socket']},\n },\n};\n\nasync plugMeIn(next, driver, socket) {\n return `Plugged in to ${socket}`;\n}\n\nasync execute(next, driver, script, args) {\n return await this.executeMethod(next, driver, script, args);\n}\n```\n\nWe have three important components shown here which make this system work, all of which are defined\ninside the plugin class:","metadata":{"loc":{"lines":{"from":425,"to":451}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"We have three important components shown here which make this system work, all of which are defined\ninside the plugin class:\n\n1. The `executeMethodMap`, defined in just the same way as for drivers\n1. The implementation of the command method as defined in `executeMethodMap` (in this case,\n `plugMeIn`)\n1. The overriding/handling of the `execute` command. Just like any plugin command handlers, the\nfirst two arguments are `next` and `driver`, followed by the script name and args. `BasePlugin`\nimplements a helper method which we can simply call with all of these arguments.\n\nOverriding Execute Methods from drivers works as you'd expect: if your plugin defines an Execute\nMethod with the same name as that of a driver, your command (in this case `plugMeIn`) will be\ncalled first. You can choose to run the driver's original behaviour via `next` if you want.\n\n### Emit BiDi Events","metadata":{"loc":{"lines":{"from":450,"to":464}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"### Emit BiDi Events\n\nYour plugin can emit custom BiDi events in [exactly the same way as Appium\ndrivers](./build-drivers.md#emit-bidi-events).\n\n### Build Appium Doctor checks\n\nYour users can run `appium plugin doctor <pluginName>` to run installation and health checks. Visit\nthe [Building Doctor Checks](./build-doctor-checks.md) guide for more information on this\ncapability.\n\n### Update the Appium server object\n\nYou probably don't normally need to update the Appium server object (which is an\n[Express](https://expressjs.com/) server having already been\n[configured](https://github.com/appium/appium/blob/master/packages/base-driver/lib/express/server.js)\nin a variety of ways). But, for example, you could add new Express middleware to the server to\nsupport your plugin's requirements. To update the server you must implement the `static async\nupdateServer` method in your class. This method takes three parameters:","metadata":{"loc":{"lines":{"from":464,"to":482}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"* `expressApp`: the Express app object\n* `httpServer`: the Node HTTP server object\n* `cliArgs`: a map of the CLI args used to start the Appium server\n\nYou can do whatever you want with them inside the `updateServer` method. You might want to\nreference how these objects are created and worked with in the BaseDriver code, so that you know\nyou're not undoing or overriding anything standard and important. But if you insist, you can, with\nresults you'll need to test! Warning: this should be considered an advanced feature and requires\nknowledge of Express, as well as the care not to do anything that could affect the operation of\nother parts of the Appium server!\n\n### Handle unexpected session shutdown","metadata":{"loc":{"lines":{"from":484,"to":495}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"### Handle unexpected session shutdown\n\nWhen developing a plugin you may want to add some cleanup logic for when a session ends. You would\nnaturally do this by adding a handler for `deleteSession`. This works in most cases, except when\nthe session does not finish cleanly. Appium sometimes determines that a session has finished\nunexpectedly, and in these situations, Appium will look for a method called `onUnexpectedShutdown`\nin your plugin class, which will be called (passing the current session driver as the first\nparameter, and the error object representing the cause of the shutdown as the second), giving you\nan opportunity to take any steps that might be necessary to clean up from the session. For example,\nkeeping in mind that the function is not `await`ed you could implement something like this:","metadata":{"loc":{"lines":{"from":495,"to":504}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"```js\nasync onUnexpectedShutdown(driver, cause) {\n try {\n // do some cleanup\n } catch (e) {\n // log any errors; don't allow anything to be thrown as they will be unhandled rejections\n }\n}\n```","metadata":{"loc":{"lines":{"from":506,"to":514}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/build-plugins.md","filename":"build-plugins.md","relativePath":"appium/developing/build-plugins.md"}},{"pageContent":"---\ntitle: Appium's Config System\n---\n\nAppium 2 supports [configuration files](../guides/config.md). A configuration file is intended to\nhave (nearly) 1:1 parity with command-line arguments. An end user can supply Appium 2 with\na configuration file, CLI args, or both (the args have precedence over the config file).\n\nThis document will be a technical overview of how the configuration system works. It is intended\nfor Appium contributors, but will also explain the system's fundamental features.\n\n## Reading a Config File\n\nA config file is a JSON, JavaScript, or YAML file which can be validated against a schema. By\ndefault, this file will be named `.appiumrc.{json,js,yaml,yml}` and should be in the root of the\nproject which depends upon `appium`. Other filenames and locations are supported via the `--config\n<file>` flag. For obvious reasons, the `config` argument is disallowed within config files.","metadata":{"loc":{"lines":{"from":1,"to":17}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"In lieu of a separate file, configuration can be embedded in a project's `package.json` using the\n`appiumConfig` property, e.g.,:\n\n```json\n{\n \"appiumConfig\": {\n \"server\": {\n \"port\": 12345\n }\n }\n}\n```\n\nWhen an Appium server is started via the `appium` executable, the `init` function in `lib/main.js`\nwill call into `lib/config-file.js` to load and/or search for a configuration file and in\n`package.json`.\n\n!!! note\n\n It is not an error if configuration isn't found!\n\nThe [`lilconfig`](https://npm.im/lilconfig) package provides the search & load functionality; refer\nto its documentation for more information about the search paths. Additionally, Appium provides\nsupport for config files written in YAML via the package [`yaml`](https://npm.im/yaml).","metadata":{"loc":{"lines":{"from":19,"to":42}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"If a config file is found and successfully [validated](#validation), the result will be merged with\na set of defaults and any additional CLI arguments. CLI arguments have precedence over config\nfiles, and config files have precedence over defaults.\n\n## Validation\n\nThe same system is used for _both_ validation of config files _and_ command-line arguments.\n\nThe package [`ajv`](https://npm.im/ajv) provides validation. Of course, to make `ajv` validate\nanything, it must be provided a _schema_.\n\nThe _base_ schema is a [JSON Schema\nDraft-7](https://json-schema.org/draft/2020-12/json-schema-core.html)-compliant object exported by\n`lib/schema/appium-config-schema.js`. This schema defines configuration _native to Appium_, and\nonly concerns its behavior as a _server_; it does not define configuration for any other\nfunctionality (e.g., the `plugin` or `driver` subcommands).\n\n!!! warning\n\n Note that this file is the _base_ schema; this will become painfully relevant.","metadata":{"loc":{"lines":{"from":44,"to":63}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"!!! warning\n\n Note that this file is the _base_ schema; this will become painfully relevant.\n\nThis file is is _not_ a JSON file, because a) JSON is painful to work with for humans, b) is\nespecially reviled by @jlipps, and c) `ajv` accepts objects, not JSON files.\n\nIt is more straightforward to explain how config files are validated, so we'll start there.\n\n### Validating Config Files\n\nWhen a config file is found (`lib/config-file.js`), it will call the `validate` function exported\nfrom `lib/schema/schema.js` with the contents of the config file. In turn, this asks `ajv` to\nvalidate the data against the schema that Appium has provided it.\n\nIf the config file is invalid, errors will be generated to be displayed to the user. Finally, the\n`init` function will detect these errors, display them, and the process will exit.\n\nI hope that made sense, because this is the easy part.\n\n### Validating CLI Arguments","metadata":{"loc":{"lines":{"from":61,"to":81}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"I hope that made sense, because this is the easy part.\n\n### Validating CLI Arguments\n\nAs mentioned earlier, the same system is used for validating both config files and CLI arguments.\n\nTotally not judging, but Appium uses [`argparse`](https://npm.im/argparse) for its CLI argument\nparsing. This package, and others like it, provides an API to define the arguments a command-line\nNode.js script accepts, and will ultimately return an object representation of the user-supplied\narguments.\n\nJust as the schema defines what's allowed in a config file, it also defines what's allowed on the\ncommand-line.\n\n#### Defining CLI Arguments via Schema\n\nCLI arguments must be _defined_ before their values can be validated.\n\nA JSON schema isn't a natural fit for defining CLI args--it needs some grease to make it work--but\nit's close enough that we can do so with an adapter and some custom metadata.","metadata":{"loc":{"lines":{"from":79,"to":98}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"A JSON schema isn't a natural fit for defining CLI args--it needs some grease to make it work--but\nit's close enough that we can do so with an adapter and some custom metadata.\n\nIn `lib/cli/parser.js`, there's a wrapper around `argparse`'s `ArgumentParser`; it's called (wait\nfor it)... `ArgParser`. The wrapper exists because we're doing some custom things with `argparse`,\nbut is has nothing to do with the schema directly.\n\nAn `ArgParser` instance is created and its `parseArgs()` method is called with the raw CLI\narguments. The definition of the accepted arguments comes from `lib/cli/args.js` in part--here, all\nof the arguments _not_ intended for use with the `server` subcommand are hard-coded (e.g., the\n`driver` subcommand and _its_ subcommands). `args.js` also contains a function `getServerArgs()`,\nwhich in turn calls into `toParserArgs` in `lib/schema/cli-args.js`. `lib/schema/cli-args.js` can\nbe considered the \"adapter\" layer between `argparse` and the schema.","metadata":{"loc":{"lines":{"from":97,"to":109}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"`toParserArgs` uses the `flattenSchema` function exported by `lib/schema/schema.js`, which\n\"squashes\" the schema into a key/value representation. Then, `toParserArgs` iterates over each\nkey/value pair and \"converts\" it into a suitable `ArgumentOption` object for final handoff to\n`ArgParser`.\n\nThis adapter (`cli-args.js`) is where most of the mess is hidden; let's explore this rat's nest\na bit further.\n\n##### CLI & Schema Incongruities\n\nThe conversion algorithm (see function `subSchemaToArgDef` in `lib/schema/cli-args.js`) is mostly\njust hacks and special cases neatly packed into a function. Things that don't cleanly map from\n`argparse` to a JSON schema include, but are not limited to:","metadata":{"loc":{"lines":{"from":111,"to":123}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"- A schema cannot natively express \"store the value of `--foo=<value>` in a property called `bar`\" in a schema (this corresponds to the `ArgumentOption['dest']` prop).\n- A schema cannot natively express aliases; e.g., `--verbose` can also be `-v`\n- A schema `enum` is not restricted to multiple types, but `argparse`'s equivalent `ArgumentOption['choices']` prop _is_\n- A schema does not know about `argparse`'s concept of \"actions\" (note that Appium is not currently using custom actions--though it did, and it could again).\n- `argparse` has no native type for `email`, `hostname`, `ipv4`, `uri` etc., and the schema does\n- Schema validation only _validates_, it does not perform translation, transformation, or coercion (mostly). `argparse` allows this.\n- Schemas allow the `null` type, for whatever reason. Ever pass `null` on the CLI?\n- `argparse` does not understand anything other than primitives; no objects, arrays, etc., and certainly not arrays of a particular type.","metadata":{"loc":{"lines":{"from":125,"to":132}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"All of the above cases and others are handled by the adapter.\n\n!!! warning\n\n Some decisions made in the adapter were arrived at via coin toss. If you are curious about why\n something is the way it is, it's likely that it had to do _something_.\n\nLet's look more closely at handling types.\n\n#### Argument Types via `ajv`\n\nWhile `argparse` allows consumers, via its API, to define the _type_ of various arguments (e.g.,\na string, number, boolean flag, etc.), Appium mostly avoids these built-in types. _Why is that?_\nWell:\n\n1. We already know the type of an argument, because we've defined it in a schema.\n2. `ajv` provides validation against a schema.\n3. A schema allows for greater expression of types, allowed values, etc., than `argparse` can provide natively.\n4. The expressiveness of a schema allows for better error messaging.","metadata":{"loc":{"lines":{"from":134,"to":152}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"To that end, the adapter eschews `argparse`'s built-in types (see allowed string values of\n`ArgumentOption['type']`) and instead abuses the ability to provide a _function_ as a `type`. The\nexception is _boolean_ flags, which do not have a `type`, but rather `action: 'store_true'`. The\nworld may never know why.\n\n##### Types as Functions\n\nWhen a `type` is a function, the function performs both validation _and_ coercion (if necessary).\nSo what are these functions?\n\n> Note: `type` is _omitted_ (and thus _not_ a function) from the `ArgumentOption` if the property\n> type is `boolean`, and is instead provided an `action` property of `store_true`. Yes, this is\n> weird. No, I don't know why.","metadata":{"loc":{"lines":{"from":154,"to":166}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"Well... it depends upon the schema. But generally speaking, we create a _pipeline_ of functions,\neach corresponding to a keyword in the schema. Let's take the example of the `port` argument. In\nlieu of asking the OS which ports the `appium`-running user can bind to, this argument is expected\nto be an integer between 1 and 65535. This turns out to be two functions which we combine into\na pipeline:\n\n1. Convert the value to an integer, if possible. Because _every value in `process.argv` is a string_, we must coerce if we want a number.\n2. Use `ajv` to validate the integer against the schema for `port`. A schema lets us define a range via the `minimum` and `maximum` keywords. Read more about how this works in\n\nMuch like the config file validation, if errors are detected, Appium nicely tells the end-user and\nthe process exits w/ some help text.\n\nFor other arguments which are naturally of non-primitive types, things are not so straightforward.\n\n##### Transformers","metadata":{"loc":{"lines":{"from":168,"to":182}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"For other arguments which are naturally of non-primitive types, things are not so straightforward.\n\n##### Transformers\n\nRemember how `argparse` doesn't understand arrays? What if the most ergonomic way to express\na value is, in fact, an array?\n\nWell, Appium can't accept an array on the CLI, even though it can accept one in the config file.\nBut Appium _can_ accept a comma-delimited string (a CSV \"line\"). Or a string filepath referring to\na file which _contains_ a delimited list. Either way: by the time the value gets out of the\nargument parser, it should be an array.\n\nAnd as mentioned above, the native facilities of a JSON schema cannot express this. However, it's\npossible to define a _custom keyword_ which Appium can then detect and handle accordingly. So\nthat's what Appium does.","metadata":{"loc":{"lines":{"from":180,"to":194}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"In this case, a custom keyword `appiumCliTransformer` is registered with `ajv`. The value of\n`appiumCliTransformer` (at the time of this writing) can be `csv` or `json`. In the base schema\nfile, `appium-config-schema.js`, Appium uses `appiumCliTransformer: 'csv'` if this behavior is\ndesired.\n\n!!! note\n\n Any property defined in the schema having type `array` will _automatically_ uses the `csv`\n transformer. Likewise, a property having type `object` will use the `json` transformer. It's\n conceivable that `array` may want to use the `json` transformer, but otherwise, the presence of\n the `appiumCliTransformer` keyword on an `array`-or-`object`-typed property is not strictly\n necessary.","metadata":{"loc":{"lines":{"from":196,"to":207}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"The adapter (remember the adapter?) creates a pipeline function including a special \"CSV\ntransformer\" (transformers are defined in `lib/schema/cli-transformers.js`), and uses this function\nas the `type` property of the `ArgumentOption` passed into `argparse`. In this case, the `type:\n'array'` in the schema is ignored.\n\n!!! note\n\n The config file doesn't _need_ to perform any complex transformation of values, because it\n naturally allows Appium to define exactly what it expects. So Appium does no post-processing of\n config file values.\n\nProperties that do not need this special treatment use `ajv` directly for validation. How this\nworks requires some explanation, so that's next.\n\n#### Validation of Individual Arguments via `ajv`\n\nWhen we think of a JSON schema, we tend to think, \"I have this JSON file and I want to validate it\nagainst the schema\". That's valid, and in fact Appium does just that with config files! However,\nAppium does not do this when validating arguments.","metadata":{"loc":{"lines":{"from":209,"to":227}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"!!! note\n\n During implementation, I was tempted to mash all of the arguments together into\n a config-file-like data structure and then validate it all at once. I think that would have\n been _possible_, but since an object full of CLI arguments is a flat key/value structure and\n the schema is not, this seemed like trouble.\n\nInstead, Appium validates a value against a specific property _within_ the schema. To do this, it\nmaintains a mapping between a CLI argument definition and its corresponding property. The mapping\nitself is a `Map` with a unique identifier for the argument as the key, and an `ArgSpec`\n(`lib/schema/arg-spec.js`) object as the value.\n\nAn `ArgSpec` object stores the following metadata:","metadata":{"loc":{"lines":{"from":229,"to":241}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"| Property Name | Description |\n| --------------- | ------------------------------------------------------------------------------------- |\n| `name` | Canonical name of the argument, corresponding to the property name in the schema. |\n| `extType?` | `driver` or `plugin`, if appropriate |\n| `extName?` | Extension name, if appropriate |\n| `ref` | Computed `$id` of the property in the schema |\n| `arg` | Argument as accepted on CLI, without leading dashes |\n| `dest` | Property name in parsed arguments object (as returned by `argparse`'s `parse_args()`) |\n| `defaultValue?` | Value of the `default` keyword in schema, if appropriate |","metadata":{"loc":{"lines":{"from":243,"to":251}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"When a schema is [finalized](#schema-loading), the `Map` is populated with `ArgSpec` objects\nfor all known arguments.\n\nSo when the adapter is creating the pipeline of functions for the argument's `type`, it already has\nan `ArgSpec` for the argument. It creates a function which calls `validate(value, ref)` (in\n`lib/schema/schema.js`) where `value` is whatever the user provided, and `ref` is the `ref`\nproperty of the `ArgSpec`. The concept is that `ajv` can validate using _any_ `ref` it knows about;\neach property in a schema can be referenced by this `ref` whether it's defined or not. To help\nvisualize, if a schema is:\n\n```json\n{\n \"$id\": \"my-schema.json\",\n \"type\": \"object\",\n \"properties\": {\n \"foo\": {\n \"type\": \"number\"\n }\n }\n}\n```","metadata":{"loc":{"lines":{"from":253,"to":273}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"```json\n{\n \"$id\": \"my-schema.json\",\n \"type\": \"object\",\n \"properties\": {\n \"foo\": {\n \"type\": \"number\"\n }\n }\n}\n```\n\nThe `ref` of `foo` would be `my-schema.json#/properties/foo`. Assuming our `Ajv` instance knows\nabout this `my-schema.json`, then we can call its `getSchema(ref)` method (which has a `schema`\nproperty, but is a misnomer nonetheless) to get a validation function; `validate(value, ref)` in\n`schema.js` calls this validation function.\n\n!!! note\n\n The schema spec says a schema author can supply an explicit `$id` keyword to override this;\n it's unsupported by Appium at this time. If needed, extension authors must carefully use `$ref`\n without custom `$id`s. It's highly unlikely an extension would have a schema so complicated as\n to need this, however; Appium itself doesn't even use `$ref` to define its own properties!\n\nNext, let's take a look at how Appium loads schemas. This actually happens _before_ any argument\nvalidation.\n\n## Schema Loading","metadata":{"loc":{"lines":{"from":263,"to":290}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"Next, let's take a look at how Appium loads schemas. This actually happens _before_ any argument\nvalidation.\n\n## Schema Loading\n\nLet's ignore extensions for a moment, and start with the base schema.\n\nWhen something first imports the `lib/schema/schema.js` module, an instance of an `AppiumSchema` is\ncreated. This is a singleton, and its methods are exported from the module (all of which are bound\nto the instance).\n\nThe constructor does very little; it instantiates an `Ajv` instance and configures it with Appium's\n[custom keywords](#custom-keyword-reference) and adds support for the `format` keyword via the\n[ajv-formats](https://npm.im/ajv-formats) module.\n\nOtherwise, the `AppiumSchema` instance does not interact with the `Ajv` instance until its\n`finalize()` method (exported as `finalizeSchema()`) is called. When this method is called, we're\nsaying \"we are not going to add any more schemas; go ahead and create `ArgSpec` objects and\nregister schemas with `ajv`\".","metadata":{"loc":{"lines":{"from":287,"to":305}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"When does finalization happen? Well:\n\n1. When the `appium` executable begins, it _checks for and configures extensions_ (hand-wave) in `APPIUM_HOME`.\n2. Only then does it start to think about arguments--it instantiates an `ArgParser`, which (as you'll recall) runs the adapter to convert the schema to arguments.\n3. _Finalization happens here_--when creating the parser. Appium need the schema(s) to be registered with `ajv` in order to create validation functions for arguments.\n4. Thereafter, Appium parses the arguments with the `ArgParser`.\n5. Finally, decides what to do with the returned object.\n\nWithout extensions, `finalize()` still knows about the Appium base schema\n(`appium-config-schema.js`), and just registers that. However, step 1. above is doing a _lot of\nwork_, so let's look at how extensions come into play.\n\n## Extension Support\n\nOne of the design goals of this system is the following:","metadata":{"loc":{"lines":{"from":307,"to":321}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"## Extension Support\n\nOne of the design goals of this system is the following:\n\n_An extension should be able to register custom CLI arguments with the Appium, and a user should be\nable to use them like any other argument_.\n\nPreviously, Appium 2 accepted arguments in this manner (via `--driverArgs`), but validation was\nhand-rolled and required extension implementors to use a custom API. It also required the user to\nawkwardly pass a JSON string as the configuration on the command-line. Further, no contextual help\n(via `--help`) existed for these arguments.\n\nNow, by providing a schema for its options, a driver or plugin can register CLI arguments and\nconfig file schemas with Appium.\n\nTo register a schema, an extension must provide the `appium.schema` property in its `package.json`.\nThe value may be a schema or a path to a schema. If the latter, the schema should be JSON or\na CommonJS module (ESM not supported at this time, nor is YAML).","metadata":{"loc":{"lines":{"from":319,"to":336}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"For any property in this schema, the property will appear as a CLI argument of the form\n`--<extension-type>-<extension-name>-<property-name>`. For example, if the `fake` driver provides\na property `foo`, the argument will be `--driver-fake-foo`, and will show in `appium server --help`\nlike any other CLI argument.\n\nThe corresponding property in a config file would be\n`server.<extension-type>.<extension-name>.<property-name>`, e.g.:\n\n```json\n{\n \"server\": {\n \"driver\": {\n \"fake\": {\n \"foo\": \"bar\"\n }\n }\n }\n}\n```\n\nThe naming convention described above avoids problems of one extension type having a name conflict\nwith a different extension type.\n\n!!! note","metadata":{"loc":{"lines":{"from":338,"to":361}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"The naming convention described above avoids problems of one extension type having a name conflict\nwith a different extension type.\n\n!!! note\n\n While an extension can provide aliases via `appiumCliAliases`, \"short\" flags are disallowed,\n since all arguments from extensions are prefixed with `--<extension-type>-<extension-name>-`.\n The extension name and argument name will be kebab-cased for the CLI, according to [Lodash's\n rules](https://lodash.com/docs/4.17.15#kebabCase) around kebab-casing.\n\nThe schema object will look much like Appium's base schema, but it will only have top-level\nproperties (nested properties are currently unsupported). Example:\n\n```json\n{\n \"title\": \"my rad schema for the cowabunga driver\",\n \"type\": \"object\",\n \"properties\": {\n \"fizz\": {\n \"type\": \"string\",\n \"default\": \"buzz\",\n \"$comment\": \"corresponds to CLI --driver-cowabunga-fizz\"\n }\n }\n}\n```","metadata":{"loc":{"lines":{"from":358,"to":383}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"As written in a user's config file, this would be the `server.driver.cowabunga.fizz` property.\n\nWhen extensions are loaded, the `schema` property is verified and the schema is registered with the\n`AppiumSchema` (it is _not_ registered with `Ajv` until `finalize()` is called).\n\nDuring finalization, each registered schema is added to the `Ajv` instance. The schema is assigned\nan `$id` based on the extension type and name (which overrides whatever the extension provides, if\nanything). Schemas are also forced to disallowed unknown arguments via the `additionalProperties:\nfalse` keyword.\n\nBehind the scenes, the base schema has `driver` and `plugin` properties which are objects. When\nfinalized, a property is added to each--corresponding to an extension name--and the value of this\nproperty is a reference to the `$id` of a property in the extension schema. For example, the\n`server.driver` property will look like this:","metadata":{"loc":{"lines":{"from":385,"to":398}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"```json\n{\n \"driver\": {\n \"cowabunga\": {\n \"$ref\": \"driver-cowabunga.json\"\n }\n }\n}\n```\n\nThis is why we call it the \"base\" schema--it is _mutated_ when extensions provide schemas. The\nextension schemas are kept separately, but the _references_ are added to the schema before it's\nultimately added to `ajv`. This works because an `Ajv` instance understands references _from_ any\nschema it knows about _to_ any schema it knows about.\n\n!!! note\n\n This makes it impossible to provide a complete static schema for Appium _and_ the installed\n extensions (as of Nov 5 2021). A static `.json` schema _is_ generated from the base (via a Gulp\n task), but it does not contain any extension schemas. The static schema also has uses beyond\n Appium; e.g., IDEs can provide contextual error-checking of config files this way. Let's solve\n this?","metadata":{"loc":{"lines":{"from":400,"to":421}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"Just like how we look up the reference ID of a particular argument in the base schema, validation\nof arguments from extensions happens the exact same way. If the `cowabunga` driver has the schema\nID `driver-cowabunga.json`, then the `fizz` property can be referenced from any schema registered\nwith `ajv` via `driver-cowabunga.json#/properties/fizz`. \"Base\" schema arguments begin with\n`appium.json#properties/` instead.\n\n## Development Environment Support\n\nDuring the flow of development, a couple extra tasks have been automated to maintain the base\nschema:","metadata":{"loc":{"lines":{"from":423,"to":432}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"## Development Environment Support\n\nDuring the flow of development, a couple extra tasks have been automated to maintain the base\nschema:\n\n- As a post-transpilation step, a `lib/appium-config.schema.json` gets generated from\n- `lib/schema/appium-config-schema.js` (in addition to its CJS counterpart generated by Babel).\n- This file is under version control. It ends up being _copied_ to\n- `build/lib/appium-config.schema.json` in this step. A pre-commit hook (see\n- `scripts/generate-schema-declarations.js` in the root monorepo) generates\n- a `types/appium-config-schema.d.ts` from the above JSON file. The types in `types/types.d.ts`\n- depend upon this file. This file is under version control.\n\n## Custom Keyword Reference\n\nKeywords are defined in `lib/schema/keywords.js`.","metadata":{"loc":{"lines":{"from":429,"to":444}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"- `appiumCliAliases`: allows a schema to express aliases (e.g., a CLI argument can be `--verbose` or `-v`). This is an array of strings. Strings shorter than three (3) characters will begin with a single dash (`-`) instead of a double-dash (`--`). Note that any argument provided by an extension will begin with a double-dash, because these are required to have the `--<extension-type>-<extension-name>-` prefix.\n- `appiumCliDest`: allows a schema to specify a custom property name in the post-`argprase` arguments objects. If not set, this becomes a camelCased string.\n- `appiumCliDescription`: allows a schema to override the description of the argument when displayed on the command-line. This is useful paired with `appiumCliTransformer` (or `array`/`object`-typed properties), since there's a substantial difference between what a CLI-using user can provide vs. what a config-file-using user can provide.","metadata":{"loc":{"lines":{"from":446,"to":448}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"- `appiumCliTransformer`: currently a choice between `csv` and `json`. These are custom functions which post-process a value. They are not used when loading & validating config files, but the idea should be that they result in the same object you'd get if you used whatever the config file wanted (e.g., an array of strings). `csv` is for comma-delimited strings and CSV files; `json` is for raw JSON strings and `.json` files.\n- `appiumCliIgnore`: If `true`, do not support this property on the CLI.\n- `appiumDeprecated`: If `true`, the property is considered \"deprecated\", and will be displayed as such to the user (e.g., in the `--help` output). Note the JSON Schema draft-2019-09 introduces a new keyword `deprecated` which we should use instead if upgrading to this metaschema. When doing so, `appiumDeprecated` should itself be marked as `deprecated`.","metadata":{"loc":{"lines":{"from":449,"to":451}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/config-system.md","filename":"config-system.md","relativePath":"appium/developing/config-system.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Intro to Development\n---\n\nAppium 2 is built with a modular structure, which means that Appium extensions (drivers and plugins)\nare decoupled from the main Appium module, and you only need to install the extensions that you\nwant to use. This modular structure also unlocks the ability to develop entirely new extensions!\n\nThis section of the Appium documentation is intended to help aspiring developers with creating their\nown Appium extension:\n\n* For creating a driver, see the [Build Drivers](./build-drivers.md) page\n* For creating a plugin, take a look at the [Build Plugins](build-plugins.md) page\n* Drivers and plugins both need documentation, so check out the [Build Documentation](./build-docs.md) page\n* For creating a doctor check, see the [Building Doctor Checks](./build-doctor-checks.md) page","metadata":{"loc":{"lines":{"from":1,"to":18}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/index.md","filename":"index.md","relativePath":"appium/developing/index.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Masking Sensitive Log Data\n---\n\nSince Appium server version 2.18.0 there is a possibility to mask sensitive\nvalues in logs. The below tutorial explains how to use this feature in third-party\nextensions.\n\n## Why It Might Be Useful\n\nIt is the right call to hide sensitive information, like passwords, tokens, etc.\nfrom server logs, so it does not accidentally leak if these logs end up in wrong hands.\nAppium server already provides a way to manipulate logs records via\n[filtering](../guides/log-filters.md), although it has its own limitations.\nThe current approach is more sophisticated though, and requires some fine-tuning\non the driver/plugin side.\n\n## How To\n\nThe assumption is that your extension uses the standard built-in\n[@appium/logger](https://www.npmjs.com/package/@appium/logger).\nIn order to get some value in logs replaced by a generic mask it is necessary:\n\n- Change the logging expression to wrap sensitive values and format them, for example:","metadata":{"loc":{"lines":{"from":1,"to":27}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/sensitive.md","filename":"sensitive.md","relativePath":"appium/developing/sensitive.md"}},{"pageContent":"- Change the logging expression to wrap sensitive values and format them, for example:\n\n ```js\n this.log.info(`Value: ${value}`);\n ```\n\n becomes\n\n ```js\n import {logger} from '@appium/support';\n\n this.log.info('Value: %s', logger.markSensitive(value));\n ```\n\n The formatting happens via the standard Node.js's\n [util.format](https://nodejs.org/api/util.html#utilformatformat-args) API.\n\n- While sending the appropriate server request, where this log line is used and should be masked,\n add the custom header `X-Appium-Is-Sensitive` with its value set to `1` or `true` (case-insensitive).\n Without such header the above log value is not going to be masked.\n This way it is possible to conditionally mask log records depending on which\n request is being handled by the extension if the log expression is used in the\n common section.","metadata":{"loc":{"lines":{"from":27,"to":49}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/developing/sensitive.md","filename":"sensitive.md","relativePath":"appium/developing/sensitive.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Appium Clients\n---\n\nYou need a client to write and run Appium scripts. You'll want to become very\nfamiliar with your client documentation (as well as the documentation of any Selenium client that\nthe Appium client depends on) since that will be your primary interface to Appium.\n\nTo learn more about clients, read our [Client Intro](../intro/clients.md).\n\n### Official Clients\n\nThese clients are currently maintained by the Appium team:\n\n|Client|Language|\n|-|-|\n|[Appium Java client](https://github.com/appium/java-client)|Java|\n|[Appium Python client](https://github.com/appium/python-client)|Python|\n|[Appium Ruby Core client](https://github.com/appium/ruby_lib_core) (Recommended)<br>[Appium Ruby client](https://github.com/appium/ruby_lib)|Ruby|\n|[Appium .NET client](https://github.com/appium/dotnet-client)|C#|\n\n### Other Clients\n\nThese clients are not maintained by the Appium team and can be used with other languages:","metadata":{"loc":{"lines":{"from":1,"to":27}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/ecosystem/clients.md","filename":"clients.md","relativePath":"appium/ecosystem/clients.md"}},{"pageContent":"### Other Clients\n\nThese clients are not maintained by the Appium team and can be used with other languages:\n\n|Client|Language|\n|-|-|\n|[WebdriverIO](https://webdriver.io/docs/appium)|Node.js|\n|[Nightwatch.js](https://nightwatchjs.org/guide/mobile-app-testing/introduction.html)|Node.js|\n|[RobotFramework](https://github.com/serhatbolsu/robotframework-appiumlibrary)|DSL|\n|[multicatch's appium-client](https://github.com/multicatch/appium-client)|Rust|\n|[SwiftAppium](https://github.com/milcgroup/swiftappium)|Swift|\n\nIn general, any W3C WebDriver spec-compatible client will also integrate well with Appium, though\nsome Appium-specific commands may not be implemented in other clients.\n\n!!! note\n\n If you maintain an Appium client that you would like to be listed in the Appium docs, feel free\n to make a PR to add it to this section with a link to the documentation for the client.","metadata":{"loc":{"lines":{"from":25,"to":43}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/ecosystem/clients.md","filename":"clients.md","relativePath":"appium/ecosystem/clients.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Appium Drivers\n---\n\nYou can't use Appium without at least one driver! Click on the link for each driver to see the\nspecific installation instructions and documentation for that driver.\n\nGenerally, drivers can be installed using their listed installation key, with the following command:\n```\nappium driver install <installation key>\n```\n\nTo learn more about drivers, check out the [Driver Intro](../intro/drivers.md).\n\n### Official Drivers\n\nThese drivers are currently maintained by the Appium team:","metadata":{"loc":{"lines":{"from":1,"to":20}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/ecosystem/drivers.md","filename":"drivers.md","relativePath":"appium/ecosystem/drivers.md"}},{"pageContent":"To learn more about drivers, check out the [Driver Intro](../intro/drivers.md).\n\n### Official Drivers\n\nThese drivers are currently maintained by the Appium team:\n\n|Driver|Installation Key|Platform(s)|Mode(s)|\n|--|--|--|--|\n|[Chromium](https://github.com/appium/appium-chromium-driver)|`chromium`|macOS, Windows, Linux|Web|\n|[Espresso](https://github.com/appium/appium-espresso-driver)|`espresso`|Android|Native|\n|[Gecko](https://github.com/appium/appium-geckodriver)|`gecko`|macOS, Windows, Linux, Android|Web|\n|[Mac2](https://github.com/appium/appium-mac2-driver)|`mac2`|macOS|Native|\n|[Safari](https://github.com/appium/appium-safari-driver)|`safari`|macOS, iOS|Web|\n|[UiAutomator2](https://github.com/appium/appium-uiautomator2-driver)|`uiautomator2`|Android|Native, Hybrid, Web|\n|[Windows](https://github.com/appium/appium-windows-driver)|`windows`|Windows|Native|\n|[XCUITest](https://github.com/appium/appium-xcuitest-driver)|`xcuitest`|iOS|Native, Hybrid, Web|\n\n### Other Drivers","metadata":{"loc":{"lines":{"from":16,"to":33}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/ecosystem/drivers.md","filename":"drivers.md","relativePath":"appium/ecosystem/drivers.md"}},{"pageContent":"### Other Drivers\n\nThese drivers are not maintained by the Appium team and can be used to target additional platforms:","metadata":{"loc":{"lines":{"from":33,"to":35}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/ecosystem/drivers.md","filename":"drivers.md","relativePath":"appium/ecosystem/drivers.md"}},{"pageContent":"|Driver|Installation Key|Platform(s)|Mode(s)|Supported By|\n|--|--|--|--|--|\n|[Flutter](https://github.com/appium/appium-flutter-driver)|`--source=npm appium-flutter-driver`|iOS, Android|Native|Community|\n|[Flutter Integration](https://github.com/AppiumTestDistribution/appium-flutter-integration-driver)|`--source=npm appium-flutter-integration-driver`|iOS, Android|Native|Community / `@AppiumTestDistribution`|\n|[LG WebOS](https://github.com/headspinio/appium-lg-webos-driver)|`--source=npm appium-lg-webos-driver`|LG TV|Web|HeadSpin|\n|[Linux](https://github.com/fantonglang/appium-linux-driver)|`--source=npm @stdspa/appium-linux-driver`|Linux|Native|`@fantonglang`|\n|[Roku](https://github.com/headspinio/appium-roku-driver)|`--source=npm @headspinio/appium-roku-driver`|Roku|Native|HeadSpin|\n|[Tizen](https://github.com/Samsung/appium-tizen-driver)|`--source=npm appium-tizen-driver`|Android|Native|Community / Samsung|","metadata":{"loc":{"lines":{"from":37,"to":44}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/ecosystem/drivers.md","filename":"drivers.md","relativePath":"appium/ecosystem/drivers.md"}},{"pageContent":"|[Tizen](https://github.com/Samsung/appium-tizen-driver)|`--source=npm appium-tizen-driver`|Android|Native|Community / Samsung|\n|[TizenTV](https://github.com/headspinio/appium-tizen-tv-driver)|`--source=npm appium-tizen-tv-driver`|Samsung TV|Web|HeadSpin|\n|[Youi](https://github.com/YOU-i-Labs/appium-youiengine-driver)|`--source=npm appium-youiengine-driver`|iOS, Android, macOS, Linux, tvOS|Native|Community / You.i|\n|[NovaWindows](https://github.com/AutomateThePlanet/appium-novawindows-driver)|`--source=npm appium-novawindows-driver`|Windows|Native|Community / Automate The Planet|","metadata":{"loc":{"lines":{"from":44,"to":47}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/ecosystem/drivers.md","filename":"drivers.md","relativePath":"appium/ecosystem/drivers.md"}},{"pageContent":"!!! note\n\n If you maintain an Appium driver that you would like to be listed in the Appium docs, feel free\n to make a PR to add it to this section with a link to the driver documentation.","metadata":{"loc":{"lines":{"from":49,"to":52}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/ecosystem/drivers.md","filename":"drivers.md","relativePath":"appium/ecosystem/drivers.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Ecosystem Overview\n---\n\nAppium has a wide ecosystem of related software and tools. This section of the Appium documentation\naims to compile a listing of various officially-supported and community-supported Appium projects:\n\n<div class=\"grid cards\" markdown>\n\n- :material-car: __Drivers__\n\n ---\n\n Link Appium to your test device\n\n [:octicons-arrow-right-24: View all drivers](./drivers.md)\n\n- :octicons-code-16: __Clients__\n\n ---\n\n Link Appium to your automation code\n\n [:octicons-arrow-right-24: View all clients](./clients.md)\n\n- :fontawesome-solid-plug: __Plugins__\n\n ---\n\n Modify and extend Appium functionality\n\n [:octicons-arrow-right-24: View all plugins](./plugins.md)\n\n- :material-wrench: __Tools__\n\n ---\n\n Interact with Appium in other ways\n\n [:octicons-arrow-right-24: View all tools](./tools.md)\n\n</div>","metadata":{"loc":{"lines":{"from":1,"to":45}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/ecosystem/index.md","filename":"index.md","relativePath":"appium/ecosystem/index.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Appium Plugins\n---\n\nPlugins offer various ways to extend or modify Appium's behaviour. They are _completely optional_\nand are not needed for standard automation functionality, but you may find them to be useful\nfor more specialised automation workflows.\n\nGenerally, plugins can be installed using their listed installation key, with the following command:\n```\nappium plugin install <installation key>\n```\n\n### Official Plugins\n\nThese plugins are are currently maintained by the Appium team:","metadata":{"loc":{"lines":{"from":1,"to":19}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/ecosystem/plugins.md","filename":"plugins.md","relativePath":"appium/ecosystem/plugins.md"}},{"pageContent":"|<div style=\"width:7em\">Plugin</div>|<div style=\"width:8em\">Installation Key</div>|Description|\n|---|---|---|\n|[Execute Driver](https://github.com/appium/appium/tree/master/packages/execute-driver-plugin)|`execute-driver`|Run entire batches of commands in a single call to the Appium server|\n|[Images](https://github.com/appium/appium/tree/master/packages/images-plugin)|`images`|Image matching and comparison features|\n|[Inspector](https://github.com/appium/appium-inspector/tree/main/plugins)|`inspector`|Integrate the [Appium Inspector](https://github.com/appium/appium-inspector) directly into your Appium server installation, providing a web-based interface for inspecting and interacting with your application under test.|\n|[Relaxed Caps](https://github.com/appium/appium/tree/master/packages/relaxed-caps-plugin)|`relaxed-caps`|Relax Appium's requirement for vendor prefixes on capabilities|","metadata":{"loc":{"lines":{"from":21,"to":26}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/ecosystem/plugins.md","filename":"plugins.md","relativePath":"appium/ecosystem/plugins.md"}},{"pageContent":"|[Relaxed Caps](https://github.com/appium/appium/tree/master/packages/relaxed-caps-plugin)|`relaxed-caps`|Relax Appium's requirement for vendor prefixes on capabilities|\n|[Storage](https://github.com/appium/appium/tree/master/packages/storage-plugin)|`storage`|Server-side storage with client-side management|\n|[Universal XML](https://github.com/appium/appium/tree/master/packages/universal-xml-plugin)|`universal-xml`|Instead of the standard XML format for iOS and Android, use an XML definition that is the same across both platforms|","metadata":{"loc":{"lines":{"from":26,"to":28}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/ecosystem/plugins.md","filename":"plugins.md","relativePath":"appium/ecosystem/plugins.md"}},{"pageContent":"### Other Plugins\n\nThese plugins are not maintained by the Appium team and can provide additional functionality:","metadata":{"loc":{"lines":{"from":30,"to":32}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/ecosystem/plugins.md","filename":"plugins.md","relativePath":"appium/ecosystem/plugins.md"}},{"pageContent":"|<div style=\"width:6em\">Plugin</div>|<div style=\"width:19em\">Installation Key</div>|Description|<div style=\"width:13em\">Supported By</div>|\n|---|---|---|---|\n|[AltUnity](https://github.com/headspinio/appium-altunity-plugin)|`--source=npm appium-altunity-plugin`|Target Unity games and apps for automation with a new context, via the AltUnityTester framework|HeadSpin|\n|[Device Farm](https://github.com/AppiumTestDistribution/appium-device-farm)|`--source=npm appium-device-farm`|Manage and create driver sessions on connected Android devices and iOS simulators|`@AppiumTestDistribution`|\n|[Gestures](https://github.com/AppiumTestDistribution/appium-gestures-plugin)|`--source=npm appium-gestures-plugin`|Perform basic gestures using W3C Actions|`@AppiumTestDistribution`|\n|[Interceptor](https://github.com/AppiumTestDistribution/appium-interceptor-plugin)|`--source=npm appium-interceptor`|Intercept and mock API requests and responses|`@AppiumTestDistribution`|","metadata":{"loc":{"lines":{"from":34,"to":39}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/ecosystem/plugins.md","filename":"plugins.md","relativePath":"appium/ecosystem/plugins.md"}},{"pageContent":"|[Interceptor](https://github.com/AppiumTestDistribution/appium-interceptor-plugin)|`--source=npm appium-interceptor`|Intercept and mock API requests and responses|`@AppiumTestDistribution`|\n|[OCR](https://github.com/jlipps/appium-ocr-plugin)|`--source=npm appium-ocr-plugin`|Find elements via OCR text|`@jlipps`|\n|[Reporter](https://github.com/AppiumTestDistribution/appium-reporter-plugin)|`--source=npm appium-reporter-plugin`|Generate standalone consolidated HTML reports with screenshots|`@AppiumTestDistribution`|\n|[Wait](https://github.com/AppiumTestDistribution/appium-wait-plugin)|`--source=npm appium-wait-plugin`|Manage global element wait timeouts|`@AppiumTestDistribution`|","metadata":{"loc":{"lines":{"from":39,"to":42}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/ecosystem/plugins.md","filename":"plugins.md","relativePath":"appium/ecosystem/plugins.md"}},{"pageContent":"!!! note\n\n If you maintain an Appium plugin that you would like to be listed in the Appium docs, feel free\n to make a PR to add it to this section with a link to the documentation for the plugin.","metadata":{"loc":{"lines":{"from":44,"to":47}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/ecosystem/plugins.md","filename":"plugins.md","relativePath":"appium/ecosystem/plugins.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Appium-Related Tools\n---\n\nThere are several Appium tools that have been created to to assist with things not directly related\nto testing, such as Appium installation, test development, and more.\n\n### [Appium Inspector](https://appium.github.io/appium-inspector/latest/)\n\nAppium has a graphical client which can be used to inspect application screenshots, view the\napplication hierarchy, run Appium commands, record app interactions, and more. It is very useful\nfor Appium test development.\n\nFind downloads and more information on its GitHub page: [Appium Inspector](https://github.com/appium/appium-inspector)\n\n### Appium Doctor\n\nAppium Doctor is a command-line tool built into Appium drivers and plugins.\nThe command is expected to be used to validate whether a driver or plugin has all of its prerequisites and other environment details set up correctly\nif the driver/plugin author implemented the `doctor` command.","metadata":{"loc":{"lines":{"from":1,"to":23}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/ecosystem/tools.md","filename":"tools.md","relativePath":"appium/ecosystem/tools.md"}},{"pageContent":"For example, `uiautomator2` driver provides the `doctor` command below.\n\n```\nappium driver doctor uiautomator2\n```\n\nIt shows no result if the driver/plugin author did not implement them.\n\nMore information on this command can be found in the [Command-Line Usage documentation](../cli/extensions.md#doctor).\nFor driver/plugin developers, please read [Building Doctor Checks](../developing/build-doctor-checks.md).\n\n### Other Tools\n\nThese tools are not maintained by the Appium team and can be used to assist with other problems:\n\n|Name|Description|Supported By|\n|---|---|---|\n|[appium-installer](https://github.com/AppiumTestDistribution/appium-installer)|Help set up an Appium environment for Android and iOS|`@AppiumTestDistribution`|","metadata":{"loc":{"lines":{"from":25,"to":42}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/ecosystem/tools.md","filename":"tools.md","relativePath":"appium/ecosystem/tools.md"}},{"pageContent":"---\ntitle: Local Validation Of Extension PRs\n---\n\nSometimes it might be necessary to validate if a remote driver or a plugin PR works for the particular local\nenvironment before it is merged or published. This tutorial describes how to achieve that.\n\n## Requirements\n\n- Recent LTS version of NodeJS. Check [Node.js main page](https://nodejs.org) for the download link.\n- Recent version of the Appium server. Use the following commands to ensure you have\n the latest version installed: `npm uninstall appium` and `npm install -g appium`.\n- [Git](https://git-scm.com/) should be available locally.\n\n## Installation","metadata":{"loc":{"lines":{"from":1,"to":15}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/branch-testing.md","filename":"branch-testing.md","relativePath":"appium/guides/branch-testing.md"}},{"pageContent":"- [Check out](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally) the PR locally.\n There is also an option (although it is less flexible, because you won't be able to easily fetch\n any changes to this PR later) to simply [download](https://docs.github.com/en/repositories/working-with-files/using-files/downloading-source-code-archives) and unzip the sources\n locally. If you choose the later option then no `git` tool would be necessary.\n- Navigate to the local driver or plugin folder and run `npm i` from that folder.\n- Make sure you don't have the given driver or plugin already installed. Use the `appium driver uninstall <driver_name>`\n or `appium plugin uninstall <plugin_name>` CLI in order to delete any leftovers. The value of\n `<driver_name>`/`<plugin_name>` depends on the actual driver or plugin name the PR has been prepared for.","metadata":{"loc":{"lines":{"from":17,"to":24}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/branch-testing.md","filename":"branch-testing.md","relativePath":"appium/guides/branch-testing.md"}},{"pageContent":"`<driver_name>`/`<plugin_name>` depends on the actual driver or plugin name the PR has been prepared for.\n If you are not sure which name you need to use then check the content of the `package.json` manifest,\n which must be always located under the root folder of the fetched sources. You should be looking for\n the `\"appium\" -> \"driverName\"` entry value there.\n- Change the current folder to the one, which is NOT the driver/plugin folder root or its subfolder.\n Also, make sure your current working folder does not contain any extra `package.json` file. If\n it does then simply navigate to any other folder that does not.\n- Run the following command in order to link the driver/plugin sources to the Appium server:\n `appium driver install --source=local <full_path_to_driver_folder_with_fetched_sources>` or\n `appium plugin install --source=local <full_path_to_plugin_folder_with_fetched_sources>`.","metadata":{"loc":{"lines":{"from":24,"to":33}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/branch-testing.md","filename":"branch-testing.md","relativePath":"appium/guides/branch-testing.md"}},{"pageContent":"`appium driver install --source=local <full_path_to_driver_folder_with_fetched_sources>` or\n `appium plugin install --source=local <full_path_to_plugin_folder_with_fetched_sources>`.\n- Stop the Appium server if it is running and start it again (`appium server --use-drivers=<driver_name>`)\n to check the list of loaded drivers. If the linking succeeded then you must see the driver name and the path to its\n parent folder in the server logs. In case of a plugin it is required to explicitly request\n this plugin to be loaded upon server startup: `appium server --use-plugins=<plugin_name>`.","metadata":{"loc":{"lines":{"from":32,"to":37}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/branch-testing.md","filename":"branch-testing.md","relativePath":"appium/guides/branch-testing.md"}},{"pageContent":"## Update\n\nAfter you have tested the PR and there are issues it might be necessary to update the local branch with\nthe recent changes from Git. Follow the next steps for that:\n\n- Navigate to the parent folder of your local driver/plugin and run `git pull`.\n- Stop Appium server if it is running.\n- Run `npm i` in the parent folder of your local driver/plugin to rebuild it and update any dependencies if necessary.\n- Start Appium server again similarly to how this is done in the corresponding [Installation](#installation) step above.\n\n## Switching Back To a Stable Release\n\nAfter the PR is merged there is no need to use the local plugin/driver deployment anymore, and it makes sense\nto switch back to the package managed by NPM. Follow the next steps for that:","metadata":{"loc":{"lines":{"from":39,"to":52}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/branch-testing.md","filename":"branch-testing.md","relativePath":"appium/guides/branch-testing.md"}},{"pageContent":"After the PR is merged there is no need to use the local plugin/driver deployment anymore, and it makes sense\nto switch back to the package managed by NPM. Follow the next steps for that:\n\n- Unlink the installed driver/plugin from the server by running `appium driver uninstall <driver_name>` or\n `appium plugin uninstall <driver_name>`.\n- Delete the local source folder (`rm -rf <full_path_to_plugin_or_driver_folder_with_fetched_sources>`).\n- Install the driver or the plugin from NPM. Check the component README in order to find a proper command for that.","metadata":{"loc":{"lines":{"from":51,"to":57}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/branch-testing.md","filename":"branch-testing.md","relativePath":"appium/guides/branch-testing.md"}},{"pageContent":"---\ntitle: Caching of Application Bundles\n---\n\nAppium's base driver provides a feature which enables caching of application builds provided, for example,\nas `app` capability value or to endpoints similar to the `installApp` one. This article explains common caching\nprinciples, so you could create more performant and efficient test suite execution strategies.\n\n## Why Caching Is Necessary\n\nMobile application bundles could reach hundreds of megabytes is size. This could become a serious\nperformance issue if a test suite is executed, and it is necessary to fetch/extract the same application\nbundle for each test.\n\n## What Is Cached","metadata":{"loc":{"lines":{"from":1,"to":15}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caching.md","filename":"caching.md","relativePath":"appium/guides/caching.md"}},{"pageContent":"## What Is Cached\n\nCaching could be applied to application bundles generated by\n[`configureApp`](https://github.com/appium/appium/blob/master/packages/base-driver/lib/basedriver/helpers.js#L107) helper call.\nInherited drivers can customize their caching logic by providing own `onPostProcess`\n(or both `inDownload` and `onPostProcess`) property definition, but the general\nrule of thumb is that we need to cache locally all application bundles need to be downloaded and/or extracted\nfirst before they could be actually installed on the device under test. On iOS, for example, these are `.ipa` or\n`.zip` compressed application bundles, or .`aab` on Android.\n\n## Caching of Remote Application Bundles\n\nIn order to validate whether an app bundle downloaded from the given URL could be (re)used from the cache the following\nsteps are applied:","metadata":{"loc":{"lines":{"from":15,"to":28}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caching.md","filename":"caching.md","relativePath":"appium/guides/caching.md"}},{"pageContent":"In order to validate whether an app bundle downloaded from the given URL could be (re)used from the cache the following\nsteps are applied:\n\n1. The script checks if the given URL is already present in the cache.\n If yes then it tries to fetch previously remembered\n [Last-Modified](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified)\n or [ETag](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag) header values for it.\n2. If `ETag` value is present then it is put into\n [If-None-Match request header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match).\n Else if `Last-Modified` header value is present then it is put into\n [If-Modified-Since request header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Modified-Since).\n Otherwise, no caching is applied.\n3. If the response status is equal to `304` then the previously cached binary is used,\n otherwise the cached entry is reset and refreshed.","metadata":{"loc":{"lines":{"from":27,"to":40}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caching.md","filename":"caching.md","relativePath":"appium/guides/caching.md"}},{"pageContent":"## Caching of Local Application Bundles\n\nIt only makes sense to cache application bundles if they need some preprocessing before being installed on the device under test.\nFor example, on iOS `.ipa` bundles must be unzipped, because the system installer only works with `.app` folders.\n\n1. The script verifies if the given bundle path is already present in the cache. If the bundle was not in the cache yet\nthen it gets preprocessed and added there.\n2. The script validates the hashsum of the bundle and compares it to the previously stored one. If hash sums don't match\nthen the cached item gets deleted and the preprocessing of the bundle repeats.\n\n## How The Cache File System Is Configured","metadata":{"loc":{"lines":{"from":42,"to":52}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caching.md","filename":"caching.md","relativePath":"appium/guides/caching.md"}},{"pageContent":"## How The Cache File System Is Configured\n\nThe cache where the base driver keeps all application bundles is located in the system temp folder. It is configured\non per-process basis, so each test session initialized in scope of the same Appium server process takes advantages\nof it. It is a [LRU Cache](https://www.npmjs.com/package/lru-cache) with the following limitations:","metadata":{"loc":{"lines":{"from":52,"to":56}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caching.md","filename":"caching.md","relativePath":"appium/guides/caching.md"}},{"pageContent":"- Max items: 1024. You may customize it by providing a new value to\n the [APPIUM_APPS_CACHE_MAX_ITEMS](../cli/env-vars.md) environment variable.\n Do not set it to a lower number than the amount of apps in all parallel sessions per process.\n- Max time to live (TTL) for each entry: 24 hours.\n You may customize it by providing a new value to the\n [APPIUM_APPS_CACHE_MAX_AGE](../cli/env-vars.md) environment variable.\n Do not set it to a lower number than the duration of a single session startup.\n- TTL is refreshed for each entry upon access\n- By default the full application URL is used as cache key. You may change this behavior\n by enabling the [APPIUM_APPS_CACHE_IGNORE_URL_QUERY](../cli/env-vars.md) environment variable.\n If the above option is enabled then the 'search' part of the app URL will be cut off from cache keys.\n See the corresponding [feature request](https://discuss.appium.io/t/regarding-app-caching-when-using-aws-s3-presigned-urls/42713)\n for more details.","metadata":{"loc":{"lines":{"from":58,"to":70}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caching.md","filename":"caching.md","relativePath":"appium/guides/caching.md"}},{"pageContent":"!!! warning\n\n Note: The cache root folder is set up for automatic deletion on Appium process termination. This would only\n work if Appium server is killed with `SIGINT` or `SIGTERM`. If `SIGKILL` is used then no cache cleanup\n would be performed.","metadata":{"loc":{"lines":{"from":72,"to":76}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caching.md","filename":"caching.md","relativePath":"appium/guides/caching.md"}},{"pageContent":"---\ntitle: Session Capabilities\n---\n\n\"Capabilities\" is the name given to the set of parameters used to start an Appium session. The\ninformation in the set describes what sort of \"capabilities\" you want your session to have, for\nexample, a certain mobile operating system or a certain version of a device. Capabilities are\nrepresented as key-value pairs, with values allowed to be any valid JSON type, including\nother objects.\n\nThe W3C WebDriver spec's [section on Capabilities](https://w3c.github.io/webdriver/#capabilities)\nidentifies a small set of 10 standard capabilities, including the following:","metadata":{"loc":{"lines":{"from":1,"to":12}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caps.md","filename":"caps.md","relativePath":"appium/guides/caps.md"}},{"pageContent":"The W3C WebDriver spec's [section on Capabilities](https://w3c.github.io/webdriver/#capabilities)\nidentifies a small set of 10 standard capabilities, including the following:\n\n| Capability Name | Type | Description |\n|------------------|----------|------------------------------------------------|\n| `browserName` | `string` | The name of the browser to launch and automate |\n| `browserVersion` | `string` | The specific version of the browser |\n| `platformName` | `string` | The type of platform hosting the browser |\n\n## Common Appium Capabilities","metadata":{"loc":{"lines":{"from":11,"to":20}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caps.md","filename":"caps.md","relativePath":"appium/guides/caps.md"}},{"pageContent":"## Common Appium Capabilities\n\nAppium understands these browser-focused capabilities, but introduces a number of additional\ncapabilities. According to the WebDriver spec, any\nnon-standard \"extension capabilities\" must include a namespace prefix (signifying the vendor\nintroducing the capability), ending in a `:`. Appium's vendor prefix is\n`appium:`, and so any Appium-specific capabilities must include this prefix. Depending on which\nclient you are using, the prefix may be added automatically or in conjunction with certain\ninterfaces, but it is always a good practice to explicitly include it for clarity.\n\nHere is a list of all the globally-recognized Appium capabilities:\n\n!!! info\n\n Individual drivers and plugins can support other capabilities, so refer to their documentation\n for lists of specific capability names. Some drivers may also not support all of these capabilities","metadata":{"loc":{"lines":{"from":20,"to":35}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caps.md","filename":"caps.md","relativePath":"appium/guides/caps.md"}},{"pageContent":"| <div style=\"width:12em\">Capability</div> | Type | Required? | Description |\n|--------------------------------------------|-----------|-----------|----------------------------|\n| `platformName` | `string` | yes | The type of platform hosting the app or browser |\n| `appium:automationName` | `string` | yes | The name of the Appium driver to use |\n| `browserName` | `string` | no | The name of the browser to launch and automate, if the driver supports web browsers as a special case |\n| `appium:app` | `string` | no | The path to an installable application |","metadata":{"loc":{"lines":{"from":37,"to":42}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caps.md","filename":"caps.md","relativePath":"appium/guides/caps.md"}},{"pageContent":"| `appium:app` | `string` | no | The path to an installable application |\n| `appium:deviceName` | `string` | no | The name of a particular device to automate, e.g., `iPhone 14` (currently only actually useful for specifying iOS simulators, since in other situations it's typically recommended to use a specific device id via the `appium:udid` capability). |\n| `appium:platformVersion` | `string` | no | The version of a platform, e.g., for iOS, `16.0` |\n| `appium:newCommandTimeout` | `number` | no | The number of seconds the Appium server should wait for clients to send commands before deciding that the client has gone away and the session should shut down. `60` seconds by default. Setting it to zero disables the timer. |","metadata":{"loc":{"lines":{"from":42,"to":45}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caps.md","filename":"caps.md","relativePath":"appium/guides/caps.md"}},{"pageContent":"| `appium:noReset` | `boolean` | no | If true, instruct an Appium driver to avoid its usual reset logic during session start and cleanup (default `false`) |\n| `appium:fullReset` | `boolean` | no | If true, instruct an Appium driver to augment its usual reset logic with additional steps to ensure maximum environmental reproducibility (default `false`) |\n| `appium:eventTimings` | `boolean` | no | If true, instruct an Appium driver to collect [Event Timings](./event-timing.md) (default `false`) |\n| `appium:printPageSourceOnFindFailure` | `boolean` | no | If true, collect the page source and print it to the Appium log whenever a request to find an element fails (default `false`) |","metadata":{"loc":{"lines":{"from":46,"to":49}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caps.md","filename":"caps.md","relativePath":"appium/guides/caps.md"}},{"pageContent":"Some drivers place more complex constraints on capabilities as a group. For example, while the\n`appium:app` and `browserName` capabilities are listed above as optional, if you want to launch\na session with a specific app, the XCUITest driver requires that at least one of `appium:app`,\n`browserName`, or `appium:bundleId` are included in the capabilities (otherwise it will not know\nwhat app to install and/or launch and will simply open a session on the home screen). Each driver\nwill document how it interprets these capabilities and any other platform-specific requirements.\n\n!!! note\n\n Capabilities are like parameters used when starting a session. After the capabilities are sent\n and the session is started, they cannot be changed. If a driver supports updating aspects of\n its behaviour in the course of a session, it will provide a [Setting](./settings.md) for this\n purpose instead of, or in addition to, a capability.","metadata":{"loc":{"lines":{"from":52,"to":64}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caps.md","filename":"caps.md","relativePath":"appium/guides/caps.md"}},{"pageContent":"Each Appium client has its own way of constructing capabilities and starting a session. For\nexamples of doing this in each client library, head to the [Ecosystem](../ecosystem/index.md) page\nand click through to the appropriate client documentation.\n\n## BiDi Protocol Support\n\nAppium supports [WebDriver BiDi](https://w3c.github.io/webdriver-bidi/) protocol since base–driver 9.5.0.\nThe actual behavior depends on individual drivers while the Appium and the baseーdriver support the protocol.\nPlease make sure if a driver supports the protocol and what kind of commands/events it supports in the documentation.\n\n| Capability Name | Type | Description |\n|-----------------|-----------|-----------------------------------------|\n| `webSocketUrl` | `boolean` | To enable BiDi protocol in the session. |\n\n## Using `appium:options` to Group Capabilities","metadata":{"loc":{"lines":{"from":66,"to":80}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caps.md","filename":"caps.md","relativePath":"appium/guides/caps.md"}},{"pageContent":"## Using `appium:options` to Group Capabilities\n\nIf you use a lot of `appium:` capabilities in your tests, it can get a little repetitive. You can\ncombine all capabilities as an object value of a single `appium:options` capability instead, in\nwhich case you don't need to use prefixes on the capabilities inside the object. For example:\n\n```json\n{\n \"platformName\": \"iOS\",\n \"appium:options\": {\n \"automationName\": \"XCUITest\",\n \"platformVersion\": \"16.0\",\n \"app\": \"/path/to/your.app\",\n \"deviceName\": \"iPhone 12\",\n \"noReset\": true\n }\n}\n```\n\nNote that constructing a capability value which is itself an object differs by language; refer to\nyour client documentation for further examples on how to achieve this.\n\n!!! warning\n\n If you include the same capabilities both inside and outside of `appium:options`, the values\n inside of `appium:options` take precedence.\n\n## Always-Match and First-Match Capabilities","metadata":{"loc":{"lines":{"from":80,"to":107}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caps.md","filename":"caps.md","relativePath":"appium/guides/caps.md"}},{"pageContent":"If you include the same capabilities both inside and outside of `appium:options`, the values\n inside of `appium:options` take precedence.\n\n## Always-Match and First-Match Capabilities\n\nThe W3C spec allows clients to give the Appium server some flexibility in the kind of session it\ncreates in response to a new session request. This is through the concept of \"always-match\" and\n\"first-match\" capabilities:\n\n- Always-match capabilities consist of a single set of capabilities, every member of which must\n be satisfied by the server in order for the new session request to proceed.\n- First-match capabilities consist of an array of capability sets. Each set is merged with the\n always-match capabilities, and the first set that the server knows how to handle will be the set\n that is used to start the session.\n\n!!! note","metadata":{"loc":{"lines":{"from":104,"to":119}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caps.md","filename":"caps.md","relativePath":"appium/guides/caps.md"}},{"pageContent":"!!! note\n\n Check out the [spec itself](https://w3c.github.io/webdriver/#processing-capabilities) or\n a [summarized version](https://github.com/jlipps/simple-wd-spec#processing-capabilities) for\n a more in-depth description of how capabilities are processed.\n\nIn practice, use of first-match capabilities is not necessary or recommended for use with Appium.\nInstead, we recommend that you define the explicit set of capabilities you want the Appium\nserver to handle. These will be encoded as the always-match capabilities, and the array of\nfirst-match capabilities will be empty.\n\nThat being said, Appium _does_ understand always-match and first-match capabilities as\ndefined in the W3C spec, so if you use these features, Appium will work as expected. The process of\ndefining always-match and first-match capabilities is unique to each client library, so refer to\nthe documentation for your client library to see examples of how it works.\n\n## Special Notes for Cloud Providers\n\n!!! warning","metadata":{"loc":{"lines":{"from":119,"to":137}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caps.md","filename":"caps.md","relativePath":"appium/guides/caps.md"}},{"pageContent":"## Special Notes for Cloud Providers\n\n!!! warning\n\n This section is not intended for end-users of Appium; it is intended for developers building\n Appium-compatible cloud services.\n\nWhen managing an Appium cloud, your users may wish to target various independent versions of Appium\ndrivers and plugins. It is of course up to each service provider how they wish to implement the\ndiscovery, installation, and availability of any official or third party drivers or plugins. But\nthe Appium team does provide several suggestions, for consistency across the industry. _These are\nrecommendations only,_ and not a standard, but adopting it will help users to navigate the increased\ncomplexity that working with Appium 2 in a cloud environment may bring.\n\n### Suggested capabilities","metadata":{"loc":{"lines":{"from":135,"to":149}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caps.md","filename":"caps.md","relativePath":"appium/guides/caps.md"}},{"pageContent":"### Suggested capabilities\n\nIn addition to the standard `platformName`, `appium:deviceName`, `appium:automationName`, and\n`appium:platformVersion`, we recommend adopting the capability `$cloud:appiumOptions`, where the\nlabel `$cloud` is not meant to be interpreted literally but instead should be replaced by your\nvendor prefix (so for HeadSpin it would be `headspin`, Sauce Labs it would be `sauce`, and\nBrowserStack it would be `browserstack`, to name just a few examples). The `$cloud:appiumOptions`\ncapability would itself be a JSON object, with the following internal keys:","metadata":{"loc":{"lines":{"from":149,"to":156}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caps.md","filename":"caps.md","relativePath":"appium/guides/caps.md"}},{"pageContent":"| <div style=\"width:10em\">Capability</div> | Usage | Example |\n| ---------------------------------------- | ------ | ------- |\n| `version` | The version of the Appium server that is used to host and manage drivers. If omitted, the behavior is left up to the provider, but the recommendation would be to provide the latest official version. | `2.0.0` |\n| `automationVersion` | The version of the driver (as specified by `appium:automationName`) that should be used. | `1.55.2` |\n| `automation` | The name of a custom driver to use (see below for more info). This would override `appium:automationName` and `$cloud:automationVersion`. | `{\"name\": \"@org/custom-driver\", \"source\": \"github\", \"package\": \"custom-driver\"}` |\n| `plugins` | The list of plugins (and potentially versions of plugins) that should be activated (see below for more info). | `[\"images\", \"universal-xml\"]` |\n\n### Basic example","metadata":{"loc":{"lines":{"from":158,"to":165}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caps.md","filename":"caps.md","relativePath":"appium/guides/caps.md"}},{"pageContent":"### Basic example\n\nAppium extensions (drivers and plugins) have a set of properties that specify where they can be\ninstalled from. Cloud providers are obviously under no obligation to provide support for\narbitrarily specified extensions, seeing as these may represent untrusted code running in a managed\nenvironment. In the case where arbitrary extensions are not supported, the `appium:automationName`,\n`$cloud:automationVersion`, and `$cloud:appiumPlugins` capabilities should be sufficient. See the\nfollowing JSON object representing capabilities for a session:\n\n```json\n{\n \"platformName\": \"iOS\",\n \"appium:platformVersion\": \"14.4\",\n \"appium:deviceName\": \"iPhone 11\",\n \"appium:app\": \"Some-App.app.zip\",\n \"appium:automationName\": \"XCUITest\",\n \"$cloud:appiumOptions\": {\n \"version\": \"2.0.0\",\n \"automationVersion\": \"3.52.0\",\n \"plugins\": [\"images\"]\n }\n}\n```","metadata":{"loc":{"lines":{"from":165,"to":187}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caps.md","filename":"caps.md","relativePath":"appium/guides/caps.md"}},{"pageContent":"This set of capabilities requests an Appium 2+ server supporting the XCUITest driver at version\n`3.52.0`, and the `images` plugin active. This set is easy for a cloud provider to verify. The\ncloud provider can obviously do anything it wants in response to these capabilities, including\ndownloading Appium and driver and plugin packages on the fly, or erroring out if the versions\nrequested are not in a supported set, or if the plugin is not supported, etc...\n\n### Basic example with `appium:options`\n\nThe previous example still looks a bit disorganized, so of course we also recommend that cloud\nproviders support the `appium:options` capability as detailed above, which could turn the previous\nset of capabilities into the following:","metadata":{"loc":{"lines":{"from":189,"to":199}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caps.md","filename":"caps.md","relativePath":"appium/guides/caps.md"}},{"pageContent":"```json\n{\n \"platformName\": \"iOS\",\n \"appium:options\": {\n \"platformVersion\": \"14.4\",\n \"deviceName\": \"iPhone 11\",\n \"app\": \"Some-App.app.zip\",\n \"automationName\": \"XCUITest\"\n },\n \"$cloud:appiumOptions\": {\n \"version\": \"2.0.0\",\n \"automationVersion\": \"3.52.0\",\n \"plugins\": [\"images\"]\n }\n}\n```\n\n### Extension objects\n\nSome service providers may wish to dynamically allow access to all of the features of the Appium\n2 CLI, including downloading arbitrary drivers and plugins. To represent these extensions, we can\ndefine special JSON \"extension objects\", with the following keys:","metadata":{"loc":{"lines":{"from":201,"to":222}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caps.md","filename":"caps.md","relativePath":"appium/guides/caps.md"}},{"pageContent":"- `name`: the name of the extension. This would be an `npm` package name (if downloading from `npm`),\n or a `git` or GitHub spec (if downloading from a `git` server or GitHub).\n- `version`: the version of the extension, e.g., the `npm` package version or `git` SHA.\n- (optional) `source`: a denotation of where the extension can be downloaded from. It is recommended\n to support the following values: `appium`, `npm`, `git`, `github`. Here, `appium` means \"Appium's\n own official list\", and should be the default value if this key is not included.\n- (optional) `package`: when downloading extensions from `git` or GitHub, the `npm` package name of\n the extension must also be provided. This is optional for non-`git` sources.\n\nSince each session is handled by a single driver, the `$cloud:appiumOptions`/`$automation`\ncapability could be used with an extension object value to denote this driver, for example:","metadata":{"loc":{"lines":{"from":224,"to":234}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caps.md","filename":"caps.md","relativePath":"appium/guides/caps.md"}},{"pageContent":"Since each session is handled by a single driver, the `$cloud:appiumOptions`/`$automation`\ncapability could be used with an extension object value to denote this driver, for example:\n\n```json\n{\n \"$cloud:appiumOptions\": {\n \"automation\": {\n \"name\": \"git+https://some-git-host.com/custom-driver-project.git\",\n \"version\": \"some-git-sha\",\n \"source\": \"git\",\n \"package\": \"driver-npm-package-name\"\n }\n }\n}\n```\n\nAnd since sessions can handle multiple plugins, each value in the list of `$cloud:appiumPlugins`\ncould also be an extension object rather than a string, so that specific versions could be\nrequested:\n\n```json\n{\n \"$cloud:appiumOptions\": {\n \"plugins\": [{\n \"name\": \"images\",\n \"version\": \"1.1.0\"\n }, {\n \"name\": \"my-github-org/my-custom-plugin\",\n \"version\": \"a83f2e\",\n \"source\": \"github\",\n \"package\": \"custom-plugin\"\n }]\n }\n}\n```","metadata":{"loc":{"lines":{"from":233,"to":267}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caps.md","filename":"caps.md","relativePath":"appium/guides/caps.md"}},{"pageContent":"These serve as illustrative examples for the recommendations here. Of course, it is up to the\nservice providers to implement the handling of these capabilities at their front end / load\nbalancer, to perform any error checking, or to actually run any of the `appium driver` or `appium\nplugin` CLI commands that support the end user's request. This section is merely a suggestion as to\nhow service providers might design their user-facing capabilities API in a way which in principle\nsupports all of the capabilities that Appium itself would provide to the end user if they were\nrunning Appium on their own.","metadata":{"loc":{"lines":{"from":269,"to":275}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/caps.md","filename":"caps.md","relativePath":"appium/guides/caps.md"}},{"pageContent":"---\ntitle: The Appium Config File\n---\n\nInstead of passing arguments on the command line to Appium, you may add them to a special config\nfile. Appium will read values from this config file when it runs. (Please note that CLI arguments\nhave _precedence_ over configuration files; if a value is set in a config file _and_ via CLI\nargument, the CLI argument is preferred.)\n\n## Supported Config File Formats\n\nYou can store your config data in the following kinds of files:\n\n- JSON\n- YAML\n- JS (a JavaScript file exporting a JS object)\n- CJS (the same as above; the extension is for common JS)\n\n!!! warning\n\n Note: Configuration files in ESM format are not currently supported.\n\n## Supported Config File Locations\n\nConfiguration files can be named anything, but the following filenames will be automatically\ndiscovered and loaded by Appium:","metadata":{"loc":{"lines":{"from":1,"to":26}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/config.md","filename":"config.md","relativePath":"appium/guides/config.md"}},{"pageContent":"## Supported Config File Locations\n\nConfiguration files can be named anything, but the following filenames will be automatically\ndiscovered and loaded by Appium:\n\n- `.appiumrc.json` (recommended)\n- `.appiumrc.yaml`\n- `.appiumrc.yml`\n- `.appiumrc.js`\n- `.appiumrc.cjs`\n- `appium.config.js`\n- `appium.config.cjs`\n- `.appiumrc` (which is considered to be JSON)\n\nFurther, _if your project uses Node.js,_ you can use store the configuration inside an `appium`\nproperty in your `package.json` and it will be automatically discovered.\n\n### Config File Search\n\nAppium will search _up_ the directory tree from the current working directory for one of these\nfiles. If it reaches the current user's home directory or filesystem root, it will stop looking.\n\nTo specify a _custom_ location for your config file, use `appium --config /path/to/config/file`.\n\n#### Configuration File Format\n\nFirst, you might want to look at some examples:","metadata":{"loc":{"lines":{"from":23,"to":49}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/config.md","filename":"config.md","relativePath":"appium/guides/config.md"}},{"pageContent":"To specify a _custom_ location for your config file, use `appium --config /path/to/config/file`.\n\n#### Configuration File Format\n\nFirst, you might want to look at some examples:\n\n- [Appium Configuration - JSON](https://github.com/appium/appium/blob/master/packages/appium/sample-code/appium.config.sample.json)\n- [Appium Configuration - YAML](https://github.com/appium/appium/blob/master/packages/appium/sample-code/appium.config.sample.yaml)\n- [Appium Configuration - JS](https://github.com/appium/appium/blob/master/packages/appium/sample-code/appium.config.sample.js)\n\nA description of the format is available, as well:\n\n- [Appium Configuration File JSON Schema](https://github.com/appium/appium/blob/master/packages/schema/lib/appium-config.schema.json)\n- [TypeScript declarations for Appium Configuration](https://github.com/appium/appium/blob/master/packages/types/lib/config.ts)","metadata":{"loc":{"lines":{"from":45,"to":58}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/config.md","filename":"config.md","relativePath":"appium/guides/config.md"}},{"pageContent":"To describe in words, the config file will have a root `server` property, and all arguments are\nchild properties. For certain properties which must be supplied on the command-line as\ncomma-delimited lists, JSON strings, and/or external filepaths, these instead will be of their\n\"native\" type. For example, `--use-plugins <value>` needs `<value>` to be comma-delimited string\nor path to a delimited file. However, the config file just wants an array, e.g.,:\n\n```json\n{\n \"server\": {\n \"use-plugins\": [\"my-plugin\", \"some-other-plugin\"]\n }\n}\n```\n\n## Configuring extensions (drivers and plugins)\n\nFor `driver`-and-`plugin`-specific configuration, these live under the `server.driver` and\n`server.plugin` properties, respectively. Each driver or plugin will have its own named property,\nand the values of any specific configuration it provides are under this. For example:\n\n```json\n{\n \"server\": {\n \"driver\": {\n \"xcuitest\": {\n \"webkit-debug-proxy-port\": 5400\n }\n }\n }\n}\n```","metadata":{"loc":{"lines":{"from":60,"to":90}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/config.md","filename":"config.md","relativePath":"appium/guides/config.md"}},{"pageContent":"```json\n{\n \"server\": {\n \"driver\": {\n \"xcuitest\": {\n \"webkit-debug-proxy-port\": 5400\n }\n }\n }\n}\n```\n\n!!! note\n\n The above configuration corresponds to the `--driver-xcuitest-webkit-debug-proxy-port` CLI argument.\n\nAll properties are case-sensitive and will be in\n[kebab-case](https://en.wikipedia.org/wiki/Naming_convention_(programming)#Delimiter-separated_words).\nFor example, `callback-port` is allowed, but `callbackPort` is not.","metadata":{"loc":{"lines":{"from":80,"to":98}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/config.md","filename":"config.md","relativePath":"appium/guides/config.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Managing Contexts\n---\n\nA common feature of many app platforms is the ability for developers to embed web content inside of\nthe platform-native app frame. This allows developers to leverage web technologies or existing web\ncontent for some or all of the app functionality. However, the additional complexity of mixing\n\"modes\" within a single application can make it difficult for automation tools that are designed to\ntarget the \"native\" elements and behaviours.\n\nAppium provides a set of APIs for working with different app modes, called \"contexts\", that Appium\ndrivers can implement if they support automation commands in these different modes. There are three\nbasic commands that Appium has added to the W3C WebDriver spec for this purpose:","metadata":{"loc":{"lines":{"from":1,"to":16}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/context.md","filename":"context.md","relativePath":"appium/guides/context.md"}},{"pageContent":"| Command Name | Method/Route | Params | Description | Returns |\n|-----------------------|-----------------------------|-------------------|-----------------------------------------------|-----------------|\n| `Get Contexts` | `GET /session/:id/contexts` | | Get a list of the available contexts | `array<string>` |\n| `Get Current Context` | `GET /session/:id/context` | | Get the name of the active context | `string` |\n| `Set Context` | `POST /session/:id/context` | `name` (`string`) | Switch into the context with the given `name` | `null` |","metadata":{"loc":{"lines":{"from":18,"to":22}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/context.md","filename":"context.md","relativePath":"appium/guides/context.md"}},{"pageContent":"This API is flexible enough to handle a variety of semantic interpretations on the part of the\ndriver. For example, the XCUITest driver includes two kinds of contexts: the native app context and\nany active webviews, as one context per webview. A call to `Get Contexts` will return the list of\nnames, which you as a test author can sift through and use to switch into the appropriate context.\nAs another example, the [Appium Altunity\nPlugin](https://github.com/headspinio/appium-altunity-plugin) introduces the concept of a `UNITY`\ncontext, which encapsulates all the plugin's specific behaviour to ensure that when outside of the\n`UNITY` context, the active driver's usual command implementations are used.\n\nIt is important to note that a call to `Get Contexts` will always contain at least one context,\nconventionally but not necessarily named `NATIVE_APP`. This is the default active context.","metadata":{"loc":{"lines":{"from":24,"to":34}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/context.md","filename":"context.md","relativePath":"appium/guides/context.md"}},{"pageContent":"It is important to note that a call to `Get Contexts` will always contain at least one context,\nconventionally but not necessarily named `NATIVE_APP`. This is the default active context.\n\nDepending on the type of context you're in, the operation of the driver might change. The XCUITest\ndriver, when targeting a webview context, will not run its typical routines for finding and\ninteracting with elements. Instead, it will run a different set of routines appropriate to web\nelements. This might have a variety of consequences, like supporting a different set of locator\nstrategies.\n\nThe command names in the table above are generic references to the commands and not code examples.\nFor examples of how to access the Context API in the language-specific client libraries, please\nvisit the documentation for a given library.","metadata":{"loc":{"lines":{"from":33,"to":44}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/context.md","filename":"context.md","relativePath":"appium/guides/context.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Retrieving Event Timings\n---\n\nAppium comes with the ability to retrieve timing information about startup\ninformation and command length. This is an advanced feature that is controlled\nby the use of the `appium:eventTimings` capability (set it to `true` to log event\ntimings).\n\nWith this capability turned on, the `POST /session/:id/appium/events` response (i.e., \nthe response to `driver.logs.events` or similar, depending on client) will be \ndecorated with an `events` property. This is the structure of that `events`\nproperty:\n\n```\n{\n \"<event_type>\": [<occurence_timestamp_1>, ...],\n \"commands\": [\n {\n \"cmd\": \"<command_name>\",\n \"startTime\": <js_timestamp>,\n \"endTime\": <js_timestamp>\n },\n ...\n ]\n}\n```\n\nIn other words, the `events` property has 2 kinds of properties of its own:\n\n* Properties which are the names of event types\n* The `commands` property","metadata":{"loc":{"lines":{"from":1,"to":35}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/event-timing.md","filename":"event-timing.md","relativePath":"appium/guides/event-timing.md"}},{"pageContent":"In other words, the `events` property has 2 kinds of properties of its own:\n\n* Properties which are the names of event types\n* The `commands` property\n\nProperties which are names of event types correspond to an array of timestamps\nwhen that event happened. It's an array because events might happen multiple\ntimes in the course of a session. Examples of event types include:\n\n* `newSessionRequested`\n* `newSessionStarted`\n\n(Individual drivers will define their own event types, so we do not have an\nexhaustive list to share here. It's best to actually get one of these responses\nfrom a real session to inspect the possible event types.)\n\nThe `commands` property is an array of objects. Each object has the name of the\nAppium-internal command (for example `click`), as well as the time the command\nstarted processing and the time it finished processing.","metadata":{"loc":{"lines":{"from":32,"to":50}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/event-timing.md","filename":"event-timing.md","relativePath":"appium/guides/event-timing.md"}},{"pageContent":"With this data, you can calculate the time between events, or a strict timeline\nof events, or statistical information about average length of a certain type of\ncommand, and so on.\n\nYou can only receive data about events that have happened when you make the\ncall to `/session/:id/appium/events`, so the best time to get data about an entire session is\nright before quitting it.\n\nThe Appium team maintains an event timings parser tool that can be used to\ngenerate various kinds of reports from event timings output:\n[appium/appium-event-parser](https://github.com/appium/appium-event-parser).\n\n!!! note\n\n In the past, events were available as a part of `GET /session/:id` response\n\n## Add a custom event","metadata":{"loc":{"lines":{"from":52,"to":68}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/event-timing.md","filename":"event-timing.md","relativePath":"appium/guides/event-timing.md"}},{"pageContent":"!!! note\n\n In the past, events were available as a part of `GET /session/:id` response\n\n## Add a custom event\n\nYou can add custom events that will show up in the event timings data. You can send a custom event\nname to the Appium server using the [Log Custom Event API](../commands/base-driver.md#logcustomevent),\nand the server will store the timestamp. The [Get Log Events](../commands/base-driver.md#getlogevents)\ncommand can be used to retrieve named events' timestamps later on.","metadata":{"loc":{"lines":{"from":64,"to":73}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/event-timing.md","filename":"event-timing.md","relativePath":"appium/guides/event-timing.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Execute Methods\n---\n\nBecause the scope of commands implemented in Appium drivers is broader than the scope of commands\ndefined by the W3C WebDriver spec, Appium needs a way for these \"extended\" commands to be accessible\nby client libraries. There are two main strategies for this:\n\n1. Appium drivers define new W3C-compatible API routes, and Appium clients are updated to include\n support for those new routes.\n2. Appium drivers define so-called \"Execute Methods\" which provide new functionality by\n overloading the existing `Execute Script` command which is already available in any WebDriver-\n based client library (including all Selenium and Appium clients).\n\nThere are pros and cons for each strategy, but it is ultimately up to the extension author to\ndecide how they wish implement new commands.","metadata":{"loc":{"lines":{"from":1,"to":19}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/execute-methods.md","filename":"execute-methods.md","relativePath":"appium/guides/execute-methods.md"}},{"pageContent":"There are pros and cons for each strategy, but it is ultimately up to the extension author to\ndecide how they wish implement new commands. \n\nThis guide is designed to specifically help you understand the \"Execute Method\" strategy. This\npattern is commonly used in official Appium drivers and other third-party extensions.\nHere's an example of how the `Execute Script` command is designed to work in the world of WebDriver\nand browser automation:\n\n=== \"JS (WebDriverIO)\"\n\n ```js\n await driver.executeScript('return arguments[0] + arguments[1]', [3, 4])\n ```\n\n=== \"Java\"\n\n ```java\n JavascriptExecutor jsDriver = (JavascriptExecutor) driver;\n jsDriver.executeScript(\"return arguments[0] + arguments[1]\", 3, 4);\n ```\n\n=== \"Python\"\n\n ```py\n driver.execute_script('return arguments[0] + arguments[1]', 3, 4)\n ```\n\n=== \"Ruby\"\n\n ```rb\n driver.execute_script 'return arguments[0] + arguments[1]', 3, 4\n ```\n\n=== \"C#\"","metadata":{"loc":{"lines":{"from":18,"to":51}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/execute-methods.md","filename":"execute-methods.md","relativePath":"appium/guides/execute-methods.md"}},{"pageContent":"```py\n driver.execute_script('return arguments[0] + arguments[1]', 3, 4)\n ```\n\n=== \"Ruby\"\n\n ```rb\n driver.execute_script 'return arguments[0] + arguments[1]', 3, 4\n ```\n\n=== \"C#\"\n\n ```dotnet\n ((IJavaScriptExecutor)driver).ExecuteScript(\"return arguments[0] + arguments[1]\", 3, 4);\n ```\n\nWhat's happening here is that we are defining a snippet of Javascript (technically,\na function body) to be executed within the web browser. The client can send arguments which are\nserialized, sent over HTTP, and finally provided to the function as parameters. In this example,\nwe are essentially defining an addition function. The return value of the `Execute Script` command\nis whatever the return value of the Javascript snippet is! In the case of this example, that value\nwould be the number `7` (`3` + `4`).","metadata":{"loc":{"lines":{"from":41,"to":62}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/execute-methods.md","filename":"execute-methods.md","relativePath":"appium/guides/execute-methods.md"}},{"pageContent":"Each client library has its own way of calling the command and providing any arguments to the script\nfunction, but the function itself—the snippet—is always a string and is the same across all languages.","metadata":{"loc":{"lines":{"from":64,"to":65}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/execute-methods.md","filename":"execute-methods.md","relativePath":"appium/guides/execute-methods.md"}},{"pageContent":"In the world of Appium, we are usually not automating a web browser, which means this command is\nnot particularly useful. But it *is* useful as a way to encode the name of an arbitrary command and\nto provide parameters. For example, the [XCUITest\nDriver](https://github.com/appium/appium-xcuitest-driver) has implemented a command that lets a client\nterminate a running application if you know the ID (the `bundleId`) of the app. The way that the\ndriver makes this command available is via the Execute Method `mobile: terminateApp`. Instead of\nproviding a JavaScript function to the \"Execute Script\" command, the user provides a _known string_\nas defined by the driver. The only other thing a client needs to know is the set of\nparameters for the method, which are documented by the driver. In this case, we have a parameter\nnamed `bundleId`, whose value should be a string encoding the ID of the app to terminate. Here is\nhow this Execute Method would be called:\n\n=== \"JS (WebDriverIO)\"","metadata":{"loc":{"lines":{"from":67,"to":79}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/execute-methods.md","filename":"execute-methods.md","relativePath":"appium/guides/execute-methods.md"}},{"pageContent":"=== \"JS (WebDriverIO)\"\n\n ```js\n await driver.executeScript('mobile: terminateApp', [{bundleId: 'com.my.app'}])\n ```\n\n=== \"Java\"\n\n ```java\n JavascriptExecutor jsDriver = (JavascriptExecutor) driver;\n jsDriver.executeScript(\"mobile: terminateApp\", ImmutableMap.of(\"bundleId\", \"com.my.app\"));\n ```\n\n=== \"Python\"\n\n ```py\n driver.execute_script('mobile: terminateApp', {'bundleId': 'com.my.app'})\n ```\n\n=== \"Ruby\"\n\n ```rb\n driver.execute_script 'mobile: terminateApp', { bundleId: 'com.my.app' }\n ```\n\n=== \"C#\"\n\n ```dotnet\n ((IJavaScriptExecutor)driver).ExecuteScript(\"mobile: terminateApp\",\n new Dictionary<string, string> { { \"bundleId\", \"com.my.app\" } });\n\n ```\n\nThere are two important differences in using Appium Execute Methods from vanilla Selenium\nJavascript execution:","metadata":{"loc":{"lines":{"from":79,"to":113}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/execute-methods.md","filename":"execute-methods.md","relativePath":"appium/guides/execute-methods.md"}},{"pageContent":"```\n\nThere are two important differences in using Appium Execute Methods from vanilla Selenium\nJavascript execution:\n\n1. The script string is just a command name; it will be provided by the driver documentation\n1. The standard way to provide parameters is as a *single* object with keys representing parameter\n names and values representing parameter values. So in this case, we had to specify both the\n parameter name (`bundleId`) as the key of the parameters object, and the parameter value\n (`com.my.app`) as the value for that key. A driver can define parameters as _required_ or _optional_.\n\nOf course, always refer to the documentation for the particular Execute Method in case the author\nhas made any alterations to the standard access method.","metadata":{"loc":{"lines":{"from":110,"to":122}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/execute-methods.md","filename":"execute-methods.md","relativePath":"appium/guides/execute-methods.md"}},{"pageContent":"---\ntitle: Appium and Selenium Grid\n---\n\n## Using Selenium Grid 4+\n\nThe\n[relay](https://www.selenium.dev/documentation/grid/configuration/toml_options/#relaying-commands-to-a-service-endpoint-that-supports-webdriver)\nfeature in Grid 4 allows you to proxy Appium requests to an Appium server instance. Here is\nan example walkthrough of how you would connect two different Appium instances to a Selenium Grid.\n\n### Define the Appium configs\n\nEach Appium instance should have a config file that can be easily updated. It should contain any\ninformation which needs to be unique to that particular server (e.g., ports its drivers should use\nthat others should not). We are going to have 2 Appium servers, so we will need 2 config files:\n\n```yaml\n# appium1.yml\nserver:\n port: 4723\n use-drivers:\n - xcuitest\n default-capabilities:\n wdaLocalPort: 8100\n mjpegServerPort: 9100\n mjpegScreenshotUrl: \"http://localhost:9100\"\n```","metadata":{"loc":{"lines":{"from":1,"to":28}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/grid.md","filename":"grid.md","relativePath":"appium/guides/grid.md"}},{"pageContent":"```yaml\n# appium1.yml\nserver:\n port: 4723\n use-drivers:\n - xcuitest\n default-capabilities:\n wdaLocalPort: 8100\n mjpegServerPort: 9100\n mjpegScreenshotUrl: \"http://localhost:9100\"\n```\n\nIn the above YAML config file, we specify the Appium server port, the driver used, and parameters\nfor the driver that will be sent in as default capabilities. Our goal is to ensure that any other\ndrivers running on this host will not compete with system ports or other resources. The second\nconfig file could look like the following, where we simply adjust a few ports to prevent clashes:\n\n```yaml\n# appium2.yml\nserver:\n port: 4733\n use-drivers:\n - xcuitest\n default-capabilities:\n wdaLocalPort: 8110\n mjpegServerPort: 9110\n mjpegScreenshotUrl: \"http://localhost:9110\"\n```\n\n### Define the Grid node configs","metadata":{"loc":{"lines":{"from":18,"to":47}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/grid.md","filename":"grid.md","relativePath":"appium/guides/grid.md"}},{"pageContent":"### Define the Grid node configs\n\nWe will be launching one Grid \"node\" per Appium server, to manage relaying commands and determining\ncapacity and online status, etc... So we should have one config file per Grid node as well. Each\nnode config should include the address of the Appium server it will target, as well as a list of\ncapability \"configs\" it should accept to relay a session request to Appium. Here is what the config\ncould look like for the two nodes:\n\n```toml\n# node1.toml\n[server]\nport = 5555\n\n[node]\ndetect-drivers = false\n\n[relay]\nurl = \"http://localhost:4723\"\nstatus-endpoint = \"/status\"\nconfigs = [\n \"1\", \"{\\\"platformName\\\": \\\"iOS\\\", \\\"appium:platformVersion\\\": \\\"15.5\\\", \\\"appium:deviceName\\\": \\\"iPhone 13\\\", \\\"appium:automationName\\\": \\\"XCUITest\\\"}\"\n]\n```\n\n```toml\n# node2.toml\n[server]\nport = 5565\n\n[node]\ndetect-drivers = false","metadata":{"loc":{"lines":{"from":47,"to":77}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/grid.md","filename":"grid.md","relativePath":"appium/guides/grid.md"}},{"pageContent":"```toml\n# node2.toml\n[server]\nport = 5565\n\n[node]\ndetect-drivers = false\n\n[relay]\nurl = \"http://localhost:4733\"\nstatus-endpoint = \"/status\"\nconfigs = [\n \"1\", \"{\\\"platformName\\\": \\\"iOS\\\", \\\"appium:platformVersion\\\": \\\"15.5\\\", \\\"appium:deviceName\\\": \\\"iPhone 12\\\", \\\"appium:automationName\\\": \\\"XCUITest\\\"}\"\n]\n```\n\nNote that each node config also specifies a different port itself for the node to run on.\n\n### Putting it together\n\nThe Grid nodes aren't enough--you'll also want a Grid \"hub\" that acts as a load balancer and\nmanager for all the nodes. So in the end we'll have 5 processes running at once: 2 Appium servers,\n2 Grid nodes, and 1 Grid hub. It's best to run each of these in a separate terminal window to avoid\nconfusion of logs. Here is how you'd start each process:","metadata":{"loc":{"lines":{"from":71,"to":94}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/grid.md","filename":"grid.md","relativePath":"appium/guides/grid.md"}},{"pageContent":"0. `appium --config appium1.yml`\n0. `appium --config appium2.yml`\n0. `java -jar /path/to/selenium.jar node --config node1.toml`\n0. `java -jar /path/to/selenium.jar node --config node2.toml`\n0. `java -jar /path/to/selenium.jar hub`\n\nOnce you wait a few moments for the nodes to detect their Appium servers, and to register with the\nhub, you'll be able to send all your Appium traffic via the single hub endpoint (defaulting to\n`http://localhost:4444`).\n\nAnd of course, you're able to link up Appium servers and nodes running on different machines in\nyour network to form a larger grid.\n\n## Using Selenium Grid 3\n\nIt is possible to register your Appium server with a local [Selenium Grid 3](https://www.selenium.dev/documentation/legacy/selenium_3/grid_3/)\n([setup docs](https://www.selenium.dev/documentation/legacy/grid_3/setting_up_your_own_grid/)) instance by using the\n`--nodeconfig` server argument.\n\n```bash\nappium server --nodeconfig /path/to/nodeconfig.json --base-path=/wd/hub\n```","metadata":{"loc":{"lines":{"from":96,"to":117}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/grid.md","filename":"grid.md","relativePath":"appium/guides/grid.md"}},{"pageContent":"```bash\nappium server --nodeconfig /path/to/nodeconfig.json --base-path=/wd/hub\n```\n\nIn the referenced config file you have to define the `browserName`, `version` and `platform`\ncapabilities and based on these parameters the grid will re-direct your test to the right device.\nYou will also need to configure your host details and the Selenium Grid details. For a full list of\nall parameters and descriptions see\n[here](https://www.selenium.dev/documentation/legacy/selenium_3/grid_setup/).\n\nOnce you start the Appium server it will register with the grid, and you will see your device on\nthe grid console page:\n\n`http://**\\<grid-ip-adress\\>**:**\\<grid-port\\>**/grid/console`\n\n### Example Grid Node Configuration JSON","metadata":{"loc":{"lines":{"from":115,"to":130}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/grid.md","filename":"grid.md","relativePath":"appium/guides/grid.md"}},{"pageContent":"`http://**\\<grid-ip-adress\\>**:**\\<grid-port\\>**/grid/console`\n\n### Example Grid Node Configuration JSON\n\n```json\n{\n \"capabilities\":\n [\n {\n \"browserName\": \"<e.g._iPhone5_or_iPad4>\",\n \"version\":\"<version_of_iOS_e.g._7.1>\",\n \"maxInstances\": 1,\n \"platform\":\"<platform_e.g._MAC_or_ANDROID>\"\n }\n ],\n \"configuration\":\n {\n \"cleanUpCycle\":2000,\n \"timeout\":30000,\n \"proxy\": \"org.openqa.grid.selenium.proxy.DefaultRemoteProxy\",\n \"url\":\"http://<host_name_appium_server_or_ip-address_appium_server>:<appium_port>/wd/hub\",\n \"host\": \"<host_name_appium_server_or_ip-address_appium_server>\",\n \"port\": <appium_port>,\n \"maxSession\": 1,\n \"register\": true,\n \"registerCycle\": 5000,\n \"hubPort\": <grid_port>,\n \"hubHost\": \"<Grid_host_name_or_grid_ip-address>\",\n \"hubProtocol\": \"<Protocol_of_Grid_defaults_to_http>\"\n }\n}\n```","metadata":{"loc":{"lines":{"from":128,"to":159}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/grid.md","filename":"grid.md","relativePath":"appium/guides/grid.md"}},{"pageContent":"If `url`, `host`, and `port` are not given, the config will be auto updated to point to\n`localhost:<appium-port>`.\n\nIf your Appium server is running on a different machine to your Selenium Grid server, make sure you\nuse an external name/IP address in your `host` and `url` configuration; `localhost` and `127.0.0.1`\nwill prevent Selenium Grid from connecting correctly.","metadata":{"loc":{"lines":{"from":161,"to":166}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/grid.md","filename":"grid.md","relativePath":"appium/guides/grid.md"}},{"pageContent":"---\ntitle: Header Handling\n---\n\n# Header Handling\n\n## Request ID Tracking\n\nAppium supports setting the request ID for each request through the `x-request-id` header. This is useful for tracing requests through your system, especially in environments where multiple services are involved or when debugging across different requests.\n\n### Using `x-request-id`\n\nWhen making requests to Appium, you can include an `x-request-id` header with a unique identifier. This ID will be:\n\n- Used to track the request through Appium's logging system\n- Preserved across the entire request lifecycle\n- Generated automatically (as a UUID) if not provided","metadata":{"loc":{"lines":{"from":1,"to":17}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/headers.md","filename":"headers.md","relativePath":"appium/guides/headers.md"}},{"pageContent":"---\ntitle: Filtering the Appium Log\n---\n\nSometimes it might be necessary to hide sensitive information, like passwords, device identifiers,\nhashes, etc..., from the server log. Appium makes it possible to ensure such information is\nredacted in logs via the `--log-filters` command line argument. This argument allows you to provide\nthe path to a special config file, containing one or more log obfuscation rules.\n\n## Config Format\n\nThe filtering config must be one of:\n\n- a path to a valid JSON file containing an array of filtering rules\n- a `log-filters` entry in an [Appium Config](./config.md) file, with the rules array inline\n\nEach rule is an object with a set of predefined properties. The following rule properties are\nsupported:","metadata":{"loc":{"lines":{"from":1,"to":18}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/log-filters.md","filename":"log-filters.md","relativePath":"appium/guides/log-filters.md"}},{"pageContent":"Each rule is an object with a set of predefined properties. The following rule properties are\nsupported:\n\n- `pattern`: A valid Javascript RegExp pattern to replace. Must be a valid non-empty pattern.\n- `text`: A simple non-empty exact text match to replace. Either this property or the above one must\n be provided. `pattern` has priority over `text` if both are provided.\n- `flags`: Regular expression flags for the given pattern. Supported flags are the same as for the\n standard JavaScript [RegExp constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Advanced_searching_with_flags_2).\n Note that the `g` (global matching) flag is always enabled.\n- `replacer`: The replacer value to use. By default it is `**SECURE**`. Empty values are allowed.\n\n### Config Examples\n\nReplace all occurrences of `my.magic.app` string with the default replacer:\n\n```json\n[\n {\n \"text\": \"my.magic.app\"\n }\n]\n```","metadata":{"loc":{"lines":{"from":17,"to":38}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/log-filters.md","filename":"log-filters.md","relativePath":"appium/guides/log-filters.md"}},{"pageContent":"### Config Examples\n\nReplace all occurrences of `my.magic.app` string with the default replacer:\n\n```json\n[\n {\n \"text\": \"my.magic.app\"\n }\n]\n```\n\nReplace all occurrences of `my.magic.<any char>` string with a custom replacer (case insensitive):\n\n```json\n[\n {\n \"pattern\": \"my\\\\.magic\\\\.\\\\w\",\n \"flags\": \"i\",\n \"replacer\": \"***\"\n }\n]\n```\n\nReplace all occurrences of `my.magic.<any chars>` and/or `your.magic` strings with a custom\nreplacer (case insensitive):\n\n```json\n[\n {\n \"pattern\": \"my\\\\.magic\\\\.\\\\w+\",\n \"flags\": \"i\",\n \"replacer\": \"***\"\n },\n {\n \"pattern\": \"your\\\\.magic\",\n \"flags\": \"i\",\n \"replacer\": \"***\"\n }\n]\n```\n\nTruncate all log lines to max 15 chars (advanced):\n\n```json\n[\n\t{\n \"pattern\": \"(.{1,15}).*\",\n \"flags\": \"s\",\n \"replacer\": \"$1\"\n }\n]\n```\n\n### Config Errors Handling","metadata":{"loc":{"lines":{"from":28,"to":82}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/log-filters.md","filename":"log-filters.md","relativePath":"appium/guides/log-filters.md"}},{"pageContent":"Truncate all log lines to max 15 chars (advanced):\n\n```json\n[\n\t{\n \"pattern\": \"(.{1,15}).*\",\n \"flags\": \"s\",\n \"replacer\": \"$1\"\n }\n]\n```\n\n### Config Errors Handling\n\nIf any of the config rules contains invalid items (such as empty/invalid pattern, empty rule, etc.)\nthen Appium will print the detailed report about collected errors and will fail to start until\nthese errors are addressed.","metadata":{"loc":{"lines":{"from":70,"to":86}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/log-filters.md","filename":"log-filters.md","relativePath":"appium/guides/log-filters.md"}},{"pageContent":"---\ntitle: Managing Drivers and Plugins\n---\n\nTo do anything useful with Appium, you need to have at least one [Driver](../intro/drivers.md)\ninstalled, otherwise Appium won't know how to automate anything. There is an entire\n[Ecosystem](../ecosystem/index.md) of drivers and plugins out there!\n\nThis guide helps explain how to manage these drivers and plugins. There are\ntwo basic strategies: using Appium's extension CLI interface, or managing extensions yourself in an\n`npm`-based project.\n\n!!! note\n\n Other package managers are not currently supported.\n\n## Using Appium's Extension CLI\n\nWith Appium's [Extension CLI](../cli/extensions.md), you let Appium manage drivers and plugins for\nyou. You will use CLI commands to tell Appium which extensions you would like to install, update,\nor remove. Here's an example of how you might install a driver using the CLI:\n\n```bash\nappium driver install xcuitest\n```","metadata":{"loc":{"lines":{"from":1,"to":25}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/managing-exts.md","filename":"managing-exts.md","relativePath":"appium/guides/managing-exts.md"}},{"pageContent":"```bash\nappium driver install xcuitest\n```\n\nThis command will install the latest version of the\n[XCUITest Driver](https://github.com/appium/appium-xcuitest-driver). The Extension CLI comes with a variety\nof commands and parameters; see the documentation for that command for all the specifics.\n\nThe all-important question when Appium is managing your extensions for you is: where are they installed?\nAppium manages extensions in a directory specified by the `APPIUM_HOME` environment variable. You\ncan set that variable to anything you like, and Appium will manage its extensions there. You can\ntherefore also use the `APPIUM_HOME` environment variable to manage different sets of extensions,\nfor example if you want to have the same driver installed at conflicting versions:\n\n```bash\nAPPIUM_HOME=/path/to/home1 appium driver install xcuitest@4.11.1\nAPPIUM_HOME=/path/to/home2 appium driver install xcuitest@4.11.2\n```","metadata":{"loc":{"lines":{"from":23,"to":40}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/managing-exts.md","filename":"managing-exts.md","relativePath":"appium/guides/managing-exts.md"}},{"pageContent":"```bash\nAPPIUM_HOME=/path/to/home1 appium driver install xcuitest@4.11.1\nAPPIUM_HOME=/path/to/home2 appium driver install xcuitest@4.11.2\n```\n\nRunning these commands will result in two separate `APPIUM_HOME` directories being created and\npopulated with the corresponding version of the XCUITest driver. You can then use the same\nenvironment variables to direct Appium which version to use on launch:\n\n```bash\nAPPIUM_HOME=/path/to/home1 appium # use xcuitest driver 4.11.1\nAPPIUM_HOME=/path/to/home2 appium # use xcuitest driver 4.11.2\n```\n\nYou don't need to set `APPIUM_HOME` if you don't want to! By default, Appium will set `APPIUM_HOME`\nto the directory `.appium` in your user home directory.\n\nThese installed packages will be managed by `extensions.yaml` in `$APPIUM_HOME/node_modules/.cache/appium/extensions.yaml`.\n\n## Do-It-Yourself with `npm`","metadata":{"loc":{"lines":{"from":37,"to":56}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/managing-exts.md","filename":"managing-exts.md","relativePath":"appium/guides/managing-exts.md"}},{"pageContent":"These installed packages will be managed by `extensions.yaml` in `$APPIUM_HOME/node_modules/.cache/appium/extensions.yaml`.\n\n## Do-It-Yourself with `npm`\n\nBecause Appium and Appium drivers are Node.js programs, if you are integrating your Appium scripts\ninto your own Node.js project, there is an alternative way to manage drivers and plugins: via `npm`,\nlike any other dependency. Basically, whenever you run Appium, if you have not explicitly set\n`APPIUM_HOME`, it will:\n\n1. Try to determine whether the _current directory_ is inside an `npm` package.\n1. If so, it will check whether `appium` is a dependency (dev, prod, or peer) in the project's\n `package.json`\n1. If so, _unless you have specified `APPIUM_HOME` in your environment_, Appium will ignore load\n drivers and plugins defined in that `package.json` file instead.","metadata":{"loc":{"lines":{"from":54,"to":67}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/managing-exts.md","filename":"managing-exts.md","relativePath":"appium/guides/managing-exts.md"}},{"pageContent":"This means you are freely able to add Appium drivers and plugins as regular package dependencies or\ndev dependencies. For example, if your project has a `package.json` which includes the following:\n\n```json\n{\n \"devDependencies\": {\n \"appium\": \"^2.0.0\",\n \"appium-xcuitest-driver\": \"^4.11.1\"\n }\n}\n```\n\nThen, if you run `npx appium` inside your project, Appium will detect that it is a dependency of\nthe project, and will load the XCUITest driver which is also listed as a dev dependency for the\nproject.\n\nThis strategy is *only* recommended if you are already using `npm` for your project.\nOtherwise, it is recommended that you use Appium's Extension CLI and, if necessary, adjust\n`APPIUM_HOME` to change the location of stored extensions.","metadata":{"loc":{"lines":{"from":69,"to":87}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/managing-exts.md","filename":"managing-exts.md","relativePath":"appium/guides/managing-exts.md"}},{"pageContent":"---\ntitle: Migrating to Appium 2\n---\n\nThis document is a guide for those who are using Appium 1 and wish to migrate to Appium 2. It\ncontains a list of breaking changes and how to migrate your environments or test suites to ensure\ncompatibility with Appium 2.\n\nAppium 2 is the biggest Appium release in over 5 years. It is _not_ focused on changing the\nautomation behavior for any particular platform, but instead re-envisions Appium into an\n_ecosystem_ of automation tools:\n\n* The core Appium module retains only platform-agnostic functionality\n* Functionality for automating specific platforms is moved to separate _driver_ modules\n* Functionality for altering/extending Appium is moved to separate _plugin_ modules\n\nAt the same time, the Appium project is taking the opportunity to remove many old and deprecated\nbits of functionality.","metadata":{"loc":{"lines":{"from":1,"to":18}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-1-to-2.md","filename":"migrating-1-to-2.md","relativePath":"appium/guides/migrating-1-to-2.md"}},{"pageContent":"At the same time, the Appium project is taking the opportunity to remove many old and deprecated\nbits of functionality.\n\nSince Appium 2 is a major architectural change, ^^we do not recommend directly updating your\nAppium 1 installations to Appium 2^^. Instead, please uninstall Appium 1 first, and only install\nAppium 2 afterwards.\n\n## Breaking Changes\n\n### Drivers Installed Separately\n\nWhen installing Appium 1, all available drivers would be installed alongside the main Appium\nserver. In Appium 2, due to its modular structure, this is no longer the case - by default,\ninstalling it only installs the core Appium server, without any drivers.\n\nWhen it comes to installing Appium 2 drivers, there are several approaches you can take:","metadata":{"loc":{"lines":{"from":17,"to":32}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-1-to-2.md","filename":"migrating-1-to-2.md","relativePath":"appium/guides/migrating-1-to-2.md"}},{"pageContent":"When it comes to installing Appium 2 drivers, there are several approaches you can take:\n\n* Add the `--drivers` flag when installing Appium, for example:\n```bash\nnpm i -g appium --drivers=xcuitest,uiautomator2\n```\n* Use the [Appium Extension CLI](../cli/extensions.md), for example:\n```bash\nappium driver install uiautomator2\n```\n* Use the [Appium Setup CLI command](../cli/setup.md) (added in Appium `2.6`), for example:\n```bash\nappium setup mobile\n```\n\nCheck the [Managing Drivers and Plugins guide](./managing-exts.md) for more information.\n\n!!! info \"Actions Needed\"\n\n When installing Appium 2, use one of the above approaches for installing your desired drivers\n\n### Driver Installation Path Changed\n\nWhen installing Appium 1, all available drivers would be installed as dependencies of the main\nAppium server, in `/path/to/appium/node_modules`. For example, `appium-webdriveragent` was located\nat `/path/to/appium/node_modules/appium-xcuitest-driver/node_modules/appium-webdriveragent`.","metadata":{"loc":{"lines":{"from":32,"to":57}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-1-to-2.md","filename":"migrating-1-to-2.md","relativePath":"appium/guides/migrating-1-to-2.md"}},{"pageContent":"In Appium 2, drivers (and plugins) are installed at the path defined by the `APPIUM_HOME`\nenvironment variable, whose default value is `~/.appium`. So, `appium-webdriveragent` would now be\nlocated at `$APPIUM_HOME/node_modules/appium-xcuitest-driver/node_modules/appium-webdriveragent`.\n\n!!! info \"Actions Needed\"\n\n If your code uses paths to Appium driver files, update it to use the `APPIUM_HOME` environment\n variable\n\n### Drivers Updated Separately\n\nIn Appium 1, in order to get updates to your drivers, you would simply wait for those updates to be\nrolled into a new release of Appium, and then update your Appium version. With Appium 2, since the\nserver and drivers are separate packages, they can release new versions independently from each\nother - this means that you no longer need to wait for a new Appium server release, but can install\nthe latest driver versions right away.\n\nChecking for driver updates is done by using the [Appium Extension CLI](../cli/extensions.md):","metadata":{"loc":{"lines":{"from":59,"to":76}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-1-to-2.md","filename":"migrating-1-to-2.md","relativePath":"appium/guides/migrating-1-to-2.md"}},{"pageContent":"Checking for driver updates is done by using the [Appium Extension CLI](../cli/extensions.md):\n\n```bash\nappium driver list --updates\n```\n\nIf any updates are available, you can then run the `update` command for any given driver:\n\n```bash\nappium driver update xcuitest\n```\n\nUpdating the Appium server itself is the same as before:\n\n```bash\nnpm update -g appium\n```\n\nHowever, in Appium 2 this process is a lot quicker, since drivers are no longer bundled with the\nserver package.\n\n!!! info \"Actions Needed\"\n\n Make sure to use the [Appium Extension CLI](../cli/extensions.md) to manage your drivers\n\n### Deprecated Packages No Longer Supported\n\nThe Appium 1 ecosystem included several drivers, clients and other packages that had since been\ndeprecated and replaced with newer packages. Appium 2 no longer includes support for these packages,\nand it is recommended to migrate to the following replacements:","metadata":{"loc":{"lines":{"from":76,"to":105}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-1-to-2.md","filename":"migrating-1-to-2.md","relativePath":"appium/guides/migrating-1-to-2.md"}},{"pageContent":"|Appium 1 Package|Replacement in Appium 2|\n|--|--|\n|iOS Driver|[XCUITest Driver](https://appium.github.io/appium-xcuitest-driver/latest/)|\n|UiAutomator Driver|[UiAutomator2](https://github.com/appium/appium-uiautomator2-driver/)|\n|`wd` Client|[WebdriverIO Client](https://webdriver.io/)|\n|Appium Desktop|[Appium Inspector](https://github.com/appium/appium-inspector)|\n\n!!! info \"Actions Needed\"\n\n If you are using any of the aforementioned package(s), migrate to their recommended replacement(s)\n\n### Default Server Base Path Changed\n\nIn Appium 1, the default Appium server URL was `http://localhost:4723/wd/hub`, where the `/wd/hub`\npart (the base path) was a legacy convention from Selenium 1. Appium 2 changes the default base\npath to `/`, therefore the default server URL is now `http://localhost:4723/`.\n\n!!! info \"Actions Needed\"","metadata":{"loc":{"lines":{"from":107,"to":124}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-1-to-2.md","filename":"migrating-1-to-2.md","relativePath":"appium/guides/migrating-1-to-2.md"}},{"pageContent":"!!! info \"Actions Needed\"\n\n In your test scripts, change the base path of the target server URL from `/wd/hub` to `/`.\n Alternatively, you can retain the Appium 1 base path by launching Appium with the\n `--base-path=/wd/hub` [command-line argument](../cli/args.md).\n\n### Server Port 0 No Longer Supported\n\nIn Appium 1, it was possible to specify `--port 0` during server startup, which had the effect of\nstarting Appium on a random free port. Appium 2 no longer allows this, and requires port values to\nbe `1` or higher. If you wish to start Appium on a random port, you must now take care of this on\nyour own prior to launching the server.\n\n!!! info \"Actions Needed\"\n\n If you are launching Appium with `--port 0`, change the port number value to `1` or higher\n\n### Driver-Specific CLI Options Changed","metadata":{"loc":{"lines":{"from":124,"to":141}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-1-to-2.md","filename":"migrating-1-to-2.md","relativePath":"appium/guides/migrating-1-to-2.md"}},{"pageContent":"!!! info \"Actions Needed\"\n\n If you are launching Appium with `--port 0`, change the port number value to `1` or higher\n\n### Driver-Specific CLI Options Changed\n\nWith Appium 1, command-line options specific to particular drivers were all hosted on the main\nAppium server. So, for example, `--chromedriver-executable` was a CLI parameter you could use to\nset the Chromedriver location for the UiAutomator2 driver.\n\nIn Appium 2, all driver-specific CLI options have been moved to the drivers themselves. However,\ndepending on the driver, these options may now need to be passed in another way:","metadata":{"loc":{"lines":{"from":137,"to":148}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-1-to-2.md","filename":"migrating-1-to-2.md","relativePath":"appium/guides/migrating-1-to-2.md"}},{"pageContent":"In Appium 2, all driver-specific CLI options have been moved to the drivers themselves. However,\ndepending on the driver, these options may now need to be passed in another way:\n\n* Some options can still be passed as different CLI flags, for example:\n```bash\nappium --webdriveragent-port=5000 # Appium 1\nappium --driver-xcuitest-webdriveragent-port=5000 # Appium 2\n```\n* Some options can now be passed as environment variables, for example:\n```bash\nappium --chromedriver-version=100 # Appium 1\nCHROMEDRIVER_VERSION=100 appium # Appium 2\n```\n* Some options can now be passed as [capabilities](https://appium.io/docs/en/latest/guides/caps/),\nfor example:\n```\nappium --chromedriver-executable=/path/to/chromedriver # Appium 1\n{\"appium:chromedriverExecutable\": \"/path/to/chromedriver\"} # Appium 2\n```\n\n!!! info \"Actions Needed\"\n\n If you are using driver-specific CLI options, refer to that driver's documentation for how to\n apply them in Appium 2","metadata":{"loc":{"lines":{"from":147,"to":170}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-1-to-2.md","filename":"migrating-1-to-2.md","relativePath":"appium/guides/migrating-1-to-2.md"}},{"pageContent":"!!! info \"Actions Needed\"\n\n If you are using driver-specific CLI options, refer to that driver's documentation for how to\n apply them in Appium 2\n\n### Filepaths No Longer Supported for Some CLI Options\n\nIn Appium 1, some server command-line options could be invoked by passing a filepath as their\nvalue, and Appium would then parse the contents of that file as the actual value for that option.\nThere were four options that supported this:\n\n* `--nodeconfig`\n* `--default-capabilities`\n* `--allow-insecure`\n* `--deny-insecure`\n\nAppium 2 no longer attempts to parse the contents of filepaths passed to these options, and offers\ntwo ways to specify the value for these options:\n\n* As strings, directly on the command line\n * `--nodeconfig` / `--default-capabilities`: JSON string\n * `--allow-insecure` / `--deny-insecure`: comma-separated list\n* In the [Appium Configuration file](./config.md)\n\n!!! info \"Actions Needed\"","metadata":{"loc":{"lines":{"from":167,"to":191}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-1-to-2.md","filename":"migrating-1-to-2.md","relativePath":"appium/guides/migrating-1-to-2.md"}},{"pageContent":"!!! info \"Actions Needed\"\n\n If you are using any of the aforementioned CLI options with a filepath value, update your code\n to pass the file contents either directly or through the Appium config file\n\n### Old Protocols Dropped\n\nAppium's API is based on the [W3C WebDriver Protocol](https://www.w3.org/TR/webdriver/), and it has\nsupported this protocol for years. Before this protocol was designed as a web standard, the \n[JSON Wire Protocol](https://www.selenium.dev/documentation/legacy/json_wire_protocol/) (JSONWP)\nand [Mobile JSON Wire Protocol](https://github.com/SeleniumHQ/mobile-spec/blob/master/spec-draft.md)\n(MJSONWP) were used instead.\n\nIn Appium 1, all of these protocols were supported, so that older Selenium/Appium clients could\nstill communicate with newer Appium servers. Appium 2 removes support for JSONWP/MJSONWP and is now\nonly compatible with the W3C WebDriver Protocol.\n\n!!! info \"Actions Needed\"","metadata":{"loc":{"lines":{"from":191,"to":208}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-1-to-2.md","filename":"migrating-1-to-2.md","relativePath":"appium/guides/migrating-1-to-2.md"}},{"pageContent":"!!! info \"Actions Needed\"\n\n Make sure you are using Selenium/Appium clients compatible with the W3C WebDriver Protocol\n\n### Capabilities Require Vendor Prefix\n\nIn Appium 1, in order to create a session, you had to specify certain desired capabilities, which\nwould indicate session parameters, e.g. the driver you want to use. Appium 2 retains this behavior\nand continues to accept desired capabilities (now renamed simply to 'capabilities'), but as part of\nthe W3C WebDriver Protocol specification, all non-standard capabilities are now required to use a\nvendor prefix.","metadata":{"loc":{"lines":{"from":208,"to":218}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-1-to-2.md","filename":"migrating-1-to-2.md","relativePath":"appium/guides/migrating-1-to-2.md"}},{"pageContent":"The list of standard capabilities is described in the [WebDriver Protocol specification](https://www.w3.org/TR/webdriver/#capabilities),\nand includes a few commonly used capabilities like `browserName` and `platformName`. All other\ncapabilities must now start with the vendor name and a colon (the vendor prefix), for example,\n`moz:` or `goog:`. Since most of Appium's capabilities go beyond the standard W3C capabilities,\nall of them must include the `appium:` prefix (unless specified otherwise):\n\n```\ndeviceName # Appium 1\nappium:deviceName # Appium 2\n```\n\nThis requirement may or may not be a breaking change for your test suites. Up-to-date versions of\nofficial Appium clients and the Appium Inspector will automatically add the `appium:` prefix to all\nnon-standard capabilities, and the same may apply to cloud-based Appium providers.","metadata":{"loc":{"lines":{"from":220,"to":233}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-1-to-2.md","filename":"migrating-1-to-2.md","relativePath":"appium/guides/migrating-1-to-2.md"}},{"pageContent":"Additionally, if you are starting a session with multiple Appium-specific capabilities (which will\nlikely be the case), it may seem repetitive to add the `appium:` prefix to each individual\ncapability. To avoid this, you can optionally group up all these capabilities under a single object\ncapability, `appium:options`, for example:\n\n=== \"Default Approach\"\n\n ```json\n {\n \"platformName\": \"iOS\",\n \"browserName\": \"Safari\",\n \"appium:platformVersion\": \"14.4\",\n \"appium:deviceName\": \"iPhone 11\",\n \"appium:automationName\": \"XCUITest\"\n }\n ```\n\n=== \"With `appium:options`\"\n\n ```json\n {\n \"platformName\": \"iOS\",\n \"browserName\": \"Safari\",\n \"appium:options\": {\n \"platformVersion\": \"14.4\",\n \"deviceName\": \"iPhone 11\",\n \"automationName\": \"XCUITest\"\n }\n }\n ```\n\n!!! warning","metadata":{"loc":{"lines":{"from":235,"to":266}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-1-to-2.md","filename":"migrating-1-to-2.md","relativePath":"appium/guides/migrating-1-to-2.md"}},{"pageContent":"!!! warning\n\n Capabilities included in the `appium:options` object will overwrite capabilities of the same\n name that are used outside of this object. Note that cloud provider support for the\n `appium:options` syntax may vary.\n\nFor more information on capabilities, have a look at the [Capabilities Guide](./caps.md).\n\n!!! info \"Actions Needed\"\n\n Add the `appium:` prefix to all Appium-specific capabilities used in your tests, or wrap them\n inside an `appium:options` object\n\n### Advanced Features Moved to Plugins\n\nOne of the design goals for Appium 2 is to extract non-core features into special extensions called\n[plugins](../ecosystem/plugins.md). Two such features of Appium 1 have been moved to plugins, and\nare no longer bundled with Appium 2:","metadata":{"loc":{"lines":{"from":266,"to":283}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-1-to-2.md","filename":"migrating-1-to-2.md","relativePath":"appium/guides/migrating-1-to-2.md"}},{"pageContent":"|Feature|Plugin Name|\n|--|--|\n|Image-related features (comparison, search by image, etc...)|[`images`](https://github.com/appium/appium/tree/master/packages/images-plugin)|\n|The Execute Driver Script feature|[`execute-driver`](https://github.com/appium/appium/tree/master/packages/execute-driver-plugin)|\n\n!!! info \"Actions Needed\"\n\n If you were using the image-related features and/or the execute driver script feature in Appium\n 1, first install their plugin(s):\n ```\n appium plugin install images \n appium plugin install execute-driver\n ```\n Afterwards, make sure to activate the plugin(s) upon launching the Appium server:\n ```\n appium --use-plugins=images,execute-driver\n ```\n\n### Endpoint Changes","metadata":{"loc":{"lines":{"from":285,"to":303}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-1-to-2.md","filename":"migrating-1-to-2.md","relativePath":"appium/guides/migrating-1-to-2.md"}},{"pageContent":"### Endpoint Changes\n\nA few server endpoints used in Appium 1 were accepting old or unused parameters. Appium 2 removes\nsupport for these parameters. The following is a list of these changed endpoints, along with the\nparameters they no longer accept, as well as the parameters they continue to accept in Appium 2.\n\n* `POST /session/:sessionId/appium/device/gsm_signal`\n * :octicons-x-24: `signalStrengh`\n * :octicons-check-24: `signalStrength`\n* `POST /session/:sessionId/appium/element/:elementId/value`\n * :octicons-x-24: `value`\n * :octicons-check-24: `text`\n* `POST /session/:sessionId/appium/element/:elementId/replace_value`\n * :octicons-x-24: `value`\n * :octicons-check-24: `text`\n\n!!! info \"Actions Needed\"\n\n Check your Appium client documentation for the methods using these endpoints, and adjust your\n code to only use the accepted parameters\n\n### Internal Packages Renamed","metadata":{"loc":{"lines":{"from":303,"to":324}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-1-to-2.md","filename":"migrating-1-to-2.md","relativePath":"appium/guides/migrating-1-to-2.md"}},{"pageContent":"Check your Appium client documentation for the methods using these endpoints, and adjust your\n code to only use the accepted parameters\n\n### Internal Packages Renamed\n\nIn Appium 1, the internal dependency packages were each located in their own repository. Appium 2\nmoves to a monorepo structure and therefore renames many of these packages, for example:\n\n```\nappium-base-driver # Appium 1\n@appium/base-driver # Appium 2\n```\n\n!!! info \"Actions Needed\"\n\n If you do not directly import Appium packages into your code - none! However, if you do, make\n sure to update the names of your Appium package imports!\n\n## Major New Features\n\nApart from the breaking changes mentioned above, here are some of the major new features you may\nwish to take advantage of with Appium 2:\n\n### Third-Party Drivers and Plugins","metadata":{"loc":{"lines":{"from":321,"to":344}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-1-to-2.md","filename":"migrating-1-to-2.md","relativePath":"appium/guides/migrating-1-to-2.md"}},{"pageContent":"## Major New Features\n\nApart from the breaking changes mentioned above, here are some of the major new features you may\nwish to take advantage of with Appium 2:\n\n### Third-Party Drivers and Plugins\n\nYou are no longer limited to official drivers or plugins, or ones that the Appium team even knows\nabout! Developers can now create their own custom drivers or plugins, which can be installed via\nAppium's [Extension CLI](../cli/extensions.md) from `npm`, `git`, GitHub, or even the local\nfilesystem. Interested in building a driver or plugin? Check out the\n[Building Drivers](../developing/build-drivers.md) and\n[Building Plugins](../developing/build-plugins.md) guides.\n\n### Configuration Files","metadata":{"loc":{"lines":{"from":339,"to":353}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-1-to-2.md","filename":"migrating-1-to-2.md","relativePath":"appium/guides/migrating-1-to-2.md"}},{"pageContent":"### Configuration Files\n\nAppium now supports _configuration files_ in addition to command-line arguments. Nearly all options\nor flags that had to be specified on the CLI in Appium 1, can now also be provided in a\nconfiguration file. The file can be in JSON, JS, or YAML format. For more information, refer to\nthe [Config File Guide](./config.md).\n\n## Special Notes for Cloud Providers\n\nMost of this guide has applied to Appium end users or developers, but some of the architectural\nchanges in Appium 2 will constitute breaking changes for different Appium service providers. At the\nend of the day, the maintainer of the Appium server is responsible for installing and exposing the\nvarious Appium drivers and plugins that end users may wish to use.\n\nWe encourage cloud providers to thoroughly read and understand our [recommendation for cloud\nprovider capabilities](./caps.md#special-notes-for-cloud-providers) in order to support user needs in\nan industry-compatible way!","metadata":{"loc":{"lines":{"from":353,"to":369}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-1-to-2.md","filename":"migrating-1-to-2.md","relativePath":"appium/guides/migrating-1-to-2.md"}},{"pageContent":"---\ntitle: Migrating to Appium 3\n---\n<style>\n .md-typeset .grid {\n grid-template-columns: repeat(auto-fit,minmax(min(100%,11rem),1fr));\n }\n</style>\n\nThis document is a guide for those who are using Appium 2 and would like to upgrade to Appium 3.\nIt contains a list of breaking changes, as well as suggestions for handling them.\n\nWhile Appium 2 was a major overhaul of the entire Appium architecture, Appium 3 is a smaller\nupgrade with fewer breaking changes, which should result in a much simpler migration process.\n\n## Breaking Changes\n\n### Node 20+ Required\n\nWith Appium 2, the minimum required Node version was `14.17.0`. Support for Node 14 had already\nended before the release of Appium 2, which meant that even users on outdated Node versions were\nable to use it.\n\nAppium 3 drops support for outdated Node versions, and bumps the minimum required version to Node\n`20.19.0`, as well as the minimum `npm` version to `10`.\n\n!!! info \"Actions Needed\"","metadata":{"loc":{"lines":{"from":1,"to":27}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"Appium 3 drops support for outdated Node versions, and bumps the minimum required version to Node\n`20.19.0`, as well as the minimum `npm` version to `10`.\n\n!!! info \"Actions Needed\"\n\n Upgrade Node.js to `v20.19.0` or newer, and `npm` to `v10` or newer\n\n### Deprecated Endpoints Removed\n\nAppium 3 removes many previously deprecated server endpoints. Some of these endpoints have now\nbecome specific to one or more drivers, while most others have direct or close-to-direct\nreplacements in other endpoints. All removed endpoints, along with replacements (where applicable)\nare listed [in the **Removed Endpoints** section](#removed).","metadata":{"loc":{"lines":{"from":24,"to":36}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"Some W3C endpoints used in Appium also existed in the old JSONWP standard, but required different\nparameters. With Appium 2, both standards for these endpoints were supported. Appium 3 changes\nthese endpoints by removing support for the JSONWP parameters, and only accepting the W3C\nparameters. These endpoints are listed [in the **Modified Endpoints** section](#modified).\n\n!!! info \"Actions Needed\"\n\n Check your Appium client documentation for the affected methods, and adjust your code to use\n their replacements\n\n### Feature Flag Prefix Required\n\nWith Appium 2, it was possible to opt into certain [insecure features](./security.md) on server\nstartup, which could be enabled using the `--allow-insecure` or `--relaxed-security` flags. Appium\n`2.13` added the ability to optionally provide a scope prefix to specific features, ensuring that\nthey would only be enabled for the specified driver (or all of them).","metadata":{"loc":{"lines":{"from":38,"to":53}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"Appium 3 makes the scope prefix mandatory, and will throw an error if features are specified\nwithout a scope. Note that the behavior of the `--relaxed-security` flag remains unchanged.\n\n!!! info \"Actions Needed\"\n\n If you use the `--allow-insecure` server flag, add a scope prefix before each feature name.\n For example, if you use the UiAutomator2 `adb_shell` feature, on Appium 2 you would enable it\n like this:\n ```\n appium --allow-insecure=adb_shell\n ```\n On Appium 3, to ensure this feature is only activated for UiAutomator2, you can run it like so:\n ```\n appium --allow-insecure=uiautomator2:adb_shell\n ```\n Alternatively, if you wish to keep the Appium 2 behavior and enable the feature for _all_\n drivers that support it, you can use the wildcard (`*`) prefix:\n ```\n appium --allow-insecure=*:adb_shell\n ```\n Server-scope features like `session_discovery` also require the wildcard prefix.\n\n\n### Session Discovery Requires Feature Flag","metadata":{"loc":{"lines":{"from":55,"to":78}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"### Session Discovery Requires Feature Flag\n\nIn Appium 2, it was possible to retrieve all active server sessions via the `GET /sessions`\nendpoint. This information could then be used, for example, in Appium Inspector, in order to attach\nto an existing session, instead of creating a new one.\n\nAppium 3 makes two changes to the session discovery process:\n\n* The `GET /sessions` endpoint is replaced with `GET /appium/sessions` (see [the Removed Endpoints section](#removed))\n* The use of the new endpoint requires the `session_discovery` [feature flag](./security.md)\n\nThe return value of `GET /appium/sessions` is largely identical to `GET /sessions`, but additionally\nincludes the `created` field for each session entry, indicating the session creation time as a Unix\ntimestamp. The rest of the result format remains unchanged.","metadata":{"loc":{"lines":{"from":78,"to":91}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"To reduce migration efforts, the `GET /appium/sessions` endpoint (locked behind the aforementioned\nfeature flag) is also available in Appium `2.19`, allowing you to adjust your code before upgrading\nto Appium 3. As for Appium Inspector, support for this new endpoint is available starting from\nversion `2025.3.1`.\n\n!!! info \"Actions Needed\"\n\n * If your code uses session retrieval, change the endpoint from `GET /sessions` to\n `GET /appium/sessions`\n * If you use Appium Inspector's Attach to Session feature, upgrade to version `2025.3.1` or later\n * In both cases, ensure your Appium server is launched with the `session_discovery`\n [feature flag](./security.md)\n\n### Unzip Logic Removed\n\nAppium 3 removes the custom unzip logic used when working with files like application packages.\nSuch files are often only relevant to particular platforms, therefore the functionality for\nhandling these operations has been moved to relevant drivers.\n\n!!! info \"Actions Needed\"","metadata":{"loc":{"lines":{"from":93,"to":112}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"!!! info \"Actions Needed\"\n\n Ensure you are using the most recent versions of your drivers\n\n### Express 5\n\nAppium 3 upgrades the internally-used `express` dependency from `v4` to `v5`. This should not\naffect users who use Appium directly, but developers integrating parts of Appium into their own\nprojects may want to check [the Express 5 Migration Guide](https://expressjs.com/en/guide/migrating-5.html).\n\n!!! info \"Actions Needed\"\n\n None! (hopefully)\n\n## Endpoint Changes\n### Removed\n\nThe following is a list of all the Appium server endpoints removed in Appium 3. For ease of\nmigration, additional information is provided for each endpoint: drivers that still support the\nendpoint; suggested replacement endpoints, or, rarely, the lack of any available replacements.\n\nIcons are used to indicate endpoint support in either certain drivers, or in the core Appium server\n(applicable to all drivers):\n\n<div class=\"grid cards\" markdown>","metadata":{"loc":{"lines":{"from":112,"to":136}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"Icons are used to indicate endpoint support in either certain drivers, or in the core Appium server\n(applicable to all drivers):\n\n<div class=\"grid cards\" markdown>\n\n- :simple-appium:{ .lg } - Appium server\n- :material-apple:{ .lg } - [XCUITest driver](https://appium.github.io/appium-xcuitest-driver/latest/)\n- :material-android:{ .lg } - [UiAutomator2 driver](https://github.com/appium/appium-uiautomator2-driver/)\n- :material-coffee:{ .lg } - [Espresso driver](https://github.com/appium/appium-espresso-driver)\n- :material-apple-finder:{ .lg } - [Mac2 driver](https://github.com/appium/appium-mac2-driver)\n- :material-microsoft-windows:{ .lg } - [Windows driver](https://github.com/appium/appium-windows-driver)\n\n</div>","metadata":{"loc":{"lines":{"from":133,"to":145}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* `GET /sessions`\n * :octicons-arrow-right-24: `GET /appium/sessions` :simple-appium:\n* `POST /session/:sessionId/accept_alert`\n * :octicons-arrow-right-24: `POST /session/:sessionId/alert/accept` :simple-appium:\n * :octicons-arrow-right-24: `mobile: alert` [execute method](./execute-methods.md) :material-apple:\n * :octicons-arrow-right-24: `mobile: acceptAlert` execute method :material-android:\n* `GET /session/:sessionId/alert_text`\n * :octicons-arrow-right-24: `GET /session/:sessionId/alert/text` :simple-appium:\n* `POST /session/:sessionId/alert_text`\n * :octicons-arrow-right-24: `POST /session/:sessionId/alert/text` :simple-appium:\n* `POST /session/:sessionId/appium/app/background`\n * :octicons-arrow-right-24: `mobile: backgroundApp` execute method :material-apple: :material-android: :material-coffee:\n* `POST /session/:sessionId/appium/app/close`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:","metadata":{"loc":{"lines":{"from":147,"to":160}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* `POST /session/:sessionId/appium/app/close`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: `mobile: terminateApp` execute method :material-apple: :material-android: :material-coffee:\n * :octicons-arrow-right-24: `macos: terminateApp` execute method :material-apple-finder:\n * :octicons-arrow-right-24: `windows: closeApp` execute method :material-microsoft-windows:\n* `POST /session/:sessionId/appium/app/end_test_coverage`\n * :octicons-arrow-right-24: `mobile: shell` execute method :material-android: :material-coffee:\n* `POST /session/:sessionId/appium/app/launch`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: `mobile: launchApp` execute method :material-apple:\n * :octicons-arrow-right-24: `mobile: activateApp` or `mobile: startActivity` execute methods :material-android: :material-coffee:","metadata":{"loc":{"lines":{"from":159,"to":169}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* :octicons-arrow-right-24: `mobile: activateApp` or `mobile: startActivity` execute methods :material-android: :material-coffee:\n * :octicons-arrow-right-24: `macos: launchApp` or `macos: activateApp` execute methods :material-apple-finder:\n * :octicons-arrow-right-24: `windows: launchApp` execute method :material-microsoft-windows:\n* `POST /session/:sessionId/appium/app/reset`\n * :octicons-arrow-right-24: `mobile: clearApp` execute method :material-apple: [^sim] :material-android: :material-coffee:\n* `POST /session/:sessionId/appium/app/strings`\n * :octicons-arrow-right-24: `mobile: getAppStrings` execute method :material-apple: :material-android: :material-coffee:\n* `GET /session/:sessionId/appium/device/app_state`\n * :octicons-arrow-right-24: `POST /session/:sessionId/appium/device/app_state` :simple-appium:\n * :octicons-arrow-right-24: `mobile: queryAppState` execute method :material-apple: :material-android: :material-coffee:","metadata":{"loc":{"lines":{"from":169,"to":178}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* :octicons-arrow-right-24: `mobile: queryAppState` execute method :material-apple: :material-android: :material-coffee:\n * :octicons-arrow-right-24: `macos: queryAppState` execute method :material-apple-finder:\n* `GET /session/:sessionId/appium/device/current_activity`\n * :octicons-arrow-right-24: `mobile: getCurrentActivity` execute method :material-android: :material-coffee:\n* `GET /session/:sessionId/appium/device/current_package`\n * :octicons-arrow-right-24: `mobile: getCurrentPackage` execute method :material-android: :material-coffee:\n* `GET /session/:sessionId/appium/device/display_density`\n * :octicons-arrow-right-24: `mobile: getDisplayDensity` execute method :material-android: :material-coffee:\n* `POST /session/:sessionId/appium/device/finger_print`\n * :octicons-arrow-right-24: `mobile: fingerPrint` execute method :material-android: [^sim] :material-coffee: [^sim]\n* `POST /session/:sessionId/appium/device/get_clipboard`","metadata":{"loc":{"lines":{"from":178,"to":188}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* :octicons-arrow-right-24: `mobile: fingerPrint` execute method :material-android: [^sim] :material-coffee: [^sim]\n* `POST /session/:sessionId/appium/device/get_clipboard`\n * :octicons-check-24: Moved to drivers: :material-android: :material-coffee:\n * :octicons-arrow-right-24: `mobile: getClipboard` execute method :material-apple: :material-android: :material-coffee:\n * :octicons-arrow-right-24: `mobile: getPasteboard` execute method :material-apple: [^sim]\n * :octicons-arrow-right-24: `windows: getClipboard` execute method :material-microsoft-windows:\n* `POST /session/:sessionId/appium/device/gsm_call`\n * :octicons-arrow-right-24: `mobile: gsmCall` execute method :material-android: [^sim] :material-coffee: [^sim]\n* `POST /session/:sessionId/appium/device/gsm_signal`\n * :octicons-arrow-right-24: `mobile: gsmSignal` execute method :material-android: [^sim] :material-coffee: [^sim]\n* `POST /session/:sessionId/appium/device/gsm_voice`","metadata":{"loc":{"lines":{"from":187,"to":197}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* :octicons-arrow-right-24: `mobile: gsmSignal` execute method :material-android: [^sim] :material-coffee: [^sim]\n* `POST /session/:sessionId/appium/device/gsm_voice`\n * :octicons-arrow-right-24: `mobile: gsmVoice` execute method :material-android: [^sim] :material-coffee: [^sim]\n* `POST /session/:sessionId/appium/device/is_locked`\n * :octicons-arrow-right-24: `mobile: isLocked` execute method :material-apple: :material-android: :material-coffee:\n* `POST /session/:sessionId/appium/device/keyevent`\n * :octicons-arrow-right-24: `mobile: keys` execute method :material-apple: (iPadOS only)\n * :octicons-arrow-right-24: `mobile: pressKey` execute method :material-android: :material-coffee:\n * :octicons-arrow-right-24: `macos: keys` execute method :material-apple-finder:\n * :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:\n* `POST /session/:sessionId/appium/device/lock`","metadata":{"loc":{"lines":{"from":196,"to":206}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:\n* `POST /session/:sessionId/appium/device/lock`\n * :octicons-arrow-right-24: `mobile: lock` execute method :material-apple: :material-android: :material-coffee:\n* `POST /session/:sessionId/appium/device/long_press_keycode`\n * :octicons-arrow-right-24: `mobile: pressKey` execute method :material-android: :material-coffee:\n* `POST /session/:sessionId/appium/device/network_speed`\n * :octicons-arrow-right-24: `mobile: networkSpeed` execute method :material-android: [^sim] :material-coffee: [^sim]\n* `POST /session/:sessionId/appium/device/open_notifications`\n * :octicons-arrow-right-24: `mobile: statusBar` execute method :material-android: :material-coffee:\n * :octicons-arrow-right-24: `mobile: openNotifications` execute method :material-android:\n* `POST /session/:sessionId/appium/device/power_ac`","metadata":{"loc":{"lines":{"from":205,"to":215}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* :octicons-arrow-right-24: `mobile: openNotifications` execute method :material-android:\n* `POST /session/:sessionId/appium/device/power_ac`\n * :octicons-arrow-right-24: `mobile: powerAC` execute method :material-android: [^sim] :material-coffee: [^sim]\n* `POST /session/:sessionId/appium/device/power_capacity`\n * :octicons-arrow-right-24: `mobile: powerCapacity` execute method :material-android: [^sim] :material-coffee: [^sim]\n* `POST /session/:sessionId/appium/device/press_keycode`\n * :octicons-arrow-right-24: `mobile: keys` execute method :material-apple: (iPadOS only)\n * :octicons-arrow-right-24: `mobile: pressKey` execute method :material-android: :material-coffee:\n * :octicons-arrow-right-24: `macos: keys` execute method :material-apple-finder:\n * :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:\n* `POST /session/:sessionId/appium/device/send_sms`","metadata":{"loc":{"lines":{"from":214,"to":224}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:\n* `POST /session/:sessionId/appium/device/send_sms`\n * :octicons-arrow-right-24: `mobile: sendSms` execute method :material-android: [^sim] :material-coffee: [^sim]\n* `POST /session/:sessionId/appium/device/set_clipboard`\n * :octicons-arrow-right-24: `mobile: setClipboard` execute method :material-apple: :material-android: :material-coffee:\n * :octicons-arrow-right-24: `mobile: setPasteboard` execute method :material-apple: [^sim]\n * :octicons-arrow-right-24: `windows: setClipboard` execute method :material-microsoft-windows:\n* `POST /session/:sessionId/appium/device/shake`\n * :octicons-arrow-right-24: `mobile: shake` execute method :material-apple: [^sim]\n* `POST /session/:sessionId/appium/device/start_activity`\n * :octicons-arrow-right-24: `mobile: startActivity` execute method :material-android: :material-coffee:\n* `GET /session/:sessionId/appium/device/system_bars`","metadata":{"loc":{"lines":{"from":223,"to":234}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* :octicons-arrow-right-24: `mobile: startActivity` execute method :material-android: :material-coffee:\n* `GET /session/:sessionId/appium/device/system_bars`\n * :octicons-arrow-right-24: `mobile: deviceScreenInfo` execute method :material-apple:\n * :octicons-arrow-right-24: `mobile: getSystemBars` execute method :material-android: :material-coffee:\n* `POST /session/:sessionId/appium/device/toggle_airplane_mode`\n * :octicons-arrow-right-24: `mobile: setConnectivity` execute method :material-android: :material-coffee:\n* `POST /session/:sessionId/appium/device/toggle_data`\n * :octicons-arrow-right-24: `mobile: setConnectivity` execute method :material-android: :material-coffee:\n* `POST /session/:sessionId/appium/device/toggle_location_services`\n * :octicons-arrow-right-24: `mobile: toggleGps` execute method :material-android: :material-coffee:\n* `POST /session/:sessionId/appium/device/toggle_wifi`","metadata":{"loc":{"lines":{"from":233,"to":243}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* :octicons-arrow-right-24: `mobile: toggleGps` execute method :material-android: :material-coffee:\n* `POST /session/:sessionId/appium/device/toggle_wifi`\n * :octicons-arrow-right-24: `mobile: setConnectivity` execute method :material-android: :material-coffee:\n* `POST /session/:sessionId/appium/device/unlock`\n * :octicons-arrow-right-24: `mobile: unlock` execute method :material-apple: :material-android: :material-coffee:\n* `POST /session/:sessionId/appium/element/:elementId/value`\n * :octicons-arrow-right-24: `POST /session/:sessionId/element/:elementId/value` :simple-appium:\n* `POST /session/:sessionId/appium/element/:elementId/replace_value`\n * :octicons-arrow-right-24: `POST /session/:sessionId/element/:elementId/value` :simple-appium:\n* `POST /session/:sessionId/appium/getPerformanceData`\n * :octicons-arrow-right-24: `mobile: getPerformanceData` execute method :material-android: :material-coffee:\n* `POST /session/:sessionId/appium/performanceData/types`","metadata":{"loc":{"lines":{"from":242,"to":253}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* :octicons-arrow-right-24: `mobile: getPerformanceData` execute method :material-android: :material-coffee:\n* `POST /session/:sessionId/appium/performanceData/types`\n * :octicons-arrow-right-24: `mobile: getPerformanceDataTypes` execute method :material-android: :material-coffee:\n* `POST /session/:sessionId/appium/receive_async_response`\n * :octicons-arrow-right-24: `POST /session/:sessionId/execute/async` :simple-appium:\n* `POST /session/:sessionId/appium/simulator/toggle_touch_id_enrollment`\n * :octicons-arrow-right-24: `mobile: enrollBiometric` execute method :material-apple: [^sim]\n* `POST /session/:sessionId/appium/simulator/touch_id`\n * :octicons-arrow-right-24: `mobile: sendBiometricMatch` execute method :material-apple: [^sim]\n* `POST /session/:sessionId/appium/start_recording_screen`\n * :octicons-check-24: Moved to drivers: :material-apple: :material-android: :material-coffee: :material-apple-finder: :material-microsoft-windows:","metadata":{"loc":{"lines":{"from":252,"to":262}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* :octicons-check-24: Moved to drivers: :material-apple: :material-android: :material-coffee: :material-apple-finder: :material-microsoft-windows:\n * :octicons-arrow-right-24: `mobile: startXCTestScreenRecording` execute method :material-apple:\n * :octicons-arrow-right-24: `mobile: startMediaProjectionRecording` execute method :material-android: :material-coffee:\n * :octicons-arrow-right-24: `macos: startRecordingScreen` or `macos: startNativeScreenRecording` execute methods :material-apple-finder:\n * :octicons-arrow-right-24: `windows: startRecordingScreen` execute method :material-microsoft-windows:\n* `POST /session/:sessionId/appium/stop_recording_screen`\n * :octicons-check-24: Moved to drivers: :material-apple: :material-android: :material-coffee: :material-apple-finder: :material-microsoft-windows:\n * :octicons-arrow-right-24: `mobile: stopXCTestScreenRecording` execute method :material-apple:","metadata":{"loc":{"lines":{"from":262,"to":269}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* :octicons-arrow-right-24: `mobile: stopXCTestScreenRecording` execute method :material-apple:\n * :octicons-arrow-right-24: `mobile: stopMediaProjectionRecording` execute method :material-android: :material-coffee:\n * :octicons-arrow-right-24: `macos: stopRecordingScreen` or `macos: stopNativeScreenRecording` execute methods :material-apple-finder:\n * :octicons-arrow-right-24: `windows: stopRecordingScreen` execute method :material-microsoft-windows:\n* `GET /session/:sessionId/application_cache/status`\n * :octicons-no-entry-24: JSONWP protocol command with no direct replacement\n* `POST /session/:sessionId/buttondown`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: [W3C Actions API](https://www.selenium.dev/documentation/webdriver/actions_api/) (`pointerDown`) :simple-appium:\n * :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:\n* `POST /session/:sessionId/buttonup`","metadata":{"loc":{"lines":{"from":269,"to":279}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:\n* `POST /session/:sessionId/buttonup`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: W3C Actions API (`pointerUp`) :simple-appium:\n * :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:\n* `POST /session/:sessionId/click`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: W3C Actions API (`pointerDown` & `pointerUp`) :simple-appium:\n* `POST /session/:sessionId/dismiss_alert`\n * :octicons-arrow-right-24: `POST /session/:sessionId/alert/dismiss` :simple-appium:\n* `POST /session/:sessionId/doubleclick`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: W3C Actions API (`pointerDown` & `pointerUp`) :simple-appium:\n* `POST /session/:sessionId/element/active`","metadata":{"loc":{"lines":{"from":278,"to":291}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* :octicons-arrow-right-24: W3C Actions API (`pointerDown` & `pointerUp`) :simple-appium:\n* `POST /session/:sessionId/element/active`\n * :octicons-arrow-right-24: `GET /session/:sessionId/element/active` :simple-appium:\n* `GET /session/:sessionId/element/:elementId/equals/:otherId`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n* `GET /session/:sessionId/element/:elementId/location`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: `GET /session/:sessionId/element/:elementId/rect` :simple-appium:\n* `GET /session/:sessionId/element/:elementId/location_in_view`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n* `GET /session/:sessionId/element/:elementId/pageIndex`\n * :octicons-no-entry-24: MJSONWP protocol command with no direct replacement\n* `GET /session/:sessionId/element/:elementId/size`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:","metadata":{"loc":{"lines":{"from":290,"to":303}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* `GET /session/:sessionId/element/:elementId/size`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: `GET /session/:sessionId/element/:elementId/rect` :simple-appium:\n* `POST /session/:sessionId/element/:elementId/submit`\n * :octicons-no-entry-24: JSONWP protocol command with no direct replacement\n* `POST /session/:sessionId/execute`\n * :octicons-arrow-right-24: `POST /session/:sessionId/execute/sync` :simple-appium:\n* `POST /session/:sessionId/execute_async`\n * :octicons-arrow-right-24: `POST /session/:sessionId/execute/async` :simple-appium:\n* `POST /session/:sessionId/keys`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: W3C Actions API (`keyDown` & `keyUp`) :simple-appium:\n * Selenium-based clients can also use [Send Keys](https://www.selenium.dev/documentation/webdriver/actions_api/keyboard/#send-keys)\n* `GET /session/:sessionId/local_storage`","metadata":{"loc":{"lines":{"from":302,"to":315}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* Selenium-based clients can also use [Send Keys](https://www.selenium.dev/documentation/webdriver/actions_api/keyboard/#send-keys)\n* `GET /session/:sessionId/local_storage`\n * :octicons-no-entry-24: JSONWP protocol command with no direct replacement\n* `POST /session/:sessionId/local_storage`\n * :octicons-no-entry-24: JSONWP protocol command with no direct replacement\n* `DELETE /session/:sessionId/local_storage`\n * :octicons-no-entry-24: JSONWP protocol command with no direct replacement\n* `GET /session/:sessionId/local_storage/key/:key`\n * :octicons-no-entry-24: JSONWP protocol command with no direct replacement\n* `DELETE /session/:sessionId/local_storage/key/:key`\n * :octicons-no-entry-24: JSONWP protocol command with no direct replacement\n* `GET /session/:sessionId/local_storage/size`\n * :octicons-no-entry-24: JSONWP protocol command with no direct replacement\n* `POST /session/:sessionId/log`","metadata":{"loc":{"lines":{"from":314,"to":327}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* `GET /session/:sessionId/local_storage/size`\n * :octicons-no-entry-24: JSONWP protocol command with no direct replacement\n* `POST /session/:sessionId/log`\n * :octicons-arrow-right-24: `POST /session/:sessionId/se/log` :simple-appium:\n* `GET /session/:sessionId/log/types`\n * :octicons-arrow-right-24: `GET /session/:sessionId/se/log/types` :simple-appium:\n* `POST /session/:sessionId/moveto`\n * :octicons-arrow-right-24: W3C Actions API (`pointerMove`) :simple-appium:\n * Selenium-based clients can also use [Move by Offset](https://www.selenium.dev/documentation/webdriver/actions_api/mouse/#move-by-offset)\n* `GET /session/:sessionId/screenshot/:elementId`\n * :octicons-arrow-right-24: `GET /session/:sessionId/element/:elementId/screenshot` :simple-appium:\n* `GET /session/:sessionId/session_storage`\n * :octicons-no-entry-24: JSONWP protocol command with no direct replacement\n* `POST /session/:sessionId/session_storage`","metadata":{"loc":{"lines":{"from":325,"to":338}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* `GET /session/:sessionId/session_storage`\n * :octicons-no-entry-24: JSONWP protocol command with no direct replacement\n* `POST /session/:sessionId/session_storage`\n * :octicons-no-entry-24: JSONWP protocol command with no direct replacement\n* `DELETE /session/:sessionId/session_storage`\n * :octicons-no-entry-24: JSONWP protocol command with no direct replacement\n* `GET /session/:sessionId/session_storage/key/:key`\n * :octicons-no-entry-24: JSONWP protocol command with no direct replacement\n* `DELETE /session/:sessionId/session_storage/key/:key`\n * :octicons-no-entry-24: JSONWP protocol command with no direct replacement\n* `GET /session/:sessionId/session_storage/size`\n * :octicons-no-entry-24: JSONWP protocol command with no direct replacement\n* `POST /session/:sessionId/timeouts/async_script`\n * :octicons-arrow-right-24: `POST /session/:sessionId/timeouts` :simple-appium:\n* `POST /session/:sessionId/timeouts/implicit_wait`","metadata":{"loc":{"lines":{"from":336,"to":350}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* `POST /session/:sessionId/timeouts/async_script`\n * :octicons-arrow-right-24: `POST /session/:sessionId/timeouts` :simple-appium:\n* `POST /session/:sessionId/timeouts/implicit_wait`\n * :octicons-arrow-right-24: `POST /session/:sessionId/timeouts` :simple-appium:\n* `POST /session/:sessionId/touch/click`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: W3C Actions API (`pointerDown` & `pointerUp`) :simple-appium:\n * Selenium-based clients can also use [Click and Release](https://www.selenium.dev/documentation/webdriver/actions_api/mouse/#click-and-release)\n * :octicons-arrow-right-24: `mobile: tap` or `mobile: tapWithNumberOfTaps` execute methods :material-apple:\n * :octicons-arrow-right-24: `mobile: clickGesture` execute method :material-android:\n * :octicons-arrow-right-24: `mobile: clickAction` execute method :material-coffee:","metadata":{"loc":{"lines":{"from":348,"to":358}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* :octicons-arrow-right-24: `mobile: clickGesture` execute method :material-android:\n * :octicons-arrow-right-24: `mobile: clickAction` execute method :material-coffee:\n * :octicons-arrow-right-24: `macos: click`, `macos: rightClick`, `macos: press` or `macos: tap` execute methods :material-apple-finder:\n * :octicons-arrow-right-24: `windows: click` execute method :material-microsoft-windows:\n* `POST /session/:sessionId/touch/doubleclick`\n * :octicons-arrow-right-24: W3C Actions API (`pointerDown` & `pointerUp`) :simple-appium:\n * Selenium-based clients can also use [Double Click](https://www.selenium.dev/documentation/webdriver/actions_api/mouse/#double-click)\n * :octicons-arrow-right-24: `mobile: doubleTap` or `mobile: tapWithNumberOfTaps` execute methods :material-apple:\n * :octicons-arrow-right-24: `mobile: doubleClickGesture` execute method :material-android:\n * :octicons-arrow-right-24: `mobile: clickAction` execute method :material-coffee:","metadata":{"loc":{"lines":{"from":357,"to":366}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* :octicons-arrow-right-24: `mobile: doubleClickGesture` execute method :material-android:\n * :octicons-arrow-right-24: `mobile: clickAction` execute method :material-coffee:\n * :octicons-arrow-right-24: `macos: doubleClick` or `macos: doubleTap` execute methods :material-apple-finder:\n * :octicons-arrow-right-24: `windows: click` execute method :material-microsoft-windows:\n* `POST /session/:sessionId/touch/down`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: W3C Actions API (`pointerDown`) :simple-appium:\n * :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:\n* `POST /session/:sessionId/touch/flick`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: W3C Actions API (`pointerDown`, `pointerMove` & `pointerUp`) :simple-appium:\n * :octicons-arrow-right-24: `mobile: flingGesture` execute method :material-android:","metadata":{"loc":{"lines":{"from":365,"to":376}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* :octicons-arrow-right-24: W3C Actions API (`pointerDown`, `pointerMove` & `pointerUp`) :simple-appium:\n * :octicons-arrow-right-24: `mobile: flingGesture` execute method :material-android:\n* `POST /session/:sessionId/touch/longclick`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: W3C Actions API (`pointerDown`, `pause` & `pointerUp`) :simple-appium:\n * :octicons-arrow-right-24: `mobile: touchAndHold` execute method :material-apple:\n * :octicons-arrow-right-24: `mobile: longClickGesture` execute method :material-android:\n * :octicons-arrow-right-24: `mobile: clickAction` execute method :material-coffee:\n * :octicons-arrow-right-24: `macos: press` execute method :material-apple-finder:\n * :octicons-arrow-right-24: `windows: click` execute method :material-microsoft-windows:\n* `POST /session/:sessionId/touch/multi/perform`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:","metadata":{"loc":{"lines":{"from":375,"to":386}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* `POST /session/:sessionId/touch/multi/perform`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: `POST /session/:sessionId/actions` :simple-appium:\n* `POST /session/:sessionId/touch/move`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: W3C Actions API (`pointerMove`) :simple-appium:\n * Selenium-based clients can also use [Move by Offset](https://www.selenium.dev/documentation/webdriver/actions_api/mouse/#move-by-offset)\n* `POST /session/:sessionId/touch/perform`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: `POST /session/:sessionId/actions` :simple-appium:\n* `POST /session/:sessionId/touch/scroll`\n * :octicons-arrow-right-24: W3C Actions API (`pointerDown`, `pointerMove` & `pointerUp`) :simple-appium:\n * :octicons-arrow-right-24: `mobile: scroll` or `mobile: swipe` execute methods :material-apple:","metadata":{"loc":{"lines":{"from":385,"to":397}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* :octicons-arrow-right-24: `mobile: scroll` or `mobile: swipe` execute methods :material-apple:\n * :octicons-arrow-right-24: `mobile: scrollGesture` or `mobile: swipeGesture` execute methods :material-android:\n * :octicons-arrow-right-24: `mobile: swipe` execute method :material-coffee:\n * :octicons-arrow-right-24: `macos: scroll` or `macos: swipe` execute methods :material-apple-finder:\n * :octicons-arrow-right-24: `windows: scroll` execute method :material-microsoft-windows:\n* `POST /session/:sessionId/touch/up`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: W3C Actions API (`pointerUp`) :simple-appium:\n * :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:\n* `GET /session/:sessionId/window_handle`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: `GET /session/:sessionId/window` :simple-appium:","metadata":{"loc":{"lines":{"from":397,"to":408}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* `GET /session/:sessionId/window_handle`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: `GET /session/:sessionId/window` :simple-appium:\n* `GET /session/:sessionId/window_handles`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: `GET /session/:sessionId/window/handles` :simple-appium:\n* `GET /session/:sessionId/window/handle`\n * :octicons-arrow-right-24: `GET /session/:sessionId/window` :simple-appium:\n* `POST /session/:sessionId/window/:windowhandle/maximize`\n * :octicons-arrow-right-24: `POST /session/:sessionId/window/maximize` :simple-appium:\n * :fontawesome-solid-triangle-exclamation: Only supported for the current window\n* `GET /session/:sessionId/window/:windowhandle/position`\n * :octicons-arrow-right-24: `GET /session/:sessionId/window/rect` :simple-appium:\n * :fontawesome-solid-triangle-exclamation: Only supported for the current window","metadata":{"loc":{"lines":{"from":406,"to":419}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"* :octicons-arrow-right-24: `GET /session/:sessionId/window/rect` :simple-appium:\n * :fontawesome-solid-triangle-exclamation: Only supported for the current window\n* `POST /session/:sessionId/window/:windowhandle/position`\n * :octicons-arrow-right-24: `POST /session/:sessionId/window/rect` :simple-appium:\n * :fontawesome-solid-triangle-exclamation: Only supported for the current window\n* `GET /session/:sessionId/window/:windowhandle/size`\n * :octicons-check-24: Moved to drivers: :material-microsoft-windows:\n * :octicons-arrow-right-24: `GET /session/:sessionId/window/rect` :simple-appium:\n * :fontawesome-solid-triangle-exclamation: Only supported for the current window","metadata":{"loc":{"lines":{"from":418,"to":426}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"### Modified\n\nThe following are all endpoints modified in Appium 3, by removing handling for old or unused\nparameters (note that no new parameters have been added). Each endpoint lists the parameters it no\nlonger accepts, as well as the parameters it continues to accept in Appium 3.\n\n* `POST /session`\n * :octicons-x-24: `desiredCapabilities`, `requiredCapabilities`\n * :octicons-check-24: `capabilities`\n* `POST /session/:sessionId/alert/text`\n * :octicons-x-24: `value`\n * :octicons-check-24: `text`\n* `GET /session/:sessionId/appium/device/system_time`\n * :octicons-x-24: `format`\n * :octicons-check-24: None\n* `POST /session/:sessionId/element/:elementId/value`\n * :octicons-x-24: `value`\n * :octicons-check-24: `text`\n* `POST /session/:sessionId/timeouts`\n * :octicons-x-24: `type`, `ms`\n * :octicons-check-24: `script`, `pageLoad`, `implicit`\n* `POST /session/:sessionId/window`\n * :octicons-x-24: `name`\n * :octicons-check-24: `handle`","metadata":{"loc":{"lines":{"from":428,"to":451}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"[^sim]: Supported in emulators/simulators only","metadata":{"loc":{"lines":{"from":453,"to":453}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/migrating-2-to-3.md","filename":"migrating-2-to-3.md","relativePath":"appium/guides/migrating-2-to-3.md"}},{"pageContent":"---\ntitle: Appium Server Security\n---\n\nThe Appium team makes every effort to ensure the security of the Appium server. This is especially\nimportant when Appium is run in a multitenant environment, or when multiple users are running\nsessions on the same Appium server. In general, you can only safely enable all Appium's features if\nall the following are true:\n\n- You're running your own Appium server locally or within a protected internal network\n- You're not sharing it with any untrusted parties\n- You don't expose Appium's port(s) to the wider internet\n\nBut because many Appium users might not be able to guarantee such a safe environment, the Appium\nteam puts many features behind a security protection mechanism which forces system admins (the\npeople that are in charge of starting the Appium server) to _explicitly opt-in_ to these features.\n(Third-party driver and plugin authors can also [hide behaviour behind security\nflags](../developing/build-drivers.md).)","metadata":{"loc":{"lines":{"from":1,"to":18}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/security.md","filename":"security.md","relativePath":"appium/guides/security.md"}},{"pageContent":"For security reasons, Appium client sessions can _not_ request feature enablement via capabilities;\nthis is the responsibility of the server admin who configures and launches the Appium server.\n\n## Security Server Args\n\nThe [Server CLI Args](../cli/args.md) doc outlines three relevant arguments which may be passed to\nAppium when starting it from the command line:\n\n|<div style=\"width:10em\">Parameter</div>|Description|\n|---------------------------------------|-----------|\n|`--relaxed-security`|Turns on _all_ insecure features, except those blocked by `--deny-insecure`|\n|`--allow-insecure`|Turns on _only_ specified features, except those blocked by `--deny-insecure`. Has no effect when used in combination with `--relaxed-security`|\n|`--deny-insecure`|Explicitly turns _off_ specified features, overriding `--relaxed-security` and `--allow-insecure`|\n\nAll of the above arguments can also be specified in the [Appium Configuration file](./config.md).","metadata":{"loc":{"lines":{"from":20,"to":34}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/security.md","filename":"security.md","relativePath":"appium/guides/security.md"}},{"pageContent":"All of the above arguments can also be specified in the [Appium Configuration file](./config.md).\n\nFeatures passed to `--allow-insecure`/`--deny-insecure` must be specified as a comma-separated list,\nand each feature in the list must additionally include a prefix, indicating the driver to which the\nfeature should apply. The prefix can be either the driver's `automationName`, or the wildcard (`*`)\nsymbol, if the feature should be applied to all drivers. The prefix and feature name are separated\nusing the colon character (`:`).\n\nFor example, `first:foo` refers to the `foo` feature for the `first` driver, whereas `*:bar` refers\nto the `bar` feature for all drivers.\n\n## Insecure Features\n\nEach Appium driver is responsible for its own security, and can create its own feature names. Thus\nyou should read through the documentation for a particular driver to know which feature names it\nmight use. Here is an incomplete list of examples from some of Appium's official drivers:","metadata":{"loc":{"lines":{"from":34,"to":49}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/security.md","filename":"security.md","relativePath":"appium/guides/security.md"}},{"pageContent":"|<div style=\"width:12em\">Feature Name</div>|Description|Supported Extension(s)|\n|------------|-----------|-------|\n|`get_server_logs`|Allows retrieving of Appium server logs via the Webdriver log interface|IOS, XCUITest, Android, UiAutomator2, Espresso|\n|`adb_shell`|Allows execution of arbitrary shell commands via ADB, using the `mobile: shell` command|Android, UiAutomator2, Espresso|\n|`record_audio`|Allow recording of host machine audio inputs|XCUITest|\n|`execute_driver_script`| Allows to send a request which has multiple Appium commands.|Execute Driver Plugin|\n\nSome insecure features operate on the server level, and do not require a driver session. Enabling\nthese features requires using the wildcard prefix:\n\n|<div style=\"width:12em\">Feature Name</div>|Description|\n|------------|-----------|\n|`session_discovery`|Allows retrieving the list of active server sessions via `GET /appium/sessions`|\n\n## Examples\n\nTurn on the `foo` feature only for the `first` driver:","metadata":{"loc":{"lines":{"from":51,"to":67}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/security.md","filename":"security.md","relativePath":"appium/guides/security.md"}},{"pageContent":"## Examples\n\nTurn on the `foo` feature only for the `first` driver:\n\n```bash\nappium --allow-insecure=first:foo\n```\n\nTurn on the `foo` feature for all drivers:\n\n```bash\nappium --allow-insecure=*:foo\n```\n\nTurn on the `foo` feature for all drivers _except_ `first`:\n\n```bash\nappium --allow-insecure=*:foo --deny-insecure=first:foo\n```\n\nTurn on all features _except_ `foo` for all drivers:\n\n```bash\nappium --relaxed-security --deny-insecure=*:foo\n```","metadata":{"loc":{"lines":{"from":65,"to":89}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/security.md","filename":"security.md","relativePath":"appium/guides/security.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Session Settings\n---\n\nAppium has a set of extension APIs that allow you to adjust parameters for a given session during\nthe session itself. Called \"Settings\", these parameters are similar to [Capabilities](./caps.md),\nbut while Capabilities _cannot be adjusted_ once a session has started, Settings _can be adjusted any\nnumber of times_ during the course of a session.\n\nThere are 3 important points to the concept of Settings:\n\n- Settings are mutable; they can be changed during a session using the Settings API\n- Settings are only relevant during the session in which they are set. They are typically reset for\n each new session, though depending on the driver, some settings may persist between sessions\n- Settings only adjust the way the Appium server behaves during test automation. They do not affect\n the device or app under test","metadata":{"loc":{"lines":{"from":1,"to":19}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/settings.md","filename":"settings.md","relativePath":"appium/guides/settings.md"}},{"pageContent":"An example of a setting would be the `ignoreUnimportantViews` setting recognized by the UiAutomator2\ndriver. The driver can be instructed to ignore elements in the view hierarchy which it deems\nirrelevant. Changing this setting to `true` can cause tests to run faster. But if later in the same\nsession you _want_ to access elements which would be ignored under this setting, you can always\nchange it back to `false`.\n\nSettings are implemented via the following API endpoints:","metadata":{"loc":{"lines":{"from":21,"to":27}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/settings.md","filename":"settings.md","relativePath":"appium/guides/settings.md"}},{"pageContent":"Settings are implemented via the following API endpoints:\n\n| Command | <div style=\"width:18em\">Method/Route</div> | Params | Description | Returns |\n|-------------------|---------------------------------------------|------------------------------------|------------------------------------|------------------------------------|\n| `Update Settings` | `POST /session/:id/appium/settings` | `settings` (`Record<string, any>`) | Update the provided setting values | `null` |\n| `Get Settings` | `GET /session/:id/appium/settings` | | Return the current settings | `settings` (`Record<string, any>`) |\n\nThe `settings` object must be a set of keys and values, where the key is the setting name, and the\nvalue is any documented valid value for that setting.\n\n!!! info","metadata":{"loc":{"lines":{"from":27,"to":37}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/settings.md","filename":"settings.md","relativePath":"appium/guides/settings.md"}},{"pageContent":"The `settings` object must be a set of keys and values, where the key is the setting name, and the\nvalue is any documented valid value for that setting.\n\n!!! info\n\n Settings are driver-specific, so refer to your driver's documentation for a list of supported settings\n\n## Initializing Settings via Capabilities\n\nIf you want to start an Appium session with a setting in a non-default state, you can do so by\nincluding a capability of the form `appium:settings[<name>]` with the appropriate value. So to turn\non the `ignoreUnimportantViews` setting mentioned above from the very beginning of a session, you\nwould construct a set of capabilities that includes the following in its JSON representation:\n\n```json\n{\n \"appium:settings[ignoreUnimportantViews]\": true\n}\n```\n\nAlso, since Appium 2.1, there is a possibility to provide multiple settings in a single\n`appium:settings` capability value:","metadata":{"loc":{"lines":{"from":34,"to":55}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/settings.md","filename":"settings.md","relativePath":"appium/guides/settings.md"}},{"pageContent":"```json\n{\n \"appium:settings[ignoreUnimportantViews]\": true\n}\n```\n\nAlso, since Appium 2.1, there is a possibility to provide multiple settings in a single\n`appium:settings` capability value:\n\n```json\n{\n \"appium:settings\": {\n \"ignoreUnimportantViews\": true,\n \"allowInvisibleElements\": true\n }\n}\n```\n\nOf course, initializing a setting via capabilities doesn't prevent you from changing it later on\nvia the Settings API. To learn more about how to use the Settings API in the context of your\nspecific client library, visit the documentation for that client.","metadata":{"loc":{"lines":{"from":48,"to":68}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/settings.md","filename":"settings.md","relativePath":"appium/guides/settings.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: SSL/TLS/SPDY Support\n---\n\nAppium 2.2 introduces the option to start the Appium server with SSL/TLS support. \n\n## Command Line Arguments\nIn order to enable secure connections to the server, you need to provide the following command\nline arguments:\n\n```bash\nappium server --ssl-cert-path=/path/to/cert.pem --ssl-key-path=/path/to/key.pem\n```\n\nBoth arguments must be provided and should contain paths to a valid\n[X509 PEM](https://www.ssl.com/guide/pem-der-crt-and-cer-x-509-encodings-and-conversions/)\ncertificate and its corresponding private key.\n\nAfter the server is started use the `https` protocol and a client supporting SSL/TLS or\n[SPDY](https://en.wikipedia.org/wiki/SPDY) to communicate to it.\n\n### Supported Features","metadata":{"loc":{"lines":{"from":1,"to":25}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/tls.md","filename":"tls.md","relativePath":"appium/guides/tls.md"}},{"pageContent":"After the server is started use the `https` protocol and a client supporting SSL/TLS or\n[SPDY](https://en.wikipedia.org/wiki/SPDY) to communicate to it.\n\n### Supported Features\n\nOnce a secure server socket is established it supports the following protocols:\n`['h2', 'spdy/3.1', 'spdy/3', 'spdy/2', 'http/1.1', 'http/1.0']`. See\n[the SPDY node module documentation](https://www.npmjs.com/package/spdy) to get more details about\nits features. All insecure client connections will be rejected by the server.\n\n### Self-Signed Certificates\n\nUse the following command in order to generate a self-signed certificate/key pair:\n\n```bash\nopenssl req -nodes -new -x509 -keyout key.pem -out cert.pem -subj \"/C=US/ST=State/L=City/O=company/OU=Com/CN=www.testserver.local\"\n```","metadata":{"loc":{"lines":{"from":22,"to":38}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/tls.md","filename":"tls.md","relativePath":"appium/guides/tls.md"}},{"pageContent":"```bash\nopenssl req -nodes -new -x509 -keyout key.pem -out cert.pem -subj \"/C=US/ST=State/L=City/O=company/OU=Com/CN=www.testserver.local\"\n```\n\nFeel free to change the value of `-subj` in the command above with your matching details. The server\nshould work just fine with a self-signed certificate, although you need to take care about a proper\nclient setup, e.g. make sure it does not reject unauthorized certificates.","metadata":{"loc":{"lines":{"from":36,"to":42}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/guides/tls.md","filename":"tls.md","relativePath":"appium/guides/tls.md"}},{"pageContent":"---\nhide:\n - navigation\n - toc\n\ntitle: Welcome\n---\n<style>\n .md-typeset h1,\n .appium-sponsor-thanks {\n display: none;\n }\n</style>\n\n<div style=\"text-align: center\">\n <img src=\"assets/images/appium-logo-horiz.png\" style=\"max-width: 400px;\" />\n</div>\n\nWelcome to the Appium documentation! Appium is an open-source project and ecosystem of related\nsoftware, designed to facilitate UI automation of many app platforms, including mobile (iOS,\nAndroid, Tizen), browser (Chrome, Firefox, Safari), desktop (macOS, Windows), TV (Roku, tvOS,\nAndroid TV, Samsung), and more!","metadata":{"loc":{"lines":{"from":1,"to":22}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/index.md","filename":"index.md","relativePath":"appium/index.md"}},{"pageContent":"<div style=\"text-align: center; margin-top: 2rem; font-style: italic;\">\n Appium is extremely grateful for the support of its key partners! (Learn more about our\n sponsorship program and contributor compensation scheme <a\n href=\"https://github.com/appium/appium/blob/master/GOVERNANCE.md#sponsorship\">here</a>)\n <div class=\"homepageSponsors\">\n <div class=\"homepageSponsor\">\n <a href=\"https://www.browserstack.com/browserstack-appium?utm_campaigncode=701OW00000AoUTQYA3&utm_medium=partnered&utm_source=appium\">\n <img src=\"assets/images/sponsor-logo-browserstack-dark.png#only-dark\" style=\"width: 220px;\" />\n <img src=\"assets/images/sponsor-logo-browserstack-light.png#only-light\" style=\"width: 220px;\" />\n </a>\n </div>\n </div>\n</div>\n\n## Explore the Documentation\n\n<div class=\"grid cards\" markdown>","metadata":{"loc":{"lines":{"from":25,"to":41}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/index.md","filename":"index.md","relativePath":"appium/index.md"}},{"pageContent":"<div class=\"grid cards\" markdown>\n\n- Check out the [__Introduction__](./intro/index.md) to make sure you understand the key concepts\n- Go through the [__Quickstart__](./quickstart/index.md) to get set up and run a basic Android test\n- Visit the [__Ecosystem__](./ecosystem/index.md) page for a list of drivers, clients and plugins you may want to use\n- Refer to the [__CLI Reference__](./cli/index.md) for using Appium from the command line\n- See the [__Command Reference__](./commands/index.md) for a list of commands exposed by Appium and plugins\n- Read the different [__Guides__](./guides/migrating-1-to-2.md) for a variety of instructions, tips and tricks\n- Check out various third-party [__Resources__](./resources.md) to explore Appium around the web\n- For creating your own Appium extensions, see the [__Developer__](./developing/index.md) documentation\n- For contributions to Appium itself, refer to the [__Contributing__](./contributing.md) page\n\n</div>","metadata":{"loc":{"lines":{"from":41,"to":53}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/index.md","filename":"index.md","relativePath":"appium/index.md"}},{"pageContent":"---\ntitle: How Does Appium Work?\n---\n\nAs mentioned on the main page, Appium is an open-source project and ecosystem of related software,\ndesigned to facilitate UI automation of many app platforms. With the release of Appium 2, Appium\nhas the following primary goals:[^1]\n\n- Make platform-specific automation capabilities available under a cross-platform, standard API\n- Allow easy access to this API from any programming language\n- Provide tools to enable convenient community development of Appium extensions\n\n[^1]:\n To meet these primary goals, we also work with a set of secondary goals or methodology\n principles, which we also encourage for Appium extension developers:","metadata":{"loc":{"lines":{"from":1,"to":15}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/appium.md","filename":"appium.md","relativePath":"appium/intro/appium.md"}},{"pageContent":"[^1]:\n To meet these primary goals, we also work with a set of secondary goals or methodology\n principles, which we also encourage for Appium extension developers:\n\n - As far as possible, rely on (and contribute to) open source technology\n - As far as possible, rely on vendor-provided tools for a given platform\n - As far as possible, rely on automation tools that allow automation of unmodified apps (prefer\n not to require the user to build in additional SDKs or software that introduce discrepancies\n between the test version of the app and the production version)\n - As far as possible, rely on existing standards instead of creating new ones\n\nSo, take any app platform you know about, like iOS or Android. Appium wants for there to be a way\nfor developers and testers to write UI automation code for that platform, according to a single,\nunified API. Based on Appium's goals, we have a lot of questions to answer to make it all work:","metadata":{"loc":{"lines":{"from":13,"to":26}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/appium.md","filename":"appium.md","relativePath":"appium/intro/appium.md"}},{"pageContent":"- Which API should that \"single, unified\" API be?\n- How do we map that API to automation behaviour for a specific platform?\n- How do we make that API accessible via multiple popular programming languages?\n\nThere's another, larger, question lurking in the background here too, given that there are more app\nplatforms out there than just iOS and Android:\n\n- How do we enable automation for *all* the platforms?\n\nExploring Appium's answers to these questions may not be the quickest way to learn what Appium is,\nbut it is certainly a good one! So let's dive in.\n\n## Appium's choice of API","metadata":{"loc":{"lines":{"from":28,"to":40}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/appium.md","filename":"appium.md","relativePath":"appium/intro/appium.md"}},{"pageContent":"Exploring Appium's answers to these questions may not be the quickest way to learn what Appium is,\nbut it is certainly a good one! So let's dive in.\n\n## Appium's choice of API\n\nAppium is very fortunate to have been preceded by a technology which has been a long-standing\npioneer in the field of UI automation, namely [Selenium](https://selenium.dev). The goal of the\nSelenium project has been to support UI automation of web browsers, and in this way we can think of\nit as occupying a subset of Appium's goals. Along the way, Selenium (and, after they merged,\nanother project called WebDriver) developed a relatively stable API for browser automation.","metadata":{"loc":{"lines":{"from":37,"to":46}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/appium.md","filename":"appium.md","relativePath":"appium/intro/appium.md"}},{"pageContent":"Over the years, Selenium worked with various web browser vendors and the [W3C](https://w3.org)\nstandards group to turn its API into an official web browser standard, called the [WebDriver\nspecification](https://w3c.github.io/webdriver/). All the main browsers now\nimplement automation capabilities inline with the WebDriver spec, without the Selenium team having\nto maintain any software that performs actual automation; standards for the win!","metadata":{"loc":{"lines":{"from":48,"to":52}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/appium.md","filename":"appium.md","relativePath":"appium/intro/appium.md"}},{"pageContent":"Appium's initial goals were to develop an automation standard for mobile apps (iOS and Android). We\ncould have made up something new, but in the spirit of joining forces and keeping standards, well,\nstandard, we decided to adopt the WebDriver spec as Appium's API.[^2] While user interaction on\nwebsites and in mobile native apps are not entirely identical (with even greater differences once\nwe start to consider, for example, TV platforms controlled by simple remotes), the fact is that\nmost software UIs are pretty much the same. This means that the WebDriver spec provides automation\nAPI primitives (finding elements, interacting with elements, loading pages or screens, etc...) that\nmore or less map to any platform.\n\n[^2]: Technically, when Appium was first written, we were dealing with something older than the\n WebDriver spec, called the JSON Wire Protocol. Since then, Appium continued to evolve along with\n the W3C spec and is fully W3C-compliant.","metadata":{"loc":{"lines":{"from":54,"to":65}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/appium.md","filename":"appium.md","relativePath":"appium/intro/appium.md"}},{"pageContent":"Of course, Appium wants to support the cases where user interaction *does* differ from web to\nmobile or web to TV, and so Appium also makes use of the built-in *extensibility* of the WebDriver\nspec. The result is that, no matter what platform you want to automate, when you use Appium, you\nwill do so using the standard WebDriver spec, with two caveats:\n\n- We might not have any way to support a particular WebDriver API command on a given platform, and\n so some commands might be unsupported (for example, getting or setting cookies is not possible in\n the world of native mobile app automation).\n- We might support automation behaviours that go *beyond* what's available in the WebDriver API\n command list, though any such commands will be valid and spec-compliant extensions to the\n WebDriver API.","metadata":{"loc":{"lines":{"from":67,"to":77}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/appium.md","filename":"appium.md","relativePath":"appium/intro/appium.md"}},{"pageContent":"How do you actually *use* the WebDriver API, particularly in the context of Appium? We'll cover\nthat in the [section below](#universal-programming-language-access) on how Appium provides\nuniversal programming language access. All you need to know for now is that the way Appium\nintroduces a universal UI automation interface is by implementing the WebDriver protocol.\n\n## Platform automation behaviour\n\nThe next question is, how does Appium map this protocol to automation behaviour on a wide range of\nplatforms? The trick is that, strictly speaking, Appium doesn't! It leaves this responsibility up\nto a kind of software module called an Appium *driver*. There's a whole [Driver\nIntroduction](./drivers.md) which you can read next, so we won't go into huge detail on how they\nwork for now.","metadata":{"loc":{"lines":{"from":79,"to":90}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/appium.md","filename":"appium.md","relativePath":"appium/intro/appium.md"}},{"pageContent":"What's important to understand at the moment is that a driver is kind of like a pluggable module\nfor Appium that gives Appium the power to automate a particular platform (or set of platforms,\ndepending on the goal of the driver). At the end of the day, a driver's responsibility is to simply\nimplement an Appium-internal interface representing the WebDriver protocol. How it implements this\ninterface is totally up to the driver, based on its strategy for making automation happen on\na specific platform. Typically, and with a lot more complexity and difficulty in the details,\na driver does this by relying on platform-specific automation technologies. For example, Apple\nmaintains an iOS automation technology called\n[XCUITest](https://developer.apple.com/documentation/xctest/user_interface_tests). The Appium\ndriver that supports iOS app automation is called the [XCUITest\nDriver](https://github.com/appium/appium-xcuitest-driver) because ultimately what it does is","metadata":{"loc":{"lines":{"from":92,"to":102}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/appium.md","filename":"appium.md","relativePath":"appium/intro/appium.md"}},{"pageContent":"driver that supports iOS app automation is called the [XCUITest\nDriver](https://github.com/appium/appium-xcuitest-driver) because ultimately what it does is\nconvert the WebDriver protocol to XCUITest library calls.","metadata":{"loc":{"lines":{"from":101,"to":103}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/appium.md","filename":"appium.md","relativePath":"appium/intro/appium.md"}},{"pageContent":"One of the reasons that drivers are independent, pluggable modules is that they work completely\ndifferently from one another. The tools and requirements for building and using drivers for\ndifferent platforms are completely different. And so Appium lets you use just the drivers that you\nneed for your automation tasks. Choosing drivers and installing them so that you can use them with\nyour Appium instance is so important that Appium has its very own [CLI for managing\ndrivers](../cli/extensions.md).\n\nSo, to answer our original question, the way that Appium provides access to automation capabilities\nfor a given platform is that the Appium team (or anyone else[^3]) writes a *driver* for that\nplatform, implementing as much or little of the WebDriver protocol as desired. The driver can then\nbe installed by anyone using Appium.","metadata":{"loc":{"lines":{"from":105,"to":115}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/appium.md","filename":"appium.md","relativePath":"appium/intro/appium.md"}},{"pageContent":"[^3]: You can build and share your own drivers! Check out [Building\n Drivers](../developing/build-drivers.md) to learn more about how to develop drivers in Node.js\n that can be used with Appium.\n\n## Universal programming language access\n\nBut what does it mean, or look like, to *use* Appium, anyway? Since Appium is ultimately a Node.js\nprogram, it *could* have looked like importing Appium and its drivers as libraries into your own\nNode.js programs. But that wouldn't meet Appium's goal of providing automation capabilities to\npeople using any popular programming language.\n\nLuckily, the fact that Appium rode in on Selenium's coattails meant that we had a solution to this\nproblem from day one. You see, the WebDriver specification is actually an HTTP-based protocol,\nmeaning it is designed to be used over a network rather than within the memory of a single program.","metadata":{"loc":{"lines":{"from":117,"to":130}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/appium.md","filename":"appium.md","relativePath":"appium/intro/appium.md"}},{"pageContent":"One of the main benefits of this \"client-server\" architecture is that it allows the automation\nimplementer (the thing doing the automation, in this case the 'server') to be completely distinct\nfrom the automation runner (the thing defining what automation should be done, in what steps,\netc..., in this case the 'client'). Basically, all the \"hard stuff\" (actually figuring out how to\nmake automation happen on a given platform) can be handled in one place by the server, and \"thin\"\nclient libraries can be written in any programming language which simply encode HTTP requests to\nthe server in language-appropriate way. It's possible, in other words, to bring basic Appium\n/ WebDriver capabilities to a new programming language relatively easily, assuming high-level HTTP\nlibraries exist, simply by coding up a basic HTTP client in that language.\n\nThere are a couple important takeaways here for you, the Appium user:","metadata":{"loc":{"lines":{"from":132,"to":142}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/appium.md","filename":"appium.md","relativePath":"appium/intro/appium.md"}},{"pageContent":"- Appium is an *HTTP server*. It must run as a process on some computer for as long as you want to\n be able to use it for automation. It must be accessible on the network to whichever computer you\n want to use to run the automation from (whether that is the same machine or one across the\n world).\n- Unless you want to write raw HTTP calls or use cURL, using Appium for automation involves the use\n of an [Appium Client](clients.md) in the language of your choice. The goal of each of these\n clients is to encapsulate the WebDriver protocol so that rather than worrying about the protocol\n itself, you can work with objects and methods that feel idiomatic for your language.\n- The Appium server and the Appium client do *not* need to be running on the same computer. You\n simply need to be able to send HTTP requests from the client to the server over some network.\n This greatly facilitates the use of cloud providers for Appium, since they can host the Appium","metadata":{"loc":{"lines":{"from":144,"to":154}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/appium.md","filename":"appium.md","relativePath":"appium/intro/appium.md"}},{"pageContent":"simply need to be able to send HTTP requests from the client to the server over some network.\n This greatly facilitates the use of cloud providers for Appium, since they can host the Appium\n server and any related drivers and devices, and all you need to do is point your client script to\n their secure endpoints.","metadata":{"loc":{"lines":{"from":153,"to":156}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/appium.md","filename":"appium.md","relativePath":"appium/intro/appium.md"}},{"pageContent":"And of course, none of this is about \"testing\" per se, purely about the use of Appium and its\nclient libraries for automation purposes. If you want to do automation for the purpose of\n\"testing\", you'll likely want to enlist the help of test runners, test frameworks, and the like,\nnone of which need be related to Appium; one of the benefits of Appium's \"universal accessibility\"\nis that it plays well with whatever set of tools you find most beneficial for your situation.\n\n## Appium's huge scope\n\nAppium's vision (automation of everything under a single API) is huge! Certainly, much bigger than\nthe team of core maintainers for the open source project. So how does Appium hope to achieve this\ngoal? Basically, by empowering the community to develop functionality on top of Appium as\na *platform*. This is what we call the Appium \"ecosystem\".","metadata":{"loc":{"lines":{"from":158,"to":169}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/appium.md","filename":"appium.md","relativePath":"appium/intro/appium.md"}},{"pageContent":"The Appium team does officially maintain a few drivers itself (for example, the XCUITest driver\nthat we spoke about earlier). But it cannot hope to have the platform-specific expertise or the\ncapacity to maintain drivers for many different platforms. But what we have done, particularly\nbeginning with Appium 2, is to provide tools to empower the community to join in our vision:","metadata":{"loc":{"lines":{"from":171,"to":174}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/appium.md","filename":"appium.md","relativePath":"appium/intro/appium.md"}},{"pageContent":"- Anyone can create a driver simply by creating a Node.js module that conforms to the appropriate\n conventions and implements any (sub|super)set of the WebDriver protocol. Creating a driver often\n involves a minimal amount of code because the WebDriver protocol details are abstracted away, and\n many helper libraries are available---the same libraries that power the Appium team's own\n drivers.\n- Sharing drivers with others is easy using the Appium driver CLI. There is no central authority.\n Anyone can share drivers publicly or privately, for free or for sale. Drivers can be open or\n closed source (though obviously we appreciate open source!).","metadata":{"loc":{"lines":{"from":176,"to":183}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/appium.md","filename":"appium.md","relativePath":"appium/intro/appium.md"}},{"pageContent":"Appium's vision of being a platform for development extends beyond the support of automation for\nall app platforms. As a popular automation tool, there are many opportunities for integrating\nAppium with all kinds of other tools and services. In addition, there are many feature ideas for\nAppium, either as a core server or in its incarnation across various drivers, which the core team\nwill never have time to build. And so, with Appium 2, Appium has released a plugin system that\nenables anyone to build and share modules that change how Appium works!","metadata":{"loc":{"lines":{"from":185,"to":190}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/appium.md","filename":"appium.md","relativePath":"appium/intro/appium.md"}},{"pageContent":"In the same way that drivers are easily shareable and consumable via the Appium driver CLI, plugins\ncan be published and consumed via a parallel [Plugin CLI](../cli/extensions.md). Plugins can do all\nsorts of things, for example adding the ability for Appium to find and interact with screen regions\nbased on a template image (as in the [`images`\nplugin](https://github.com/appium/appium/tree/master/packages/images-plugin)). There are very few\nlimitations on what you can do with plugins, so you might also be interested in learning how to\n[Build Plugins](../developing/build-plugins.md) in Node.js that can be used with Appium.\n\nSo that's Appium: an extensible, universal interface for the UI automation of potentially\neverything! Read on into some of the specific intro docs for more details, or check out the various\nguides to dive into some more general concepts and features of Appium.","metadata":{"loc":{"lines":{"from":192,"to":202}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/appium.md","filename":"appium.md","relativePath":"appium/intro/appium.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Intro to Appium Clients\n---\n\nFor all the reasons discussed in the [main Overview](./appium.md), Appium is based on the [W3C\nWebDriver specification](https://w3c.github.io/webdriver/). This means that\nAppium implements a client-server architecture. The server (consisting of Appium itself along with\nany drivers or plugins you are using for automation) is connected to the devices under test, and\nis actually responsible for making automation happen on those devices. The client (driven by *you*,\nthe Appium test author) is responsible for sending commands to the server over the network, and\nreceiving responses from the server as a result. These responses can be used to tell whether\nautomation commands are successful, or might contain information that you queried about the state\nof the application. This document is a conceptual introduction to the client side of this equation.\n\n!!! info","metadata":{"loc":{"lines":{"from":1,"to":18}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/clients.md","filename":"clients.md","relativePath":"appium/intro/clients.md"}},{"pageContent":"!!! info\n\n For more about the server side of the equation (i.e., how does Appium actually control\n devices?), check out our [Intro to Appium Drivers](./drivers.md). To skip to a list of links to\n Appium client libraries, check out the [list of clients](../ecosystem/clients.md).\n\nWhat sorts of automation commands are available? That is up to the particular driver and plugins\nthat you are using in any given session. A standard set of commands would include, for example, the\nfollowing:\n\n- Find Element\n- Click Element\n- Get Page Source\n- Take Screenshot\n\nIf you look at these commands in the WebDriver specification, you'll notice that they are not\ndefined in terms of any particular programming language. They are not Java commands, or JavaScript\ncommands, or Python commands. Instead, they form part of an HTTP API which can be accessed from\nwithin *any* programming language (or none! you could just use cURL if you want).","metadata":{"loc":{"lines":{"from":18,"to":36}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/clients.md","filename":"clients.md","relativePath":"appium/intro/clients.md"}},{"pageContent":"So, for example, the `Find Element` command corresponds to an HTTP `POST` request sent to the HTTP\nendpoint `/session/:sessionid/element` (where in this case, `:sessionid` is a placeholder for the\nunique session ID generated by the server in a previous call to `Create Session`).\n\nThis information is primarily useful for people developing technology that works with the WebDriver\nspec. It's not particularly useful for people trying to write Appium or Selenium tests. When you\nwrite an Appium test, you want to use a programming language you're familiar with. Luckily, there\nexist a set of [Appium client libraries](../ecosystem/clients.md)[^1] that take care of the\nresponsibility of speaking HTTP to the Appium server. Instead, they expose a set of \"native\"\ncommands for a particular programming language, so that, to the test author, it just feels like\nyou're writing Python, or JavaScript, or Java.","metadata":{"loc":{"lines":{"from":38,"to":48}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/clients.md","filename":"clients.md","relativePath":"appium/intro/clients.md"}},{"pageContent":"As an example, here's the same simple set of Appium commands in five different programming\nlanguages, using the recommended Appium client binding for each language (note that this is not\nworking sample code including all appropriate imports; see each client library's instructions for\nsetup and command reference):\n\n=== \"JavaScript (Webdriver.io)\"\n\n ```js\n const element = await driver.$('//*[@text=\"Foo\"]');\n await element.click();\n console.log(await element.getText())\n console.log(await driver.getPageSource())\n ```\n\n=== \"Java\"\n\n ```java\n WebElement element = driver.findElement(By.Xpath(\"//*[@text='Foo']\"))\n element.click()\n System.out.println(element.getText())\n System.out.println(driver.getPageSource())\n ```\n\n=== \"Python\"\n\n ```py\n element = driver.find_element(by=By.XPATH, value='//*[@text=\"Foo\"]')\n element.click()\n print(element.text)\n print(driver.page_source)\n ```\n\n=== \"Ruby\"","metadata":{"loc":{"lines":{"from":50,"to":82}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/clients.md","filename":"clients.md","relativePath":"appium/intro/clients.md"}},{"pageContent":"=== \"Python\"\n\n ```py\n element = driver.find_element(by=By.XPATH, value='//*[@text=\"Foo\"]')\n element.click()\n print(element.text)\n print(driver.page_source)\n ```\n\n=== \"Ruby\"\n\n ```rb\n element = driver.find_element :xpath, '//*[@text=\"Foo\"]'\n element.click\n puts element.text\n puts driver.page_source\n ```\n \n=== \"C#\"\n\n ```dotnet\n AppiumElement element = driver.FindElement(MobileBy.AccessibilityId(\"Views\")); \n element.click();\n System.Console.WriteLine(element.Text);\n System.Console.WriteLine(driver.PageSource);\n ```\n \nEach of these scripts, despite being in different languages, does the same thing under the hood:","metadata":{"loc":{"lines":{"from":73,"to":100}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/clients.md","filename":"clients.md","relativePath":"appium/intro/clients.md"}},{"pageContent":"1. Call `Find Element` with a `using` parameter of `xpath` and a `value` parameter expressing the\n XPath query used to find an element. (If you're confused about these terms, you might find an\n introduction to Appium or Selenium useful)\n2. Call `Click Element` with the ID of the element found in the previous call.\n3. Call `Get Element Text` with the ID of the same element, and print it to the console.\n4. Call `Get Page Source` to retrieve the page/app source and print it to the console.","metadata":{"loc":{"lines":{"from":102,"to":107}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/clients.md","filename":"clients.md","relativePath":"appium/intro/clients.md"}},{"pageContent":"The only other thing to keep in mind before choosing or using a client is that each client is\nindependently maintained. Just because a feature is available in one client, it doesn't mean it's\navailable in another client (though all clients support at least the standard W3C protocol plus any\ncommon appium extensions). Just because one client has a nice set of helper functions, doesn't mean\nanother will. Some clients are kept very frequently up to date, and others are not! So when\nthinking about choosing a library, the first consideration is the language you want to use, and the\nsecond consideration is how full-featured and well-maintained the library is!","metadata":{"loc":{"lines":{"from":109,"to":115}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/clients.md","filename":"clients.md","relativePath":"appium/intro/clients.md"}},{"pageContent":"To learn how to use an Appium client, visit that client's homepage to learn more. In many cases,\nthe Appium client for a given language is built *on top of* the *Selenium* client for that\nlanguage, and so certain Appium clients may only document the features which the Appium client\nadded on top of the Selenium client. All that to say, for a full reference, you may need to visit\nboth the Appium client documentation as well as the Selenium client documentation.\n\nThat's all you need to know about Appium clients! Head over to the\n[Clients](../ecosystem/clients.md) page to check out the current list of clients.\n\n[^1]: These libraries are alternately called \"clients\", \"client libraries\", or \"client bindings\".\n They all mean the same thing!","metadata":{"loc":{"lines":{"from":117,"to":127}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/clients.md","filename":"clients.md","relativePath":"appium/intro/clients.md"}},{"pageContent":"---\ntitle: Intro to Appium Drivers\n---\n\nAs the [main Overview](./appium.md) makes clear, \"drivers\" are basically Appium's answer to the\nquestion, \"how do we support automation of multiple, unrelated platforms?\" In this doc we'll get\ninto a little more detail about how drivers work. The specific details of how drivers work probably\ndon't matter too much for you, unless you're planning on writing your own driver or contributing to\nan existing driver (things we hope you do!).\n\nThe main benefit in understanding a bit more of how drivers work is that being aware of the typical\ncomplexity or the typical driver architecture will inform your debugging process when you\ninevitably run into an issue in one of your tests.\n\n## Interface Implementations\n\nAt the most basic level, drivers are simply Node.js classes that extend a special class included in\nAppium, called `BaseDriver`. You could have something very close to a \"working\" driver, with these\nvery simple lines of code:","metadata":{"loc":{"lines":{"from":1,"to":19}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/drivers.md","filename":"drivers.md","relativePath":"appium/intro/drivers.md"}},{"pageContent":"```js\nimport BaseDriver from '@appium/base-driver'\n\nclass MyNewDriver extends BaseDriver {\n}\n```\n\nThis empty driver doesn't *do* anything, but you could wrap it up in a Node.js module, add a few\nAppium-related fields to the module's manifest (`package.json`), and then install it using `appium\ndriver install`.\n\nSo, from a technical perspective, an Appium driver is just a bit of code that inherits from some\nother Appium code. That's it! Now, inheriting from `BaseDriver` actually gives us a lot, because\n`BaseDriver` is essentially an encapsulation of the entire WebDriver protocol. So all a driver\nneeds to do something useful is to *implement* Node.js methods with names corresponding to\ntheir WebDriver protocol equivalents.","metadata":{"loc":{"lines":{"from":21,"to":36}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/drivers.md","filename":"drivers.md","relativePath":"appium/intro/drivers.md"}},{"pageContent":"So let's say I wanted to do something with this empty driver; first I have to decide which\nWebDriver command I want to implement. For our example, let's take the [Navigate\nTo](https://w3c.github.io/webdriver/#navigate-to) WebDriver command. Leave aside for the moment\nwhat I want to have the driver *do* when this command is executed. To tell Appium the driver can\nhandle the command, all we have to do is define a method like this in our driver class:[^1]\n\n```js\nasync setUrl(url) {\n // do whatever we want here\n}\n```","metadata":{"loc":{"lines":{"from":38,"to":48}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/drivers.md","filename":"drivers.md","relativePath":"appium/intro/drivers.md"}},{"pageContent":"```js\nasync setUrl(url) {\n // do whatever we want here\n}\n```\n\n[^1]: You might notice that `setUrl` doesn't look anything like `Navigate To`, so how did we know\n to use it rather than some other random string? Well, Appium's WebDriver-protocol-to-method-name\n mapping is defined in a special file within the `@appium/base-driver` package called\n [routes.js](https://github.com/appium/appium/blob/master/packages/base-driver/lib/protocol/routes.js).\n So if you're writing a driver, this is where you would go to figure out what method names to use\n and what parameters to expect. Or you could look at the source for any of the main Appium\n drivers!\n\nThat's it! How we actually implement the command is totally up to us, and depends on the\nplatform(s) we want to support. Here are some different example implementations of this command for\ndifferent platforms:","metadata":{"loc":{"lines":{"from":44,"to":60}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/drivers.md","filename":"drivers.md","relativePath":"appium/intro/drivers.md"}},{"pageContent":"- Browsers: execute some JavaScript to set `window.location.href`\n- iOS apps: launch an app using a deep link\n- Android apps: launch an app using a deep link\n- React apps: load a specific route\n- Unity: go to a named scene\n\nSo you can see there can be a lot of differences between how drivers implement the same WebDriver\ncommand across platforms.[^2] What is the *same*, though, is how they express that they can handle\na protocol command.\n\n[^2]: Of course, we want to keep the semantics as similar as possible, but in the world of iOS, for\n example, launching an app via a deep link (a URL with a special app-specific scheme) is about as\n close as we are going to get to navigating to a web URL.","metadata":{"loc":{"lines":{"from":62,"to":74}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/drivers.md","filename":"drivers.md","relativePath":"appium/intro/drivers.md"}},{"pageContent":"We're going into this great amount of detail (which you don't need to remember, by the way),\nbecause it's important to stress the point that an Appium driver is not inherently anything in\nparticular, other than a bit of JS code that can handle WebDriver protocol commands. Where you go\nfrom there is up to you, the driver author!\n\n## Automation mapping\n\nBut *typically* what driver authors want to do is to provide automation behaviours for a given\nplatform(s) that are semantically very similar to the the WebDriver spec implementations for\nbrowsers. When you want to find an element, you should get a reference to a UI element. When you\nwant to click or tap that element, the resulting behaviour should be the same as if a person were\nto click or tap on the element. And so on.","metadata":{"loc":{"lines":{"from":76,"to":87}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/drivers.md","filename":"drivers.md","relativePath":"appium/intro/drivers.md"}},{"pageContent":"So the real challenge for driver authors is not how to work with the WebDriver protocol (because\n`BaseDriver` encapsulates all that for you), but how to make the actual automation happen on the\ntarget platform. Every driver relies on its own set of underlying technologies here. As mentioned\nin the [Overview](index.md), the iOS driver uses an Apple technology called\n[XCUITest](https://developer.apple.com/documentation/xctest/xcuielement). These underlying\nautomation technologies usually have proprietary or idiosyncratic APIs of their own. Writing\na driver becomes the task of mapping the WebDriver protocol to this underlying API (or sometimes\na set of different underlying APIs--for example, the UiAutomator2 driver relies not only on the\n[UiAutomator2](https://developer.android.com/training/testing/other-components/ui-automator)\ntechnology from Google, but also functions only available through\n[ADB](https://developer.android.com/tools/adb), as well as functions only available","metadata":{"loc":{"lines":{"from":89,"to":99}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/drivers.md","filename":"drivers.md","relativePath":"appium/intro/drivers.md"}},{"pageContent":"technology from Google, but also functions only available through\n[ADB](https://developer.android.com/tools/adb), as well as functions only available\nvia the Android SDK inside a helper app). Tying it all together into a single, usable, WebDriver\ninterface is the incredibly useful (but incredibly challenging) art of driver development!","metadata":{"loc":{"lines":{"from":98,"to":101}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/drivers.md","filename":"drivers.md","relativePath":"appium/intro/drivers.md"}},{"pageContent":"## Multi-level architecture\n\nIn practice, this often results in a pretty complex architecture. Let's take iOS for example again.\nThe XCUITest framework (the one used by the Appium driver) expects code that calls it to be written\nin Objective-C or Swift. Furthermore, XCUITest code can only be run in a special mode triggered by\nXcode (and directly or indirectly, the Xcode command line tools). In other words, there's no\nstraightforward way to go from a Node.js function implementation (like `setUrl()` above) to\nXCUITest API calls.\n\nWhat the XCUITest driver authors have done is instead to split the driver into two parts: one part\nwritten in Node.js (the part which is incorporated into Appium and which initially handles the\nWebDriver commands), and the other part written in Objective-C (the part which actually gets run on\nan iOS device and makes XCUITest API calls). This makes interfacing with XCUITest possible, but\nintroduces the new problem of coordination between the two parts.","metadata":{"loc":{"lines":{"from":103,"to":116}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/drivers.md","filename":"drivers.md","relativePath":"appium/intro/drivers.md"}},{"pageContent":"The driver authors could have chosen any of a number of very different strategies to model the\ncommunication between the Node.js side and the Objective-C side, but at the end of the day decided\nto use ... the WebDriver protocol! That's right, the Objective-C side of the XCUITest driver is\nitself a WebDriver implementation, called\n[WebDriverAgent](https://github.com/appium/webdriveragent).[^3]\n\n[^3]: You could in theory, therefore, point your WebDriver client straight to WebDriverAgent and\n bypass Appium entirely. This is usually not convenient, however, for a few reasons:\n\n - The Appium XCUITest driver builds and manages WebDriverAgent for you, which can be a pain and\n involves the use of Xcode.\n - The XCUITest driver does lots more than what can be done by WebDriverAgent, for example working\n with simulators or devices, installing apps, and the like.","metadata":{"loc":{"lines":{"from":118,"to":130}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/drivers.md","filename":"drivers.md","relativePath":"appium/intro/drivers.md"}},{"pageContent":"The moral of the story is that driver architectures can become quite complicated and multilayered,\ndue to the nature of the problem we're trying to solve. It also means it can be difficult sometimes\nto tell where in this chain of technologies something has gone wrong, if you run into a problem\nwith a particular test. With the XCUITest world again, we have something like the following set of\ntechnologies all in play at the same time:\n\n- Your test code (in its programming language) - owned by you\n- The Appium client library - owned by Appium\n- The Selenium client library - owned by Selenium\n- The network (local or Internet)\n- The Appium server - owned by Appium\n- The Appium XCUITest driver - owned by Appium\n- WebDriverAgent - owned by Appium\n- Xcode - owned by Apple\n- XCUITest - owned by Apple\n- iOS itself - owned by Apple\n- macOS (where Xcode and iOS simulators run) - owned by Apple\n\nIt's a pretty deep stack!\n\n## Proxy mode","metadata":{"loc":{"lines":{"from":132,"to":152}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/drivers.md","filename":"drivers.md","relativePath":"appium/intro/drivers.md"}},{"pageContent":"It's a pretty deep stack!\n\n## Proxy mode\n\nThere's one other important architectural aspect of drivers to understand. It can be exemplified\nagain by the XCUITest driver. Recall that we just discussed how the two \"halves\" of the XCUITest\ndriver both speak the WebDriver protocol---the Node.js half clicks right into Appium's WebDriver\nserver, and the Objective-c half (WebDriverAgent) is its own WebDriver implementation.","metadata":{"loc":{"lines":{"from":150,"to":157}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/drivers.md","filename":"drivers.md","relativePath":"appium/intro/drivers.md"}},{"pageContent":"This opens up the possibility of Appium taking a shortcut in certain cases. Let's imagine that the\nXCUITest driver needs to implement the `Click Element` command. The internal code of this\nimplementation would look something like taking the appropriate parameters and constructing an HTTP\nrequest to the WebDriverAgent server. In this case, we're basically just reconstructing the\nclient's original call to the Appium server![^4] So there's really no need to even write a function\nimplementing the `Click Element` command. Instead, the XCUITest driver can just let Appium know\nthat this command should be proxied directly to some other WebDriver server.\n\n[^4]: It's not *exactly* the same call, because the Appium server and the WebDriverAgent server\n will generate different session IDs, but these differences will be handled transparently.","metadata":{"loc":{"lines":{"from":159,"to":168}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/drivers.md","filename":"drivers.md","relativePath":"appium/intro/drivers.md"}},{"pageContent":"[^4]: It's not *exactly* the same call, because the Appium server and the WebDriverAgent server\n will generate different session IDs, but these differences will be handled transparently.\n\nIf you're not familiar with the concept of \"proxying,\" in this case it just means that the XCUITest\ndriver will not be involved at all in handling the command. Instead it will merely be repackaged\nand forwarded to WebDriverAgent at the protocol level, and WebDriverAgent's response will likewise\nbe passed back directly to the client, without any XCUITest driver code seeing it or modifying it.","metadata":{"loc":{"lines":{"from":167,"to":173}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/drivers.md","filename":"drivers.md","relativePath":"appium/intro/drivers.md"}},{"pageContent":"This architectural pattern provides a nice bonus for driver authors who choose to deal with the\nWebDriver protocol everywhere, rather than constructing bespoke protocols. It also means that\nAppium can create wrapper drivers for any other existing WebDriver implementation very easily. If\nyou look at the [Appium Safari driver](https://github.com/appium/appium-safari-driver) code, for\nexample, you'll see that it implements basically no standard commands, because all of these are\nproxied directly to an underlying SafariDriver process.\n\nIt's important to understand that this proxying business is sometimes happening under the hood,\nbecause if you're ever diving into some open source driver code trying to figure out where\na command is implemented, you might be surprised to find no implementation at all in the Node.js\ndriver code itself! In that case, you'll need to figure out where commands are being proxied to so\nyou can look there for the appropriate implementation.","metadata":{"loc":{"lines":{"from":175,"to":186}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/drivers.md","filename":"drivers.md","relativePath":"appium/intro/drivers.md"}},{"pageContent":"OK, that's enough for this very detailed introduction to drivers!","metadata":{"loc":{"lines":{"from":188,"to":188}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/drivers.md","filename":"drivers.md","relativePath":"appium/intro/drivers.md"}},{"pageContent":"---\ntitle: Appium Project History\n---\n\nAppium has been around in one form or another since 2012. It's been under the\ndirection of various individuals and organizations, and it's even been\nimplemented in 3 different programming languages! Welcome to more than you ever\nwanted to know about how Appium got to be what is it today...\n\n## Early Inspiration\n\n[Dan Cuellar](https://twitter.com/thedancuellar) was the Test Manager at Zoosk\nin 2011, when he encountered a problem. The length of the test passes on the\niOS product was getting out of hand. Less testing was an option, but would come\nwith additional risk, especially with it taking several days to get patches\nthrough the iOS App Store Review process. He thought back to his days working\non websites and realized automation was the answer.","metadata":{"loc":{"lines":{"from":1,"to":17}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/history.md","filename":"history.md","relativePath":"appium/intro/history.md"}},{"pageContent":"Dan surveyed the existing landscape of tools, only to find that all of them\nhand major drawbacks. The tool supplied by Apple, UIAutomation, required tests\nto be written in JavaScript, and did not allow for real-time debugging or\ninterpretation. It also had to be executed inside the Xcode profiling tool,\nInstruments. Other 3rd-party tools used private APIs and required SDKs and HTTP\nServers to be embedded into the application. This seemed highly undesirable.\n\nUnsatisfied with the existing options, Dan asked his manager for some\nadditional time to see if he could find a better way. He spent 2 weeks poking\nand prodding around to see if there was a way to use approved Apple\ntechnologies to automate an iOS application. The first implementation he tried\nused AppleScript to send messages to Mac UI elements using the OS\nX accessibility APIs. This worked to some degree, but would never work on real\ndevices, not to mention other drawbacks.","metadata":{"loc":{"lines":{"from":19,"to":32}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/history.md","filename":"history.md","relativePath":"appium/intro/history.md"}},{"pageContent":"So he thought, what if I could get the UIAutomation framework to run in real\ntime like an interpreter? He looked into it and he determined that all he would\nneed to do is find a way to receive, execute, and reply to commands from within\na UIAutomation javascript program. Using the utility Apple provided for\nexecuting shell commands he was able to `cat` sequentially ordered text files\nto receive commands, `eval()` the output to execute them, and write them back\nto disk with `python`. He then prepared code in C# that implemented the\nSelenium-style syntax to write the sequentially ordered javascript commands.\niOSAuto is born.\n\n## Selenium Conference 2012","metadata":{"loc":{"lines":{"from":34,"to":44}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/history.md","filename":"history.md","relativePath":"appium/intro/history.md"}},{"pageContent":"## Selenium Conference 2012\n\nDan was selected to speak at Selenium Conference 2012 in London about an\nentirely different topic. As part of his presentation, he showed off iOS\nAutomation using Selenium syntax to demonstrate writing platform-agnostic tests\nthat use separate platform-specific page objects with a common interface. To\nhis surprise, the cool test architecture would take a backseat to the spectacle\nof iOS tests running like WebDriver tests. Several people suggested that he\ngive a lightning talk later in the conference to explain exactly how it worked.","metadata":{"loc":{"lines":{"from":44,"to":52}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/history.md","filename":"history.md","relativePath":"appium/intro/history.md"}},{"pageContent":"On the second day of the conference, Dan stepped up on stage to give the\nlightning talk. Jason Huggins, co-creator of Selenium, moderated the lightning\ntalks. Dan experienced technical difficulties getting his presentation to\nload, and Jason nearly had to move on to the next lightning talk. At the last\nmoment, the screen turned on and Dan jumped into his presentation. He explained\nthe details of his implementation and how it worked, begged for contributors,\nand in five minutes it was over. The crowd applauded politely, and he left the\nstage.\n\n## The Phone Rings\n\nFour months after the Selenium Conference, Jason called Dan. Jason had been\nworking on iOS testing support for a client at Sauce Labs. Jason remembered\nDan's lightning talk and thought the project might be useful to Jason's work,\nbut Dan's source code was not public. Jason asked Dan to meet up. Later that\nweek, Dan met Jason in a bar in San Francisco and showed him the source code\nfor iOS Auto.","metadata":{"loc":{"lines":{"from":54,"to":70}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/history.md","filename":"history.md","relativePath":"appium/intro/history.md"}},{"pageContent":"A long-time open source advocate, Jason encouraged Dan to release his code\nunder an open source license. In August, Dan [released the source\ncode](https://github.com/penguinho/appium-old/commit/3ab56d3a5601897b2790b5256351f9b5af3f9e90)\non GitHub in C#. Jason encouraged Dan to change the language to make the\nproject more appealing to potential contributors. Dan [uploaded a new version\nin\nPython](https://github.com/penguinho/appium-old/commit/9b891207be0957bf209a77242750da17d3eb8eda).\nIn September, Jason added a web server and [began to implement the WebDriver\nwire\nprotocol](https://github.com/hugs/appium-old/commit/ae8fe4578640d9af9137d0546190fa29317d1499)\nover HTTP, making iOS Auto scriptable from any Selenium WebDriver client\nlibrary in any language.\n\n## The Mobile Testing Summit","metadata":{"loc":{"lines":{"from":72,"to":85}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/history.md","filename":"history.md","relativePath":"appium/intro/history.md"}},{"pageContent":"## The Mobile Testing Summit\n\nJason decided that the project should be presented at the [Mobile Testing\nSummit](https://twitter.com/mobtestsummit) in November, but suggested that the\nproject get a new name first. Many ideas were thrown out and they settled on\nAppleCart. A day later, while he was perusing some of Apple's guidance on\ncopyright and trademarks, Jason noticed that under the section of examples for\nnames Apple would defend its trademarks against, the first example was\n\"AppleCart\". He called Dan and informed him of the situation, and they\nbrainstormed for a bit before Jason hit the jackpot. Appium... Selenium for\nApps.\n\n## Sauce Labs and Node.js","metadata":{"loc":{"lines":{"from":85,"to":97}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/history.md","filename":"history.md","relativePath":"appium/intro/history.md"}},{"pageContent":"## Sauce Labs and Node.js\n\nIn January 2013, not long after the Mobile Testing Summit, Sauce Labs decided\nto fully back Appium and provide more developer power. A task force was created\nto evaluate the current state and how best to move forward with the project.\nThe team, which included Jonathan Lipps (the current project lead), decided\nthat Appium needed a rebirth, and ultimately settled on Node.js as the\nframework to use. Node is well-known as a fast and efficient web server\nbackend, and at the end of the day, Appium is just a highly-specialized web\nserver. It was also decided that JavaScript as a language was accessible enough\nthat Appium would be able to grow into a larger community of open-source\ndevelopers with JavaScript than the other options on the table.","metadata":{"loc":{"lines":{"from":97,"to":108}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/history.md","filename":"history.md","relativePath":"appium/intro/history.md"}},{"pageContent":"In just a few days, the team leveraged the existing work on Appium and had\na new version of Appium with as much functionality as the previous Python\nversion. The foundation had been laid for Appium's basic architecture, and we\nhave been successfully building on it since. A few weeks into this sprint,\nJonathan Lipps was formally designated project lead and he began to strategize\nhow to get more people from the community involved with Appium's development.\n\n## Appium Around the World","metadata":{"loc":{"lines":{"from":110,"to":117}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/history.md","filename":"history.md","relativePath":"appium/intro/history.md"}},{"pageContent":"## Appium Around the World\n\nUltimately, Jonathan decided that getting Appium in front of as many developers\nat conferences and meetups was the best way to attract users and contributions.\nAppium in its new incarnation was debuted at the [Google Test Automation\nConference 2013](https://www.youtube.com/watch?v=1J0aXDbjiUE). Later in 2013,\nAppium was presented at conferences and meetups all around the US, as well as\nin England, Poland, Portugal, and Australia. Notably, Jonathan had Appium\n[perform as instruments in a band](https://www.youtube.com/watch?v=zsbNVkayYRQ)\nand Dan Cuellar put together a fun [Appium video\nmontage](https://www.youtube.com/watch?v=xkzrEn0v0II) for Selenium Conference.","metadata":{"loc":{"lines":{"from":117,"to":127}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/history.md","filename":"history.md","relativePath":"appium/intro/history.md"}},{"pageContent":"But during all these presentations and conferences, the project continued to\ndevelop. Early in 2013 we released Android and Selendroid support, making\nAppium the first truly cross-platform automation framework. The project also\ncontinued to attract users and contributors, and by the end of 2013, we'd\nalready had well over 1,000 commits.\n\n## The Road to Appium 1.0","metadata":{"loc":{"lines":{"from":129,"to":135}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/history.md","filename":"history.md","relativePath":"appium/intro/history.md"}},{"pageContent":"## The Road to Appium 1.0\n\nAppium began to grow and mature significantly. In May 2014,\nwe released Appium 1.0, which stood as a milestone in Appium's development.\nAppium was given\n[various](https://www.prnewswire.com/news-releases/black-duck-announces-black-duck-open-source-rookies-of-the-year-winners-242383341.html)\n[awards](https://www.infoworld.com/article/2241247/164642-bossie-awards-2014-the-best-open-source-application-development-tools.html)\nand became the most popular open-source cross-platform mobile automation\nframework. Stability improved, bugs were prioritized and fixed, and features\nadded. Sauce Labs increased the number of developers it donated to working\non Appium, but the entire community stayed involved in guiding the project and\ncontributing to it, and project governance continued to happen in the open, on\npublic mailing lists and GitHub's issue tracker.\n\n## The Appium Umbrella Broadens","metadata":{"loc":{"lines":{"from":135,"to":149}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/history.md","filename":"history.md","relativePath":"appium/intro/history.md"}},{"pageContent":"## The Appium Umbrella Broadens\n\nEventually, it became clear that the Appium codebase was not optimized for\na large team of distributed, sometime contributors. We took the opportunity as\na committer team to rewrite Appium from the ground up, using a more modern\nversion of the JavaScript language, and redoing Appium's architecture so that\nit was easy for users or third-party developers to build their own Appium\n\"drivers\". We wanted for it to be easier for new contributors to get ramped up\non the Appium codebase, and to see support for new platforms added to Appium by\ngroups other than the core team. That vision has begun to be fulfilled, with\ngroups like Microsoft and Youi.tv adding drivers to Appium for Windows desktop\napp automation and Youi.tv app automation, respectively. Who knows what\nplatforms will be added next?\n\n## Appium To The People","metadata":{"loc":{"lines":{"from":149,"to":163}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/history.md","filename":"history.md","relativePath":"appium/intro/history.md"}},{"pageContent":"## Appium To The People\n\nIn late 2016, Sauce Labs donated Appium as a project to the [JS\nFoundation](https://js.foundation), in order to cement for the world Sauce's\ncommitment that Appium remains open source. The JS Foundation is a non-profit\nopen source stewardship organization which takes responsibility for holding the\ncopyright for open source projects, as well as ensuring they have a long and\nsuccessful tenure in the community. As a result of our move to a non-profit\nfoundation, we hope that the door will open even more widely for new\ncontributors, either as individuals or representing one of the many companies\nwhich now have an interest in seeing Appium move forward.\n\nEventually, the JS Foundation merged into the [OpenJS Foundation](https://openjsf.org), and Appium\nis currently an Impact Project in the foundation.\n\n## Appium 2.0","metadata":{"loc":{"lines":{"from":163,"to":178}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/history.md","filename":"history.md","relativePath":"appium/intro/history.md"}},{"pageContent":"Eventually, the JS Foundation merged into the [OpenJS Foundation](https://openjsf.org), and Appium\nis currently an Impact Project in the foundation.\n\n## Appium 2.0\n\nAppium 2 was released in 2023, with a new focus on Appium as an ecosystem rather than a singular\nproject. Drivers and plugins can be developed and shared by anyone, opening up a world of\npossibilities for automation-related development for platforms far beyond iOS and Android.","metadata":{"loc":{"lines":{"from":175,"to":182}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/history.md","filename":"history.md","relativePath":"appium/intro/history.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Appium in a Nutshell\n---\n\nAs mentioned on the main page, Appium aims to support UI automation of many _different platforms_\n(mobile, web, desktop, etc.). Not only that, but it also aims to support automation code written in\n_different languages_ (JS, Java, Python, etc.). Combining all of this functionality in a single\nprogram is a very daunting, if not impossible task!\n\nIn order to achieve this, Appium is effectively split into four parts:\n\n<div class=\"grid cards\" markdown>\n\n- :material-image-filter-center-focus-strong: __Appium Core__ - defines the core APIs\n- :material-car: __Drivers__ - implement connectivity to specific platforms\n- :octicons-code-16: __Clients__ - implement Appium's API in specific languages\n- :fontawesome-solid-plug: __Plugins__ - change or extend Appium's core functionality\n\n</div>\n\nTherefore, in order to start automating something with Appium, you need to:","metadata":{"loc":{"lines":{"from":1,"to":24}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/index.md","filename":"index.md","relativePath":"appium/intro/index.md"}},{"pageContent":"</div>\n\nTherefore, in order to start automating something with Appium, you need to:\n\n- Install Appium itself\n- Install a driver for your target platform\n- Install a client library for your target programming language\n- (Optional) install one or more plugins\n\nThese are the basics! If you are ready to jump in, proceed with the [Quickstart](../quickstart/index.md)!\n\nIf you wish to learn more details about how it all works, see these pages for background material:\n\n- [Appium Core](./appium.md)\n- [Appium Drivers](./drivers.md)\n- [Appium Clients](./clients.md)\n\nFinally, to learn about the origins of Appium, check out the [Appium Project History](./history.md).","metadata":{"loc":{"lines":{"from":22,"to":39}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/intro/index.md","filename":"index.md","relativePath":"appium/intro/index.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Quickstart Intro\n---\n\nLet's get up and running with Appium! To successfully use this quickstart, it's recommended that\nyou first have read the [Introduction](../intro/index.md), so that you understand the concepts involved in\nrunning Appium and writing Appium scripts.\n\nThe basic plan for this quickstart is as follows:\n\n1. Install Appium\n1. Install an Appium driver and its dependencies\n - This guide provides instructions for the [UiAutomator2 driver](https://github.com/appium/appium-uiautomator2-driver)\n1. Install an Appium client library in your language of choice\n - This guide contains options for JavaScript, Python, Java, Ruby, and .NET\n1. Write and run a simple Appium automation script using a sample application\n\n### Requirements","metadata":{"loc":{"lines":{"from":1,"to":21}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/index.md","filename":"index.md","relativePath":"appium/quickstart/index.md"}},{"pageContent":"### Requirements\n\nBefore getting started, make sure your system satisfies the\n[requirements](../quickstart/requirements.md) for running the Appium server. Additional requirements\nwill be discussed in conjunction with installing the UiAutomator2 driver. The guide also assumes\nyou have basic command line proficiency on your platform, for example being able to run commands, set\nand persist environment variables, etc...\n\nNow you're ready to get started! So head on over to [Installing Appium](./install.md).","metadata":{"loc":{"lines":{"from":21,"to":29}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/index.md","filename":"index.md","relativePath":"appium/quickstart/index.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Install Appium\n---\n\n!!! info\n\n Before installing, make sure to check the [System Requirements](./requirements.md).\n\nAppium can be installed globally using `npm`:\n\n```bash\nnpm install -g appium\n```\n\n!!! note\n\n Other package managers are not currently supported.\n\n## Starting Appium\n\nAppium can be started [using the command line](../cli/index.md):\n\n```\nappium\n```\n\nThis launches the Appium server process, which loads all the installed Appium drivers, and\nbegins waiting for new session requests from client connections (such as test automation scripts).\nSince the server process is independent from its clients, it must be explicitly launched before\nattempting to start a new session.\n\nWhen the server is launched, the console log will list all the valid URLs that clients can use to\nconnect to this server:","metadata":{"loc":{"lines":{"from":1,"to":36}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/install.md","filename":"install.md","relativePath":"appium/quickstart/install.md"}},{"pageContent":"When the server is launched, the console log will list all the valid URLs that clients can use to\nconnect to this server:\n\n```\n[Appium] You can provide the following URLs in your client code to connect to this server:\n[Appium] \thttp://127.0.0.1:4723/ (only accessible from the same host)\n(... any other URLs ...)\n```\n\nOnce a client requests a new session, the Appium server process will start logging all details about\nthis session until its termination. Keep this in mind - if you ever encounter issues with Appium\ntests, you can always check the server log for more details.\n\nSo what's next? Even though Appium is installed and running, it does not come bundled with any\ndrivers, which means it cannot automate anything yet. We will therefore set up automation for\nAndroid - continue to [Installing the UiAutomator2 Driver](./uiauto2-driver.md).","metadata":{"loc":{"lines":{"from":35,"to":50}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/install.md","filename":"install.md","relativePath":"appium/quickstart/install.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Next Steps\n---\n\nNow that you've successfully set up your system for Android automation and run a simple test,\nyou'll want to continue exploring this documentation. In particular, these are good guides and\nreference materials especially for beginners:\n\n- The [Ecosystem](../ecosystem/index.md) page: browse the available drivers, clients, plugins, and tools\n- [Managing Appium Drivers and Plugins](../guides/managing-exts.md)\n- [Capabilities](../guides/caps.md)\n- [Settings](../guides/settings.md)\n\nYou'll also find that the [Appium Inspector](https://github.com/appium/appium-inspector) is an\nindispensable tool for writing Appium tests, as it enables visual inspection of apps and\nhelps you to discover element locators for use in your test scripts.\n\nYou might also take advantage of one of the many online Appium courses available to you.\n\nGood luck and have fun!","metadata":{"loc":{"lines":{"from":1,"to":23}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/next-steps.md","filename":"next-steps.md","relativePath":"appium/quickstart/next-steps.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: System Requirements\n---\n\nThe basic requirements for the Appium server are:\n\n* A macOS, Linux, or Windows operating system\n* [Node.js](https://nodejs.org) version in the [SemVer](https://semver.org) range `^20.19.0 || ^22.12.0 || >=24.0.0`\n * LTS is recommended\n* [`npm`](https://npmjs.com) version `>=10` (`npm` is usually bundled with Node.js, but can be upgraded\nindependently)\n\nBy itself, Appium is relatively lightweight and doesn't have significant disk space or RAM\nrequirements. It can even be run in resource-constrained environments like Raspberry Pi, so long as\nNode.js is available.\n\n### Driver Requirements","metadata":{"loc":{"lines":{"from":1,"to":20}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/requirements.md","filename":"requirements.md","relativePath":"appium/quickstart/requirements.md"}},{"pageContent":"### Driver Requirements\n\nDrivers for automating specific platforms will likely have other requirements. Refer to the\ndocumentation of the [Appium driver(s)](../ecosystem/drivers.md) for that platform for additional\ndependencies. It is almost universally the case that Appium drivers for a given platform will\nrequire the developer toolchain and SDKs for that platform to be installed.\n\nIn order to assist with driver requirements, each (official) driver comes with the Appium Doctor tool,\nwhich allows to verify if all requirements have been set up. Learn more about how to use this tool in\nthe [Command-Line Usage documentation](../cli/extensions.md#doctor).","metadata":{"loc":{"lines":{"from":20,"to":29}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/requirements.md","filename":"requirements.md","relativePath":"appium/quickstart/requirements.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Write a Test (.NET)\n---\n\nThe [Appium .NET Client](https://github.com/appium/dotnet-client/) is\nan official Appium client in C#. This driver is an extension of the Selenium C# client. It has all the functionalities of the regular driver, but add Appium-specific methods on top of this. The driver is available on the public NuGet Gallery as [Appium.WebDriver](https://www.nuget.org/packages/Appium.WebDriver/).\n\nNow, we get inside the directory and create a new [NUnit](https://nunit.org/) project. We will also add the references to the Appium.Net driver, and other dependencies.\n\n```bash\ncd dotnet-client\ndotnet new nunit --name appiumtest \n\ncd appiumtest\n\n# This will install the latest 5.x version\ndotnet add package Appium.WebDriver --prerelease\ndotnet add package Newtonsoft.Json --version 13.0.3\n```","metadata":{"loc":{"lines":{"from":1,"to":22}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/test-dotnet.md","filename":"test-dotnet.md","relativePath":"appium/quickstart/test-dotnet.md"}},{"pageContent":"cd appiumtest\n\n# This will install the latest 5.x version\ndotnet add package Appium.WebDriver --prerelease\ndotnet add package Newtonsoft.Json --version 13.0.3\n```\n\nOnce this is done, your project should have a placeholder file `UnitTest1.cs`. We will replace the code to include the OpenQA namespaces, an initialization of the driver, and the actual test.\n\n```C# title=\"UnitTest1.cs\"\nusing OpenQA.Selenium;\nusing OpenQA.Selenium.Appium;\nusing OpenQA.Selenium.Appium.Android;\nusing OpenQA.Selenium.Appium.Enums;\n\nnamespace appiumtest;\n\npublic class Tests\n{\n private AndroidDriver _driver;\n\n [OneTimeSetUp]\n public void SetUp()\n {\n var serverUri = new Uri(Environment.GetEnvironmentVariable(\"APPIUM_HOST\") ?? \"http://127.0.0.1:4723/\");\n var driverOptions = new AppiumOptions() {\n AutomationName = AutomationName.AndroidUIAutomator2,\n PlatformName = \"Android\",\n DeviceName = \"Android Emulator\",\n };","metadata":{"loc":{"lines":{"from":17,"to":46}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/test-dotnet.md","filename":"test-dotnet.md","relativePath":"appium/quickstart/test-dotnet.md"}},{"pageContent":"driverOptions.AddAdditionalAppiumOption(\"appPackage\", \"com.android.settings\");\n driverOptions.AddAdditionalAppiumOption(\"appActivity\", \".Settings\");\n // NoReset assumes the app com.google.android is preinstalled on the emulator\n driverOptions.AddAdditionalAppiumOption(\"noReset\", true);\n\n _driver = new AndroidDriver(serverUri, driverOptions, TimeSpan.FromSeconds(180));\n _driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);\n }\n\n [OneTimeTearDown]\n public void TearDown()\n {\n _driver.Dispose();\n }\n\n [Test]\n public void TestBattery()\n {\n _driver.StartActivity(\"com.android.settings\", \".Settings\");\n _driver.FindElement(By.XPath(\"//*[@text='Battery']\")).Click();\n }\n}\n```\n\n!!! note","metadata":{"loc":{"lines":{"from":48,"to":72}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/test-dotnet.md","filename":"test-dotnet.md","relativePath":"appium/quickstart/test-dotnet.md"}},{"pageContent":"!!! note\n\n It's not within the scope of this guide to give a complete run-down on the dotnet client\n library or everything that's happening here, so we'll leave the code itself unexplained in\n detail for now. You may want to read up particularly on Appium\n [Capabilities](../guides/caps.md) in addition to familiarizing yourself with the \n [dotnet client driver documentation](https://github.com/appium/dotnet-client/) for a fuller explanation\n of the various API commands you see and what their purpose is.\n\nBasically, this code is doing the following:\n\n1. Defining a set of \"Capabilities\" (parameters) to send to the Appium server so Appium knows what\nkind of thing you want to automate. Some of these parameters can be overridden using environment variables.\n1. Starting an Appium session on the built-in Android settings app.\n1. Finding the \"Battery\" list item and clicking it.\n1. Ending the Appium session.","metadata":{"loc":{"lines":{"from":72,"to":87}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/test-dotnet.md","filename":"test-dotnet.md","relativePath":"appium/quickstart/test-dotnet.md"}},{"pageContent":"That's it! Let's give it a try. Before you run the test, make sure that you have an Appium server\nrunning in another terminal session, otherwise you'll get an error about not being able to connect\nto one. Then, you can execute the script:\n\n```bash\ndotnet test\n\n# Example output:\n# Starting test execution, please wait...\n# A total of 1 test files matched the specified pattern.\n\n# Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: 323 ms - appiumtest.dll (net7.0)\n```\n\nIf all goes well, you'll see the Settings app open up and navigate to the \"Battery\" view in the emulator before the app closes again.\n\nCongratulations, you've started your Appium journey! Read on for some [next steps](./next-steps.md) to explore.","metadata":{"loc":{"lines":{"from":89,"to":105}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/test-dotnet.md","filename":"test-dotnet.md","relativePath":"appium/quickstart/test-dotnet.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Write a Test (Java)\n---\n\nThe Appium team maintains an official [client](https://github.com/appium/java-client) for the Java programming language.\nIt is built on top of [Selenium](https://github.com/SeleniumHQ/selenium).\nYou can also use this client in your Kotlin projects.\n\nFollow the [Add Appium java client to your test framework](https://github.com/appium/java-client#add-appium-java-client-to-your-test-framework)\ntutorial in order to connect the library to your test framework sources.\n\nThe Appium Java client has dedicated classes to support most of the official Appium drivers. For other drivers\nyou could simply use the [AppiumDriver](https://github.com/appium/java-client/blob/master/src/main/java/io/appium/java_client/AppiumDriver.java) class\nor build your custom derivatives from it. Check the [Drivers Support](https://github.com/appium/java-client#drivers-support)\narticle to learn more about the current driver class implementations.","metadata":{"loc":{"lines":{"from":1,"to":18}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/test-java.md","filename":"test-java.md","relativePath":"appium/quickstart/test-java.md"}},{"pageContent":"Follow the [Usage Examples](https://github.com/appium/java-client#usage-examples) article in order understand\nhow to invoke Java client features from your test framework.\n\nOnce you've managed to successfully run a test, you can read on for some [next steps](./next-steps.md) to explore.","metadata":{"loc":{"lines":{"from":20,"to":23}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/test-java.md","filename":"test-java.md","relativePath":"appium/quickstart/test-java.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Write a Test (JS)\n---\n\nTo write an Appium test in JavaScript (Node.js), we need to choose an Appium-compatible client\nlibrary. The best-maintained library and the one the Appium team recommends using is\n[WebdriverIO](https://webdriver.io), so let's use that. Since we already have Appium installed we\nknow our Node and NPM requirements are already satisfied. So just create a new project directory\nsomewhere on your computer and then initialize a new Node.js project in it:\n\n```bash\nnpm init\n```\n\nIt doesn't really matter what you put in the prompts, just so long as you end up with a valid\n`package.json`.\n\n\nNow, install the `webdriverio` package via NPM:\n\n```bash\nnpm i --save-dev webdriverio\n```\n\nOnce this is done, your `package.json` file should include a section like the following:\n\n```json title=\"package.json\"\n--8<-- \"./sample-code/quickstarts/js/package.json\"\n```","metadata":{"loc":{"lines":{"from":1,"to":32}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/test-js.md","filename":"test-js.md","relativePath":"appium/quickstart/test-js.md"}},{"pageContent":"Once this is done, your `package.json` file should include a section like the following:\n\n```json title=\"package.json\"\n--8<-- \"./sample-code/quickstarts/js/package.json\"\n```\n\nNow it's time to type up the test itself. Create a new file called `test.js` with the following\ncontents:\n\n```js title=\"test.js\"\n--8<-- \"./sample-code/quickstarts/js/test.js\"\n```\n\n!!! note\n\n It's not within the scope of this guide to give a complete run-down on the WebdriverIO client\n library or everything that's happening here, so we'll leave the code itself unexplained in\n detail for now. You may want to read up particularly on Appium\n [Capabilities](../guides/caps.md) in addition to familiarizing yourself with the excellent\n [WebdriverIO documentation](https://webdriver.io/docs/gettingstarted) for a fuller explanation\n of the various API commands you see and what their purpose is.\n\n!!! note","metadata":{"loc":{"lines":{"from":28,"to":50}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/test-js.md","filename":"test-js.md","relativePath":"appium/quickstart/test-js.md"}},{"pageContent":"!!! note\n\n The sample code is available from [GitHub Appium repository](https://github.com/appium/appium/tree/master/packages/appium/sample-code/quickstarts/js).\n\n\nBasically, this code is doing the following:\n\n1. Defining a set of \"Capabilities\" (parameters) to send to the Appium server so Appium knows what\nkind of thing you want to automate.\n1. Starting an Appium session on the built-in Android settings app.\n1. Finding the \"Battery\" list item and clicking it.\n1. Pausing for a moment purely for visual effect.\n1. Ending the Appium session.\n\nThat's it! Let's give it a try. Before you run the test, make sure that you have an Appium server\nrunning in another terminal session, otherwise you'll get an error about not being able to connect\nto one. Then, you can execute the script:\n\n```bash\nnode test.js\n```\n\nIf all goes well, you'll see the Settings app open up and navigate to the \"Battery\" view before the\napp closes again.","metadata":{"loc":{"lines":{"from":50,"to":73}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/test-js.md","filename":"test-js.md","relativePath":"appium/quickstart/test-js.md"}},{"pageContent":"```bash\nnode test.js\n```\n\nIf all goes well, you'll see the Settings app open up and navigate to the \"Battery\" view before the\napp closes again.\n\nCongratulations, you've started your Appium journey! Read on for some [next steps](./next-steps.md) to explore.","metadata":{"loc":{"lines":{"from":68,"to":75}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/test-js.md","filename":"test-js.md","relativePath":"appium/quickstart/test-js.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Write a Test (Python)\n---\n\nThe [Appium Python Client](https://github.com/appium/python-client) is\nan official Appium client in Python, which is available via pypi under the [Appium-Python-Client](https://pypi.org/project/Appium-Python-Client/) package name.\nIt inherits from the [Selenium Python Binding](https://pypi.org/project/selenium/),\nso installing the Appium Python Client includes the selenium binding.\n\n```bash\npip install Appium-Python-Client\n```\n\nThis example uses Python's built-in `unittest` module, though you can use any Python test framework you want.\nThe Appium Python client adds the `appium:` vendor prefix automatically.\nYou usually do not need to worry about the prefix.\n\n```python title=\"test.py\"\n--8<-- \"./sample-code/quickstarts/py/test.py\"\n```\n\n!!! note","metadata":{"loc":{"lines":{"from":1,"to":25}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/test-py.md","filename":"test-py.md","relativePath":"appium/quickstart/test-py.md"}},{"pageContent":"```python title=\"test.py\"\n--8<-- \"./sample-code/quickstarts/py/test.py\"\n```\n\n!!! note\n\n It's not within the scope of this guide to give a complete run-down on the Python client\n library or everything that's happening here, so we'll leave the code itself unexplained in detail for now.\n\n - You may want to read up particularly on Appium [Capabilities](../guides/caps.md).\n - [functional test code](https://github.com/appium/python-client/tree/master/test/functional) in Python Client GitHub repository should help to find more working example.\n - [Documentation](https://appium.github.io/python-client-sphinx/) also helps to find methods\n defined in the Appium Python Client.\n\n!!! note\n\n The sample code is available from [GitHub Appium repository](https://github.com/appium/appium/tree/master/packages/appium/sample-code/quickstarts/py).\n\n\nBasically, this code is doing the following:","metadata":{"loc":{"lines":{"from":21,"to":40}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/test-py.md","filename":"test-py.md","relativePath":"appium/quickstart/test-py.md"}},{"pageContent":"Basically, this code is doing the following:\n\n1. Defining a set of \"Capabilities\" (parameters) to send to the Appium server so Appium knows what\nkind of thing you want to automate.\n1. Starting an Appium session on the built-in Android settings app.\n1. Finding the \"Battery\" list item and clicking it.\n1. Pausing for a moment purely for visual effect.\n1. Ending the Appium session.\n\nThat's it! Let's give it a try. Before you run the test, make sure that you have an Appium server\nrunning in another terminal session, otherwise you'll get an error about not being able to connect\nto one. Then, you can execute the script:\n\n```bash\npython test.py\n```\n\nIf all goes well, you'll see the Settings app open up and navigate to the \"Battery\" view before the\napp closes again.\n\nCongratulations, you've started your Appium journey! Read on for some [next steps](./next-steps.md) to explore.","metadata":{"loc":{"lines":{"from":40,"to":60}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/test-py.md","filename":"test-py.md","relativePath":"appium/quickstart/test-py.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Write a Test (Ruby)\n---\n\n\nThe [AppiumLib](https://github.com/appium/ruby_lib) and the [AppiumLibCore](https://github.com/appium/ruby_lib_core) (**recommended**) are official Appium client libraries in Ruby, which are available via gem under the [appium_lib](https://rubygems.org/gems/appium_lib) and the [appium_lib_core](https://rubygems.org/gems/appium_lib_core) package names. The appium_lib_core inherits from the Selenium Ruby Binding, and the appium_lib inherits from the appium_lib_core, so installing these libraries include the selenium binding. We recommend `appium_lib_core` if you need a less complex client-side solution. The `appium_lib` has some useful methods the core does not have, but for the cost of greater complexity and historical methods which may not work in the latest environment.\n\nAs the first step, let's initialize a Gemfile to manage the dependency:\n\n```bash\nbundle init\n```\n\nThen, you could add Appium Ruby Client dependency as below:","metadata":{"loc":{"lines":{"from":1,"to":17}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/test-rb.md","filename":"test-rb.md","relativePath":"appium/quickstart/test-rb.md"}},{"pageContent":"As the first step, let's initialize a Gemfile to manage the dependency:\n\n```bash\nbundle init\n```\n\nThen, you could add Appium Ruby Client dependency as below:\n\n```bash\nbundle add appium_lib_core\n# or\n# bundle add appium_lib\n```\n\nTest code example below uses `test-unit` module, thus please run:\n\n```bash\nbundle add test-unit\n```\n\nOnce these steps has done, your `Gemfile` file should include:\n\n```ruby title=\"Gemfile\"\n--8<-- \"./sample-code/quickstarts/rb/Gemfile\"\n```\n\nThe `appium_lib_core` is the main part as an Appium client.\n`appium_lib` has various helper methods, but the driver instance was ordinary designed to be used as a global variable. It could causes an issue to handle the instance.\n`appium_lib_core` does not have such a global variable.\n\nThis example is by the `appium_lib_core` with `test-unit` gem module.\nTes code in `appium_lib` should be similar.\n\n```ruby title=\"test.rb\"\n--8<-- \"./sample-code/quickstarts/rb/test.rb\"\n```\n\n!!! note","metadata":{"loc":{"lines":{"from":11,"to":48}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/test-rb.md","filename":"test-rb.md","relativePath":"appium/quickstart/test-rb.md"}},{"pageContent":"This example is by the `appium_lib_core` with `test-unit` gem module.\nTes code in `appium_lib` should be similar.\n\n```ruby title=\"test.rb\"\n--8<-- \"./sample-code/quickstarts/rb/test.rb\"\n```\n\n!!! note\n\n It's not within the scope of this guide to give a complete run-down on the Ruby client\n library or everything that's happening here, so we'll leave the code itself unexplained in detail for now.\n\n - You may want to read up particularly on Appium [Capabilities](../guides/caps.md).\n - [functional test code](https://github.com/appium/ruby_lib_core/tree/master/test/functional) in the appium_lib_core GitHub repository should help to find more working example.\n - Documentation [appium_lib_core](https://www.rubydoc.info/github/appium/ruby_lib_core) and [appium_lib](https://www.rubydoc.info/github/appium/ruby_lib) also helps to find available methods.\n\n!!! note","metadata":{"loc":{"lines":{"from":41,"to":57}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/test-rb.md","filename":"test-rb.md","relativePath":"appium/quickstart/test-rb.md"}},{"pageContent":"!!! note\n\n The sample code is available from [GitHub Appium repository](https://github.com/appium/appium/tree/master/packages/appium/sample-code/quickstarts/rb).\n\n\nBasically, this code is doing the following:\n\n1. Defining a set of \"Capabilities\" (parameters) to send to the Appium server so Appium knows what\nkind of thing you want to automate.\n1. Starting an Appium session on the built-in Android settings app.\n1. Finding the \"Battery\" list item and clicking it.\n1. Pausing for a moment purely for visual effect.\n1. Ending the Appium session.\n\nThat's it! Let's give it a try. Before you run the test, make sure that you have an Appium server\nrunning in another terminal session, otherwise you'll get an error about not being able to connect\nto one. Then, you can execute the script:\n\n```bash\n# Please run \"bundle install\" first if your environment has not run the installation command yet.\nbundle exec ruby test.rb\n```","metadata":{"loc":{"lines":{"from":57,"to":78}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/test-rb.md","filename":"test-rb.md","relativePath":"appium/quickstart/test-rb.md"}},{"pageContent":"```bash\n# Please run \"bundle install\" first if your environment has not run the installation command yet.\nbundle exec ruby test.rb\n```\n\nIf all goes well, you'll see the Settings app open up and navigate to the \"Battery\" view before the\napp closes again.\n\nCongratulations, you've started your Appium journey! Read on for some [next steps](./next-steps.md) to explore.","metadata":{"loc":{"lines":{"from":75,"to":83}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/test-rb.md","filename":"test-rb.md","relativePath":"appium/quickstart/test-rb.md"}},{"pageContent":"---\ntitle: Install the UiAutomator2 Driver\n---\n\nYou can't do much with Appium unless you have a [driver](../intro/drivers.md), which is an\ninterface that allows Appium to automate a particular platform.\n\n!!! info\n\n For this quickstart guide, we're going to be automating an app on the Android platform, because\n the system requirements for Android automation via Appium are the same as for Appium itself\n (whereas the iOS driver, for example, requires you to be using macOS).\n\nThe driver we're going to use is called the [UiAutomator2\nDriver](https://github.com/appium/appium-uiautomator2-driver). It's worth visiting that driver's\ndocumentation and bookmarking it, because it will be an invaluable reference down the line.\n\n## Set up Android automation requirements\n\nAccording to the driver, in addition to a working Appium server, we also need to set up the following:\n\n### Android SDK","metadata":{"loc":{"lines":{"from":1,"to":22}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/uiauto2-driver.md","filename":"uiauto2-driver.md","relativePath":"appium/quickstart/uiauto2-driver.md"}},{"pageContent":"### Android SDK\n\n- The easiest way to set up the Android SDK requirements is by downloading [Android Studio](https://developer.android.com/studio).\nWe need to use its SDK manager (_Settings -> Languages & Frameworks -> Android SDK_)\nto download the following items:\n - Android SDK Platform (select whichever Android platform we want to automate, for example, API level 30)\n - Android SDK Platform-Tools\n- If you wish, you can also download these items without Android Studio:\n - Android SDK Platform can be downloaded using `sdkmanager` included in [Android command-line tools](https://developer.android.com/studio#command-line-tools-only)\n - [Android SDK Platform-Tools](https://developer.android.com/tools/releases/platform-tools)\n- Set up the `ANDROID_HOME` environment variable to point to the directory where the Android SDK is\ninstalled. You can usually find the path to this directory in the Android Studio SDK manager. It\nwill contain the `platform-tools` and other directories.","metadata":{"loc":{"lines":{"from":22,"to":34}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/uiauto2-driver.md","filename":"uiauto2-driver.md","relativePath":"appium/quickstart/uiauto2-driver.md"}},{"pageContent":"### Java JDK\n\n- Install the Java JDK (for the most recent Android API levels, JDK 9 is required, otherwise JDK\n8 is required). You can download this from [Oracle](https://jdk.java.net/) or [Adoptium](https://adoptium.net/en-GB/temurin/releases/).\nMake sure you get the JDK and not the JRE.\n- Set up the `JAVA_HOME` environment variable to point to the JDK home directory. It will contain\nthe `bin`, `include`, and other directories.\n\n### Prepare the Device","metadata":{"loc":{"lines":{"from":36,"to":44}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/uiauto2-driver.md","filename":"uiauto2-driver.md","relativePath":"appium/quickstart/uiauto2-driver.md"}},{"pageContent":"### Prepare the Device\n\n- If using an emulator, use Android Studio to create and launch an Android Virtual Device (AVD).\nYou may need to download the system images for the API level of the emulator you want to\ncreate. Using the AVD creation wizard in Android Studio is generally the easiest way to do all of\nthis.\n- If using a real device, you should [set it up for development and enable USB Debugging](https://developer.android.com/studio/debug/dev-options).\n- With the emulator or device connected, you can run `adb devices` (via the binary located at\n`$ANDROID_HOME/platform-tools/adb`) to verify that your device shows up as connected.\n\nOnce your device shows up as connected in `adb`, and you've verified that the environment variables\nare set up correctly, you should be good to go! If you ran into problems with any of these steps,\nrefer to the driver documentation, or the various Android or Java documentation sites as necessary.","metadata":{"loc":{"lines":{"from":44,"to":56}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/uiauto2-driver.md","filename":"uiauto2-driver.md","relativePath":"appium/quickstart/uiauto2-driver.md"}},{"pageContent":"Also, congratulations: whether or not you intended to, you now have the Android developer toolchain\nset up on your system, so you can get busy making Android apps if you want!\n\n## Install the driver itself\n\n### Standard Install\n\nLike all Appium drivers, the UiAutomator2 driver is installed via the [Appium Extension CLI](../cli/extensions.md).\nSince UiAutomator2 is maintained by the core Appium team, it has an 'official' driver name\n(`uiautomator2`), which makes the installation simpler.\n\nBefore installing, make sure your Appium server is _not_ running (if it is, quit it with _Ctrl-C_).\nThen run the following command:\n\n```bash\nappium driver install uiautomator2\n```\n\nIt should produce output that looks something like:\n\n```\nAttempting to find and install driver 'uiautomator2'\n✔ Installing 'uiautomator2' using NPM install spec 'appium-uiautomator2-driver'\nDriver uiautomator2@2.0.5 successfully installed\n- automationName: UiAutomator2\n- platformNames: [\"Android\"]\n```","metadata":{"loc":{"lines":{"from":58,"to":84}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/uiauto2-driver.md","filename":"uiauto2-driver.md","relativePath":"appium/quickstart/uiauto2-driver.md"}},{"pageContent":"Note how the installation process specifies what platforms is the driver valid for (in this case,\n`Android`), and what automation name (the `appium:automationName` [capability](../guides/caps.md))\nmust be used to select this driver for use during an Appium session (in this case, `UiAutomator2`).\n\n!!! note\n\n In this quickstart we have used the [Extension CLI](../cli/extensions.md) to install the\n UiAutomator2 driver, but if you are incorporating Appium into a Node.js project, you might\n prefer to use `npm` to manage Appium and its connected drivers. To learn more about this\n technique, visit the guide on [managing Appium extensions](../guides/managing-exts.md).\n\n### Batch Install\n\nYou may want to use Appium with more than one driver. One way to accomplish this is to run\n`appium driver install <driver-name>` for each individual driver, but you can also install multiple\ndrivers in one go:\n\n```\nappium setup\n```","metadata":{"loc":{"lines":{"from":86,"to":105}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/uiauto2-driver.md","filename":"uiauto2-driver.md","relativePath":"appium/quickstart/uiauto2-driver.md"}},{"pageContent":"```\nappium setup\n```\n\nRunning this will install Appium's mobile-specific drivers: UiAutomator2, [XCUITest](https://appium.github.io/appium-xcuitest-driver/)\n(only if running macOS), and [Espresso](https://github.com/appium/appium-espresso-driver).\n\nYou can also use this command to batch install drivers for desktop applications or desktop browsers.\nFor more details on this, refer to the [Setup command documentation](../cli/setup.md).\n\n### Validating the Install\n\nThe UiAutomator2 driver, like all official Appium drivers, comes with the Appium Doctor tool, which\nallows validating whether all prerequisites have been set up correctly:\n\n```\nappium driver doctor uiautomator2\n```\n\nThis guide has focused on essential requirements, so Appium Doctor may suggest one or more optional\nfixes. But if you see `0 required fixes needed`, that means everything is set up!\n\nNow, start the Appium server again (run `appium`), and you should see that the newly-installed\ndriver is listed as available:","metadata":{"loc":{"lines":{"from":103,"to":126}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/uiauto2-driver.md","filename":"uiauto2-driver.md","relativePath":"appium/quickstart/uiauto2-driver.md"}},{"pageContent":"Now, start the Appium server again (run `appium`), and you should see that the newly-installed\ndriver is listed as available:\n\n```\n[Appium] Available drivers:\n[Appium] - uiautomator2@2.0.5 (automationName 'UiAutomator2')\n```\n\nWith the Android setup complete and the UiAutomator2 driver installed, you're ready to write your\nfirst test! Now select your preferred language and give it a shot:\n\n<div class=\"grid cards\" markdown>\n\n- :material-language-javascript: [__JavaScript__](./test-js.md)\n- :material-language-java: [__Java__](./test-java.md)\n- :material-language-python: [__Python__](./test-py.md)\n- :material-language-ruby: [__Ruby__](./test-rb.md)\n- :material-dot-net: [__.NET C#__](./test-dotnet.md)\n\n</div>","metadata":{"loc":{"lines":{"from":125,"to":144}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/quickstart/uiauto2-driver.md","filename":"uiauto2-driver.md","relativePath":"appium/quickstart/uiauto2-driver.md"}},{"pageContent":"---\nhide:\n - navigation\n - toc\n\ntitle: Additional Resources\n---\n\nHere you can find links to additional Appium resources around the web:\n\n## Websites\n\n- [Appium Pro](https://appiumpro.com) - a blog and newsletter written by one of Appium's\nmaintainers, Jonathan Lipps, with lots of useful guides\n\n## Online Courses\n\n- [Appium and Selenium Fundamentals](https://ui.headspin.io/university/learn/appium-selenium-fundamentals-2020) - a comprehensive video course on learning Python, Selenium, and Appium by Jonathan Lipps\n- [Mobile Test Automation with Appium](https://testautomationu.applitools.com/appium-java-tutorial/) - a video course by Moataz Nabil\n- [Advanced Appium](https://www.linkedin.com/learning/advanced-appium) - a video course by Jonathan Lipps","metadata":{"loc":{"lines":{"from":1,"to":20}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium/resources.md","filename":"resources.md","relativePath":"appium/resources.md"}},{"pageContent":"# Appium UiAutomator2 Driver\n\n[![NPM version](http://img.shields.io/npm/v/appium-uiautomator2-driver.svg)](https://npmjs.org/package/appium-uiautomator2-driver)\n[![Downloads](http://img.shields.io/npm/dm/appium-uiautomator2-driver.svg)](https://npmjs.org/package/appium-uiautomator2-driver)\n\n[![Release](https://github.com/appium/appium-uiautomator2-driver/actions/workflows/publish.js.yml/badge.svg)](https://github.com/appium/appium-uiautomator2-driver/actions/workflows/publish.js.yml)\n\n\nAppium UiAutomator2 Driver is a test automation framework for Android devices. Appium UiAutomator2 Driver automates native, hybrid and mobile web apps, tested on emulators and real devices. Appium UiAutomator2 Driver is part of the [Appium](https://github.com/appium/appium) mobile test automation tool. The driver operates in scope of [W3C WebDriver protocol](https://www.w3.org/TR/webdriver/) with several custom extensions to cover operating-system specific scenarios.","metadata":{"loc":{"lines":{"from":1,"to":9}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"UiAutomator2 Driver proxies most of the commands to [UiAutomator2 server](https://github.com/appium/appium-uiautomator2-server), which uses Google's [UiAutomator](https://developer.android.com/training/testing/ui-automator) framework under the hood. Some commands are proxied directly to [appium-adb](https://github.com/appium/appium-adb) and other helpers built on top of Android platform tools.\n\n> [!Note]\n>\n> Since version 2.0.0 UiAutomator2 driver has dropped the support of Appium 1, and is only compatible to Appium 2.\n> Use the `appium driver install uiautomator2` command to add it to your Appium 2 dist.\n\n\n## Requirements\n\nOn top of standard Appium requirements UiAutomator2 driver also expects the following prerequisites:","metadata":{"loc":{"lines":{"from":11,"to":21}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"- Windows, Linux and macOS are supported as hosts\n- [Android SDK Platform tools](https://developer.android.com/studio/releases/platform-tools) must be installed. [Android Studio IDE](https://developer.android.com/studio) also provides a convenient UI to install and manage the tools.\n- ANDROID_HOME or ANDROID_SDK_ROOT [environment variable](https://developer.android.com/studio/command-line/variables) must be set\n- Java JDK must be installed and [JAVA_HOME](https://www.baeldung.com/java-home-on-windows-7-8-10-mac-os-x-linux) environment variable must be set. Android SDK below API 30 requires Java 8. Android SDK 30 and above requires Java 9 or newer.\n- [Emulator](https://developer.android.com/studio/run/managing-avds) platform image must be installed if you plan to run your tests on it. [Android Studio IDE](https://developer.android.com/studio) also provides a convenient UI to install and manage emulators.","metadata":{"loc":{"lines":{"from":23,"to":27}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"- Real Android devices must have [USB debugging enabled](https://developer.android.com/studio/debug/dev-options) and should be visible as `online` in `adb devices -l` output.\n- The minimum version of Android API must be 5.0 (API level 21) (6.0 is recommended as version 5 has some known compatibility issues).","metadata":{"loc":{"lines":{"from":28,"to":29}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### Doctor\n\nSince driver version 2.39.0 you can automate the validation for the most of the above\nrequirements as well as various optional ones needed by driver extensions by running the\n`appium driver doctor uiautomator2` server command.\n\n## Capabilities\n\n### General","metadata":{"loc":{"lines":{"from":31,"to":39}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Capability Name | Description\n--- | ---\nplatformName | Could be set to `android`. Appium itself is not strict about this capability value if `automationName` is provided, so feel free to assign it to any supported platform name if this is needed, for example, to make Selenium Grid working.\nappium:automationName | Must always be set to `uiautomator2`. Values of `automationName` are compared case-insensitively.\nappium:deviceName | The name of the device under test (actually, it is not used to select a device under test). Consider setting `udid` for real devices and `avd` for emulators instead\nappium:platformVersion | The platform version of an emulator or a real device. This capability is used for device autodetection if `udid` is not provided\nappium:udid | UDID of the device to be tested. Could be retrieved from `adb devices -l` output. If unset then the driver will try to use the first connected device. Always set this capability if you run parallel tests.","metadata":{"loc":{"lines":{"from":41,"to":47}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:noReset | Prevents the device to be reset before the session startup if set to `true`. This means that the application under test is not going to be terminated neither its data cleaned. `false` by default\nappium:fullReset | Being set to `true` always enforces the application under test to be fully uninstalled before starting a new session. `false` by default\nappium:printPageSourceOnFindFailure | Enforces the server to dump the actual XML page source into the log if any error happens. `false` by default.","metadata":{"loc":{"lines":{"from":48,"to":50}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### Driver/Server","metadata":{"loc":{"lines":{"from":52,"to":52}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Capability Name | Description\n--- | ---\nappium:systemPort | The number of the port on the host machine used for the UiAutomator2 server. By default the first free port from 8200..8299 range is selected. It is recommended to set this value if you are running [parallel tests](#parallel-tests) on the same machine.\nappium:skipServerInstallation | Skip the UiAutomator2 Server component installation on the device under test and all the related checks if set to `true`. This could help to speed up the session startup if you know for sure the correct server version is installed on the device. In case the server is not installed or an incorrect version of it is installed then you may get an unexpected error later. `false` by default\nappium:uiautomator2ServerLaunchTimeout | The maximum number of milliseconds to wait util UiAutomator2Server is listening on the device. `30000` ms by default","metadata":{"loc":{"lines":{"from":54,"to":58}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:uiautomator2ServerLaunchTimeout | The maximum number of milliseconds to wait util UiAutomator2Server is listening on the device. `30000` ms by default\nappium:uiautomator2ServerInstallTimeout | The maximum number of milliseconds to wait util UiAutomator2Server is installed on the device. `20000` ms by default\nappium:uiautomator2ServerReadTimeout | The maximum number of milliseconds to wait for a HTTP response from UiAutomator2Server. Only values greater than zero are accepted. If the given value is too low then expect driver commands to fail with `timeout of Xms exceeded` error. `240000` ms by default\nappium:disableWindowAnimation | Whether to disable window animations when starting the instrumentation process. The animation scale will be restored automatically after the instrumentation process ends for API level 26 and higher. The animation scale could remain if the session ends unexpectedly for API level 25 and lower. `false` by default","metadata":{"loc":{"lines":{"from":58,"to":61}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:skipDeviceInitialization | If set to `true` then device startup checks (whether it is ready and whether Settings app is installed) will be canceled on session creation. Could speed up the session creation if you know what you are doing. `false` by default","metadata":{"loc":{"lines":{"from":62,"to":62}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### App","metadata":{"loc":{"lines":{"from":64,"to":64}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Capability Name | Description\n--- | ---\nappium:app | Full path to the application to be tested (the app must be located on the same machine where the server is running). Both `.apk` and `.apks` application extensions are supported. Could also be an URL to a remote location. If neither of the `app`, `appPackage` or `browserName` capabilities are provided then the driver starts from the Dashboard and expects the test knows what to do next. Do not provide both `app` and `browserName` capabilities at once.\nbrowserName | The name of the browser to run the test on. If this capability is provided then the driver will try to start the test in Web context mode (Native mode is applied by default). Read [Automating hybrid apps](#hybrid-mode) for more details. Usually equals to `chrome`.","metadata":{"loc":{"lines":{"from":66,"to":69}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:appPackage | Application package identifier to be started. If not provided then UiAutomator2 will try to detect it automatically from the package provided by the `app` capability. Read [How To Troubleshoot Activities Startup](docs/activity-startup.md) for more details\nappium:appActivity | Main application activity identifier. If not provided then UiAutomator2 will try to detect it automatically from the package provided by the `app` capability. Read [How To Troubleshoot Activities Startup](docs/activity-startup.md) for more details\nappium:appWaitActivity | Identifier of the first activity that the application invokes. If not provided then equals to `appium:appActivity`. Read [How To Troubleshoot Activities Startup](docs/activity-startup.md) for more details\nappium:appWaitPackage | Identifier of the first package that is invoked first. If not provided then equals to `appium:appPackage`. Read [How To Troubleshoot Activities Startup](docs/activity-startup.md) for more details","metadata":{"loc":{"lines":{"from":70,"to":73}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:appWaitDuration | Maximum amount of milliseconds to wait until the application under test is started (e. g. an activity returns the control to the caller). `20000` ms by default. Read [How To Troubleshoot Activities Startup](docs/activity-startup.md) for more details\nappium:androidInstallTimeout | Maximum amount of milliseconds to wait until the application under test is installed. `90000` ms by default\nappium:appWaitForLaunch | Whether to block until the app under test returns the control to the caller after its activity has been started by Activity Manager (`true`, the default value) or to continue the test without waiting for that (`false`).\nappium:intentCategory | Set an optional intent category to be applied when starting the given appActivity by [Activity Manager](https://developer.android.com/studio/command-line/adb#am). Defaults to `android.intent.category.LAUNCHER`. Please use [mobile:startActivity](#mobile-startactivity) in case you don't set an explicit value.","metadata":{"loc":{"lines":{"from":74,"to":77}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:intentAction | Set an optional intent action to be applied when starting the given appActivity by [Activity Manager](https://developer.android.com/studio/command-line/adb#am). Dfaults to `android.intent.action.MAIN`. Please use [mobile:startActivity](#mobile-startactivity) in case you don't set an explicit value.\nappium:intentFlags | Set an optional intent flags to be applied when starting the given appActivity by [Activity Manager](https://developer.android.com/studio/command-line/adb#am). Defaults to `0x10200000` (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flags). Please use [mobile:startActivity](#mobile-startactivity) in case you don't set an explicit value.\nappium:optionalIntentArguments | Set an optional intent arguments to be applied when starting the given appActivity by [Activity Manager](https://developer.android.com/studio/command-line/adb#am)","metadata":{"loc":{"lines":{"from":78,"to":80}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:optionalIntentArguments | Set an optional intent arguments to be applied when starting the given appActivity by [Activity Manager](https://developer.android.com/studio/command-line/adb#am)\nappium:dontStopAppOnReset | Set it to `true` if you don't want the application to be restarted if it was already running. If `appium:noReset` is falsy, then the app under test is going to be restarted if either this capability is falsy (the default behavior) or `appium:forceAppLaunch` is set to `true`. `false` by default\nappium:forceAppLaunch | Set it to `true` if you want the application under test to be always forcefully restarted on session startup even if `appium:noReset` is `true`, and the app was already running. If `noReset` is falsy, then the app under test is going to be restarted if either this capability set to `true` or `appium:dontStopAppOnReset` is falsy (the default behavior). `false` by default. Available since driver version 2.12","metadata":{"loc":{"lines":{"from":80,"to":82}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:shouldTerminateApp | Set it to `true` if you want the application under test to be always terminated on session end even if `appium:noReset` is `true`. If `noReset` is falsy, then the app under test is going to be terminated if `appium:dontStopAppOnReset` is also falsy (the default behavior). `false` by default\nappium:autoLaunch | Whether to launch the application under test automatically (`true`, the default value) after a test starts","metadata":{"loc":{"lines":{"from":83,"to":84}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:autoLaunch | Whether to launch the application under test automatically (`true`, the default value) after a test starts\nappium:autoGrantPermissions | Whether to grant all the requested application permissions automatically when a test starts(`true`). The targetSdkVersion in the application manifest must be greater or equal to 23 and the Android version on the device under test must be greater or equal to Android 6 (API level 23) to grant permissions. Applications whose targetSdkVersion is lower than or equal to 22 must be reinstalled to grant permissions, for example, by setting the `appium:fullReset` capability as `true` for Android 6+ devices. If your app needs some special security permissions, like access to notifications or media recording, consider using [mobile: changePermissions](#mobile-changepermissions) extension with `appops` target. `false` by default","metadata":{"loc":{"lines":{"from":84,"to":85}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:otherApps | Allows to set one or more comma-separated paths to Android packages that are going to be installed along with the main application under test. This might be useful if the tested app has dependencies\nappium:uninstallOtherPackages | Allows to set one or more comma-separated package identifiers to be uninstalled from the device before a test starts\nappium:allowTestPackages | If set to `true` then it would be possible to use packages built with the test flag for the automated testing (literally adds `-t` flag to the `adb install` command). `false` by default\nappium:remoteAppsCacheLimit | Sets the maximum amount of application packages to be cached on the device under test. This is needed for devices that don't support streamed installs (Android 7 and below), because ADB must push app packages to the device first in order to install them, which takes some time. Setting this capability to zero disables apps caching. `10` by default.","metadata":{"loc":{"lines":{"from":86,"to":89}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:enforceAppInstall | If set to `true` then the application under test is always reinstalled even if a newer version of it already exists on the device under test. This capability has no effect if `appium:noReset` is set to `true`. `false` by default","metadata":{"loc":{"lines":{"from":90,"to":90}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### App Localization","metadata":{"loc":{"lines":{"from":92,"to":92}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Capability Name | Description\n--- | ---\nappium:localeScript | Canonical name of the locale to be set for the app under test, for example `Hans` in `zh-Hans-CN`. See https://developer.android.com/reference/java/util/Locale.html for more details.\nappium:language | Name of the language to extract application strings for. Strings are extracted for the current system language by default. Also sets the language for the app under test. See https://developer.android.com/reference/java/util/Locale.html for more details. If `language` is provided then `locale` is also required to be set. The combination of both capability values must be a known locale and should be present in the list of available locales returned by the ICU's [getAvailableULocales()](https://unicode-org.github.io/icu/userguide/locale/#usage-retrieving-locales) method. The full list of supported locales is also dumped into the logcat output on failure. Example: `en`, `ja`","metadata":{"loc":{"lines":{"from":94,"to":97}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:locale | Sets the locale for the app under test. See https://developer.android.com/reference/java/util/Locale.html for more details. If `locale` is provided then `language` is also required to be set. The combination of both capability values must be a known locale and should be present in the list of available locales returned by the ICU's [getAvailableULocales()](https://unicode-org.github.io/icu/userguide/locale/#usage-retrieving-locales) method. The full list of supported locales is also dumped into the logcat output on failure. Example: `US`, `JP`","metadata":{"loc":{"lines":{"from":98,"to":98}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### ADB","metadata":{"loc":{"lines":{"from":100,"to":100}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Capability Name | Description\n--- | ---\nappium:adbPort | Number of the port on the host machine where ADB is running. `5037` by default\nappium:remoteAdbHost | Address of the host where ADB is running (the value of `-H` ADB command line option). Unset by default\nappium:adbExecTimeout | Maximum number of milliseconds to wait until single ADB command is executed. `20000` ms by default\nappium:clearDeviceLogsOnStart | If set to `true` then UiAutomator2 deletes all the existing logs in the device buffer before starting a new test\nappium:buildToolsVersion | The version of Android build tools to use. By default UiAutomator2 driver uses the most recent version of build tools installed on the machine, but sometimes it might be necessary to give it a hint (let say if there is a known bug in the most recent tools version). Example: `28.0.3`\nappium:skipLogcatCapture | Being set to `true` disables automatic logcat output collection during the test run. `false` by default","metadata":{"loc":{"lines":{"from":102,"to":109}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:skipLogcatCapture | Being set to `true` disables automatic logcat output collection during the test run. `false` by default\nappium:suppressKillServer | Being set to `true` prevents the driver from ever killing the ADB server explicitly. Could be useful if ADB is connected wirelessly. `false` by default\nappium:ignoreHiddenApiPolicyError | Being set to `true` ignores a failure while changing hidden API access policies to [enable access to non-SDK interfaces](https://developer.android.com/guide/app-compatibility/restrictions-non-sdk-interfaces#how_can_i_enable_access_to_non-sdk_interfaces). Could be useful on some devices, where access to these policies has been locked by its vendor. `false` by default.","metadata":{"loc":{"lines":{"from":109,"to":111}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:hideKeyboard | Being set to `true` hides the on-screen keyboard while the session is running. Use it instead of the legacy `appium:unicodeKeyboard` one (which will be dropped in the future). This effect is achieved by assigning a custom \"artificial\" [input method](https://developer.android.com/develop/ui/views/touch-and-input/creating-input-method). Only use this feature for special/exploratory cases as it violates the way your application under test is normally interacted with by a human. Setting this capability explicitly to `false` enforces `adb shell ime reset` call on session startup, which resets the currently selected/enabled IMEs to the default ones as if the device is initially booted with the current locale. `undefined` by default.","metadata":{"loc":{"lines":{"from":112,"to":112}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:mockLocationApp | Sets the package identifier of the app, which is used as a system mock location provider since Appium 1.18.0+. This capability has no effect on emulators. If the value is set to `null` or an empty string, then the driver will reset the mocked location provider, e.g. the location won't be mocked anymore. Defaults to Appium Setting package identifier (`io.appium.settings`). Termination of a mock location provider application resets the mocked location data.\nappium:logcatFormat | The log print format, where `format` is one of: `brief` `process` `tag` `thread` `raw` `time` `threadtime` `long`. `threadtime` is the default value.","metadata":{"loc":{"lines":{"from":113,"to":114}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:logcatFormat | The log print format, where `format` is one of: `brief` `process` `tag` `thread` `raw` `time` `threadtime` `long`. `threadtime` is the default value.\nappium:logcatFilterSpecs | Series of `tag[:priority]` where `tag` is a log component tag (or * for all) and priority is: `V Verbose`, `D Debug`, `I Info`, `W Warn`, `E Error`, `F Fatal`, `S Silent (supress all output)`. '*' means '*:d' and `tag` by itself means `tag:v`. If not specified on the commandline, filterspec is set from ANDROID_LOG_TAGS. If no filterspec is found, filter defaults to '*:I'.\nappium:allowDelayAdb | Being set to `false` prevents emulator to use `-delay-adb` feature to detect its startup. See https://github.com/appium/appium/issues/14773 for more details.","metadata":{"loc":{"lines":{"from":114,"to":116}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### Emulator (Android Virtual Device)","metadata":{"loc":{"lines":{"from":118,"to":118}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Capability Name | Description\n--- | ---\nappium:avd | The name of Android emulator to run the test on. The names of currently installed emulators could be listed using `avdmanager list avd` command. If the emulator with the given name is not running then it is going to be launched on automated session startup.\nappium:avdLaunchTimeout | Maximum number of milliseconds to wait until Android Emulator is started. `60000` ms by default\nappium:avdReadyTimeout | Maximum number of milliseconds to wait until Android Emulator is fully booted and is ready for usage. `60000` ms by default\nappium:avdArgs | Either a string or an array of emulator [command line arguments](https://developer.android.com/studio/run/emulator-commandline). If arguments contain the `-wipe-data` one then the emulator is going to be killed on automated session startup in order to wipe its data.\nappium:avdEnv | Mapping of emulator [environment variables](https://developer.android.com/studio/command-line/variables).","metadata":{"loc":{"lines":{"from":120,"to":126}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:avdEnv | Mapping of emulator [environment variables](https://developer.android.com/studio/command-line/variables).\nappium:networkSpeed | Sets the desired network speed limit for the emulator. It is only applied if the emulator is not running before the test starts. See emulator [command line arguments](https://developer.android.com/studio/run/emulator-commandline) description for more details.\nappium:gpsEnabled | Sets whether to enable (`true`) or disable (`false`) GPS service in the Emulator. Unset by default, which means to not change the current value\nappium:isHeadless | If set to `true` then emulator starts in headless mode (e.g. no UI is shown). It is only applied if the emulator is not running before the test starts. `false` by default.","metadata":{"loc":{"lines":{"from":126,"to":129}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:injectedImageProperties | Allows adjusting of injected image properties, like size, position or rotation. The image itself is expected to be injected by [mobile: injectEmulatorCameraImage](#mobile-injectemulatorcameraimage) extension. It is also mandatory to provide this capability if you are going to use the injection feature on a newly created/resetted emulator as it __enforces emulator restart__, so it could properly reload the modified image properties. The value itself is a map, where possible keys are `size`, `position` and `rotation`. All of them are optional. If any of values is not provided then the following defaults are used: `{size: {scaleX: 1, scaleY: 1}, position: {x: 0, y: 0, z: -1.5}, rotation: {x: 0, y: 0, z: 0}}`. The `size` value contains scale multipliers for X and Y axes. The `position` contains normalized coefficients for X/Y/Z axes, where `0` means it should be centered in the viewport. Values in the `rotation` are measured in degrees respectively for X,","metadata":{"loc":{"lines":{"from":130,"to":130}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"and Y axes. The `position` contains normalized coefficients for X/Y/Z axes, where `0` means it should be centered in the viewport. Values in the `rotation` are measured in degrees respectively for X, Y and Z axis. The capability is available since the driver version 3.6.0.","metadata":{"loc":{"lines":{"from":130,"to":130}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### App Signing","metadata":{"loc":{"lines":{"from":132,"to":132}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Capability Name | Description\n--- | ---\nappium:useKeystore | Whether to use a custom keystore to sign the app under test. `false` by default, which means apps are always signed with the default Appium debug certificate (unless canceled by `noSign` capability). This capability is used in combination with `keystorePath`, `keystorePassword`, `keyAlias` and `keyPassword` capabilities.\nappium:keystorePath | The full path to the keystore file on the server filesystem. This capability is used in combination with `useKeystore`, `keystorePath`, `keystorePassword`, `keyAlias` and `keyPassword` capabilities. Unset by default\nappium:keystorePassword | The password to the keystore file provided in `keystorePath` capability. This capability is used in combination with `useKeystore`, `keystorePath`, `keystorePassword`, `keyAlias` and `keyPassword` capabilities. Unset by default","metadata":{"loc":{"lines":{"from":134,"to":138}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:keyAlias | The alias of the key in the keystore file provided in `keystorePath` capability. This capability is used in combination with `useKeystore`, `keystorePath`, `keystorePassword`, `keyAlias` and `keyPassword` capabilities. Unset by default\nappium:keyPassword | The password of the key in the keystore file provided in `keystorePath` capability. This capability is used in combination with `useKeystore`, `keystorePath`, `keystorePassword`, `keyAlias` and `keyPassword` capabilities. Unset by default\nappium:noSign | Set it to `true` in order to skip application signing. By default all apps are always signed with the default Appium debug signature if they don't have any. This capability cancels all the signing checks and makes the driver to use the application package as is. This capability does not affect `.apks` packages as these are expected to be already signed.","metadata":{"loc":{"lines":{"from":139,"to":141}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### Device Locking","metadata":{"loc":{"lines":{"from":143,"to":143}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Capability Name | Description\n--- | ---\nappium:skipUnlock | Whether to skip the check for lock screen presence (`true`). The default driver behaviour is to verify the presence of the screen lock (e.g. 'false' value of the capability) before starting the test and to unlock that (which sometimes might be unstable). Note, that this operation takes some time, so it is highly recommended to set this capability to `true` and disable screen locking on device(s) under test. Read the [Unlock tutorial](./docs/unlock/main.md) for more details.\nappium:unlockType | Set one of the possible types of Android lock screens to unlock. Read the [Unlock tutorial](./docs/unlock/main.md) for more details.\nappium:unlockKey | Allows to set an unlock key. Read the [Unlock tutorial](./docs/unlock/main.md) for more details.\nappium:unlockStrategy | Either 'locksettings' (default) or 'uiautomator'. Read the [Unlock tutorial](./docs/unlock/main.md) for more details.","metadata":{"loc":{"lines":{"from":145,"to":150}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:unlockStrategy | Either 'locksettings' (default) or 'uiautomator'. Read the [Unlock tutorial](./docs/unlock/main.md) for more details.\nappium:unlockSuccessTimeout | Maximum number of milliseconds to wait until the device is unlocked. `2000` ms by default. Read the [Unlock tutorial](./docs/unlock/main.md) for more details.","metadata":{"loc":{"lines":{"from":150,"to":151}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### MJPEG\n\nCapability Name | Description\n--- | ---\nappium:mjpegServerPort | The number of the port on the host machine that UiAutomator2 server starts the MJPEG server on. If not provided then the screenshots broadcasting service on the remote device does not get exposed to a local port (e.g. no adb port forwarding is happening)\nappium:mjpegScreenshotUrl | The URL of a service that provides realtime device screenshots in MJPEG format. If provided then the actual command to retrieve a screenshot will be requesting pictures from this service rather than directly from the server\n\n### Web Context","metadata":{"loc":{"lines":{"from":153,"to":160}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Capability Name | Description\n--- | ---\nappium:autoWebview | If set to `true` then UiAutomator2 driver will try to switch to the web view with name `WEBVIEW_ + appium:appPackage` after the session is started. For example, if `appium:appPackage` capability is set to `com.mypackage` then `WEBVIEW_com.mypackage` will be used. `false` by default.\nappium:autoWebviewName | Set the name of webview context in which UiAutomator2 driver will try to switch if `autoWebview` capability is set to `true` (available since driver version 2.9.1). Has priority over using the `appium:appPackage` value in webview name. For example, if `appium:autoWebviewName` capability is set to `myWebviewName` then `WEBVIEW_myWebviewName` will be used. Unset by default.\nappium:autoWebviewTimeout | Set the maximum number of milliseconds to wait until a web view is available if `autoWebview` capability is set to `true`. `2000` ms by default.","metadata":{"loc":{"lines":{"from":162,"to":166}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:autoWebviewTimeout | Set the maximum number of milliseconds to wait until a web view is available if `autoWebview` capability is set to `true`. `2000` ms by default.\nappium:webviewDevtoolsPort | The local port number to use for devtools communication. By default the first free port from 10900..11000 range is selected. Consider setting the custom value if you are running parallel tests.\nappium:ensureWebviewsHavePages | Whether to skip web views that have no pages from being shown in `getContexts` output. The driver uses devtools connection to retrieve the information about existing pages. `true` by default since Appium 1.19.0, `false` if lower than 1.19.0.\nappium:enableWebviewDetailsCollection | Whether to retrieve extended web views information using devtools protocol. Enabling this capability helps to detect the necessary chromedriver version more precisely. `true` by default since Appium 1.22.0, `false` if lower than 1.22.0.","metadata":{"loc":{"lines":{"from":166,"to":169}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:chromedriverPort | The port number to use for Chromedriver communication. Any free port number is selected by default if unset.\nappium:chromedriverPorts | Array of possible port numbers to assign for Chromedriver communication. If none of the port in this array is free then an error is thrown.\nappium:chromedriverArgs | Array of chromedriver command line arguments, listed with `chromedriver --help`. Note that not all command line arguments available for the desktop browser are also available for the mobile one.\nappium:chromedriverExecutable | Full path to the chromedriver executable on the server file system.\nappium:chromedriverExecutableDir | Full path to the folder where chromedriver executables are located. This folder is used then to store the downloaded chromedriver executables if automatic download is enabled. Read [Automatic Chromedriver Discovery article](#automatic-discovery-of-compatible-chromedriver) for more details.","metadata":{"loc":{"lines":{"from":170,"to":174}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:chromedriverChromeMappingFile | Full path to the chromedrivers mapping file. This file is used to statically map webview/browser versions to the chromedriver versions that are capable of automating them. Read [Automatic Chromedriver Discovery article](#automatic-discovery-of-compatible-chromedriver) for more details.\nappium:chromedriverUseSystemExecutable | Set it to `true` in order to enforce the usage of chromedriver, which gets downloaded by Appium automatically upon installation. This driver might not be compatible with the destination browser or a web view. `false` by default.\nappium:chromedriverDisableBuildCheck | Being set to `true` disables the compatibility validation between the current chromedriver and the destination browser/web view. Use it with care.","metadata":{"loc":{"lines":{"from":175,"to":177}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:chromedriverDisableBuildCheck | Being set to `true` disables the compatibility validation between the current chromedriver and the destination browser/web view. Use it with care.\nappium:recreateChromeDriverSessions | If this capability is set to `true` then chromedriver session is always going to be killed and then recreated instead of just suspending it on context switching. `false` by default\nappium:nativeWebScreenshot | Whether to use screenshoting endpoint provided by UiAutomator framework (`true`) rather than the one provided by chromedriver (`false`, the default value). Use it when you experience issues with the latter.\nappium:extractChromeAndroidPackageFromContextName | If set to `true`, tell chromedriver to attach to the android package we have associated with the context name, rather than the package of the application under test. `false` by default.","metadata":{"loc":{"lines":{"from":177,"to":180}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:showChromedriverLog | If set to `true` then all the output from chromedriver binary will be forwarded to the Appium server log. `false` by default.\npageLoadStrategy | One of the available page load strategies. See https://www.w3.org/TR/webdriver/#capabilities\nappium:chromeOptions | A mapping, that allows to customize chromedriver options. See https://chromedriver.chromium.org/capabilities for the list of available entries.\nappium:chromeLoggingPrefs | Chrome logging preferences mapping. Basically the same as [goog:loggingPrefs](https://newbedev.com/getting-console-log-output-from-chrome-with-selenium-python-api-bindings). It is set to `{\"browser\": \"ALL\"}` by default.","metadata":{"loc":{"lines":{"from":181,"to":184}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### Other","metadata":{"loc":{"lines":{"from":186,"to":186}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Capability Name | Description\n--- | ---\nappium:disableSuppressAccessibilityService | Being set to `true` tells the instrumentation process to not suppress accessibility services during the automated test. This might be useful if your automated test needs these services. `false` by default\nappium:userProfile | Integer identifier of a [user profile](https://source.android.com/devices/tech/admin/multi-user). By default the app under test is installed for the currently active user, but in case it is necessary to test how the app performs while being installed for a user profile, which is different from the current one, then this capability might come in handy.\nappium:newCommandTimeout | How long (in seconds) the driver should wait for a new command from the client before assuming the client has stopped sending requests. After the timeout the session is going to be deleted. `60` seconds by default. Setting it to zero disables the timer.","metadata":{"loc":{"lines":{"from":188,"to":192}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appium:skipLogcatCapture | Skips to start capturing logs such as logcat. It might improve network performance. Log-related commands won't work if the capability is enabled. Defaults to `false`.\nappium:timeZone | Overrides the current device's time zone since the driver version 3.1.0. This change is preserved until the next override. The time zone identifier must be a valid name from the list of [available time zone identifiers](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones), for example `Europe/Kyiv`","metadata":{"loc":{"lines":{"from":193,"to":194}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"## Element Attributes\n\nUiAutomator2 driver supports the following element attributes:","metadata":{"loc":{"lines":{"from":197,"to":199}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Name | Description | Example\n--- | --- | ---\ncheckable | Whether the element is checkable or not | 'true'\nchecked | Whether the element is checked. Always `false` if the element is not checkable | 'false'\nclass or className | The full name of the element's class. Could be `null` for some elements | 'android.view.View'\nclickable | Whether the element could be clicked | 'false'\ncontent-desc or contentDescription | The content-description attribute of the accessible element | 'foo'\nenabled | Whether the element could be clicked | 'true'\nfocusable | Whether the element could be focused | 'true'\nfocused | Whether the element could is focused. Always `false` if the element is not focusable | 'false'\nlong-clickable or longClickable | Whether the element accepts long clicks | 'false'\npackage | Identifier of the package the element belongs to | 'com.mycompany'\npassword | Whether the element is a password input field | 'true'","metadata":{"loc":{"lines":{"from":201,"to":213}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"package | Identifier of the package the element belongs to | 'com.mycompany'\npassword | Whether the element is a password input field | 'true'\nresource-id or resourceId | Element's resource identifier. Could be `null` | 'com.mycompany:id/resId'\nscrollable | Whether the element is scrollable | 'true'\nselection-start | Contains the index of the char where the selection starts. Could be `null` if the element provides no range info | '5'\nselection-end | Contains the index of the char where the selection ends. Could be `null` if the element provides no range info | '8'\nselected | Whether the element is selected | 'false'\ntext or name | The element's text. It never equals to null | 'my text'\nhint | Element's hint text. On Android versions below Oreo it always equals to `null`. | 'my hint text'\nbounds | The element's visible frame (`[left, top][right, bottom]`) | `[0,0][100,100]`\ndisplayed | Whether the element is visible to the user | 'true'","metadata":{"loc":{"lines":{"from":212,"to":222}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"bounds | The element's visible frame (`[left, top][right, bottom]`) | `[0,0][100,100]`\ndisplayed | Whether the element is visible to the user | 'true'\ncontentSize | The dimensions of the element's content area | `{\"left\": 0, \"top\":0, \"width\": 100, \"height\": 100, \"scrollableOffset\": 10, \"touchPadding\": 0}`\nextras | The result of [getExtras](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#getExtras()). The value includes all key-value pairs as `key=value` separated by a semicolon (`;`). If the value is empty, then only key part ending with the equal sign will be present. Available only if `includeExtrasInPageSource` setting is turned on. | Part of extras in chrome browser:<br> `AccessibilityNodeInfo.roleDescription=;`<br>`AccessibilityNodeInfo.chromeRole=rootWebArea;`<br> `ACTION_ARGUMENT_HTML_ELEMENT_STRING_VALUES=`<br> `ARTICLE,BLOCKQUOTE,BUTTON,CHECKBOX`","metadata":{"loc":{"lines":{"from":221,"to":224}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"a11y-important | Whether the element originates from a view considered important for accessibility. Available for API 24+ | 'true'\nscreen-reader-focusable | Whether the element is explicitly marked as a focusable unit by a screen reader. Available for API 28+ | 'true'\ninput-type | Bitmask, input type of the editable text element, defined by [InputType](https://developer.android.com/reference/android/text/InputType). Available only for text input fields. | '1'\ndrawing-order | The drawing position of the view corresponding to this element relative to its siblings. Available for API 24+ | '3'\nshowing-hint | Whether the element's text represents a hint for the user to enter text. Available for API 26+ | 'true'\ntext-entry-key | Whether the element represents a text entry key that is part of a keyboard or keypad. Available for API 29+ | 'true'\nmultiline | If the element is a multi line editable text. Available only for text input fields. | 'true'","metadata":{"loc":{"lines":{"from":225,"to":231}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"multiline | If the element is a multi line editable text. Available only for text input fields. | 'true'\ndismissable | If the element can be dismissed | 'true'\na11y-focused | Whether this element is accessibility focused | 'true'\nheading | Whether element represents a heading. Available for API 28+ | 'true'\nlive-region | Bitmask, live region mode value for the element, like '1' for [ACCESSIBILITY_LIVE_REGION_POLITE](https://developer.android.com/reference/android/view/View#ACCESSIBILITY_LIVE_REGION_POLITE) | '1'\ncontext-clickable | Whether this element is context clickable. Available for API 23+ | 'true'\nmax-text-length | The maximum text length for the editable text element. Available only for text input fields. | '300'\ncontent-invalid | If the content of this element is invalid. For example, a date is not well-formed. | 'true'\nerror | The error text of the element. | 'text string'\npane-title | Title of the pane represented by this element. Available for API 28+ | 'text string'","metadata":{"loc":{"lines":{"from":231,"to":240}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"error | The error text of the element. | 'text string'\npane-title | Title of the pane represented by this element. Available for API 28+ | 'text string'\nactions | The comma-separated id names of the available accessibility actions for the element from [getActionList](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#getActionList()). Available only if `includeA11yActionsInPageSource` setting is turned on. | 'ACTION_FOCUS,ACTION_SELECT,ACTION_CLEAR_SELECTION,ACTION_CLICK,ACTION_ACCESSIBILITY_FOCUS,ACTION_NEXT_AT_MOVEMENT_GRANULARITY,ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,ACTION_SET_SELECTION,ACTION_SHOW_ON_SCREEN'","metadata":{"loc":{"lines":{"from":239,"to":241}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"## Element Location\n\nUiAutomator2 driver supports the following location strategies:","metadata":{"loc":{"lines":{"from":244,"to":246}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Name | Description | Speed Ranking | Example\n--- | --- | --- | ---\nid | This strategy is mapped to the native UiAutomator's `By.res` [locator](https://developer.android.com/reference/androidx/test/uiautomator/BySelector#res(java.lang.String)) (exact match of element's resource name). Package identifier prefix is added automatically if unset and is equal to the identifier of the current application under test. | `⭐⭐⭐⭐⭐` | 'com.mycompany:id/resourceId'\naccessibilityId | This strategy is mapped to the native UiAutomator's `By.desc` [locator](https://developer.android.com/reference/androidx/test/uiautomator/BySelector#desc(java.lang.String)) (exact match of element's content description). In applications written using [ReactNative](https://reactnative.dev/) framework this attribute reflects the value of the `accessibilityLabel` property. | `⭐⭐⭐⭐⭐` | 'my description'","metadata":{"loc":{"lines":{"from":248,"to":251}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"className | This strategy is mapped to the native UiAutomator's `By.clazz` [locator](https://developer.android.com/reference/androidx/test/uiautomator/BySelector#clazz(java.lang.String)) (exact match of element's class). | `⭐⭐⭐⭐⭐` | 'android.view.View'\n-android uiautomator | This strategy is mapped to the native UiAutomator's `UiSelector` [locator](https://developer.android.com/reference/androidx/test/uiautomator/UiSelector)). It is even possible to perform some advanced operations, like scrolling, with this locator type. Check [Guide on UiAutomator Locator Types](docs/uiautomator-uiselector.md) | `⭐⭐⭐⭐` | new UiScrollable(new UiSelector().resourceId(\\\"android:id/list\\\")).scrollIntoView(new UiSelector().text(\\\"Radio Group\\\"))","metadata":{"loc":{"lines":{"from":252,"to":253}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"xpath | For elements lookup Xpath strategy the driver uses the same XML tree that is generated by page source API. Only Xpath 1.0 is supported for appium-uiatomator2-server versions below 4.25.0. All server versions starting from 4.25.0 support both Xpath 1.0 and 2.0 | `⭐⭐⭐` | By.xpath(\"//android.view.View[@text=\\\"Regular\\\" and @checkable=\\\"true\\\"]\")","metadata":{"loc":{"lines":{"from":254,"to":254}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"> [!WARNING]\n> Google is going to [deprecate](https://developer.android.com/training/testing/other-components/ui-automator#ui-automator)\n> and remove `UiCollection`, `UiObject`, `UiScrollable`, and `UiSelector` support from the UiAutomator framework.\n> This will render all `-android uiautomator`-based locators invalid, so please keep it in mind while\n> using them or plan to use them in the future.\n\n\n## BiDi Protocol Support\n\nUIAutomator2 driver has partial support of the [BiDi Protocol](https://w3c.github.io/webdriver-bidi/) since version 3.7.10. Check the [Supported BiDi Commands And Events](./docs/bidi.md) document for more details.\n\n\n## Parallel Tests","metadata":{"loc":{"lines":{"from":256,"to":268}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"## Parallel Tests\n\nIt is possible to execute tests in parallel using UiAutomator2 driver.\nAppium allows to do this on per-process (multiple server processes running on different ports managing single session)\nor per-request basis (single server process managing multiple sessions, more preferable, uses less resources and ensures better control over running sessions).\n\n_Note_: If you are not going to run your tests in parallel then consider enabling the `--session-override` Appium server argument.\nIt forces the server to close all pending sessions before a new one could be opened,\nwhich allows you to avoid possible issues with such sessions silently running/expiring in the background.\n\n### Important Real Device Capabilities","metadata":{"loc":{"lines":{"from":268,"to":278}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### Important Real Device Capabilities\n\n- `udid`: The unique device id.\n- `systemPort`: Set a unique system port number for each parallel session. Otherwise you might get a port conflict such as in [this issue](https://github.com/appium/appium/issues/7745).\n- `chromedriverPort`: The unique chromedriver port if testing web views or Chrome.\n- `mjpegServerPort`: Set a unique MJPEG server port for each parallel session if you are going to record a video.\n\n### Important Emulator Capabilities\n\n- `avd`: The unique emulator name.\n- `systemPort`: Set a unique system port number for each parallel session.\n- `chromedriverPort`: The unique chromedriver port (if testing web views or Chrome).\n- `mjpegServerPort`: Set a unique MJPEG server port for each parallel session if you are going to record a video.\n\n\n## Settings API","metadata":{"loc":{"lines":{"from":278,"to":293}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"## Settings API\n\nUiAutomator2 driver supports Appium [Settings API](https://appium.io/docs/en/latest/guides/settings/).\nAlong with the common settings the following driver-specific settings are currently available:","metadata":{"loc":{"lines":{"from":293,"to":296}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Name | Type | Description\n--- | --- | ---\nactionAcknowledgmentTimeout | long | Maximum number of milliseconds to wait for an acknowledgment of generic uiautomator actions, such as clicks, text setting, and menu presses. The acknowledgment is an [AccessibilityEvent](http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html) corresponding to an action, that lets the framework determine if the action was successful. Generally, this timeout should not be modified. `3000` ms by default\nallowInvisibleElements | boolean | Whether to include elements that are not visible to the user (e. g. whose `displayed` attribute is `false`) to the XML source tree. `false` by default","metadata":{"loc":{"lines":{"from":298,"to":301}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"allowInvisibleElements | boolean | Whether to include elements that are not visible to the user (e. g. whose `displayed` attribute is `false`) to the XML source tree. `false` by default\nignoreUnimportantViews | boolean | Enables or disables layout hierarchy compression. If compression is enabled, the layout hierarchy derived from the Acessibility framework will only contain nodes that are important for uiautomator testing. Any unnecessary surrounding layout nodes that make viewing and searching the hierarchy inefficient are removed. `false` by default\nelementResponseAttributes | string | Comma-separated list of element attribute names to be included into findElement response. By default only element UUID is present there, but it is also possible to add the following items: `name`, `text`, `rect`, `enabled`, `displayed`, `selected`, `attribute/<element_attribute_name>`. It is required that `shouldUseCompactResponses` setting is set to `false` in order for this one to apply.","metadata":{"loc":{"lines":{"from":301,"to":303}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"enableMultiWindows | boolean | Whether to include all windows that the user can interact with (for example an on-screen keyboard) while building the XML page source (`true`). By default it is `false` and only the single active application window is included to the page source.\nenableTopmostWindowFromActivePackage | boolean | Whether to limit the window with the highest Z-order from the active package for interactions and page source retrieval. By default it is `false` and the active application window, which may not necessarily have this order, is included to the page source.\nenableNotificationListener | boolean | Whether to enable (`true`) toast notifications listener to listen for new toast notifications. By default this listener is enabled and UiAutomator2 server includes the text of toast messages to the generated XML page source, but not for longer than `3500` ms after the corresponding notification expires.","metadata":{"loc":{"lines":{"from":304,"to":306}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"keyInjectionDelay | long | Delay in milliseconds between key presses when injecting text input. 0 ms by default\nscrollAcknowledgmentTimeout | long | Timeout for waiting for an acknowledgement of an uiautomator scroll swipe action. The acknowledgment is an [AccessibilityEvent](http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html), corresponding to the scroll action, that lets the framework determine if the scroll action was successful. Generally, this timeout should not be modified. `200` ms by default\nshouldUseCompactResponses | boolean | Used in combination with `elementResponseAttributes` setting. If set to `false` then the findElement response is going to include the items enumerated in `elementResponseAttributes` setting. `true` by default","metadata":{"loc":{"lines":{"from":307,"to":309}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"waitForIdleTimeout | long | Timeout used for waiting for the user interface to go into an idle state. By default, all core uiautomator objects except UiDevice will perform this wait before starting to search for the widget specified by the object's locator. Once the idle state is detected or the timeout elapses (whichever occurs first), the object will start to wait for the selector to find a match. Consider lowering the value of this setting if you experience long delays while interacting with accessibility elements in your test. `10000` ms by default.","metadata":{"loc":{"lines":{"from":310,"to":310}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"waitForSelectorTimeout | long | Timeout for waiting for a widget to become visible in the user interface so that it can be matched by a selector. Because user interface content is dynamic, sometimes a widget may not be visible immediately and won't be detected by a selector. This timeout allows the uiautomator framework to wait for a match to be found, up until the timeout elapses. This timeout is only applied to `android uiautomator` location strategy. `10000` ms by default\nnormalizeTagNames | boolean | Being set to `true` applies unicode-to-ascii normalization of element class names used as tag names in the page source XML document. This is necessary if the application under test has some Unicode class names, which cannot be used as XML tag names by default due to known bugs in Android's XML DOM parser implementation. `false` by default","metadata":{"loc":{"lines":{"from":311,"to":312}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"shutdownOnPowerDisconnect | boolean | Whether to shutdown the server if the device under test is disconnected from a power source (e. g. stays on battery power). `true` by default.\nsimpleBoundsCalculation | boolean | Whether to calculate element bounds as absolute values (`true`) or check if the element is covered by other elements and thus partially hidden (`false`, the default behaviour). Setting this setting to `true` helps to improve the performance of XML page source generation, but decreases bounds preciseness. Use with care.\ntrackScrollEvents | boolean | Whether to apply scroll events tracking (`true`, the default value), so the server could calculate the value of `contentSize` attribute. Having this setting enabled may add delays to all scrolling actions.","metadata":{"loc":{"lines":{"from":313,"to":315}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"wakeLockTimeout | long | The timeout in milliseconds of wake lock that UiAutomator2 server acquires by default to prevent the device under test going to sleep while an automated test is running. By default the server acquires the lock for 24 hours. Setting this value to zero forces the server to release the wake lock.\nserverPort | int | The number of the port on the remote device to start UiAutomator2 server on. Do not mix this with `systemPort`, which is acquired on the host machine. Must be in range 1024..65535. `6790` by default\nmjpegServerPort | int | The number of the port on the remote device to start MJPEG screenshots broadcaster on. Must be in range 1024..65535. `7810` by default\nmjpegServerFramerate | int | The maximum count of screenshots per second taken by the MJPEG screenshots broadcaster. Must be in range 1..60. `10` by default","metadata":{"loc":{"lines":{"from":316,"to":319}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"mjpegServerFramerate | int | The maximum count of screenshots per second taken by the MJPEG screenshots broadcaster. Must be in range 1..60. `10` by default\nmjpegScalingFactor | int | The percentage value used to apply downscaling on the screenshots generated by the MJPEG screenshots broadcaster. Must be in range 1..100. `50` is by default, which means that screenshots are downscaled to the half of their original size keeping their original proportions.\nmjpegServerScreenshotQuality | int | The percentage value used to apply lossy JPEG compression on the screenshots generated by the MJPEG screenshots broadcaster. Must be in range 1..100. `50` is by default, which means that screenshots are compressed to the half of their original quality.","metadata":{"loc":{"lines":{"from":319,"to":321}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"mjpegBilinearFiltering | boolean | Controls whether (`true`) or not (`false`, the default value) to apply bilinear filtering to MJPEG screenshots broadcaster resize algorithm. Enabling this flag may improve the quality of the resulting scaled bitmap, but may introduce a small performance hit.\nuseResourcesForOrientationDetection | boolean | Defines the strategy used by UiAutomator2 server to detect the original device orientation. By default (`false` value) the server uses device rotation value for this purpose. Although, this approach may not work for some devices and a portrait orientation may erroneously be detected as the landscape one (and vice versa). In such case it makes sense to play with this setting.","metadata":{"loc":{"lines":{"from":322,"to":323}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"enforceXPath1 | boolean | Since UiAutomator2 driver version `4.25.0` XPath2 is set as the default and the recommended interpreter for the corresponding element locators. This interpreter is based on [Psychopath XPath2](https://wiki.eclipse.org/PsychoPathXPathProcessor) implementation, which is now a part of the Eclipse foundation. In most of the cases XPath1 locators are also valid XPath2 locators, so there should be no issues while locating elements. Although, since the XPath2 standard is much more advanced in comparison to the previous version, some [issues](https://github.com/appium/appium/issues/16142) are possible for more sophisticated locators, which cannot be fixed easily, as we depend on the third-party library mentioned above. Then try to workaround such issues by enforcing XPath1 usage (whose implementation is a part of the Android platform itself) and assigning this setting to `true`. Note, this setting is actually applied at the time when the element lookup by XPath is","metadata":{"loc":{"lines":{"from":324,"to":324}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"usage (whose implementation is a part of the Android platform itself) and assigning this setting to `true`. Note, this setting is actually applied at the time when the element lookup by XPath is executed, so you could switch it on or off whenever needed throughout your automated testing session.","metadata":{"loc":{"lines":{"from":324,"to":324}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"limitXPathContextScope | boolean | Due to historical reasons UiAutomator2 driver limits scopes of element context-based searches to the parent element. This means a request like `findElement(By.xpath, \"//root\").findElement(By.xpath, \"./..\")` would always fail, because the driver only collects descendants of the `root` element for the destination XML source. The `limitXPathContextScope` setting being set to `false` changes that default behavior, so the collected page source includes the whole page source XML where `root` node is set as the search context. With that setting disabled the search query above should not fail anymore. Although, you must still be careful while building XPath requests for context-based searches with the `limitXPathContextScope` setting set to `false`. A request like `findElement(By.xpath, \"//root\").findElement(By.xpath, \"//element\")` would ignore the current context and search for `element` trough the whole page source. Use `.` notation to correct that","metadata":{"loc":{"lines":{"from":325,"to":325}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"like `findElement(By.xpath, \"//root\").findElement(By.xpath, \"//element\")` would ignore the current context and search for `element` trough the whole page source. Use `.` notation to correct that behavior and only find `element` nodes which are descendants of the `root` node: `findElement(By.xpath, \"//root\").findElement(By.xpath, \".//element\")`.","metadata":{"loc":{"lines":{"from":325,"to":325}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"disableIdLocatorAutocompletion | boolean | According to internal Android standards it is expected that each resource identifier is prefixed with `<packageName>:id/` string. This should guarantee uniqueness of each identifier. Although some application development frameworks ignore this rule and don't add such prefix automatically or, rather, let it up to the developer to decide how to represent their application identifiers. For example, [testTag modifier attribute in the Jetpack Compose](https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/package-summary#(androidx.compose.ui.Modifier).testTag(kotlin.String)) with [testTagsAsResourceId](https://developer.android.com/reference/kotlin/androidx/compose/ui/semantics/package-summary#(androidx.compose.ui.semantics.SemanticsPropertyReceiver).testTagsAsResourceId()) allows developers to set an arbitrary string without the prefix rule. [Interoperability with","metadata":{"loc":{"lines":{"from":326,"to":326}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"allows developers to set an arbitrary string without the prefix rule. [Interoperability with UiAutomator](https://developer.android.com/jetpack/compose/testing) also explains how to set it. By default UIA2 driver adds the above prefixes automatically to all resource id locators if they are not prefixed, but in case of such \"special\" apps this feature might be disabled by assigning the setting to `true`.","metadata":{"loc":{"lines":{"from":326,"to":326}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"includeExtrasInPageSource | boolean | Whether to include `extras` element attribute in the XML page source result. Then, XPath locator can find the element by the extras. Its value consists of combined [getExtras](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#getExtras()) as `keys=value` pair separated by a semicolon (`;`), thus you may need to find the element with partial matching like `contains` e.g. `driver.find_element :xpath, '//*[contains(@extras, \"AccessibilityNodeInfo.roleDescription=\")]'`. The value could be huge if elements in the XML page source have large `extras`. It could affect the performance of XML page source generation.","metadata":{"loc":{"lines":{"from":327,"to":327}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"includeA11yActionsInPageSource | boolean | Whether to include `actions` element attribute in the XML page source result. Its value consists of names of available accessibility actions from [getActionList](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#getActionList()), separated by a comma. The value could be huge if elements in the XML page source have a lot of actions and could affect the performance of XML page source generation.\nsnapshotMaxDepth | int | The number of maximum depth for the source tree snapshot. The default value is `70`. This number should be in range [1, 500]. A part of the elements source tree might be lost if the value is too low. Also, StackOverflowError might be caused if the value is too high (Issues [12545](https://github.com/appium/appium/issues/12545), [12892](https://github.com/appium/appium/issues/12892)). The available driver version is `2.27.0` or higher.","metadata":{"loc":{"lines":{"from":328,"to":329}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"currentDisplayId | int | The id of the display that should be used when finding elements, taking screenshots, etc. It can be found in the output of `adb shell dumpsys display` (search for `mDisplayId`). The default value is [Display.DEFAULT_DISPLAY](https://developer.android.com/reference/android/view/Display#DEFAULT_DISPLAY). **Please note that it is different from the physical display id, reported by `adb shell dumpsys SurfaceFlinger --display-id`**. **Additionally, please note that `-android uiautomator` (e.g., `UiSelector`) doesn't work predictably with multiple displays, as this is an Android limitation.** **Multi-display support is only available since Android R (30 API level).**","metadata":{"loc":{"lines":{"from":330,"to":330}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"## Platform-Specific Extensions\n\nBeside of standard W3C APIs the driver provides the below custom command extensions to execute platform specific scenarios. Use the following source code examples in order to invoke them from your client code:\n\n```java\n// Java 11+\nvar result = driver.executeScript(\"mobile: <methodName>\", Map.ofEntries(\n Map.entry(\"arg1\", \"value1\"),\n Map.entry(\"arg2\", \"value2\")\n // you may add more pairs if needed or skip providing the map completely\n // if all arguments are defined as optional\n));\n```\n\n```js\n// WebdriverIO\nconst result = await driver.executeScript('mobile: <methodName>', [{\n arg1: \"value1\",\n arg2: \"value2\",\n}]);\n```\n\n```python\n# Python\nresult = driver.execute_script('mobile: <methodName>', {\n 'arg1': 'value1',\n 'arg2': 'value2',\n})\n```\n\n```ruby\n# Ruby\nresult = @driver.execute_script 'mobile: <methodName>', {\n arg1: 'value1',\n arg2: 'value2',\n}\n```","metadata":{"loc":{"lines":{"from":333,"to":369}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"```ruby\n# Ruby\nresult = @driver.execute_script 'mobile: <methodName>', {\n arg1: 'value1',\n arg2: 'value2',\n}\n```\n\n```csharp\n// Dotnet\nobject result = driver.ExecuteScript(\"mobile: <methodName>\", new Dictionary<string, object>() {\n {\"arg1\", \"value1\"},\n {\"arg2\", \"value2\"}\n});\n```\n\n### mobile: shell\n\nExecutes the given shell command on the device under test via ADB connection. This extension exposes a potential security risk and thus is only enabled when explicitly activated by the `adb_shell` server command line feature specifier.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":363,"to":383}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ncommand | string | yes | Shell command name to execute, for example `echo` or `rm` | echo\nargs | Array&lt;string&gt; | no | Array of command arguments | `['-f', '/sdcard/myfile.txt']`\ntimeout | number | no | Command timeout in milliseconds. If the command blocks for longer than this timeout then an exception is going to be thrown. The default timeout is `20000` ms | 100000\nincludeStderr | boolean | no | Whether to include stderr stream into the returned result. `false` by default | true\n\n#### Returned Result","metadata":{"loc":{"lines":{"from":383,"to":392}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Returned Result\n\nDepending on the `includeStderr` value this API could either return a string, which is equal to the `stdout` stream content of the given command or a dictionary whose elements are `stdout` and `stderr` and values are contents of the corresponding outgoing streams. If the command exits with a non-zero return code then an exception is going to be thrown. The exception message will be equal to the command stderr.\n\n### mobile: execEmuConsoleCommand\n\nExecutes a command through emulator telnet console interface and returns its output.\nThe `emulator_console` server feature must be enabled in order to use this method.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":392,"to":401}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Executes a command through emulator telnet console interface and returns its output.\nThe `emulator_console` server feature must be enabled in order to use this method.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ncommand | string | yes | The actual command to execute. See [Android Emulator Console Guide](https://developer.android.com/studio/run/emulator-console) for more details on available commands | help-verbose\nexecTimeout | number | no | Timeout used to wait for a server reply to the given command in milliseconds. `60000` ms by default | 100000\nconnTimeout | boolean | no | Console connection timeout in milliseconds. `5000` ms by default | 10000\ninitTimeout | boolean | no | Telnet console initialization timeout in milliseconds (the time between the connection happens and the command prompt). `5000` ms by default | 10000\n\n#### Returned Result\n\nThe actual command output. An error is thrown if command execution fails.","metadata":{"loc":{"lines":{"from":398,"to":412}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Returned Result\n\nThe actual command output. An error is thrown if command execution fails.\n\n### Mobile Gesture Commands\n\nUiAutomator2 provides several extensions that allow to automate popular mobile gesture shortcuts:\n\n- mobile: dragGesture\n- mobile: flingGesture\n- mobile: doubleClickGesture\n- mobile: clickGesture\n- mobile: longClickGesture\n- mobile: pinchCloseGesture\n- mobile: pinchOpenGesture\n- mobile: swipeGesture\n- mobile: scrollGesture\n\nThese gestures are documented in the [Automating Mobile Gestures](docs/android-mobile-gestures.md) tutorial. Check [W3C Actions API](https://appiumpro.com/editions/29-automating-complex-gestures-with-the-w3c-actions-api) and\n[Low-Level Insights on Android Input Events](docs/actions.md) if you need to automate more complicated gestures.\n\n### mobile: scroll","metadata":{"loc":{"lines":{"from":410,"to":431}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: scroll\n\nScrolls the given scrollable element until an element identified by `strategy` and `selector` becomes visible. This function returns immediately if the destination element is already visible in the view port. Otherwise it would scroll to the very beginning of the scrollable control and tries to reach the destination element by scrolling its parent to the end step by step. The scroll direction (vertical or horizontal) is detected automatically.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":431,"to":435}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId | string | no | The identifier of the scrollable element. It is required this element is a valid scrollable container and it was located by `-android uiautomator` strategy. If this property is not provided then the first currently available scrollable view is selected for the interaction. | 123456-3456-3435-3453453\nstrategy | string | yes | The following strategies are supported: `accessibility id` (UiSelector().description), `class name` (UiSelector().className), `-android uiautomator` (UiSelector) | 'accessibility id'\nselector | string | yes | The corresponding lookup value for the selected strategy. | 'com.mycompany:id/table'\nmaxSwipes | number | no | The maximum number of swipes to perform on the target scrollable view in order to reach the destination element. In case this value is unset then it would be retrieved from the scrollable element itself (vua `getMaxSearchSwipes()` property). | 10","metadata":{"loc":{"lines":{"from":437,"to":442}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: deepLink\n\nStart URI that may take users directly to the specific content in the app. Read [Reliably Opening Deep Links Across Platforms and Devices](https://appiumpro.com/editions/84-reliably-opening-deep-links-across-platforms-and-devices) for more details.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nurl | string | yes | The URL to start | theapp://login/\npackage | string | no | The name of the package to start the URI with. This argument was required previously but became optional since version 3.9.3 | 'com.mycompany'\nwaitForLaunch | boolean | no | If `false` then ADB won't wait for the started activity to return the control. `true` by default | false\n\n### mobile: startLogsBroadcast","metadata":{"loc":{"lines":{"from":444,"to":456}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: startLogsBroadcast\n\nStarts Android logcat broadcast websocket on the same host and port where Appium server is running at `/ws/session/:sessionId:/appium/device/logcat` endpoint. The method will return immediately if the web socket is already listening. Each connected websocket listener will receive logcat log lines as soon as they are visible to Appium. Read [Using Mobile Execution Commands to Continuously Stream Device Logs with Appium](https://appiumpro.com/editions/55-using-mobile-execution-commands-to-continuously-stream-device-logs-with-appium) for more details.\n\nConsider using [logs broadcast via BiDi](./docs/bidi.md#logentryadded) over this extension.\n\n### mobile: stopLogsBroadcast","metadata":{"loc":{"lines":{"from":456,"to":462}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Consider using [logs broadcast via BiDi](./docs/bidi.md#logentryadded) over this extension.\n\n### mobile: stopLogsBroadcast\n\nStops the previously started logcat broadcasting websocket server. This method will return immediately if no server is running. Read [Using Mobile Execution Commands to Continuously Stream Device Logs with Appium](https://appiumpro.com/editions/55-using-mobile-execution-commands-to-continuously-stream-device-logs-with-appium) for more details.\n\nConsider using [logs broadcast via BiDi](./docs/bidi.md#logentryadded) over this extension.\n\n### mobile: deviceidle\n\nThis is a wrapper to 'adb shell dumpsys deviceidle' interface.\nRead [Diving Into Android 'M' Doze](https://www.protechtraining.com/blog/post/diving-into-android-m-doze-875) for more details.\nThis API only exists since Android 6.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":460,"to":474}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\naction | whitelistAdd or whitelistRemove | yes | The name of the action to perform | whitelistAdd\npackages | string or string[] | yes | One or more package names to perfom the above action on | 'com.mycompany'\n\n### mobile: acceptAlert\n\nTries to accept an Android alert. This method might not always be reliable as there is no single standard for how Android alerts should look like within the Accessibility representation.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nbuttonLabel | string | no | The name/text of the alert button to click in order to accept it. If not provided then the driver will try to autodetect it | Accept\n\n### mobile: dismissAlert\n\nTries to dismiss an Android alert. This method might not always be reliable as there is no single standard for how Android alerts should look like within the Accessibility representation.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":474,"to":495}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nbuttonLabel | string | no | The name/text of the alert button to click in order to dismiss it. If not provided then the driver will try to autodetect it | Dismiss\n\n### mobile: batteryInfo\n\nRetrieves the battery information from the device under test.\n\n#### Returned Result\n\nThe extension returns a dictionary whose entries are:\n\nName | Type | Description | Example\n--- | --- | --- | ---\nlevel | number | Battery level in range [0.0, 1.0], where 1.0 means 100% charge. -1 is returned if the actual value cannot be retrieved from the system. | 0.5\nstate | number| Battery state. The following values are possible: BATTERY_STATUS_UNKNOWN = 1; BATTERY_STATUS_CHARGING = 2; BATTERY_STATUS_DISCHARGING = 3; BATTERY_STATUS_NOT_CHARGING = 4; BATTERY_STATUS_FULL = 5. -1 is returned if the actual value cannot be retrieved from the system. | 4\n\n### mobile: deviceInfo","metadata":{"loc":{"lines":{"from":495,"to":514}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: deviceInfo\n\nRetrieves the information about the device under test, like the device model, serial number, network connectivity info, etc.\n\n#### Returned Result\n\nThe extension returns a dictionary whose entries are the device properties. Check https://github.com/appium/appium-uiautomator2-server/blob/master/app/src/main/java/io/appium/uiautomator2/handler/GetDeviceInfo.java to get the full list of returned keys and their corresponding values.\n\n### mobile: getDeviceTime\n\nRetrieves the current device's timestamp.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nformat | string | no | The set of format specifiers. Read https://momentjs.com/docs/ to get the full list of supported datetime format specifiers. The default format is `YYYY-MM-DDTHH:mm:ssZ`, which complies to ISO-8601 | YYYY-MM-DDTHH:mm:ssZ\n\n#### Returned Result\n\nThe device timestamp string formatted according to the given specifiers\n\n### mobile: changePermissions","metadata":{"loc":{"lines":{"from":514,"to":536}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Returned Result\n\nThe device timestamp string formatted according to the given specifiers\n\n### mobile: changePermissions\n\nChanges package permissions in runtime.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":532,"to":540}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---","metadata":{"loc":{"lines":{"from":542,"to":543}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"permissions | string or Array&lt;string&gt; | yes | The full name of the permission to be changed or a list of permissions. Consider checking [the full list](https://developer.android.com/reference/android/Manifest.permission) of standard Android permission names. If `all` magic string is passed (available since driver version 2.8.0) and `target` equals `pm` (the default value) then the chosen action is going to be applied to all permissions requested/granted by the 'appPackage'. If `target` is set to `appops` (available since v2.11.0) then check [AppOpsManager.java](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/AppOpsManager.java) sources to get the full list of supported appops permission names for the given Android platform. The `all` magic string is unsupported for the `appops` target. | `['android.permission.ACCESS_FINE_LOCATION', 'android.permission.BROADCAST_SMS']` `all` `['READ_SMS', 'ACCESS_NOTIFICATIONS']`","metadata":{"loc":{"lines":{"from":544,"to":544}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"appPackage | string | no | The application package to set change permissions on. Defaults to the package name under test | com.mycompany.myapp\naction | string | no | Either `grant` (the default action) or `revoke` if `target` is set to `pm`, otherwise one of: `allow` (default), `deny`, `ignore`, `default`. | allow\ntarget | string | no | Either `pm` (default) or `appops` (available since v2.11.0). The `appops` one requires *adb_shell* server security option to be enabled | appops","metadata":{"loc":{"lines":{"from":545,"to":547}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: getPermissions\n\nGets runtime permissions list for the given application package.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ntype | string | no | One of possible permission types to get. Can be one of: `denied`, `granted` or `requested` (the default value). | granted\nappPackage | string | no | The application package to get permissions from. Defaults to the package name under test | com.mycompany.myapp\n\n#### Returned Result\n\nArray of strings, where each string is a permission name. the array could be empty.\n\n### mobile: performEditorAction\n\nPerforms IME action on the _currently focused_ edit element.","metadata":{"loc":{"lines":{"from":549,"to":566}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Array of strings, where each string is a permission name. the array could be empty.\n\n### mobile: performEditorAction\n\nPerforms IME action on the _currently focused_ edit element.\n\nVery often Android developers use [onEditorAction](https://developer.android.com/reference/android/widget/TextView.OnEditorActionListener.html#onEditorAction(android.widget.TextView,%20int,%20android.view.KeyEvent)) callback with `actionId` argument to implement actions handling, for example, when `Search` or `Done` button is pressed on the on-screen keyboard. This mobile extension is supposed to emulate the invokation of such callback on the focused element.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":562,"to":570}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\naction | string | yes | The name or an integer code of the editor action to be executed. The following action names are supported: `normal, unspecified, none, go, search, send, next, done, previous`. Read [EditorInfo](https://developer.android.com/reference/android/view/inputmethod/EditorInfo) for more details on this topic. | search\n\n### mobile: startScreenStreaming\n\nStarts device screen broadcast by creating MJPEG server. Multiple calls to this method have no effect unless the previous streaming session is stopped. This method only works if the `adb_screen_streaming` feature is enabled on the server side. It is also required that [GStreamer](https://gstreamer.freedesktop.org/) with `gst-plugins-base`, `gst-plugins-good` and `gst-plugins-bad` packages are installed and available in PATH on the server machine.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":570,"to":580}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nwidth | number | no | The scaled width of the device's screen. If unset then the script will assign it to the actual screen width measured in pixels. | 768\nheight | number | no | The scaled height of the device's screen. If unset then the script will assign it to the actual screen height measured in pixels. | 1024\nbitRate | number | no | The video bit rate for the video, in bits per second. The default value is 4000000 (4 Mb/s). You can increase the bit rate to improve video quality, but doing so results in larger movie files. | 1024000\nhost | string | no | The IP address/host name to start the MJPEG server on. You can set it to `0.0.0.0` to trigger the broadcast on all available network interfaces. `127.0.0.1` by default | 0.0.0.0","metadata":{"loc":{"lines":{"from":582,"to":587}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"host | string | no | The IP address/host name to start the MJPEG server on. You can set it to `0.0.0.0` to trigger the broadcast on all available network interfaces. `127.0.0.1` by default | 0.0.0.0\npathname | string | no | The HTTP request path the MJPEG server should be available on. If unset then any pathname on the given `host`/`port` combination will work. Note that the value should always start with a single slash: `/` | /myserver\ntcpPort | number | no | The port number to start the internal TCP MJPEG broadcast on. This type of broadcast always starts on the loopback interface (`127.0.0.1`). `8094` by default | 5024\nport | number | no | The port number to start the MJPEG server on. `8093` by default | 5023\nquality | number | no | The quality value for the streamed JPEG images. This number should be in range [1, 100], where 100 is the best quality. `70` by default | 80","metadata":{"loc":{"lines":{"from":587,"to":591}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"quality | number | no | The quality value for the streamed JPEG images. This number should be in range [1, 100], where 100 is the best quality. `70` by default | 80\nconsiderRotation | boolean | no | If set to `true` then GStreamer pipeline will increase the dimensions of the resulting images to properly fit images in both landscape and portrait orientations. Set it to `true` if the device rotation is not going to be the same during the broadcasting session. `false` by default | false\nlogPipelineDetails | boolean | no | Whether to log GStreamer pipeline events into the standard log output. Might be useful for debugging purposes. `false` by default | true","metadata":{"loc":{"lines":{"from":591,"to":593}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: stopScreenStreaming\n\nStop the previously started screen streaming. If no screen streaming server has been started then nothing is done.\n\n### mobile: getNotifications\n\nRetrieves Android notifications via Appium Settings helper. Appium Settings app itself must be *manually* granted to access notifications under device Settings in order to make this feature working. Different vendors [might](https://github.com/appium/io.appium.settings/issues/147#issue-2130780990) require more than just the normal Notification permissions at the usual Apps menu. Try to look in places like Privacy menus if you are getting zero items retrieved while expecting some results.","metadata":{"loc":{"lines":{"from":595,"to":601}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Appium Settings helper keeps all the active notifications plus notifications that appeared while it was running in the internal buffer, but no more than 100 items altogether. Newly appeared notifications are always added to the head of the notifications array. The `isRemoved` flag is set to `true` for notifications that have been removed.\nSee https://developer.android.com/reference/android/service/notification/StatusBarNotification and https://developer.android.com/reference/android/app/Notification.html for more information on available notification properties and their values.\n\n#### Returned Result","metadata":{"loc":{"lines":{"from":603,"to":606}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Returned Result\n\nThe example output is:\n```json\n{\n \"statusBarNotifications\":[\n {\n \"isGroup\":false,\n \"packageName\":\"io.appium.settings\",\n \"isClearable\":false,\n \"isOngoing\":true,\n \"id\":1,\n \"tag\":null,\n \"notification\":{\n \"title\":null,\n \"bigTitle\":\"Appium Settings\",\n \"text\":null,\n \"bigText\":\"Keep this service running, so Appium for Android can properly interact with several system APIs\",\n \"tickerText\":null,\n \"subText\":null,\n \"infoText\":null,\n \"template\":\"android.app.Notification$BigTextStyle\"\n },\n \"userHandle\":0,\n \"groupKey\":\"0|io.appium.settings|1|null|10133\",\n \"overrideGroupKey\":null,\n \"postTime\":1576853518850,\n \"key\":\"0|io.appium.settings|1|null|10133\",\n \"isRemoved\":false\n }\n ]\n}\n```\n\n### mobile: openNotifications","metadata":{"loc":{"lines":{"from":606,"to":640}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: openNotifications\n\nOpens notifications drawer on the device under test. Does nothing if the drawer is already opened. Available since driver version 2.23\n\n### mobile: listSms\n\nRetrieves the list of the most recent SMS properties list via Appium Settings helper. Messages are sorted by date in descending order.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nmax | number | no | The maximum count of recent messages to retrieve. `100` by default | 10\n\n#### Returned Result","metadata":{"loc":{"lines":{"from":640,"to":654}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nmax | number | no | The maximum count of recent messages to retrieve. `100` by default | 10\n\n#### Returned Result\n\nThe example output is:\n```json\n {\n \"items\":[\n {\n \"id\":\"2\",\n \"address\":\"+123456789\",\n \"person\":null,\n \"date\":\"1581936422203\",\n \"read\":\"0\",\n \"status\":\"-1\",\n \"type\":\"1\",\n \"subject\":null,\n \"body\":\"\\\"text message2\\\"\",\n \"serviceCenter\":null\n },\n {\n \"id\":\"1\",\n \"address\":\"+123456789\",\n \"person\":null,\n \"date\":\"1581936382740\",\n \"read\":\"0\",\n \"status\":\"-1\",\n \"type\":\"1\",\n \"subject\":null,\n \"body\":\"\\\"text message\\\"\",\n \"serviceCenter\":null\n }\n ],\n \"total\":2\n }\n```\n\n### mobile: type","metadata":{"loc":{"lines":{"from":650,"to":689}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: type\n\nTypes the given Unicode string. It is expected that the focus is already put to the destination input field before this method is called. The main difference between this method and the sendKeys one is that it emulates `true` typing like it was done from an on-screen keyboard. It also properly supports Unicode input characters.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ntext | string | yes | The text to type | testing\n\n### mobile: sensorSet\n\nEmulate changing of sensor values on the connected emulator.\nThis extension does not work on real devices.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":689,"to":704}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: sensorSet\n\nEmulate changing of sensor values on the connected emulator.\nThis extension does not work on real devices.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nsensorType | string | yes | The set of all supported sensor types could be found in [adb-emu-commands.js](https://github.com/appium/appium-adb/blob/master/lib/tools/adb-emu-commands.js) (look for *SENSORS* object values). Check the output of `sensor status` command in the [emulator console](https://developer.android.com/studio/run/emulator-console) to see more details on the available sensor types | light\nvalue | string | yes | Check the output of `sensor get <sensorType>` command in the [emulator console](https://developer.android.com/studio/run/emulator-console) to see the acceptable value format for the given sensor type | 50\n\n### mobile: pullFile\n\nPulls a remote file from the device.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":699,"to":715}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: pullFile\n\nPulls a remote file from the device.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nremotePath | string | yes | The full path to the remote file or a specially formatted path, which points to an item inside an app bundle, for example `@my.app.id/my/path`. It is mandatory for the app bundle to have [debugging enabled](https://developer.android.com/studio/debug) in order to use the latter remotePath format. If the file with the given name does not exist then an exception will be thrown. | /sdcard/foo.bar\n\n#### Returned Result\n\nBase64-encoded string, which represents the content of the remote file.\n\n### mobile: pushFile\n\nPushes a local file to the device.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":711,"to":729}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Returned Result\n\nBase64-encoded string, which represents the content of the remote file.\n\n### mobile: pushFile\n\nPushes a local file to the device.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nremotePath | string | yes | The path on the device to where the payload should be written. The value format is similar to the one used in [pullFile](#mobile-pullfile) extension. If the file with the same name already exists then it will be silently overridden. | /sdcard/foo.bar\npayload | string | yes | Base64-encoded content of the file to be pushed. | QXBwaXVt\n\n### mobile: pullFolder\n\nPulls a remote folder from the device.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nremotePath | string | yes | Same as for [pullFile](#mobile-pullfile) extension, but should be pointing to a remote folder | /sdcard/yolo/\n\n#### Returned Result","metadata":{"loc":{"lines":{"from":721,"to":746}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Returned Result\n\nBase64-encoded string, which represents the zipped content of the remote folder.\n\n### mobile: deleteFile\n\nDeletes a file on the remote device.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nremotePath | string | yes | The full path to the remote file or a file inside an application bundle | `/sdcard/myfile.txt` or `@my.app.id/path/in/bundle`\n\n### mobile: isAppInstalled\n\nVerify whether an application is installed on the device under test.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nappId | string | yes | The identifier of the application package to be checked | `my.app.id`\nuser | number or string | no | The user ID for which the package is installed.. The `current` user is used by default | 1006\n\n#### Returned Result\n\nTrue or false\n\n### mobile: queryAppState\n\nQueries the current state of the app.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":746,"to":779}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Returned Result\n\nTrue or false\n\n### mobile: queryAppState\n\nQueries the current state of the app.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nappId | string | yes | The identifier of the application package to be checked | `my.app.id`\n\n#### Returned Result\n\nThe following numbers could returned:\n- The app is not installed: `0`\n- The app is installed and is not running: `1`\n- The app is running in background: `3`\n- The app is running in foreground: `4`\n\n### mobile: activateApp\n\nActivates the given application or launches it if necessary.\nThe action literally simulates\nclicking the corresponding application icon on the dashboard.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nappId | string | yes | The identifier of the application package to be activated | `my.app.id`\n\n### mobile: removeApp","metadata":{"loc":{"lines":{"from":771,"to":805}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nappId | string | yes | The identifier of the application package to be activated | `my.app.id`\n\n### mobile: removeApp\n\nRemove the corresponding application if is installed.\nThe call is ignored if the app is not installed.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nappId | string | yes | The identifier of the application package to be removed | `my.app.id`\ntimeout | number | no | The count of milliseconds to wait until the app is terminated. 20000ms by default. | 1500, 0\nkeepData | boolean | no | Set to true in order to keep the application data and cache folders after uninstall. | true\n\n#### Returned Result\n\nTrue is the app has been found on the device and successfully removed. Otherwise false.\n\n### mobile: terminateApp","metadata":{"loc":{"lines":{"from":801,"to":822}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Returned Result\n\nTrue is the app has been found on the device and successfully removed. Otherwise false.\n\n### mobile: terminateApp\n\nTerminates the app and waits until the app is terminated up to the given timeout\nby checking the app state to ensure if the app process is actually stopped.\n\nThe app state check can be skipped if the given timeout is lower or equal to zero since UIAutomator driver 2.9.0.\nThe skip helps when you want to terminate the app process but do not want to check the process existence\nbecause the app under test may, for example, restart it automatically.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nappId | string | yes | The identifier of the application package to be terminated | `my.app.id`\ntimeout | number | no | The count of milliseconds to wait until the app is terminated. 500ms by default. | 1500, 0\n\n#### Returned Result\n\nTrue if the app has been successfully terminated.\n\n### mobile: installApp","metadata":{"loc":{"lines":{"from":818,"to":842}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Returned Result\n\nTrue if the app has been successfully terminated.\n\n### mobile: installApp\n\nInstalls the given application package to the device under test.\nIt might raise the `INSTALL_FAILED_VERSION_DOWNGRADE` error if the installation was a version downgrade.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":838,"to":847}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nappPath | string | yes | The local .apk(s) path on the server filesystem or a remote url. | `/app/path.apk`\ntimeout | number | no | The count of milliseconds to wait until the app is installed.. 6000ms by default. | 120000\nallowTestPackages | boolean | no | Set to true in order to allow test packages installation. false by default | true\nuseSdcard | boolean | no | Set to true to install the app on sdcard instead of the device memory. false by default | true","metadata":{"loc":{"lines":{"from":849,"to":854}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"useSdcard | boolean | no | Set to true to install the app on sdcard instead of the device memory. false by default | true\ngrantPermissions | boolean | no | Set to true in order to grant all the permissions requested in the application's manifest automatically after the installation is completed under Android 6+. The targetSdkVersion in the application manifest must be greater or equal to 23 and the Android version on the device under test must be greater or equal to Android 6 (API level 23) to grant permissions. Applications whose targetSdkVersion is lower than or equal to 22 must be reisntalled to grant permissions for Android 6+ devices. false by default | true\nreplace | boolean | no | Set it to false if you don't want the application to be upgraded/reinstalled if it is already present on the device, but throw an error instead. true by default | false","metadata":{"loc":{"lines":{"from":854,"to":856}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"replace | boolean | no | Set it to false if you don't want the application to be upgraded/reinstalled if it is already present on the device, but throw an error instead. true by default | false\ncheckVersion | boolean | no | Set to true, in order to skip the application installation if the device under test has a greater or equal to the application version. It may help to avoid `INSTALL_FAILED_VERSION_DOWNGRADE` error and unnecessary installation. | true","metadata":{"loc":{"lines":{"from":856,"to":857}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: clearApp\n\nDeletes all data associated with a package. Calls `adb shell pm clear` under the hood.\nThe app should be accessible, should not be running,\nand should exist on the device under test for this extension to work properly.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nappId | string | yes | The identifier of the application package to be cleared | `my.app.id`\n\n#### Returned Result\n\nStdout of the corresponding adb command.\n\n### mobile: startActivity\n\nStarts the given activity intent. Invokes `am start`/`am start-activity` command under the hood.\nThis method extends the functionality of the [Start Activity](#applications-management) app management API.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":859,"to":880}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nintent | string | yes | The full name of the activity intent to start | `com.some.package.name/.YourActivityClassName`\nuser | number or string | no | The user ID for which the service is started. The `current` user is used by default | 1006\nwait | boolean | no | Set it to `true` if you want to block the method call until the Activity Manager's process returns the control to the system. | false\nstop | boolean | no | Set it to `true` to force stop the target app before starting the activity. | false\nwindowingMode | integer | no | The windowing mode to launch the activity into. Check [WindowConfiguration.java](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/WindowConfiguration.java) for more details on possible windowing modes (constants starting with `WINDOWING_MODE_`). | 1","metadata":{"loc":{"lines":{"from":882,"to":888}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"activityType | integer | no | The activity type to launch the activity as. Check [WindowConfiguration.java](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/WindowConfiguration.java) for more details on possible activity types (constants starting with `ACTIVITY_TYPE_`). | 1\naction | string | no | Action name. The actual value for the Activity Manager's `-a` argument. | android.intent.action.MAIN\nuri | string | no | Unified resource identifier. The actual value for the Activity Manager's `-d` argument. | https://appium.io\nmimeType | string | no | Mime type. The actual value for the Activity Manager's `-t` argument. | application/json\nidentifier | string | no | Optional identifier. The actual value for the Activity Manager's `-i` argument. | my_identifier\ncategories | string or Array&lt;string&gt; | no | One or more category names. The actual value(s) for the Activity Manager's `-c` argument. | android.intent.category.LAUNCHER","metadata":{"loc":{"lines":{"from":889,"to":894}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"categories | string or Array&lt;string&gt; | no | One or more category names. The actual value(s) for the Activity Manager's `-c` argument. | android.intent.category.LAUNCHER\ncomponent | string | no | Component name. The actual value for the Activity Manager's `-n` argument. | com.myapp/com.myapp.SplashActivity\npackage | string | no | Package name. The actual value for the Activity Manager's `-p` argument. | com.myapp","metadata":{"loc":{"lines":{"from":894,"to":896}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"extras | Array&lt;Array&lt;string&gt;&gt; | no | Optional intent arguments. Must be represented as an array of arrays, where each subarray item contains two (only in case it no value is required for the given type) or three string items: value type, key (variable name) and the value itself. Supported value types are: `s`: string. Value must be a valid string; `sn`: null. Value is ignored for this type; `z`: boolean. Value must be either `true` or `false`; `i`: integer. Value must be a valid 4-byte integer number; `l`: long. Value must be a valid 8-byte long number; `f`: float: Value must be a valid float number; `u`: uri. Value must be a valid uniform resource identifier string; `cn`: component name. Value must be a valid component name string; `ia`: Integer[]. Value must be a string of comma-separated integers; `ial`: List&lt;Integer&gt;. Value must be a string of comma-separated integers; `la`: Long[]. Value must be a string of comma-separated long numbers; `lal`: List&lt;Long&gt;.","metadata":{"loc":{"lines":{"from":897,"to":897}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"integers; `ial`: List&lt;Integer&gt;. Value must be a string of comma-separated integers; `la`: Long[]. Value must be a string of comma-separated long numbers; `lal`: List&lt;Long&gt;. Value must be a string of comma-separated long numbers; `fa`: Float[]. Value must be a string of comma-separated float numbers; `fal`: List&lt;Float&gt;. Value must be a string of comma-separated float numbers; `sa`: String[]. Value must be comma-separated strings. To embed a comma into a string escape it using \"\\,\"; `sal`: List&lt;String&gt;. Value must be comma-separated strings. To embed a comma into a string, escape it using \"\\,\" | [['s', 'varName1', 'My String1'], ['s', 'varName2', 'My String2'], ['ia', 'arrName', '1,2,3,4']]","metadata":{"loc":{"lines":{"from":897,"to":897}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"flags | string | no | Intent startup-specific flags as a hexadecimal string. Check [Intent documentation](https://developer.android.com/reference/android/content/Intent.html) for the list of available flag values (constants starting with `FLAG_ACTIVITY_`). Flag values could be merged using the logical 'or' operation. | 0x10200000 is the combination of two flags: 0x10000000 `FLAG_ACTIVITY_NEW_TASK` `|` 0x00200000 `FLAG_ACTIVITY_RESET_TASK_IF_NEEDED`","metadata":{"loc":{"lines":{"from":898,"to":898}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Returned Result\n\nThe actual stdout of the downstream `am` command.\n\n#### Example\n\nUse the code snippet below to represent the following shell command: `shell am start-activity -W -n io.appium.android.apis/io.appium.android.apis.ApiDemos -S -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -f 0x10200000'`, which is usually similar to what is called in a new session request.\nIf you replace `'io.appium.android.apis/io.appium.android.apis.ApiDemos'` with your expected launchable activity, it would be the alternative method to start the activity in session.\n\nPlease check [how appium adds flags](https://github.com/appium/appium-android-driver/blob/master/lib/commands/intent.js) for more details to understand how Appium builds flags.","metadata":{"loc":{"lines":{"from":900,"to":909}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Please check [how appium adds flags](https://github.com/appium/appium-android-driver/blob/master/lib/commands/intent.js) for more details to understand how Appium builds flags.\n\n```ruby\n# Ruby\ndriver.execute_script 'mobile: startActivity', {\n wait: true,\n stop: true,\n action: 'android.intent.action.MAIN',\n component: 'io.appium.android.apis/io.appium.android.apis.ApiDemos',\n categories: ['android.intent.category.LAUNCHER'],\n flags: '0x10200000'\n}\n```\n\n### mobile: startService\n\nStarts the given service intent. Invokes `am startservice` or `am start-service` command under the hood.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":909,"to":927}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nintent | string | no | The full name of the service intent to start | `com.some.package.name/.YourServiceSubClassName`\nuser | number or string | no | The user ID for which the service is started. The `current` user id is used by default | 1006\nforeground | boolean | no | Set it to `true` if your service must be started as a foreground service. The argument only works for Android 8 and above. | false\naction | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | android.intent.action.MAIN\nuri | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | https://appium.io\nmimeType | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | application/json\nidentifier | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | my_identifier","metadata":{"loc":{"lines":{"from":929,"to":937}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"identifier | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | my_identifier\ncategories | string or Array&lt;string&gt; | no | See the documentation for [startActivity extension](#mobile-startactivity) | com.myapp/com.myapp.SplashActivity\ncomponent | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | android.intent.category.LAUNCHER\npackage | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | com.myapp\nextras | Array&lt;Array&lt;string&gt;&gt; | no | See the documentation for [startActivity extension](#mobile-startactivity) | [['s', 'varName1', 'My String1'], ['s', 'varName2', 'My String2'], ['ia', 'arrName', '1,2,3,4']]\nflags | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | 0x10200000 is the combination of two flags: 0x10000000 `FLAG_ACTIVITY_NEW_TASK` `|` 0x00200000 `FLAG_ACTIVITY_RESET_TASK_IF_NEEDED`","metadata":{"loc":{"lines":{"from":937,"to":942}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Returned Result\n\nThe actual stdout of the downstream `am` command.\n\n### mobile: stopService\n\nStops the given service intent. Invokes `am stopservice` or `am stop-service` command under the hood.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":944,"to":952}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nintent | string | no | The full name of the service intent to stop | `com.some.package.name/.YourServiceSubClassName`\nuser | number or string | no | The user ID for which the service is started. The `current` user id is used by default | 1006\naction | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | android.intent.action.MAIN\nuri | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | https://appium.io\nmimeType | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | application/json\nidentifier | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | my_identifier\ncategories | string or Array&lt;string&gt; | no | See the documentation for [startActivity extension](#mobile-startactivity) | com.myapp/com.myapp.SplashActivity","metadata":{"loc":{"lines":{"from":954,"to":962}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"categories | string or Array&lt;string&gt; | no | See the documentation for [startActivity extension](#mobile-startactivity) | com.myapp/com.myapp.SplashActivity\ncomponent | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | android.intent.category.LAUNCHER\npackage | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | com.myapp\nextras | Array&lt;Array&lt;string&gt;&gt; | no | See the documentation for [startActivity extension](#mobile-startactivity) | [['s', 'varName1', 'My String1'], ['s', 'varName2', 'My String2'], ['ia', 'arrName', '1,2,3,4']]\nflags | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | 0x10200000 is the combination of two flags: 0x10000000 `FLAG_ACTIVITY_NEW_TASK` `|` 0x00200000 `FLAG_ACTIVITY_RESET_TASK_IF_NEEDED`","metadata":{"loc":{"lines":{"from":962,"to":966}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: broadcast\n\nSend a broadcast Intent. Invokes `am broadcast` command under the hood.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":968,"to":972}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nintent | string | no | The full name of the intent to broadcast | `com.some.package.name/.YourIntentClassName`\nuser | number or string | no | Specify which user to send to; if not specified then send to all users. Possible values are `all`/`current`/`<numeric user id>` | current\nreceiverPermission | string | no | Require receiver to hold the given permission | android.permission.READ_PROFILE\nallowBackgroundActivityStarts | boolean | no | The receiver may start activities even if in the background if set to `true` | false\naction | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | android.intent.action.MAIN\nuri | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | https://appium.io\nmimeType | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | application/json","metadata":{"loc":{"lines":{"from":974,"to":982}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"mimeType | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | application/json\nidentifier | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | my_identifier\ncategories | string or Array&lt;string&gt; | no | See the documentation for [startActivity extension](#mobile-startactivity) | com.myapp/com.myapp.SplashActivity\ncomponent | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | android.intent.category.LAUNCHER\npackage | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | com.myapp\nextras | Array&lt;Array&lt;string&gt;&gt; | no | See the documentation for [startActivity extension](#mobile-startactivity) | [['s', 'varName1', 'My String1'], ['s', 'varName2', 'My String2'], ['ia', 'arrName', '1,2,3,4']]","metadata":{"loc":{"lines":{"from":982,"to":987}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"flags | string | no | See the documentation for [startActivity extension](#mobile-startactivity) | 0x10200000 is the combination of two flags: 0x10000000 `FLAG_ACTIVITY_NEW_TASK` `|` 0x00200000 `FLAG_ACTIVITY_RESET_TASK_IF_NEEDED`","metadata":{"loc":{"lines":{"from":988,"to":988}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Returned Result\n\nThe actual stdout of the downstream `am` command.\n\n### mobile: getContexts\n\nRetrieves a WebViews mapping based on CDP endpoints\n\n#### Arguments","metadata":{"loc":{"lines":{"from":990,"to":998}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nwaitForWebviewMs | number | no | Tells UiAutomator2 driver for how long (in milliseconds) to wait for web view(s) to appear since UiAutomator2 driver v2.53.0. If a Chrome process running on the device under test fails to create a connection to the devtools socket, then the chromedriver will rise an error similar to `failed to connect to socket 'localabstract:chrome_devtools_remote'` in UiAutomator2 driver. It could cause no WebViews found result, although a couple of retrials may fix it. This argument helps to keep trying to get WebView(s) up to the given time milliseconds as one command call. This issue tends to occur Chrome v115 and over so far. [issues#19251](https://github.com/appium/appium/issues/19251) contains more details. If set to `0`ms (the default value), then UiAutomator2 driver only checks the WebView(s) availability once. | 10000\n\n#### Returned Result","metadata":{"loc":{"lines":{"from":998,"to":1004}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Returned Result\n\nThe following json demonstrates the example of WebviewsMapping object.\nNote that `description` in `page` can be an empty string most likely when it comes to Mobile Chrome)","metadata":{"loc":{"lines":{"from":1004,"to":1007}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"```json\n {\n \"proc\": \"@webview_devtools_remote_22138\",\n \"webview\": \"WEBVIEW_22138\",\n \"info\": {\n \"Android-Package\": \"io.appium.settings\",\n \"Browser\": \"Chrome/74.0.3729.185\",\n \"Protocol-Version\": \"1.3\",\n \"User-Agent\": \"Mozilla/5.0 (Linux; Android 10; Android SDK built for x86 Build/QSR1.190920.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.185 Mobile Safari/537.36\",\n \"V8-Version\": \"7.4.288.28\",\n \"WebKit-Version\": \"537.36 (@22955682f94ce09336197bfb8dffea991fa32f0d)\",\n \"webSocketDebuggerUrl\": \"ws://127.0.0.1:10900/devtools/browser\"\n },\n \"pages\": [\n {\n \"description\": \"{\\\"attached\\\":true,\\\"empty\\\":false,\\\"height\\\":1458,\\\"screenX\\\":0,\\\"screenY\\\":336,\\\"visible\\\":true,\\\"width\\\":1080}\",\n \"devtoolsFrontendUrl\": \"http://chrome-devtools-frontend.appspot.com/serve_rev/@22955682f94ce09336197bfb8dffea991fa32f0d/inspector.html?ws=127.0.0.1:10900/devtools/page/27325CC50B600D31B233F45E09487B1F\",","metadata":{"loc":{"lines":{"from":1009,"to":1025}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"\"id\": \"27325CC50B600D31B233F45E09487B1F\",\n \"title\": \"Releases · appium/appium · GitHub\",\n \"type\": \"page\",\n \"url\": \"https://github.com/appium/appium/releases\",\n \"webSocketDebuggerUrl\": \"ws://127.0.0.1:10900/devtools/page/27325CC50B600D31B233F45E09487B1F\"\n }\n ],\n \"webviewName\": \"WEBVIEW_com.io.appium.setting\"\n }\n```","metadata":{"loc":{"lines":{"from":1026,"to":1035}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: installMultipleApks\n\nInstall applications via `install-multiple` option.\nPlease read more details in the corresponding section of the `adb --help` command output.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\napks | Array&lt;string&gt; | yes | The path to APKs. Each path should be the full path to the apk to be installed, or an URL to a remote location. | `['/path/to/local.apk', 'https://github.com/appium/ruby_lib_core/blob/master/test/functional/app/api.apk.zip?raw=true']`\noptions | object | no | Installation options. If you want enable `-g` option, you could specify that `{grantPermissions: true}`. `allowTestPackages` corresponds `-t`, `useSdcard` corresponds `-s`, `replace` corresponds `-r` (`-r` is enabled by default), `partialInstall` corresponds `-p`. | `{grantPermissions: true, partialInstall: true}`\n\n### mobile: lock","metadata":{"loc":{"lines":{"from":1037,"to":1049}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: lock\n\nLock the device (and optionally unlock it after a certain amount of time). Only simple (e.g. without a password) locks are supported.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nseconds | number|string | no | The number of seconds after which to unlock the device. Set to `0` or leave it empty to require manual unlock (e.g. do not block and automatically unlock afterwards). | 5\n\n### mobile: unlock\n\nUnlocks the device if it is locked. Noop if the device's screen is not locked.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1049,"to":1063}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: unlock\n\nUnlocks the device if it is locked. Noop if the device's screen is not locked.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nkey | string | yes | The unlock key. See the documentation on [appium:unlockKey](#device-locking) capability for more details | 12345\ntype | string | yes | The unlock type. See the documentation on [appium:unlockType](#device-locking) capability for more details | password\nstrategy | string | no | Unlock strategy. See the documentation on [appium:unlockStrategy](#device-locking) capability for more details | uiautomator\ntimeoutMs | number | no | Unlock timeout. See the documentation on [appium:unlockSuccessTimeout](#device-locking) capability for more details | 5000\n\n### mobile: isLocked\n\nDetermine whether the device is locked.\n\n#### Returned Result\n\nEither `true` or `false`\n\n### mobile: setGeolocation\n\nSets emulated geolocation coordinates on the device under test.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1059,"to":1084}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nlatitude | number | yes | [Latitude](https://en.wikipedia.org/wiki/Latitude) value | 32.456\nlongitude | number | yes | [longitude](https://en.wikipedia.org/wiki/Longitude) value | 32.456\naltitude | number | no | [Altitude](https://en.wikipedia.org/wiki/Altitude) value. Zero by default | 5.678\nsatellites | number | no | Number of satellites being tracked (1-12). Available for emulators. | 2\nspeed | number | no | [Set the speed](https://developer.android.com/reference/android/location/Location#setSpeed(float)) in meters per second. Valid value is `0.0` or greater. | 30.0\nbearing | number | no | [Set the bearing](https://developer.android.com/reference/android/location/Location#setBearing(float)) at the time of this location, in degrees. Available for real devices. Valid values should be in range `[0, 360)`. | 10","metadata":{"loc":{"lines":{"from":1086,"to":1093}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"accuracy | number | no | [Set the horizontal accuracy](https://developer.android.com/reference/android/location/Location#setAccuracy(float)) in meters of this location. Available for real devices. Valid value is `0.0` or greater. | 10.0","metadata":{"loc":{"lines":{"from":1094,"to":1094}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: getGeolocation\n\nRetrieves current geolocation coordinates from the device under test. If coordinates are mocked/emulated\nthen these coordinates would be returned.\n\n#### Returned Result\n\nA map with the following entries:\n\nName | Type | Description | Example\n--- | --- | --- | ---\nlatitude | number | [Latitude](https://en.wikipedia.org/wiki/Latitude) value | 32.456\nlongitude | number | [longitude](https://en.wikipedia.org/wiki/Longitude) value | 32.456\naltitude | number | [Altitude](https://en.wikipedia.org/wiki/Altitude) value | 5.678\n\n### mobile: resetGeolocation\n\nResets mocked geolocation provider to the default/system one. Only works for real devices.\n\n### mobile: refreshGpsCache","metadata":{"loc":{"lines":{"from":1096,"to":1115}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: resetGeolocation\n\nResets mocked geolocation provider to the default/system one. Only works for real devices.\n\n### mobile: refreshGpsCache\n\nSends a request to refresh the GPS cache on the device under test.\nBy default the location tracking is configured for\n[low battery consumption](https://github.com/appium/io.appium.settings/blob/master/app/src/main/java/io/appium/settings/LocationTracker.java),\nso you might need to call this extension periodically to get the updated geo\nlocation if the actual (or mocked) device location is changed too frequently.\nThe feature only works if the device under test has Google Play Services installed.\nIn case the vanilla\n[LocationManager](https://developer.android.com/reference/android/location/LocationManager)\nis used the device API level must be at version 30 (Android R) or higher.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1111,"to":1127}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ntimeoutMs | number | no | The maximum number of milliseconds to block until GPS cache is refreshed. If the API call does not receive a confirmation about successful cache refresh within this timeout then an error is thrown. Providing zero or a negative value to it skips waiting completely and does not check for any errors. 20000 ms by default. | 60000\n\n### mobile: startMediaProjectionRecording\n\nStarts a new recording of the device activity using [Media Projection](https://developer.android.com/reference/android/media/projection/MediaProjection) API. This API is available since Android 10 (API level 29) and allows to record device screen and audio in high quality. Video and audio encoding is done by Android itself.\nThe recording is done by [Appium Settings helper](https://github.com/appium/io.appium.settings#internal-audio--video-recording).\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1127,"to":1138}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nresolution | string | no | The resolution of the resulting video, which usually equals to Full HD 1920x1080 on most phones, however you could change it to one of the following supported resolutions: \"1920x1080\", \"1280x720\", \"720x480\", \"320x240\", \"176x144\" | 1280x720\nmaxDurationSec | number | no | The maximum number of seconds allowed for the recording to run. 900 seconds by default (15 minutes) | 300\npriority | string | no | Recording thread priority is set to maximum (`high`) by default. However if you face performance drops during testing with recording enabled, you could reduce the recording priority to `normal` or `low`. | low","metadata":{"loc":{"lines":{"from":1140,"to":1144}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"filename | string | no | You can type recording video file name as you want, but recording currently supports only \"mp4\" format so your filename must end with \".mp4\". An invalid file name will fail to start the recording. If not provided then the current timestamp will be used as file name. | screen.mp4","metadata":{"loc":{"lines":{"from":1145,"to":1145}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Returned Result\n\n`true` if a new recording has successfully started. `false` if another recording is currently running.\n\n### mobile: isMediaProjectionRecordingRunning\n\nCheck if a media projection recording is currently running\n\n#### Returned Result\n\n`true` if a recording is running.\n\n### mobile: stopMediaProjectionRecording\n\nStops a recording and retrieves the recently recorded media. If no recording has been started before then an error is thrown. If the recording has been already finished before this API has been called then the most recent recorded media is returned.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1147,"to":1163}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nremotePath | string | no | The path to the remote location, where the resulting video should be uploaded. The following protocols are supported: http/https, ftp. Null or empty string value (the default setting) means the content of resulting file should be encoded as Base64 and passed as the endpoont response value. An exception will be thrown if the generated media file is too big to fit into the available process memory. | https://myserver.com/upload\nuser | string | no | The name of the user for the remote authentication. | admin\npass | string | no | The password for the remote authentication. | pa$$w0rd\nmethod | string | no | The http multipart upload method name. The 'PUT' one is used by default. | POST\nheaders | Map&lt;string, string&gt; | no | Additional headers mapping for multipart http(s) uploads | {'Agent': '007'}","metadata":{"loc":{"lines":{"from":1165,"to":1171}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"headers | Map&lt;string, string&gt; | no | Additional headers mapping for multipart http(s) uploads | {'Agent': '007'}\nfileFieldName | string | no | The name of the form field, where the file content BLOB should be stored for http(s) uploads. `file` by default | blob\nformFields | Map&lt;string, string&gt; or Array&lt;Pair&gt; | no | Additional form fields for multipart http(s) uploads. | {'name': 'yolo.mp4'}\nuploadTimeout | number | no | The maximum number of milliseconds to wait until the media file is uploaded to the remote location. 240000 ms by default. | 30000","metadata":{"loc":{"lines":{"from":1171,"to":1174}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Returned Result\n\nBase64-encoded content of the recorded media file if `remotePath` argument is falsy or an empty string.\n\n### mobile: getConnectivity\n\nReturns connectivity states for different services\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nservices | string or string[] | no | One or more services to get the connectivity for. Supported service names are: wifi, data, airplaneMode. If no service names are provided then all supported names are assumed by default. | [wifi, data]\n\n#### Returned Result\n\nA map is returned containing the following possible items (depending on which values have been passed to `services` argument):\n\nName | Type | Description\n--- | --- | ---\nwifi | boolean | True if wifi is enabled\ndata | boolean | True if mobile data connection is enabled\nairplaneMode | boolean | True if Airplane Mode is enabled\n\n### mobile: setConnectivity","metadata":{"loc":{"lines":{"from":1176,"to":1200}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: setConnectivity\n\nSet the connectivity state for different services. At least one valid service name must be provided in arguments.\nMissing values tell the driver to not change the corresponding service's state.\n\n> [!Note]\n>\n> Switching Wi-Fi and mobile data states reliably work on emulators for all Android versions.\n> Real devices support proper state switching only since Android 11.\n\n> [!Note]\n>\n> UiAutomator2 REST server app is running on the device under test and might be terminated/disconnected by Android\n> thus failing the driver session as a result of using this API. The only way to restore the session would be to quit it\n> after the network state is changed and then reopen it with `noReset` capability being set to `true` when the connectivity\n> is restored.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1200,"to":1217}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nwifi | booolean | no | Either to enable or disable Wi-Fi. | false\ndata | booolean | no | Either to enable or disable mobile data. | false\nairplaneMode | booolean | no | Either to enable or disable Airplane Mode. | false\n\n### mobile: getAppStrings\n\nRetrieves string resources for the given app language. An error is thrown if strings cannot be fetched or no strings exist\nfor the given language abbreviation. Available since driver version 2.15.0\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nlanguage | string | no | The language abbreviation to fetch app strings mapping for. If no language is provided then strings for the default language on the device under test would be returned | fr\n\n#### Returned Result\n\nApp strings map, where keys are resource identifiers.\n\n### mobile: hideKeyboard","metadata":{"loc":{"lines":{"from":1217,"to":1240}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Returned Result\n\nApp strings map, where keys are resource identifiers.\n\n### mobile: hideKeyboard\n\nTries to hide the on-screen keyboard. Throws an exception if the keyboard cannot be hidden.\nDoes nothing if the keyboard is already hidden.\n\n#### Returned Result\n\n`true` if the keyboard was successfully hidden or `false` if it was already invisible.\n\n### mobile: isKeyboardShown\n\nChecks if the system on-screen keyboard is visible.\n\n#### Returned Result\n\n`true` if the keyboard is visible\n\n### mobile: pressKey\n\nEmulates single key press on the key with the given code. Available since driver version 2.17.0\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1236,"to":1261}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: pressKey\n\nEmulates single key press on the key with the given code. Available since driver version 2.17.0\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nkeycode | number | yes | A valid Android key code. See [KeyEvent documentation](https://developer.android.com/reference/android/view/KeyEvent) for the list of available key codes | 0x00000099 (which is KEYCODE_NUMPAD_9)\nmetastate | number | no | An integer in which each bit set to 1 represents a pressed meta key. See [KeyEvent documentation](https://developer.android.com/reference/android/view/KeyEvent) for more details. | 0x00000010 (which is META_ALT_LEFT_ON)\nflags | number | no | Flags for the particular key event. See [KeyEvent documentation](https://developer.android.com/reference/android/view/KeyEvent) for more details. | 0x00000001 (which is FLAG_WOKE_HERE)\nisLongPress | boolean | no | Whether to emulate long key press. `false` by default. | true","metadata":{"loc":{"lines":{"from":1257,"to":1268}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: backgroundApp\n\nPuts the app to the background and waits the given number of seconds. Then restores the app\nif necessary. The call is blocking. Available since driver version 2.19.0\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nseconds | number | no | The amount of seconds to wait between putting the app to background and restoring it. Any negative value means to not restore the app after putting it to background (the default behavior). | 5\n\n### mobile: getCurrentActivity\n\nReturns the name of the currently focused app activity. Available since driver version 2.20\n\n#### Returned Result\n\nThe activity class name. Could be `null`\n\n### mobile: getCurrentPackage\n\nReturns the name of the currently focused app package identifier. Available since driver version 2.20\n\n#### Returned Result\n\nThe package class name. Could be `null`\n\n### mobile: getDisplayDensity","metadata":{"loc":{"lines":{"from":1270,"to":1297}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Returns the name of the currently focused app package identifier. Available since driver version 2.20\n\n#### Returned Result\n\nThe package class name. Could be `null`\n\n### mobile: getDisplayDensity\n\nReturns the display density value measured in DPI. Available since driver version 2.21\n\n#### Returned Result\n\nThe actual DPI value as integer number\n\n### mobile: getSystemBars\n\nReturns properties of various system bars. Available since driver version 2.21\n\n#### Returned Result\n\nA dictionary whose entries are:\n- `statusBar`\n- `navigationBar`","metadata":{"loc":{"lines":{"from":1291,"to":1313}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: getSystemBars\n\nReturns properties of various system bars. Available since driver version 2.21\n\n#### Returned Result\n\nA dictionary whose entries are:\n- `statusBar`\n- `navigationBar`\n\nValues are dictionaries with the following properties:\n- `visible`: Whether the bar is visible (equals to `false` if the bar is not present in the system info output)\n- `x`: Bar x coordinate (might be zero if the bar is not present in the system info output)\n- `y`: Bar y coordinate (might be zero if the bar is not present in the system info output)\n- `width`: Bar width (might be zero if the bar is not present in the system info output)\n- `height`: Bar height (might be zero if the bar is not present in the system info output)\n\n### mobile: fingerprint\n\nEmulate [fingerprint](https://learn.microsoft.com/en-us/xamarin/android/platform/fingerprint-authentication/enrolling-fingerprint) on Android Emulator. Only works on API 23+. Available since driver version 2.22\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1305,"to":1326}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nfingerprintId | number | yes | The value is the id for the finger that was \"scanned\". It is a unique integer that you assign for each virtual fingerprint. When the app is running you can run this same command each time the emulator prompts you for a fingerprint, you can run the adb command and pass it the fingerprintId to simulate the fingerprint scan. | 1\n\n### mobile: sendSms\n\nEmulate sending an SMS to the given phone number. Only works on emulators. Available since driver version 2.22\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nphoneNumber | string | yes | The phone number to send SMS to | 0123456789\nmessage | string | yes | The SMS message payload | Hello\n\n### mobile: gsmCall\n\nEmulate a GSM call to the given phone number. Only works on emulators. Available since driver version 2.22\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1326,"to":1347}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: gsmCall\n\nEmulate a GSM call to the given phone number. Only works on emulators. Available since driver version 2.22\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nphoneNumber | string | yes | The phone number to call to | 0123456789\naction | call or accept or cancel or hold | yes | One of possible actions to take | accept\n\n### mobile: gsmSignal\n\nEmulate GSM signal strength change event. Only works on emulators. Available since driver version 2.22\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nstrength | 0 or 1 or 2 or 3 or 4 | yes | One of possible signal strength values, where 4 is the best signal. | 3\n\n### mobile: gsmVoice\n\nEmulate GSM voice state change event. Only works on emulators. Available since driver version 2.22\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1343,"to":1368}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: gsmVoice\n\nEmulate GSM voice state change event. Only works on emulators. Available since driver version 2.22\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nstate | on or off or denied or searching or roaming or home or unregistered | yes | Voice state | off\n\n### mobile: powerAC\n\nEmulate AC power state change. Only works on emulators. Available since driver version 2.22\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nstate | on or off | yes | AC Power state | off\n\n### mobile: powerCapacity\n\nEmulate power capacity change. Only works on emulators. Available since driver version 2.22\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\npercent | 0 to 100 | yes | Percentage value in range [0, 100] | 50\n\n### mobile: networkSpeed\n\nEmulate different network connection speed modes. Only works on emulators. Available since driver version 2.22","metadata":{"loc":{"lines":{"from":1364,"to":1396}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: networkSpeed\n\nEmulate different network connection speed modes. Only works on emulators. Available since driver version 2.22\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nspeed | gsm or scsd or gprs or edge or umts or hsdpa or lte or evdo or full | yes | Mobile network speed mode name | edge\n\n### mobile: replaceElementValue\n\nSends a text to the given element by replacing its previous content. Available since driver version 2.22\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1394,"to":1408}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: replaceElementValue\n\nSends a text to the given element by replacing its previous content. Available since driver version 2.22\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId | string | yes | Hexadecimal identifier of the destination text input | 123456-3456-3435-3453453\ntext | string | yes | The text to enter. It could also contain Unicode characters. If the text ends with `\\\\n` (the backslash must be escaped, so the char is NOT translated into `0x0A`) then the Enter key press is going to be emulated after it is entered (the `\\\\n` substring itself will be cut off from the typed text). | yolo\n\n### mobile: toggleGps\n\nSwitches GPS setting state. This API only works reliably since Android 12 (API 31). Available since driver version 2.23\n\n### mobile: isGpsEnabled\n\nReturns `true` if GPS is enabled on the device under test. Available since driver version 2.23\n\n### mobile: getPerformanceDataTypes","metadata":{"loc":{"lines":{"from":1404,"to":1423}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: isGpsEnabled\n\nReturns `true` if GPS is enabled on the device under test. Available since driver version 2.23\n\n### mobile: getPerformanceDataTypes\n\nFetches the list of supported performance data types that could be used as `dataType` argument value to [mobile: getPerformanceData](#mobile-getperformancedata) extension. Available since driver version 2.24\n\n#### Returned Result\n\nList of strings, where each item is data type name.\n\n### mobile: getClipboard\n\nRetrieves the plaintext content of the device's clipboard. Available since driver version 3.7\n\n#### Returned Result\n\nBase64-encoded content of the clipboard or an empty string if the clipboard is empty.\n\n### mobile: setClipboard\n\nAllows to set the plain text content of the device's clipboard. Available since driver version 3.7\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1419,"to":1443}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: setClipboard\n\nAllows to set the plain text content of the device's clipboard. Available since driver version 3.7\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ncontent | string | yes | Base64-encoded clipboard payload. | YXBwaXVt\ncontentType | string | no | The only supported and the default value is `plaintext` | plaintext\nlable | string | no | Optinal label to identify the current clipboard payload. | yolo\n\n### mobile: getPerformanceData\n\nRetrieves performance data about the given Android subsystem. The data is parsed from the output of the dumpsys utility. Available since driver version 2.24\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1439,"to":1455}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Retrieves performance data about the given Android subsystem. The data is parsed from the output of the dumpsys utility. Available since driver version 2.24\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\npackageName | string | yes | The name of the package identifier to fetch the data for | com.myapp\ndataType | string | yes | One of supported subsystem names. The full list of supported values is returned by [mobile: getPerformanceDataTypes](#mobile-getperformancedatatypes) extension. | batteryinfo or cpuinfo or memoryinfo or networkinfo\n\n#### Returned Result\n\nThe output depends on the selected subsystem. It is organized into a table, where the first row represents column names and the following rows represent the sampled data for each column.\nExample output for different data types:","metadata":{"loc":{"lines":{"from":1453,"to":1465}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"- batteryinfo:\n```\n[\n [power],\n [23]\n]\n```\n- memoryinfo:\n```\n[\n [totalPrivateDirty, nativePrivateDirty, dalvikPrivateDirty, eglPrivateDirty, glPrivateDirty, totalPss, nativePss, dalvikPss, eglPss, glPss, nativeHeapAllocatedSize, nativeHeapSize],\n [18360, 8296, 6132, null, null, 42588, 8406, 7024, null, null, 26519, 10344]\n]\n```\n- networkinfo:\n```\n// emulator\n[\n [bucketStart, activeTime, rxBytes, rxPackets, txBytes, txPackets, operations, bucketDuration],\n [1478091600000, null, 1099075, 610947, 928, 114362, 769, 0, 3600000],\n [1478095200000, null, 1306300, 405997, 509, 46359, 370, 0, 3600000]\n]\n// real devices\n[\n [st, activeTime, rb, rp, tb, tp, op, bucketDuration],\n [1478088000, null, null, 32115296, 34291, 2956805, 25705, 0, 3600],\n [1478091600, null, null, 2714683, 11821, 1420564, 12650, 0, 3600],\n [1478095200, null, null, 10079213, 19962, 2487705, 20015, 0, 3600],\n [1478098800, null, null, 4444433, 10227, 1430356, 10493, 0, 3600]\n]\n```\n- cpuinfo:\n```\n[","metadata":{"loc":{"lines":{"from":1467,"to":1500}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"[1478095200, null, null, 10079213, 19962, 2487705, 20015, 0, 3600],\n [1478098800, null, null, 4444433, 10227, 1430356, 10493, 0, 3600]\n]\n```\n- cpuinfo:\n```\n[\n [user, kernel],\n [0.9, 1.3]\n]\n```","metadata":{"loc":{"lines":{"from":1494,"to":1504}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: statusBar\n\nPerforms commands on the system status bar. A thin wrapper over `adb shell cmd statusbar` CLI. Works on Android 8 (Oreo) and newer. Available since driver version 2.25\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ncommand | string | yes | One of [supported status bar commands](#status-bar-commands). | expandNotifications\ncomponent | string | no | The name of the tile component. It is only required for (add\\|remove\\|click)Tile commands. | com.package.name/.service.QuickSettingsTileComponent\n\n#### Status Bar Commands","metadata":{"loc":{"lines":{"from":1506,"to":1517}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Status Bar Commands\n\n- expandNotifications: Open the notifications panel.\n- expandSettings: Open the notifications panel and expand quick settings if present.\n- collapse: Collapse the notifications and settings panel.\n- addTile: Add a TileService of the specified component.\n- removeTile: Remove a TileService of the specified component.\n- clickTile: Click on a TileService of the specified component.\n- getStatusIcons: Returns the list of status bar icons and the order they appear in. Each list item is separated with a new line character.\n\n#### Returned Result\n\nThe actual downstream command output. It depends on the selected command and might be empty.\n\n### mobile: scheduleAction\n### mobile: unscheduleAction\n### mobile: getActionHistory\n\nThese extensions allow to deal with short-living UI elements. Read [the documentation on Scheduled Actions](docs/scheduled-actions.md) for more details and code examples.\n\n### mobile: screenshots","metadata":{"loc":{"lines":{"from":1517,"to":1537}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"These extensions allow to deal with short-living UI elements. Read [the documentation on Scheduled Actions](docs/scheduled-actions.md) for more details and code examples.\n\n### mobile: screenshots\n\nRetrieves a screenshot of each display available to Android.\nThis functionality is only supported since Android 10.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ndisplayId | number or string | no | Display identifier to take a screenshot for. If not provided then all display screenshots are going to be returned. If no matches were found then an error is thrown. Actual display identifiers could be retrived from the `adb shell dumpsys SurfaceFlinger --display-id` command output. | 1\n\n#### Returns","metadata":{"loc":{"lines":{"from":1535,"to":1548}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Returns\n\nA dictionary where each key is the display identifier and the value has the following keys:\n- `id`: The same display identifier\n- `name`: Display name\n- `isDefault`: Whether this display is the default one\n- `payload`: The actual PNG screenshot data encoded to base64 string\n\n### mobile: setUiMode\n\nSet the device UI appearance. A thin wrapper over `adb shell cmd uimode` CLI.\nWorks on Android 10 and newer. Available since driver version 2.34\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nmode | string | yes | One of the supported UI mode names: `night` or `car`. | night\nvalue | string | yes | The actual mode value to set. Supported values for different UI modes are: `night`: yes,no,auto,custom_schedule,custom_bedtime, `car`: yes,no. For example, to switch the device UI to the dark mode you should set `mode` to `night` and `value` to `yes`, or to `no` in order to switch back to the light mode. | yes\n\n### mobile: getUiMode","metadata":{"loc":{"lines":{"from":1548,"to":1568}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: getUiMode\n\nGets the device UI appearance for the given mode. A thin wrapper over `adb shell cmd uimode` CLI. Works on Android 10 and newer. Available since driver version 2.34\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nmode | string | yes | One of the supported UI mode names: `night` or `car`. | night\n\n#### Returned Result\n\nThe actual mode value. Supported values for different UI modes are:\n\n- `night`: yes,no,auto,custom_schedule,custom_bedtime\n- `car`: yes,no\n\n### mobile: sendTrimMemory\n\nSimulates the [onTrimMemory()](https://developer.android.com/reference/android/content/ComponentCallbacks2#onTrimMemory(int)) event for the given package, which allows to verify the app functinality under different RAM-related circumstances.\nRead [Manage your app's memory](https://developer.android.com/topic/performance/memory) for more details.\nAvailable since driver version 2.41\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1568,"to":1591}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\npkg | string | yes | The package name to send the `trimMemory` event to. | com.my.company\nlevel | 'COMPLETE' or 'MODERATE' or 'BACKGROUND' or 'UI_HIDDEN' or 'RUNNING_CRITICAL' or 'RUNNING_LOW' or 'RUNNING_MODERATE' | yes | The actual memory trim level to simulate | RUNNING_CRITICAL\n\n### mobile: injectEmulatorCameraImage\n\nSimulates an image injection into the VirtualScene emulator camera background.\nCalls to this extension should seamlessly change the foreground picture\nin the VirtualScene emulator camera view to the supplied one.\nThis extension could, for example, be useful if you need to verify QR codes scanning\nby the application under test.\nAvailable since driver version 3.2.0\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1591,"to":1607}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\npayload | string | yes | A valid base64-encoded .PNG image payload. Other image formats are not supported. This image will be shown on the virtual scene foreground as soon as you open a camera client app. | iVBORw0KGgoAAAANSUh...\n\n#### Required Preconditions\n\nThis feature only works on Android emulators.\nIt is mandatory to provide a value (it could also be an empty map to use defaults) to\nthe [appium:injectedImageProperties capability](#emulator-android-virtual-device)\nin order to prepare the emulator for image injection if this extension is used\non a newly created or resetted device.\n\nThere is also a possiblity to perform a manual configuration of the necessary preconditions\nif you don't want to restart the emulator on session startup. For that replace the content\nof the `Toren1BD.posters` file located in `$ANDROID_HOME/emulator/resources` folder with the\nfollowing text:","metadata":{"loc":{"lines":{"from":1607,"to":1624}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"```\nposter wall\nsize 2 2\nposition -0.807 0.320 5.316\nrotation 0 -150 0\ndefault poster.png\n\nposter table\nsize 1 1\nposition 0 0 -1.5\nrotation 0 0 0\n```\n\nSave the changed file and re(start) the emulator to pick up the changes.\nYou may also customize values for different image properties under `poster table` in the above\ntext snippet.\n\n### mobile: bluetooth\n\nAllows to control the bluetooth adapter in the device under test.\nAn error is thrown if the device has no default bluetooth adapter.\nAvailable since driver version 3.4.0\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\naction | string | yes | The action to execute on the bluetooth adapter. The following actions are supported: `enable`, `disable`, `unpairAll`. Calling the same action more than once is a noop. | disable\n\n### mobile: nfc\n\nAllows to control the NFC adapter in the device under test.\nAn error is thrown if the device has no default NFC adapter.\nAvailable since driver version 3.4.0","metadata":{"loc":{"lines":{"from":1626,"to":1659}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### mobile: nfc\n\nAllows to control the NFC adapter in the device under test.\nAn error is thrown if the device has no default NFC adapter.\nAvailable since driver version 3.4.0\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\naction | string | yes | The action to execute on the NFC adapter. The following actions are supported: `enable`, `disable`. Calling the same action more than once is a noop. | disable\n\n## Applications Management","metadata":{"loc":{"lines":{"from":1655,"to":1667}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"UiAutomator2 driver supports Appium endpoints for applications management:\n- Check if app is installed ([mobile: isAppInstalled](#mobile-isappinstalled))\n- Install/upgrade app ([mobile: installApp](#mobile-installapp))\n- Activate app ([mobile: activateApp](#mobile-activateapp))\n - Since UIAutomator2 driver v2.2.0, the server calls `am start`/`am start-activity` to start the application on devices with API level 24+. [monkey](https://developer.android.com/studio/test/other-testing-tools/monkey) tool is called on devices below API level 24.\n - UIAutomator2 driver v2.1.2 and lower versions call the `monkey` tool on all devices.\n - The `monkey` tool [turns on auto rotation](https://stackoverflow.com/questions/56684778/adb-shell-monkey-command-changing-device-orientation-lock), so please consider using [mobile: startActivity](#mobile-startactivity) if you would like to keep your current rotation preferences.\n- Uninstall app ([mobile: removeApp](#mobile-removeapp))","metadata":{"loc":{"lines":{"from":1669,"to":1676}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"- Uninstall app ([mobile: removeApp](#mobile-removeapp))\n- Terminate app ([mobile: terminateApp](#mobile-terminateapp))\n- Start app activity ([mobile: startActivity](#mobile-startactivity))\n- Query the current app state ([mobile: queryAppState](#mobile-queryappstate))\n- Background app ([mobile: backgroundApp](#mobile-backgroundapp))","metadata":{"loc":{"lines":{"from":1676,"to":1680}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Refer to the corresponding Appium client tutorial to find out the names of the corresponding wrappers for these APIs.\n\nUseful links:\n- https://appiumpro.com/editions/9-testing-android-app-upgrades\n- https://github.com/appium/python-client/blob/master/appium/webdriver/extensions/applications.py\n- https://github.com/appium/java-client/blob/master/src/main/java/io/appium/java_client/InteractsWithApps.java\n\n\n## Files Management\n\nUiAutomator2 driver supports Appium endpoints for files management:\n- Push file ([mobile: pushFile](#mobile-pushfile))\n- Pull file ([mobile: pullFile](#mobile-pullfile))\n- Pull folder ([mobile: pullFolder](#mobile-pullfolder))\n\nRefer to the corresponding Appium client tutorial to find out the names of the corresponding wrappers for these APIs.\n\nUseful links:\n- https://github.com/appium/java-client/blob/master/src/main/java/io/appium/java_client/PushesFiles.java\n- https://github.com/appium/python-client/blob/master/appium/webdriver/extensions/remote_fs.py","metadata":{"loc":{"lines":{"from":1682,"to":1701}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"## Clipboard Management\n\nUiAutomator2 driver supports Appium endpoints for clipboard management:\n- Set clipboard content (`POST /appium/device/set_clipboard'`)\n- Get clipboard content (`POST /appium/device/get_clipboard`)\n- [mobile: getClipboard](#mobile-getclipboard)\n- [mobile: setClipboard](#mobile-setclipboard)\n\nUseful links:\n- https://github.com/appium/python-client/blob/master/appium/webdriver/extensions/clipboard.py\n- https://github.com/appium/java-client/blob/master/src/main/java/io/appium/java_client/clipboard/HasClipboard.java\n- https://appiumpro.com/editions/16-automating-the-clipboard-on-ios-and-android\n\n\n## Hybrid Mode\n\nUIA2 driver supports automation of web pages opened in mobile Chrome or Chromium, and\nhybrid apps that use Chrome-based web views, by managing a\n[Chromedriver](https://sites.google.com/a/chromium.org/chromedriver/) instance and\nproxying commands to it when necessary.\n\nThe following endpoints are used to control the current context:","metadata":{"loc":{"lines":{"from":1704,"to":1725}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"The following endpoints are used to control the current context:\n\n- POST `/session/:sessionId/context`: To set the current context. The body contains a single mandatory `name` parameter, which has the name of the context to be set. The name of the default context is `NATIVE_APP`.\n- GET `/session/:sessionId/context`: To retrieve the name of the current context\n- GET `/session/:sessionId/contexts`: To retrieve the list of available context names\n- [mobile: getContexts](#mobile-getcontexts)","metadata":{"loc":{"lines":{"from":1725,"to":1730}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"By default, the driver starts in the native context, which means that most of REST API commands are being\nforwarded to the downstream [appium-uiautomator2-server](https://github.com/appium/appium-uiautomator2-server).\nThis server is running on the device under test, and trasforms API commands to appropriate low-level UiAutomator framework calls. There is always only one native context, although multiple web contexts are possible.\nEach web context could contain zero or more pages/windows. It is possible to start UIA2 driver session in web context by default by setting the `browserName` capability value or by enabling the `appium:autoWebview` capability.","metadata":{"loc":{"lines":{"from":1732,"to":1735}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Web context(s) could be detected if a browser or a web view is active on the device. If a context is switched to\na web one then UIA2 driver spins up a Chromedriver instance for it and forwards most of the commands\nto that Chromedriver instance. Note that web views must be properly configured and\ndebuggable in order to connect to them or get their names in the list of available contexts.\nThe availability of a particular web view could be easily verified by using\n[Chrome Remote Debugger](https://developer.chrome.com/docs/devtools/remote-debugging/).\nYou could switch between different contexts (and windows in them) at any time during the session.","metadata":{"loc":{"lines":{"from":1737,"to":1743}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"The [appium-chromedriver](https://github.com/appium/appium-chromedriver) package bundled with UIA2 always\ntries to download the most recent version of Chromedriver known to it. Google requires that the used Chromedriver version must always match to the version of the browser or a web view engine being automated. If these versions do not match then Chromedriver fails its creation, and context switch API shows a failure message\nsimilar to:\n\n```\nAn unknown server-side error occurred while processing the command.\nOriginal error: unknown error: Chrome version must be >= 55.0.2883.0\n```\n\nTo work around this issue it is necessary to provide UIA2 driver with a proper Chromedriver binary\nthat matches to the Chrome engine version running on the device under test.\nRead the [Chromedriver/Chrome compatibility](#chromedriverchrome-compatibility) topic below to\nknow more about finding a matching Chromedriver executable.\n\nThere are several ways to provide a customized Chromedriver to UIA2 driver:","metadata":{"loc":{"lines":{"from":1745,"to":1759}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"There are several ways to provide a customized Chromedriver to UIA2 driver:\n\n#### When installing the driver\n\n_Note_: This only works for driver versions below 3.8.0\n\nSpecify the Chromedriver version in the `CHROMEDRIVER_VERSION` environment variable:\n\n```bash\nCHROMEDRIVER_VERSION=2.20 appium install driver uiautomator2\n```\n\n#### When starting a session (manual discovery)\n\nChromedriver version can be specified in session capabilities, by providing the\n`appium:chromedriverExecutable` [capability](#web-context),\ncontaining the full path to a matching Chromedriver executable, which must be manually\ndownloaded and put to the server file system.\n\n#### When starting a session (automated discovery)","metadata":{"loc":{"lines":{"from":1759,"to":1778}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"#### When starting a session (automated discovery)\n\nUIA2 driver could also try to detect the version of the target Chrome engine and\ndownload matching chromedriver for it automatically if it does not exist on the local file system.\nRead the [Automatic discovery of compatible Chromedriver](#automatic-discovery-of-compatible-chromedriver)\ntopic below for more details.\n\n### Chromedriver/Chrome Compatibility\n\nSince version *2.46* Google has changed their rules for Chromedriver versioning, so now the major Chromedriver version corresponds to the major web view/browser version, that it can automate. Follow the [Version Selection](https://chromedriver.chromium.org/downloads/version-selection) document in order to manually find the Chromedriver, that supports your current browser/web view if its major version is equal or above *73*.","metadata":{"loc":{"lines":{"from":1778,"to":1787}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"To find the minimum supported browsers for older Chromedriver versions (below *73*), get the\n[Chromium](https://www.chromium.org/Home)\n[source code](https://chromium.googlesource.com/chromium/src/+/master/docs/get_the_code.md),\ncheck out the release commit, and check the variable `kMinimumSupportedChromeVersion`\nin the file `src/chrome/test/chromedriver/chrome/version.cc`. (To find the\nrelease commits, you could use `git log --pretty=format:'%h | %s%d' | grep -i \"Release Chromedriver version\"`.)\n\nThe complete list of available Chromedriver releases and release notes is located at [Chromedriver Storage](https://chromedriver.storage.googleapis.com/index.html).\n\nThe list of Chromedriver versions and their matching minimum\nChrome versions known to appium-chromedriver package is stored at\nhttps://raw.githubusercontent.com/appium/appium-chromedriver/master/config/mapping.json\n\n### Automatic Discovery of Compatible Chromedriver","metadata":{"loc":{"lines":{"from":1789,"to":1802}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### Automatic Discovery of Compatible Chromedriver\n\nUIA2 driver is able to pick the correct Chromedriver for the\nversion of Chrome/web view under test. While appium-chromedriver only comes bundled with the Chromedriver\nmost recently released at the time of the corresponding package version's release, more Chromedriver\nversions could be downloaded and placed into a custom location indicated to UIA2 driver via the `appium:chromedriverExecutableDir` [capability](#web-context).\n\nA custom mapping of Chromedrivers to the minimum\nChrome/web view version they support could be given to UIA2 driver through the\n`appium:chromedriverChromeMappingFile` [capability](#web-context). This should be the\nabsolute path to a file with the mapping\nin it. The contents of the file needs to be parsable as a JSON object, like:\n\n```json\n{\n \"2.42\": \"63.0.3239\",\n \"2.41\": \"62.0.3202\"\n}\n```","metadata":{"loc":{"lines":{"from":1802,"to":1820}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"```json\n{\n \"2.42\": \"63.0.3239\",\n \"2.41\": \"62.0.3202\"\n}\n```\n\nThere is a possibility to automatically download the necessary chromedriver(s) into `appium:chromedriverExecutableDir` from the official Google storage. The script will automatically search for the newest chromedriver version that supports the given browser/web view, download it (the hash sum is verified as well for the downloaded archive) and add to the `appium:chromedriverChromeMappingFile` mapping. Everything, which is needed to be done from your side is to execute the server with `chromedriver_autodownload` feature enabled (like `appium server --allow-insecure chromedriver_autodownload`).\n\n### Troubleshooting Chromedriver Download Issues\n\nCheck the [Custom binaries url](https://github.com/appium/appium-chromedriver?tab=readme-ov-file#custom-binaries-url)\nsection of appium-chromedriver README for more details on how to customize the download CDN.","metadata":{"loc":{"lines":{"from":1815,"to":1827}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"It may also be necessary to adjust network proxy and firewall settings for the above to work.\n\nIf you use a UIA2 driver below version 3.8.0, and you\nwould like skip the automated download of Chromedriver upon driver install, do it by\ndefining the `APPIUM_SKIP_CHROMEDRIVER_INSTALL` environment variable:\n\n```bash\nAPPIUM_SKIP_CHROMEDRIVER_INSTALL=1 appium driver install uiautomator2\n```\n\n### W3C Support in Web Context","metadata":{"loc":{"lines":{"from":1829,"to":1839}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"```bash\nAPPIUM_SKIP_CHROMEDRIVER_INSTALL=1 appium driver install uiautomator2\n```\n\n### W3C Support in Web Context\n\nChromedriver did not follow the W3C standard until version 75. If you encounter proxy command error like [this issue](https://github.com/appium/python-client/issues/234), please update your Chromedriver version.\nOld Android devices can't use newer Chromedriver versions. You could avoid the error if you enforce\nMobile JSON Wire Protocol for Chromedriver. This could be done by providing `{'w3c': False}` item\nto `appium:chromeOptions` capability value.\nSince major version *75* W3C mode is the default one for Chromedriver, although it could be still switched to JSONWP one as described above (keep in mind that eventually Chromedriver will drop the support of\nJSON Wire protocol completely).\nThe history of W3C support in Chromedriver is available for reading at\n[downloads section](https://sites.google.com/a/chromium.org/chromedriver/downloads).\n\n\n## Troubleshooting","metadata":{"loc":{"lines":{"from":1835,"to":1851}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"## Troubleshooting\n\n### Activity Startup\n\nIf you experience issues with application activities being not found or not starting then consider checking [How To Troubleshoot Activities Startup](docs/activity-startup.md) article.\n\n### Poor Elements Interaction Performance","metadata":{"loc":{"lines":{"from":1851,"to":1857}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### Poor Elements Interaction Performance\n\nIf you observe automated tests need at least 10 seconds or more to locate/interact with a single element then consider changing the default value for [waitForIdleTimeout setting](#settings-api). By default, UiAutomator framework (and all other Accessibility-based frameworks) always waits for the accessibility event stream to become idle before interacting with it (the default timeout there is 10000ms). This is needed to make sure all animations/transitions are finished before you, for example, interact with an element by clicking it. In case the application under test constantly runs some background animations or hogs the accessibility event stream in some other way these waits may significantly slow down the automation flow.","metadata":{"loc":{"lines":{"from":1857,"to":1859}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Setting the value of `waitForIdleTimeout` to zero `0` ms should completely disable any waits, and enforce interactions to happen immediately ignoring the accessibility event stream state. The downside of that would be that all interactions are never going to be delayed, so clicks and other actions might happen at wrong places of the application UI. That is why is it important to check the app under test first and fix its source to get rid of activities hogging the event loop. Sometimes it makes sence to disable animations completely for the app build under test, which could speed up your flows significantly in some situations.\n\n> [!Warning]\n> `waitForIdleTimeout` is a setting, not a capability.\n\n### Session Startup Issues\n\nSometimes various legacy driver parts might be cached on the device under test (like settings.apk), which would prevent a new/upgraded driver version from starting a session. Run\n\n```bash\nappium driver run uiautomator2 reset\n```","metadata":{"loc":{"lines":{"from":1861,"to":1872}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"```bash\nappium driver run uiautomator2 reset\n```\n\nin order to cleanup the cached UIA2 driver binaries from all connected devices on the current machine.\n\n### Socket Hangup Error","metadata":{"loc":{"lines":{"from":1870,"to":1876}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"This type of error means the driver is unable to connect to the UiAutomator2 REST server, which is running on the device under test. There might be multiple causes to this issue:","metadata":{"loc":{"lines":{"from":1878,"to":1878}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"- The automation session gets unexpectedly deleted if your test code sends the `DELETE /session/<id>` request to it, also the corresponding session and the server itself are terminated as a result. Sending further commands to the same server would create the error above because it is not listening anymore and must be newly started by the instrumentation first. Such issues usually happen if the session management is not configured properly in your code, so one starts a new session while an existing one is still running and has not been quit properly, or there is a timeout while waiting for a new command. Fixing session management logic (e.g. make sure each session is being properly created in the test setup section and is terminated in the test teardown) or changing/disabling the commands' timeout (check the [newCommandTimeout capability](#other)) might help to address such type of errors.","metadata":{"loc":{"lines":{"from":1879,"to":1879}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"- The server has been unexpectedly killed by Android OS itself. There might be several reasons to that. Usually fetching the [logcat](https://developer.android.com/studio/command-line/logcat) output and finding occurrences of `io.appium.uiautomator2.server` traces with `error` or `exception` label might help to figure out what happens. Sometimes it is necessary to turn off some internal phone optimizations, sometimes the server crashes because of an internal UiAutomator framework bug, sometimes because of a bug in the server code itself. Each case should be investigated separately if the search over the internet shows no matches…\n- The connectivity between the phone and the host is unstable. Nothing much to add on this one. Maybe the phone has a defect, or the USB cable is damaged, or the installed Android SDK is out of date…","metadata":{"loc":{"lines":{"from":1880,"to":1881}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### Element(s) Cannot be Found\n\nAll element location strategies in UIA2 driver work similarly under the hood except of the xpath one.\nIf some element is not found, but you see/assume it is present in the page source then make sure no race condition\nhappens. Add a timer and wait for a couple of seconds before giving up on the element location. In case the lookup\nstill fails after the timeout and your non-xpath locator is used then, most likely, it contains a typo, or the\ndestination element is not present. There is not much that could be done in UIA2 to change/influence that, since it passes such lookup calls directly to Google's UiAutomator framework.\n\nIn case of _xpath_ locators you could try to change values of the following settings:\n\n1. [allowInvisibleElements](#settings-api)\n2. [ignoreUnimportantViews](#settings-api)\n3. [enableMultiWindows](#settings-api)\n4. [snapshotMaxDepth](#settings-api)","metadata":{"loc":{"lines":{"from":1883,"to":1896}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"1. [allowInvisibleElements](#settings-api)\n2. [ignoreUnimportantViews](#settings-api)\n3. [enableMultiWindows](#settings-api)\n4. [snapshotMaxDepth](#settings-api)\n\nBy default, the first setting is set to `false`, which hides\nelements that are not visible from the page source and from the xpath location. Changing the setting value\nto `true` would add such invisible elements to the page source and make them locatable.\n\nThe second one is enabled by default (e.g. `true`). By disabling it the page source could receive more elements\nthat are normally hidden, because of their unimportance.\n\nThe third setting being set to `true` extends the page source by adding the actual content of other windows that are currently present on the device's screen. For example, the on-screen keyboard in Android is not a part of the current app hierarchy, but rather belongs to a separate window.","metadata":{"loc":{"lines":{"from":1893,"to":1905}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"It only makes sense to change the default value of the `snapshotMaxDepth` setting if the application under test\nhas deeply nested elements in the page tree hierarchy (e.g. more than 70 levels), and the destination element\nis suspected to be a part of these deeply nested views. Increasing the value of this\nsetting will reduce the performance of xPath searches and page tree retrievals, so be careful while assigning too\nhigh values to it.\n\nIn case of _id_ locators you could try to change the value of the following setting:\n\n1. [disableIdLocatorAutocompletion](#settings-api)","metadata":{"loc":{"lines":{"from":1907,"to":1915}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"In case of _id_ locators you could try to change the value of the following setting:\n\n1. [disableIdLocatorAutocompletion](#settings-api)\n\nThe general resources naming convention for Android apps is `<app_id>:id/<resource_name>`. This should guarantee uniqueness of each identifier accross the user interface. Although, this is only a convention and it is still allowed to have various resource names that do not follow it. If you have gotten one of such applications for automated testing then consider assigning `disableIdLocatorAutocompletion` setting value to `true`, so UiAutomator2 driver does not automatically rewrite supplied id values by adding `<app_id>:id/` prefixes to them.","metadata":{"loc":{"lines":{"from":1913,"to":1917}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"> [!Warning]\n> Default values for settings above have been selected to optimize xpath lookup and page source generation performance.\n> Having these settings always different from their default values may sometimes significantly (especially in case of huge accessbility hierarchies) reduce xpath lookup and page source generation speed.\n\n> [!Warning]\n> All items above are settings, not capabilities.\n\n### ClassCastException: java.util.ArrayList$ListItr cannot be cast to org.eclipse.wst.xml.xpath2.processor","metadata":{"loc":{"lines":{"from":1919,"to":1926}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"> [!Warning]\n> All items above are settings, not capabilities.\n\n### ClassCastException: java.util.ArrayList$ListItr cannot be cast to org.eclipse.wst.xml.xpath2.processor\n\nThis exception happens due to a known bug in the [Eclipse's Psychopath](https://wiki.eclipse.org/PsychoPathXPathProcessor) library used by UiAutomator2 driver to support [XPath2](https://www.w3.org/TR/xpath20/) syntax. The issue has been observed while using `following::` or `preceding::` axes in xpath queries. Unfortunately, this library has not been maintained for quite a while, and there is no good open source alternative to it. The only known workaround would be to forcefully switch the driver's XPath processor to the standard Android's Apache Harmony-based XPath1, which does not have this issue (but also does not support XPath2 syntax). See the Appium issue [#16142](https://github.com/appium/appium/issues/16142#issuecomment-1003954166) for more details.","metadata":{"loc":{"lines":{"from":1923,"to":1928}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"### A gesture, like scroll or swipe, does not have any effect / It is unclear how to do it\n\nThe UiAutomator2 driver provides multiple options for touch gestures automation.\nFor simple gestures, like swipe, scroll, drag, double click, fling or pinch use the corresponding\n[gesture shortcuts](#mobile-gesture-commands).\nYou may also use [UiScrollable-based UiAutomator locators](./docs/uiautomator-uiselector.md)\nto automate various scrolling behaviours.\nFor more sophisticated gestures\nconsider using [W3C actions](https://w3c.github.io/webdriver/#actions).\n\n\nMake sure you don't use deprecated JWP touch actions APIs. They have been\nremoved from the UIA2 driver since version 3.\n\nIf the action code in the client source looks good and satisfies the above requirements,\nbut its execution still does not deliver the expected result then the following debugging\nmeassures might be applied:","metadata":{"loc":{"lines":{"from":1930,"to":1946}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"- Enable `Show taps` and `Pointer location` Developer options in the device Settings. After running\n your automation code with the above options enabled you would be able to see the exact pointer trace path\n and check the velocity of the gesture. It also works for multi-touch gestures. Compare the trace\n to how the same gesture is usually done manually and apply the necessary updates to your code.\n- Check the device [logcat](https://developer.android.com/studio/debug/logcat) output for possible\n error messages. Usually a single gesture consists of hundreds of atomic steps. If any of these steps\n receives incorrect/unsupported parameters then the whole gesture might fail. The log has details\n about each step being executed and arguments passed to it.\n- Make sure the gesture has valid coordinates and respects pauses between pointer state changes.\n For example, it is always mandatory to provide a valid element or valid `absolute` coordinates","metadata":{"loc":{"lines":{"from":1948,"to":1957}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"- Make sure the gesture has valid coordinates and respects pauses between pointer state changes.\n For example, it is always mandatory to provide a valid element or valid `absolute` coordinates\n to any gesture at the beginning. Android only registers\n a long touch/click if the pointer has been depressed for longer than 500ms. For shorter actions\n a simple click is registered instead.\n- Do not mix webview and native elements in actions arguments. It simply won't work. Native\n actions could only consume native elements. A single possibility to perform a native action\n on a web element would be to traslate its coordinates into the native context and pass these\n coordinates as native action arguments.","metadata":{"loc":{"lines":{"from":1956,"to":1964}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"Check the below tutorials for more details on how to build reliable action chains:\n\n- [Automating Complex Gestures with the W3C Actions API](https://appiumpro.com/editions/29-automating-complex-gestures-with-the-w3c-actions-api)\n- [Swiping your way through Appium by Wim Selles #AppiumConf2021](https://www.youtube.com/watch?v=oAJ7jwMNFVU)\n- [Low-Level Insights on Android Input Events](./docs/actions.md)\n\n### window/tab hanlding in WEBVIEW context implemented by chrome custom tabs\n\n[Chrome custom tabs](https://developer.chrome.com/docs/android/custom-tabs/) could have its own window handlings as same as regular Selenium Web automation.","metadata":{"loc":{"lines":{"from":1966,"to":1974}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"[Chrome custom tabs](https://developer.chrome.com/docs/android/custom-tabs/) could have its own window handlings as same as regular Selenium Web automation.\n\nAppium lets you switch the context from `NATIVE_APP` to `WEBVIEW_xyz`, for example, to interact with the WEBVIEW contents over chromedriver. Then, if the WEBVIEW was chrome custom tabs implementation, the WEBVIEW context may require you to switch the window handler properly to interact with contents in a handler.\nIt is worth to try out this idea if `chrome://inspect` or [mobile: getContexts](#mobile-getcontexts) shows you available pages more than availale contexts.\n\n```ruby\n# Ruby\n# Change the context to WebView (Attach to a chromedriver session)\ndriver.set_context('WEBVIEW_XYZ')\n\n# Get available tabs/windows in the chrome instance\ndriver.window_handles\n\n# Change the tab/window in the \"chrome\" instance\ndriver.switch_to.window('a window_handle name')\n\n# interact with the tab/window\n```\n\n## Usage Examples","metadata":{"loc":{"lines":{"from":1974,"to":1993}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"# Change the tab/window in the \"chrome\" instance\ndriver.switch_to.window('a window_handle name')\n\n# interact with the tab/window\n```\n\n## Usage Examples\n\n```python\n# Python3 + PyTest\nimport pytest\n\nfrom appium import webdriver\n# Options are available in Python client since v2.6.0\nfrom appium.options.android import UiAutomator2Options","metadata":{"loc":{"lines":{"from":1987,"to":2001}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"def generate_options():\n common_caps = {\n # A real device udid could be retrieved from `adb devices -l` output\n # If it is ommitted then the first available device will be used\n 'appium:udid': '123456',\n # ...or run the test on an emulator\n # 'appium:avd': 'emulator-5554',\n }\n app_options = UiAutomator2Options().load_capabilities(common_caps)\n app_options.app = '/Projects/myapp.apk'\n # It might also be necessary to provide more info about app activities\n # Read [How To Troubleshoot Activities Startup](docs/activity-startup.md)\n # for more details\n # app_options.appPackage = 'com.mypackage'\n # app_options.appActivity = '.myMainActivity'\n # app_options.appWaitActivity = '.mySplashScreenActivity'\n chrome_options = UiAutomator2Options().load_capabilities(common_caps)\n chrome_options.browser_name = 'chrome'\n # Read [Hybrid Mode](#hybrid-mode)","metadata":{"loc":{"lines":{"from":2004,"to":2022}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"chrome_options = UiAutomator2Options().load_capabilities(common_caps)\n chrome_options.browser_name = 'chrome'\n # Read [Hybrid Mode](#hybrid-mode)\n chrome_options.chromedriver_executable = '/Project/chromedriver_linux64'\n return [app_options, chrome_options]","metadata":{"loc":{"lines":{"from":2020,"to":2024}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"@pytest.fixture(params=generate_options())\ndef driver(request):\n # The default URL is http://127.0.0.1:4723/wd/hub in Appium1\n drv = webdriver.Remote('http://localhost:4723', options=request.param)\n yield drv\n drv.quit()\n\n\ndef test_edit_text(driver):\n locator = 'android.view.TextEdit' if driver.current_context == 'NATIVE_APP' else 'input'\n edit_field = driver.find_element_by_class_name(locator)\n edit_field.send_keys('hello world')\n assert edit_field.text == 'hello world'\n edit_field.clear()\n assert edit_field.text == ''\n\n```\n\n\n## API Notes\n\n`lock` behaves differently in Android than it does in iOS. In Android it does not take any arguments, and locks the screen and returns immediately.\n\n\n## Development\n\n```\nnpm install appium-uiautomator2-driver\nnpm run dev\n```\n\nUnit tests:\n\n```\nnpm run test\n```\n\nFunctional tests:","metadata":{"loc":{"lines":{"from":2027,"to":2064}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"## Development\n\n```\nnpm install appium-uiautomator2-driver\nnpm run dev\n```\n\nUnit tests:\n\n```\nnpm run test\n```\n\nFunctional tests:\n\n```\nnpm run e2e-test:commands\nnpm run e2e-test:commands:find\nnpm run e2e-test:commands:general\nnpm run e2e-test:commands:keyboard\nnpm run e2e-test:driver\n```","metadata":{"loc":{"lines":{"from":2051,"to":2072}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/README.md","filename":"README.md","relativePath":"appium-uiautomator2-driver/README.md"}},{"pageContent":"## Low-Level Insights on Android Input Events\n\n\n### What Are Input Events\n\nAndroid OS uses events concept to handle signals received from different input devices.\nIt supports a wide range of different devices, such as touch screen, light pen, mouse, keyboard,\nbut most of them are using [MotionEvent](https://developer.android.com/reference/android/view/MotionEvent) or [KeyEvent](https://developer.android.com/reference/android/view/KeyEvent) APIs, which are derived from the base [InputEvent](https://developer.android.com/reference/android/view/InputEvent) class. These APIs are quite flexible and support a wide range of different settings.\nWe are particularly interested in the part of these APIs, which are responsible for touch and\nkeyboard events generation/emulation.\n\n\n### How Input Events Are Working","metadata":{"loc":{"lines":{"from":1,"to":13}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/actions.md","filename":"actions.md","relativePath":"appium-uiautomator2-driver/actions.md"}},{"pageContent":"### How Input Events Are Working\n\nAn event is an object, which is generated in response to a signal from an input device.\nThese objects are then delivered to the corresponding kernel subsystem, which processes them\nand notifies all listening processes about taps, key presses, swipes, etc.\nThis means that in order to emulate a signal generated by\nan external device, such as touch screen, it is necessary to just send event objects with\nthe same properties and in the same sequence as they would be generated by a real device.\n\n\n### Lets Simulate a Single Tap","metadata":{"loc":{"lines":{"from":13,"to":23}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/actions.md","filename":"actions.md","relativePath":"appium-uiautomator2-driver/actions.md"}},{"pageContent":"### Lets Simulate a Single Tap\n\nEach input device has a set of actions whose property ranges and sequences are already predefined\nin the operating system. These actions we call \"tap\", \"swipe\" or \"double tap\", etc. The properties\nof each action could be found either in the Android documentation or in the OS source code.\nIn order to perform events sequence, which is recognized as single tap, it is necessary to generate\nthe following motion events:\n - `ACTION_POINTER_DOWN`\n - wait 125ms (525ms or longer wait will synthesize a long tap action instead)\n - `ACTION_POINTER_UP`. The `downTime` property should be set to the same timestamp as for `ACTION_POINTER_DOWN`","metadata":{"loc":{"lines":{"from":23,"to":32}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/actions.md","filename":"actions.md","relativePath":"appium-uiautomator2-driver/actions.md"}},{"pageContent":"It is also important, that coordinates and other properties of both the starting and the closing event should be equal except of the `eventTime` one, which is always equal to the current system timestamp in milliseconds (`SystemClock.uptimeMillis()`).\nThe `MotionEvent` object itself could be created via [obtain](https://developer.android.com/reference/android/view/MotionEvent#obtain(long,%20long,%20int,%20float,%20float,%20int)) API, where parameters are the corresponding event properties.","metadata":{"loc":{"lines":{"from":34,"to":35}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/actions.md","filename":"actions.md","relativePath":"appium-uiautomator2-driver/actions.md"}},{"pageContent":"After events are created they must be passed to the system for execution.\nSuch action is not secure, so it is only possible in instrumented tests via [injectInputEvent](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/IUiAutomationConnection.aidl) method of `IUiAutomationConnection` interface.\nThis is a very low-level method and it can only be accessed via reflection in automated tests.\nNormally, UiAutomator APIs have wrappers over it (like `touchDown`, `touchMove`, etc.), that already simulate the stuff described above.\n\n\n### How About More Complicated Actions","metadata":{"loc":{"lines":{"from":37,"to":43}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/actions.md","filename":"actions.md","relativePath":"appium-uiautomator2-driver/actions.md"}},{"pageContent":"In theory it is possible to emulate any input action using a generated events sequence.\nAlthough, some actions, like multi-finger swipe,\nare really complicated and require a lot of events to be generated\nwith correct properties and timings. The OS simply ignores given events if they don't follow\ninternal action requirements. There is also a little assistance from UiAutomator framework,\nbecause Google only has wrappers for a limited set of simple actions, like `tap`, `drag` or `swipe`.\nSo, in order to generate two-finger symmetric swipe we need to supply the following events chain:\n - `ACTION_POINTER_DOWN` (finger1)\n - `ACTION_POINTER_DOWN` (finger2)","metadata":{"loc":{"lines":{"from":45,"to":53}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/actions.md","filename":"actions.md","relativePath":"appium-uiautomator2-driver/actions.md"}},{"pageContent":"So, in order to generate two-finger symmetric swipe we need to supply the following events chain:\n - `ACTION_POINTER_DOWN` (finger1)\n - `ACTION_POINTER_DOWN` (finger2)\n - start a loop, that generates `ACTION_POINTER_MOVE` event each `20ms` for both `finger1` and `finger2` until `ACTION_POINTER_UP` is performed. The `downTime` should be set to the same timestamp as for the corresponding `ACTION_POINTER_DOWN`. The coordinates of each move event should be points belonging to the path between the corresponding start and end point coordinates normalized by the current timestamp (x0 + sqrt(sqr(x0) + sqr(x1))) * k, y0 + sqrt(sqr(y0) + sqr(y1))) * k).\n - `ACTION_POINTER_UP` (finger1) The `downTime` property should be set to the same timestamp as for the corresponding `ACTION_POINTER_DOWN`\n - `ACTION_POINTER_UP` (finger2) The `downTime` property should be set to the same timestamp as for the corresponding `ACTION_POINTER_DOWN`","metadata":{"loc":{"lines":{"from":51,"to":56}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/actions.md","filename":"actions.md","relativePath":"appium-uiautomator2-driver/actions.md"}},{"pageContent":"Google uses 5ms as interval duration between move events in UiAutomator code,\nbut according to our observations this value is too little,\nwhich causes noticeable delays in actions execution.\n\n\n### Further Reading\n\nUnfortunately, there is no so much detailed information on this topic. The only reliable source\nof the information are Android OS sources themselves. Consider visiting the following resources:\n\n- https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/ViewConfiguration.java\n- https://android.googlesource.com/platform/frameworks/uiautomator/+/refs/heads/master\n- https://github.com/appium/appium-uiautomator2-server/tree/master/app/src/main/java/io/appium/uiautomator2/utils/w3c\n- https://github.com/appium/appium-uiautomator2-server/tree/master/app/src/test/java/io/appium/uiautomator2/utils/w3c\n- https://github.com/appium/appium-espresso-driver/tree/master/espresso-server/library/src/main/java/io/appium/espressoserver/lib/helpers/w3c","metadata":{"loc":{"lines":{"from":58,"to":72}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/actions.md","filename":"actions.md","relativePath":"appium-uiautomator2-driver/actions.md"}},{"pageContent":"## How To Troubleshoot Activities Startup\n\n\n### Capabilities\n\n> The Activity class is a crucial component of an Android app, and the way activities are launched and put together is a fundamental part of the platform's application model. Unlike programming paradigms in which apps are launched with a main() method, the Android system initiates code in an Activity instance by invoking specific callback methods that correspond to specific stages of its lifecycle.\n> &copy; [Android Developer Documentation](https://developer.android.com/guide/components/activities/intro-activities)\n\nAppium needs to know package and activity names in order to properly initialize the application under test. This information is expected to be provided in driver capabilities and consists of the following keys:","metadata":{"loc":{"lines":{"from":1,"to":9}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/activity-startup.md","filename":"activity-startup.md","relativePath":"appium-uiautomator2-driver/activity-startup.md"}},{"pageContent":"- `appActivity`: The name of the main application activity\n- `appPackage`: The identifier of the application package\n- `appWaitActivity`: The name of the application activity to wait for/which starts the first\n- `appWaitPackage`: The id of the application package to wait for/which starts the first\n- `appWaitDuration`: The maximum duration to wait until the `appWaitActivity` is focused in milliseconds (20000 by default)\n- `appWaitForLaunch`: Whether to wait until Activity Manager returns the control to the calling process. By default the driver always waits until `appWaitDuration` is expired. Setting this capability to `false` effectively cancels this wait and unblocks the server loop as soon as `am` successfully triggers the command to start the activity.","metadata":{"loc":{"lines":{"from":11,"to":16}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/activity-startup.md","filename":"activity-startup.md","relativePath":"appium-uiautomator2-driver/activity-startup.md"}},{"pageContent":"All these capabilities are optional. If they are not set explicitly then Appium tries to auto detect them by reading their values from the APK manifest. Although, if the application under test is supposed to be already installed on the device (`noReset=true`) then at least `appActivity` and `appPackage` options are required to be set, since no package manifest is available in such case. If you don't set `appWaitPackage` and `appWaitActivity` explicitly then these are getting assigned to `appPackage`/`appActivity` values automatically. For more details check on the implementation of `packageAndLaunchActivityFromManifest` method in the [appium-adb](https://github.com/appium/appium-adb/blob/master/lib/tools/android-manifest.js) package.\n\n\n### How Appium Starts Activities","metadata":{"loc":{"lines":{"from":18,"to":21}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/activity-startup.md","filename":"activity-startup.md","relativePath":"appium-uiautomator2-driver/activity-startup.md"}},{"pageContent":"### How Appium Starts Activities\n\nActivities are started by [Call activity manager `am`](https://developer.android.com/studio/command-line/adb#am). Appium tries to start the `appPackage`/`appActivity` combination using `am start` and then waits until the `appWaitPackage`/`appWaitActivity` is focused or the `appWaitDuration` timeout expires. The currently focused activity name is parsed from `adb shell dumpsys window windows` command output (`mFocusedApp` or `mCurrentFocus` entries). For more details check on the implementation of `startApp`, and `getFocusedPackageAndActivity` methods in the [appium-adb](https://github.com/appium/appium-adb/blob/master/lib/tools/apk-utils.js) package.\n\n\n### Possible Problems And Solutions\n\n#### java.lang.SecurityException: Permission Denial: starting Intent","metadata":{"loc":{"lines":{"from":21,"to":28}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/activity-startup.md","filename":"activity-startup.md","relativePath":"appium-uiautomator2-driver/activity-startup.md"}},{"pageContent":"The full error description usually looks like `'java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.mypackage/.myactivity.MainActivity launchParam=MultiScreenLaunchParams { mDisplayId=0 mBaseDisplayId=0 mFlags=0 } } from null (pid=11366, uid=2000) not exported from uid 10191`. Such error might be the indication of the fact that the combination of application package and activity name, which has been passed to Appium as `appPackage`/`appActivity` (or auto detected implicitly), is not the correct one to start the application under test. As a solution, it is necessary to check the correct values with the application developer and test them manually first by executing: `adb shell am start -W -n com.myfixedpackage/.myfixedactivity.MainActivity -S -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -f 0x10200000`. If this commands succeeds manually and starts the","metadata":{"loc":{"lines":{"from":30,"to":30}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/activity-startup.md","filename":"activity-startup.md","relativePath":"appium-uiautomator2-driver/activity-startup.md"}},{"pageContent":"am start -W -n com.myfixedpackage/.myfixedactivity.MainActivity -S -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -f 0x10200000`. If this commands succeeds manually and starts the necessary application on the device then it will work for Appium as well.","metadata":{"loc":{"lines":{"from":30,"to":30}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/activity-startup.md","filename":"activity-startup.md","relativePath":"appium-uiautomator2-driver/activity-startup.md"}},{"pageContent":"Some devices might require customization of the security configruation in the developer options, or security preference. For example, Realme devices require [_Disable Permission Monitoring_ and a couple of flags in the developer options](https://github.com/appium/appium/issues/13802#issuecomment-702789411) to avoid the _Permission Denial_ error.\n\n#### com.myactivity or com.myapp.com.myactivity never started","metadata":{"loc":{"lines":{"from":32,"to":34}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/activity-startup.md","filename":"activity-startup.md","relativePath":"appium-uiautomator2-driver/activity-startup.md"}},{"pageContent":"#### com.myactivity or com.myapp.com.myactivity never started\n\nThus exception usually indicates, that the first application activity is not the same package/activity, as it is set (or auto detected) by `appWaitPackage`/`appWaitActivity`. Such error normally happens in applications having multiple activities. In order to resolve the problem one should check with application developer regarding which activity/package is the very first one that appears on application startup. The currently focused activity name might be verified using the `adb shell dumpsys window windows` command mentioned above. Also, Appium allows to use wildcards while setting `appWaitActivity` value. This might be particularly useful if the activity name is generated dynamically or it is not the same all the time. For example `com.mycomany.*` will match any of `com.mycomany.foo`, `com.mycomany.bar`.\n\n#### Command '…' timed out after X ms","metadata":{"loc":{"lines":{"from":34,"to":38}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/activity-startup.md","filename":"activity-startup.md","relativePath":"appium-uiautomator2-driver/activity-startup.md"}},{"pageContent":"#### Command '…' timed out after X ms\n\nIf you've double checked that activity names are correct, but the startup still times out, then try to increase the value of `appWaitDuration` capability. Normally, the default 20 seconds is enough for the most of applications, however, some bigger apps might require more time to start and show the first activity. Please, don't create such apps.\n\nThere might be also situations where an activity does not return the control to the calling process at all, so `am start` call blocks forever independently of the value of `appWaitDuration`, thus causing the timeout. In such case setting `appWaitForLaunch` to `false` might help to resolve the issue. Although, by choosing this option, the driver cannot make sure the activity has fully started, so then it is up to the client code to verify the initial UI state is the one that is expected.\n\n\n#### java.util.concurrent.ExecutionException: com.google.firebase.installations.FirebaseInstallationsException","metadata":{"loc":{"lines":{"from":38,"to":45}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/activity-startup.md","filename":"activity-startup.md","relativePath":"appium-uiautomator2-driver/activity-startup.md"}},{"pageContent":"#### java.util.concurrent.ExecutionException: com.google.firebase.installations.FirebaseInstallationsException\n\n`firebaseinstallations.googleapis.com` sends the apk's certificate information as the header `X-Android-Cert` in its initialization step. Appium UiAutomator2 driver resigins the application under test with the default Appium debug signature. It causes an exception, `java.util.concurrent.ExecutionException: com.google.firebase.installations.FirebaseInstallationsException`, when the application under test starts. To avoid the exception, the session must have `noSign: true` capability to avoid re-signing. [Unblocking Firebase Network Traffic in Modified Android Applications](https://www.thecobraden.com/posts/unblocking_firebase_ids/) explains the cause more.","metadata":{"loc":{"lines":{"from":45,"to":47}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/activity-startup.md","filename":"activity-startup.md","relativePath":"appium-uiautomator2-driver/activity-startup.md"}},{"pageContent":"## How To Test Android App Bundle\n\nGoogle has released the [Android App Bundle](https://developer.android.com/platform/technology/app-bundle/) feature.\nAn `.aab` file is generated by the feature, which we are supposed to upload to the Google Play Store. We can manage the `.aab` file via CLI using the official [bundletool](https://developer.android.com/studio/command-line/bundletool) which is available from [bundletool](https://github.com/google/bundletool). [The guide](https://developer.android.com/guide/app-bundle/) also help us to understand the feature.\n\nWe can get distributed apk files from the `.aab` file via the CLI. Using the generated files, we can test against the release module. Since Appium 1.9.2, you can Appium tests against an `.apks` file using UiAutomator2 driver. [1](https://github.com/appium/appium-adb/pull/367) and [2](https://github.com/appium/appium-base-driver/pull/271) are PRs for the feature.\n\n## How to run tests","metadata":{"loc":{"lines":{"from":1,"to":8}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-appbundle.md","filename":"android-appbundle.md","relativePath":"appium-uiautomator2-driver/android-appbundle.md"}},{"pageContent":"## How to run tests\n\n1. Export `bundletool.jar` in your path\n - Appium looks for `bundletool.jar` in your local environemnt. Make sure you can find the path with `which 'bundletool.jar'`. If you can't find it, please set the path correctly.\n - Please make sure the bundletool version is above 1.6.0\n2. Generate the `.apks` file from the `.aab` file\n - The `.aab` is available over Android Studio 3.2\n - You must sign correctly when you generate `.apks` from `.aab`. This step requires data signing.","metadata":{"loc":{"lines":{"from":8,"to":15}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-appbundle.md","filename":"android-appbundle.md","relativePath":"appium-uiautomator2-driver/android-appbundle.md"}},{"pageContent":"```bash\n$ java -jar apks/bundletool.jar build-apks \\\n --bundle apks/release/release/app.aab \\ # A generated aab file\n --output apks/AppBundleSample.apks \\ # An apks file you'd like to out put to\n --ks apks/sign \\ # Signing keystore\n --ks-key-alias key0 \\ # Alias of the keytstore\n --ks-pass pass:kazucocoa \\ # Password of the keystore\n --overwrite # Overwrite any existing apks files\n```\n\n3. Use the path to the `.apks` file as your `app` capability.\n\n```ruby\ncapabilities = {\n platformName: :android,\n automationName: 'uiautomator2',\n platformVersion: '8.1',\n deviceName: 'Android Emulator',\n app: \"path/to/your.apks\", # This line is important\n fullReset: true,\n ...\n}\n\ncore = ::Appium::Core.for capabilities: capabilities\ndriver = core.start_driver\n```\n\nYou can find another way to get test APKs in https://developer.android.com/guide/app-bundle/","metadata":{"loc":{"lines":{"from":17,"to":44}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-appbundle.md","filename":"android-appbundle.md","relativePath":"appium-uiautomator2-driver/android-appbundle.md"}},{"pageContent":"core = ::Appium::Core.for capabilities: capabilities\ndriver = core.start_driver\n```\n\nYou can find another way to get test APKs in https://developer.android.com/guide/app-bundle/\n\nYou could also install `.apks` bundles via Install App command like below.\n\n```ruby\n# Ruby\ndriver.execute_script 'mobile: installApp', {appPath: 'path/to/your.apks'}\n```\n\n## Tips\n### Make `bundletool.jar` executable\n\nMake sure the bundletool is executable.\n`$ chmod 655 /path/to/bundletool.jar` can make it executable, for example.\n\n### Test with different languages\n\nSet `fullReset: true` if you would like to test against the app using different languages' resources.\n\nAppium only installs the minimum set of resources, following the behavior of the appbundle feature. For example, if a device's language is set of English, Appium will only install the `en` resource. The installed apk will have no Japanese resources.","metadata":{"loc":{"lines":{"from":40,"to":63}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-appbundle.md","filename":"android-appbundle.md","relativePath":"appium-uiautomator2-driver/android-appbundle.md"}},{"pageContent":"In orfer to force re-install with a different set of language resources, specify `fullReset: true`\n\n## An example project\n\n- https://github.com/KazuCocoa/AppBundleSample","metadata":{"loc":{"lines":{"from":65,"to":69}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-appbundle.md","filename":"android-appbundle.md","relativePath":"appium-uiautomator2-driver/android-appbundle.md"}},{"pageContent":"## Automating Mobile Gestures With UiAutomator2 Backend\n\nTouch actions are the most advanced and the most complicated way to\nimplement any Android gesture. Although, there is a couple of basic\ngestures, like swipe, fling or pinch, which are commonly used in\nAndroid applications and for which it makes sense to have shortcuts,\nwhere only high-level options are configurable.\n\n\n### mobile: longClickGesture\n\nThis gesture performs long click action on the given element/coordinates.\nAvailable since Appium v1.19\n\n#### Supported arguments","metadata":{"loc":{"lines":{"from":1,"to":15}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-mobile-gestures.md","filename":"android-mobile-gestures.md","relativePath":"appium-uiautomator2-driver/android-mobile-gestures.md"}},{"pageContent":"### mobile: longClickGesture\n\nThis gesture performs long click action on the given element/coordinates.\nAvailable since Appium v1.19\n\n#### Supported arguments\n\n * _elementId_: The id of the element to be clicked.\n If the element is missing then both click offset coordinates must be provided.\n If both the element id and offset are provided then the coordinates\n are parsed as relative offsets from the top left corner of the element.\n * _x_: The x-offset coordinate\n * _y_: The y-offset coordinate\n * _duration_: Click duration in milliseconds. `500` by default. The value must not be negative\n * _locator_: The map containing [strategy and selector](../README.md#element-location) items to make it possible\n to click dynamic elements.\n\n#### Usage examples\n\n```java\n// Java\n((JavascriptExecutor) driver).executeScript(\"mobile: longClickGesture\", ImmutableMap.of(\n \"elementId\", ((RemoteWebElement) element).getId()\n));\n```","metadata":{"loc":{"lines":{"from":10,"to":34}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-mobile-gestures.md","filename":"android-mobile-gestures.md","relativePath":"appium-uiautomator2-driver/android-mobile-gestures.md"}},{"pageContent":"#### Usage examples\n\n```java\n// Java\n((JavascriptExecutor) driver).executeScript(\"mobile: longClickGesture\", ImmutableMap.of(\n \"elementId\", ((RemoteWebElement) element).getId()\n));\n```\n\n```python\n# Python\ndriver.execute_script('mobile: longClickGesture', {'x': 100, 'y': 100, 'duration': 1000})\n```\n\n\n### mobile: doubleClickGesture\n\nThis gesture performs double click action on the given element/coordinates.\nAvailable since Appium v1.21\n\n#### Supported arguments\n\n * _elementId_: The id of the element to be clicked.\n If the element is missing then both click offset coordinates must be provided.\n If both the element id and offset are provided then the coordinates\n are parsed as relative offsets from the top left corner of the element.\n * _x_: The x-offset coordinate\n * _y_: The y-offset coordinate\n * _locator_: The map containing [strategy and selector](../README.md#element-location) items to make it possible\n to click dynamic elements.\n\n#### Usage examples","metadata":{"loc":{"lines":{"from":27,"to":58}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-mobile-gestures.md","filename":"android-mobile-gestures.md","relativePath":"appium-uiautomator2-driver/android-mobile-gestures.md"}},{"pageContent":"#### Usage examples\n\n```java\n// Java\n((JavascriptExecutor) driver).executeScript(\"mobile: doubleClickGesture\", ImmutableMap.of(\n \"elementId\", ((RemoteWebElement) element).getId()\n));\n```\n\n```python\n# Python\ndriver.execute_script('mobile: doubleClickGesture', {'x': 100, 'y': 100})\n```\n\n\n### mobile: clickGesture\n\nThis gesture performs click action on the given element/coordinates.\nAvailable since Appium UiAutomator2 driver 1.71.0. Usage of this gesture is recommended\nas a possible workaround for cases where the \"native\" tap call fails,\neven though tap coordinates seem correct. This issue is related to the fact\nthese calls use the legacy UIAutomator-based calls while this extension\nis based on the same foundation as W3C does.\n\n\n#### Supported arguments","metadata":{"loc":{"lines":{"from":58,"to":83}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-mobile-gestures.md","filename":"android-mobile-gestures.md","relativePath":"appium-uiautomator2-driver/android-mobile-gestures.md"}},{"pageContent":"#### Supported arguments\n\n * _elementId_: The id of the element to be clicked.\n If the element is missing then both click offset coordinates must be provided.\n If both the element id and offset are provided then the coordinates\n are parsed as relative offsets from the top left corner of the element.\n * _x_: The x-offset coordinate\n * _y_: The y-offset coordinate\n * _locator_: The map containing [strategy and selector](../README.md#element-location) items to make it possible\n to click dynamic elements.\n\n#### Usage examples\n\n```java\n// Java\ndriver.executeScript(\"mobile: clickGesture\", ImmutableMap.of(\n \"elementId\", ((RemoteWebElement) element).getId()\n));\n```\n\n```python\n# Python\ndriver.execute_script('mobile: clickGesture', {'x': 100, 'y': 100})\n```\n\n```javascript\n// Javascript - @wdio\nawait driver.executeScript('mobile: clickGesture', [{x: 100, y: 100}]);\n```\n\n### mobile: dragGesture","metadata":{"loc":{"lines":{"from":83,"to":113}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-mobile-gestures.md","filename":"android-mobile-gestures.md","relativePath":"appium-uiautomator2-driver/android-mobile-gestures.md"}},{"pageContent":"```javascript\n// Javascript - @wdio\nawait driver.executeScript('mobile: clickGesture', [{x: 100, y: 100}]);\n```\n\n### mobile: dragGesture\n\nThis gesture performs drag action from the given element/coordinates to the given point.\nAvailable since Appium v1.19\n\n#### Supported arguments\n\n * _elementId_: The id of the element to be dragged.\n If the element id is missing then both start coordinates must be provided.\n If both the element id and the start coordinates are provided then these\n coordinates are considered as offsets from the top left element corner.\n * _startX_: The x-start coordinate\n * _startY_: The y-start coordinate\n * _endX_: The x-end coordinate. Mandatory argument\n * _endY_: The y-end coordinate. Mandatory argument\n * _speed_: The speed at which to perform this gesture in pixels per second.\n The value must not be negative. The default value is `2500 * displayDensity`\n\n#### Usage examples","metadata":{"loc":{"lines":{"from":108,"to":131}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-mobile-gestures.md","filename":"android-mobile-gestures.md","relativePath":"appium-uiautomator2-driver/android-mobile-gestures.md"}},{"pageContent":"#### Usage examples\n\n```java\n// Java\n((JavascriptExecutor) driver).executeScript(\"mobile: dragGesture\", ImmutableMap.of(\n \"elementId\", ((RemoteWebElement) element).getId(),\n \"endX\", 100,\n \"endY\", 100\n));\n```\n\n\n### mobile: flingGesture\n\nThis gesture performs fling gesture on the given element/area.\nAvailable since Appium v1.19\n\n#### Supported arguments","metadata":{"loc":{"lines":{"from":131,"to":148}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-mobile-gestures.md","filename":"android-mobile-gestures.md","relativePath":"appium-uiautomator2-driver/android-mobile-gestures.md"}},{"pageContent":"### mobile: flingGesture\n\nThis gesture performs fling gesture on the given element/area.\nAvailable since Appium v1.19\n\n#### Supported arguments\n\n * _elementId_: The id of the element to be flinged.\n If the element id is missing then fling bounding area must be provided.\n If both the element id and the fling bounding area are provided then this\n area is effectively ignored.\n * _left_: The left coordinate of the fling bounding area\n * _top_: The top coordinate of the fling bounding area\n * _width_: The width of the fling bounding area\n * _height_: The height of the fling bounding area\n * _direction_: Direction of the fling. Mandatory value.\n Acceptable values are: `up`, `down`, `left` and `right` (case insensitive)\n * _speed_: The speed at which to perform this\n gesture in pixels per second. The value must be greater than the minimum fling\n velocity for the given view (50 by default). The default value is `7500 * displayDensity`\n\n#### Returned value","metadata":{"loc":{"lines":{"from":143,"to":164}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-mobile-gestures.md","filename":"android-mobile-gestures.md","relativePath":"appium-uiautomator2-driver/android-mobile-gestures.md"}},{"pageContent":"#### Returned value\n\nThe returned value is a boolean one and equals to `true` if the object can still scroll in the given direction\n\n#### Usage examples\n\n```java\n// Java\nboolean canScrollMore = (Boolean) ((JavascriptExecutor) driver).executeScript(\"mobile: flingGesture\", ImmutableMap.of(\n \"elementId\", ((RemoteWebElement) element).getId(),\n \"direction\", \"down\",\n \"speed\", 500\n));\n```\n\n```javascript\n// Javascript - @wdio\nawait driver.executeScript('mobile: flingGesture', [{\n elementId: element.elementId,\n direction: 'right',\n speed: 500,\n}]);\n```\n\n\n### mobile: pinchOpenGesture\n\nThis gesture performs pinch-open gesture on the given element/area.\nAvailable since Appium v1.19\n\n#### Supported arguments","metadata":{"loc":{"lines":{"from":164,"to":194}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-mobile-gestures.md","filename":"android-mobile-gestures.md","relativePath":"appium-uiautomator2-driver/android-mobile-gestures.md"}},{"pageContent":"### mobile: pinchOpenGesture\n\nThis gesture performs pinch-open gesture on the given element/area.\nAvailable since Appium v1.19\n\n#### Supported arguments\n\n * _elementId_: The id of the element to be pinched.\n If the element id is missing then pinch bounding area must be provided.\n If both the element id and the pinch bounding area are provided then the\n area is effectively ignored.\n * _left_: The left coordinate of the pinch bounding area\n * _top_: The top coordinate of the pinch bounding area\n * _width_: The width of the pinch bounding area\n * _height_: The height of the pinch bounding area\n * _percent_: The size of the pinch as a percentage of the pinch area size.\n Valid values must be float numbers in range 0..1, where 1.0 is 100%.\n Mandatory value.\n * _speed_: The speed at which to perform this gesture in pixels per second.\n The value must not be negative. The default value is `2500 * displayDensity`\n\n#### Usage examples","metadata":{"loc":{"lines":{"from":189,"to":210}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-mobile-gestures.md","filename":"android-mobile-gestures.md","relativePath":"appium-uiautomator2-driver/android-mobile-gestures.md"}},{"pageContent":"#### Usage examples\n\n```java\n// Java\n((JavascriptExecutor) driver).executeScript(\"mobile: pinchOpenGesture\", ImmutableMap.of(\n \"elementId\", ((RemoteWebElement) element).getId(),\n \"percent\", 0.75\n));\n```\n\n\n### mobile: pinchCloseGesture\n\nThis gesture performs pinch-close gesture on the given element/area.\nAvailable since Appium v1.19\n\n#### Supported arguments","metadata":{"loc":{"lines":{"from":210,"to":226}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-mobile-gestures.md","filename":"android-mobile-gestures.md","relativePath":"appium-uiautomator2-driver/android-mobile-gestures.md"}},{"pageContent":"### mobile: pinchCloseGesture\n\nThis gesture performs pinch-close gesture on the given element/area.\nAvailable since Appium v1.19\n\n#### Supported arguments\n\n * _elementId_: The id of the element to be pinched.\n If the element id is missing then pinch bounding area must be provided.\n If both the element id and the pinch bounding area are provided then the\n area is effectively ignored.\n * _left_: The left coordinate of the pinch bounding area\n * _top_: The top coordinate of the pinch bounding area\n * _width_: The width of the pinch bounding area\n * _height_: The height of the pinch bounding area\n * _percent_: The size of the pinch as a percentage of the pinch area size.\n Valid values must be float numbers in range 0..1, where 1.0 is 100%.\n Mandatory value.\n * _speed_: The speed at which to perform this gesture in pixels per second.\n The value must not be negative. The default value is `2500 * displayDensity`\n\n#### Usage examples","metadata":{"loc":{"lines":{"from":221,"to":242}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-mobile-gestures.md","filename":"android-mobile-gestures.md","relativePath":"appium-uiautomator2-driver/android-mobile-gestures.md"}},{"pageContent":"#### Usage examples\n\n```java\n// Java\n((JavascriptExecutor) driver).executeScript(\"mobile: pinchCloseGesture\", ImmutableMap.of(\n \"elementId\", ((RemoteWebElement) element).getId(),\n \"percent\", 0.75\n));\n```\n\n```python\n# Python\ncan_scroll_more = driver.execute_script('mobile: pinchCloseGesture', {\n 'elementId': element.id,\n 'percent': 0.75\n})\n```\n\n\n### mobile: swipeGesture\n\nThis gesture performs swipe gesture on the given element/area.\nAvailable since Appium v1.19\n\n#### Supported arguments","metadata":{"loc":{"lines":{"from":242,"to":266}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-mobile-gestures.md","filename":"android-mobile-gestures.md","relativePath":"appium-uiautomator2-driver/android-mobile-gestures.md"}},{"pageContent":"#### Supported arguments\n\n * _elementId_: The id of the element to be swiped.\n If the element id is missing then swipe bounding area must be provided.\n If both the element id and the swipe bounding area are provided then the\n area is effectively ignored.\n * _left_: The left coordinate of the swipe bounding area\n * _top_: The top coordinate of the swipe bounding area\n * _width_: The width of the swipe bounding area\n * _height_: The height of the swipe bounding area\n * _direction_: Swipe direction. Mandatory value.\n Acceptable values are: `up`, `down`, `left` and `right` (case insensitive)\n * _percent_: The size of the swipe as a percentage of the swipe area size.\n Valid values must be float numbers in range 0..1, where 1.0 is 100%.\n Mandatory value.\n * _speed_: The speed at which to perform this gesture in pixels per second.\n The value must not be negative. The default value is `5000 * displayDensity`\n\n#### Usage examples","metadata":{"loc":{"lines":{"from":266,"to":284}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-mobile-gestures.md","filename":"android-mobile-gestures.md","relativePath":"appium-uiautomator2-driver/android-mobile-gestures.md"}},{"pageContent":"#### Usage examples\n\n```java\n// Java\n((JavascriptExecutor) driver).executeScript(\"mobile: swipeGesture\", ImmutableMap.of(\n \"left\", 100, \"top\", 100, \"width\", 200, \"height\", 200,\n \"direction\", \"left\",\n \"percent\", 0.75\n));\n```\n\n```python\n# Python\ndriver.execute_script('mobile: swipeGesture', {\n 'left': 100,\n 'top': 100,\n 'width': 200,\n 'height': 200,\n 'direction': direction, 'percent': 0.75\n})\n```\n\n\n### mobile: scrollGesture\n\nThis gesture performs scroll gesture on the given element/area.\nAvailable since Appium v1.19\n\n#### Supported arguments","metadata":{"loc":{"lines":{"from":284,"to":312}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-mobile-gestures.md","filename":"android-mobile-gestures.md","relativePath":"appium-uiautomator2-driver/android-mobile-gestures.md"}},{"pageContent":"#### Supported arguments\n\n * _elementId_: The id of the element to be scrolled.\n If the element id is missing then scroll bounding area must be provided.\n If both the element id and the scroll bounding area are provided then this\n area is effectively ignored.\n * _left_: The left coordinate of the scroll bounding area\n * _top_: The top coordinate of the scroll bounding area\n * _width_: The width of the scroll bounding area\n * _height_: The height of the scroll bounding area\n * _direction_: Scrolling direction. Mandatory value.\n Acceptable values are: `up`, `down`, `left` and `right` (case insensitive)\n * _percent_: The size of the scroll as a percentage of the scrolling area size.\n Valid values must be float numbers greater than zero, where 1.0 is 100%.\n Mandatory value.\n * _speed_: The speed at which to perform this gesture in pixels per second.\n The value must not be negative. The default value is `5000 * displayDensity`\n\n#### Returned value","metadata":{"loc":{"lines":{"from":312,"to":330}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-mobile-gestures.md","filename":"android-mobile-gestures.md","relativePath":"appium-uiautomator2-driver/android-mobile-gestures.md"}},{"pageContent":"#### Returned value\n\nThe returned value is a boolean one and equals to `true` if the object can still scroll in the given direction\n\n#### Usage examples\n\n```java\n// Java\nboolean canScrollMore = (Boolean) ((JavascriptExecutor) driver).executeScript(\"mobile: scrollGesture\", ImmutableMap.of(\n \"left\", 100, \"top\", 100, \"width\", 200, \"height\", 200,\n \"direction\", \"down\",\n \"percent\", 1.0\n));\n```\n\n```python\n# Python\ncan_scroll_more = driver.execute_script('mobile: scrollGesture', {\n 'left': 100, 'top': 100, 'width': 200, 'height': 200,\n 'direction': 'down',\n 'percent': 3.0\n})\n```","metadata":{"loc":{"lines":{"from":330,"to":352}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/android-mobile-gestures.md","filename":"android-mobile-gestures.md","relativePath":"appium-uiautomator2-driver/android-mobile-gestures.md"}},{"pageContent":"# Supported BiDi Commands And Events\n\nOnly events and commands mentioned below are supported.\nAll other entities described in the spec throw not implemented errors.\n\n# Supported Events\n\n## log.entryAdded\n\nThis event is emitted if the driver retrieves a new entry for any of the below log types.\n\n### syslog\n\nEvents are emitted for both emulator and real devices. Each event contains a single device logcat line.\nEvents are always emitted with the `NATIVE_APP` context.\nThese events might be disabled if the `appium:skipLogcatCapture` capability is enabled.\n\n### server\n\nEvents are emitted for both emulator and real devices. Each event contains a single Appium server log line.\nEvents are always emitted with the `NATIVE_APP` context.\nEvents are only emitted if the `get_server_logs` server security feature is enabled.\n\n## appium:uiautomator2.contextUpdate","metadata":{"loc":{"lines":{"from":1,"to":24}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/bidi.md","filename":"bidi.md","relativePath":"appium-uiautomator2-driver/bidi.md"}},{"pageContent":"## appium:uiautomator2.contextUpdate\n\nThis event is emitted upon the context change, either explicit or implicit.\nThe event is always emitted upon new session initialization.\nSee the [GitHub feature ticket](https://github.com/appium/appium/issues/20741) for more details.\n\n### CDDL\n\n```cddl\nappium:uiautomator2.contextUpdated = {\n method: \"appium:uiautomator2.contextUpdated\",\n params: {\n name: text,\n type: \"NATIVE\" / \"WEB\",\n },\n}\n```\n\nThe event contains the following params:\n\n### name\n\nContains the actual name of the new context, for example `NATIVE_APP`.\n\n### type\n\nEither `NATIVE` or `WEB` depending on which context is currently active in the driver session.","metadata":{"loc":{"lines":{"from":24,"to":50}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/bidi.md","filename":"bidi.md","relativePath":"appium-uiautomator2-driver/bidi.md"}},{"pageContent":"## Basic Examples of Session Capability Sets\n\nThis article describes necessary capabilities that must be provided in order\nto implement some common automation testing scenarios.\nIt only describes very minimum sets of capabilities required to\nbe included. For refined setups more of them might need to be provided. Check the\n[Capabilities](../README.md#capabilities) section in README for more details\non each option available for the fine-tuning of UIAutomator2 driver sessions.\n\n### Application File (Real Device)\n\n```json\n{\n \"platformName\": \"Android\",\n \"appium:automationName\": \"uiautomator2\",\n \"appium:platformVersion\": \"<Android_Version>\",\n \"appium:udid\": \"<Phone_ID>\",\n \"appium:app\": \"/path/to/local/package.apk\"\n}\n```\n\n`appium:app` could also be a remote app or an archive:\n\n```\n \"appium:app\": \"https://example.com/package.apk\"\n \"appium:app\": \"https://example.com/package.zip\"\n```","metadata":{"loc":{"lines":{"from":1,"to":27}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/capability-sets.md","filename":"capability-sets.md","relativePath":"appium-uiautomator2-driver/capability-sets.md"}},{"pageContent":"`appium:app` could also be a remote app or an archive:\n\n```\n \"appium:app\": \"https://example.com/package.apk\"\n \"appium:app\": \"https://example.com/package.zip\"\n```\n\nSometimes it might also be necessary to explicitly provide\n`appium:appPackage` and `appium:appActivity` capability values\nif the driver is unable to autodetect them from the provided app package manifest.\nCheck the [How To Troubleshoot Activities Startup](./activity-startup.md) article\nfor more details.\n\n### Application File (Emulator)\n\n```json\n{\n \"platformName\": \"Android\",\n \"appium:automationName\": \"uiautomator2\",\n \"appium:avd\": \"<Emulator_Name>\",\n \"appium:platformVersion\": \"<Android_Version>\",\n \"appium:app\": \"/path/to/local/package.apk\"\n}\n```\n\n`appium:app` could also be a remote app or an archive:\n\n```\n \"appium:app\": \"https://example.com/package.apk\"\n```\n\n### Chrome (Real Device)","metadata":{"loc":{"lines":{"from":22,"to":53}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/capability-sets.md","filename":"capability-sets.md","relativePath":"appium-uiautomator2-driver/capability-sets.md"}},{"pageContent":"`appium:app` could also be a remote app or an archive:\n\n```\n \"appium:app\": \"https://example.com/package.apk\"\n```\n\n### Chrome (Real Device)\n\n```json\n{\n \"platformName\": \"Android\",\n \"appium:automationName\": \"uiautomator2\",\n \"browserName\": \"Chrome\",\n \"appium:platformVersion\": \"<Android_Version>\",\n \"appium:udid\": \"<Phone_ID>\"\n}\n```\n\n### Chrome (Emulator)\n\n```json\n{\n \"platformName\": \"Android\",\n \"appium:automationName\": \"uiautomator2\",\n \"browserName\": \"Chrome\",\n \"appium:avd\": \"<Emulator_Name>\",\n \"appium:platformVersion\": \"<Android_Version>\"\n}\n```\n\n### Pre-Installed App (Real Device)\n\n```json\n{\n \"platformName\": \"Android\",\n \"appium:automationName\": \"uiautomator2\",\n \"appium:platformVersion\": \"<Android_Version>\",\n \"appium:udid\": \"<Phone_ID>\",\n \"appium:appPackage\": \"<App_Package_Id>\",\n \"appium:appActivity\": \"<App_Activity_Id>\",\n \"appium:noReset\": true\n}\n```","metadata":{"loc":{"lines":{"from":47,"to":89}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/capability-sets.md","filename":"capability-sets.md","relativePath":"appium-uiautomator2-driver/capability-sets.md"}},{"pageContent":"The `appium:noReset` capability is set to `true` in order to tell the driver\nthe app identified by `appium:appPackage` is already preinstalled and must not be reset.\n\n### Pre-Installed App (Emulator)\n\n```json\n{\n \"platformName\": \"Android\",\n \"appium:automationName\": \"uiautomator2\",\n \"appium:avd\": \"<Emulator_Name>\",\n \"appium:platformVersion\": \"<Android_Version>\",\n \"appium:appPackage\": \"<App_Package_Id>\",\n \"appium:appActivity\": \"<App_Activity_Id>\",\n \"appium:noReset\": true\n}\n```\n\n### Custom Launch (Real Device)\n\n```json\n{\n \"platformName\": \"Android\",\n \"appium:automationName\": \"uiautomator2\",\n \"appium:platformVersion\": \"<Android_Version>\",\n \"appium:udid\": \"<Phone_ID>\"\n}\n```","metadata":{"loc":{"lines":{"from":91,"to":117}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/capability-sets.md","filename":"capability-sets.md","relativePath":"appium-uiautomator2-driver/capability-sets.md"}},{"pageContent":"```json\n{\n \"platformName\": \"Android\",\n \"appium:automationName\": \"uiautomator2\",\n \"appium:platformVersion\": \"<Android_Version>\",\n \"appium:udid\": \"<Phone_ID>\"\n}\n```\n\nThis will start your test at the Home screen.\nAfterwards you may use any of the application management\nmethods, like [mobile: installApp](../README.md#mobile-installapp)\nor [mobile: activateApp](../README.md#mobile-activateapp)\nto manage the life cycle of your app or switch between contexts to\nmanage web pages. Check the full list of\n[mobile: execute methods](../README.md#platform-specific-extensions) for more details.\n\n### Custom Launch (Emulator)\n\n```json\n{\n \"platformName\": \"Android\",\n \"appium:automationName\": \"uiautomator2\",\n \"appium:avd\": \"<Emulator_Name>\",\n \"appium:platformVersion\": \"<Android_Version>\"\n}\n```","metadata":{"loc":{"lines":{"from":110,"to":136}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/capability-sets.md","filename":"capability-sets.md","relativePath":"appium-uiautomator2-driver/capability-sets.md"}},{"pageContent":"# Scheduled Actions\n\n## Problem Statement","metadata":{"loc":{"lines":{"from":1,"to":3}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/scheduled-actions.md","filename":"scheduled-actions.md","relativePath":"appium-uiautomator2-driver/scheduled-actions.md"}},{"pageContent":"Sometimes it is necessary to verify a UI scenario where one has to assert a UI control has appeared on the screen and then perform a decision action on this control. An example of such control might be a notification or any other popup that automatically disappears shortly after being shown. The WebDriver protocol uses HTTP REST API to communicate with clients. This means if you want to assert the existence of the above popup in your test script or perform any action on it then it is necessary to send an HTTP request to the server and receive an answer from it. Furthermore, this is needed for each particular command or assertion you want to perform, e.g. click, find element, get text, etc. The time an HTTP request needs to reach the server and then its response to reach the client is the roundtrip time, and the length of it depends on many factors. For some complex setups the roundtrip duration may even be counted in seconds, which makes it impossible to quickly handle an UI element,","metadata":{"loc":{"lines":{"from":5,"to":5}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/scheduled-actions.md","filename":"scheduled-actions.md","relativePath":"appium-uiautomator2-driver/scheduled-actions.md"}},{"pageContent":"roundtrip time, and the length of it depends on many factors. For some complex setups the roundtrip duration may even be counted in seconds, which makes it impossible to quickly handle an UI element, because it would already not exist/disappear by the time your next request reaches the server.","metadata":{"loc":{"lines":{"from":5,"to":5}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/scheduled-actions.md","filename":"scheduled-actions.md","relativePath":"appium-uiautomator2-driver/scheduled-actions.md"}},{"pageContent":"## Scheduled Actions Concept\n\nIn order to address the problem above we have created the Scheduled Actions concept. The main idea there is to run the action code on the server side in asynchronous manner and only retrieve the detailed execution history if needed. `Action` is this context means emulating a gesture, or taking a screenshot, or taking a xml page source. More actions could be added later. The `scheduled` means after you create an action, or rather describe it in JSON, it is parsed and stored by the server for the further async execution. The client does not have any control over the previously scheduled action and can only unschedule it later or fetch its execution history. All actions are being scheduled on the main UI thread. All scheduled actions are reset automatically upon a new session creation.\n\nThis feature is available in the UIA2 driver since version *2.26.0*\n\n## mobile: scheduleAction\n\nAdds a new action to the list of scheduled actions.\n\n### Arguments","metadata":{"loc":{"lines":{"from":7,"to":17}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/scheduled-actions.md","filename":"scheduled-actions.md","relativePath":"appium-uiautomator2-driver/scheduled-actions.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nname | string | yes | The unique name of the action. | popupHandlingAction\nsteps | ActionStep[] | yes | One or more action steps to execute. Steps are executed in sequential order. All steps are executed even if any of them fails. The execution is considered failed if at least one step fails. | Check [Action Steps](#action-steps)\nmaxPass | number | no | If set to a number greater than zero then the action will stop rescheduling itself after it passes the desired number of times | 1\nmaxFail | number | no | If set to a number greater than zero then the action will stop rescheduling itself after it fails the desired number of times | 1\ntimes | number | no | How many times the action must be executed itself. 1 by default | 10\nintervalMs | number | no | How long the interval in milliseconds between the next action reschedule should be. 1000 ms by default. | 100","metadata":{"loc":{"lines":{"from":19,"to":26}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/scheduled-actions.md","filename":"scheduled-actions.md","relativePath":"appium-uiautomator2-driver/scheduled-actions.md"}},{"pageContent":"intervalMs | number | no | How long the interval in milliseconds between the next action reschedule should be. 1000 ms by default. | 100\nmaxHistoryItems | number | no | The maximum size of the history items array that are stored for this action. Each action execution creates a new history item. All items are sorted in descending order by action execution timestamp. If the amount of executions reaches `maxHistoryItems` value then the oldest history item gets deleted. Be careful to not set this parameter to large values as you might get out of memory issues. 20 history items are being stored for each action by default. | 100","metadata":{"loc":{"lines":{"from":26,"to":27}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/scheduled-actions.md","filename":"scheduled-actions.md","relativePath":"appium-uiautomator2-driver/scheduled-actions.md"}},{"pageContent":"#### Action Steps\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ntype | string | yes | One of supported step types: `gesture`, `source`, `screenshot`. | gesture\nname | string | yes | Step name. It must not be unique, but is useful to track the step execution history. | click\npayload | map | yes | Step payload. The payload format depends on the actual step type. | Check on [Step Payload](#step-payload) below\n\n#### Step Payload\n\nEach step payload is required to contain the `subtype` item. Then the combination of step's `type` and `subtype` defines the actual payload content:","metadata":{"loc":{"lines":{"from":29,"to":39}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/scheduled-actions.md","filename":"scheduled-actions.md","relativePath":"appium-uiautomator2-driver/scheduled-actions.md"}},{"pageContent":"Type | Subtype | Description | Payload Example\n--- | --- | --- | ---\ngesture | click | The payload is expected to be similar to the one the [mobile: clickGesture](./android-mobile-gestures.md#mobile-clickgesture) requires. | {subtype: 'click', locator: {strategy: 'id', selector: 'buttonIdentifier'}}\ngesture | longClick | The payload is expected to be similar to the one the [mobile: longClickGesture](./android-mobile-gestures.md#mobile-longclickgesture) requires. | {subtype: 'click', locator: {strategy: 'accessbility id', selector: 'buttonIdentifier'}}\ngesture | doubleClick | The payload is expected to be similar to the one the [mobile: doubleClickGesture](./android-mobile-gestures.md#mobile-doubleclickgesture) requires. | {subtype: 'click', elementId: 'yolo', x: 150, y: 200}\nsource | xml | The payload does not need to contain any other items. | {subtype: 'xml'}\nscreenshot | png | The payload does not need to contain any other items. | {subtype: 'png'}\n\n## mobile: getActionHistory","metadata":{"loc":{"lines":{"from":41,"to":49}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/scheduled-actions.md","filename":"scheduled-actions.md","relativePath":"appium-uiautomator2-driver/scheduled-actions.md"}},{"pageContent":"## mobile: getActionHistory\n\nReturns the history of executions for the particular action.\n\n### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nname | string | yes | The unique name of the action. | popupHandlingAction\n\n### Returned Result\n\nThe history of executions of the particular action. An error is thrown if no action with the given name has been scheduled before calling this API or if it has been already unscheduled.\n\nThe returned result map has the following items:\n\nName | Type | Description | Example\n--- | --- | --- | ---\nrepeats | number | The number of times this action has been repeated so far. | 1\nstepResults | list&lt;list&lt;map&gt;&gt; | The history of step executions for each action run. Items in this list are sorted by execution timestamp in descending order. The maximum length of the list is limited by `maxHistoryItems` action value | See below","metadata":{"loc":{"lines":{"from":49,"to":68}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/scheduled-actions.md","filename":"scheduled-actions.md","relativePath":"appium-uiautomator2-driver/scheduled-actions.md"}},{"pageContent":"The result of each action step is represented by the map inside each `stepResulsts` array item containing the following items:","metadata":{"loc":{"lines":{"from":70,"to":70}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/scheduled-actions.md","filename":"scheduled-actions.md","relativePath":"appium-uiautomator2-driver/scheduled-actions.md"}},{"pageContent":"Name | Type | Description | Example\n--- | --- | --- | ---\nname | string | The name of the corresponding step. | clickStep\ntype | string | One of supported step typed. | gesture\ntimestamp | number | The Unix timestamp in milliseconds when the step started its execution. | 1685370112000\npassed | boolean | Whether the step has passed, e.g. no exceptions occurred during its execution. | true\nresult | any | The actual step result. Depends on the step type and subtype. Might be null. Always null if exception is not null. | something\nexception | map | If an exception happens during the step execution then this map will contain the following items: name (the exception class name), message (the actual exception message), stacktrace (full exception stacktrace). If no exceptions occurs during step execution then the value of this item is always null | {name: 'java.lang.Exception', message: 'Bad things happen', stacktrace: 'happened somewhere'}\n\n## mobile: unscheduleAction","metadata":{"loc":{"lines":{"from":72,"to":81}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/scheduled-actions.md","filename":"scheduled-actions.md","relativePath":"appium-uiautomator2-driver/scheduled-actions.md"}},{"pageContent":"## mobile: unscheduleAction\n\nUnschedules an action from the async execution and returns its history.\n\n### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nname | string | yes | The unique name of the action. | popupHandlingAction\n\n### Returned Result\n\nThe same as in [mobile: getActionHistory](#mobile-getactionhistory) endpoint\n\n## Usage Example\n\nLet's assume our application under test shows a short-living popup with two buttons to either accept or reject it.\nAt first, we need to figure out how the popup looks like in the page source to build element locators. For that we are going to create an action that periodically retrieves page source snapshots:\n\n```python\ndriver.execute_script('mobile: scheduleAction', {\n 'name': 'myPopupHandlingAction',\n 'steps': [{\n 'type': 'source',\n 'name': 'fetchPageSourceStep',\n 'payload': {\n 'subtype': 'xml'\n }\n }],\n 'intervalMs': 1000,\n 'times': 30,\n 'maxHistoryItems': 30,\n})","metadata":{"loc":{"lines":{"from":81,"to":113}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/scheduled-actions.md","filename":"scheduled-actions.md","relativePath":"appium-uiautomator2-driver/scheduled-actions.md"}},{"pageContent":"# doing some other stuff which is supposed to trigger the popup for the next 30 seconds\n\nhistory: Dict[str, Any] = driver.execute_script('mobile: unscheduleAction', {\n 'name': 'myPopupHandlingAction',\n})\n```\n\nIn the example above we have scheduled an action which takes UI hierarchy snapshot every second. Eventually we can\ndebug the value of `history` list and inspect each item for the presence of our expected popup element. After we have figured out locators for its Accept button our action may be updated to:\n\n```python\ndriver.execute_script('mobile: scheduleAction', {\n 'name': 'myPopupHandlingAction',\n 'steps': [{\n 'type': 'gesture',\n 'name': 'acceptPopupStep',\n 'payload': {\n 'subtype': 'click'\n 'locator': {\n 'strategy': 'id',\n 'selector': 'acceptButtonIdentifier',\n }\n }\n }],\n 'intervalMs': 1000,\n 'times': 30,\n 'maxPass': 1,\n 'maxHistoryItems': 30,\n})","metadata":{"loc":{"lines":{"from":115,"to":143}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/scheduled-actions.md","filename":"scheduled-actions.md","relativePath":"appium-uiautomator2-driver/scheduled-actions.md"}},{"pageContent":"# doing some other stuff which is supposed to trigger the popup for the next 30 seconds\n\nhistory: Dict[str, Any] = driver.execute_script('mobile: unscheduleAction', {\n 'name': 'myPopupHandlingAction',\n})\n\ndef did_execution_pass(execution: List[Dict]) -> bool:\n return all((step['passed'] for step in execution))\n\nassert any((did_execution_pass(execution) for exection in history['stepResults']))\n```","metadata":{"loc":{"lines":{"from":145,"to":155}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/scheduled-actions.md","filename":"scheduled-actions.md","relativePath":"appium-uiautomator2-driver/scheduled-actions.md"}},{"pageContent":"## Guide on UiAutomator Locator Types\n\nUIA2 driver enables elements lookup using [UiSelector](https://developer.android.com/reference/androidx/test/uiautomator/UiSelector).\n[UiScrollable](https://developer.android.com/reference/androidx/test/uiautomator/UiScrollable)\nis also supported.\nBoth locator types are supported natively by Google's [UiAutomator](https://developer.android.com/training/testing/other-components/ui-automator) framework for Android. With these locators you could create flexible ways to reference complicated element paths, and their performance is very close to native.\n\n### Examples\n\nNote that the index selector is unreliable so prefer instance instead. The\nfollowing examples are written against the [ApiDemos](https://github.com/appium/android-apidemos) apk using Ruby.\n\nFind the first textview.\n\n```ruby\n# ruby\nfirst_textview = find_element(:uiautomator, 'new UiSelector().className(\"android.widget.TextView\").instance(0)');\n```\n\nFind the first element by text.","metadata":{"loc":{"lines":{"from":1,"to":20}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/uiautomator-uiselector.md","filename":"uiautomator-uiselector.md","relativePath":"appium-uiautomator2-driver/uiautomator-uiselector.md"}},{"pageContent":"Find the first textview.\n\n```ruby\n# ruby\nfirst_textview = find_element(:uiautomator, 'new UiSelector().className(\"android.widget.TextView\").instance(0)');\n```\n\nFind the first element by text.\n\n```ruby\n# ruby\nfirst_text = find_element(:uiautomator, 'new UiSelector().text(\"Animation\")')\nfirst_text.text # \"Animation\"\n```\n\nFind the first scrollable element, then find a TextView with the text \"Tabs\".\nThe \"Tabs\" element will be scrolled into view.\n\n```ruby\n# ruby\nelement = find_element(:uiautomator, 'new UiScrollable(new UiSelector().scrollable(true).instance(0)).getChildByText(new UiSelector().className(\"android.widget.TextView\"), \"Tabs\")')\n```\n\nAs a special case, scrollIntoView returns the element that is scrolled into view.\nscrollIntoView allows scrolling to any UiSelector.\n\n```ruby\n# ruby\nelement = find_element(:uiautomator, 'new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().text(\"WebView\").instance(0));')\nelement.text # \"WebView\"\n```","metadata":{"loc":{"lines":{"from":13,"to":43}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/uiautomator-uiselector.md","filename":"uiautomator-uiselector.md","relativePath":"appium-uiautomator2-driver/uiautomator-uiselector.md"}},{"pageContent":"### More Resources\n\n- [How to Use UISelector in Appium](http://code2test.com/appium-tutorial/how-to-use-uiselector-in-appium/)\n- [How to use UiSelector to inspect elements on Android](https://www.automationtestinghub.com/uiselector-android/)\n- [UiAutomatorParserTests.java](https://github.com/appium/appium-uiautomator2-server/blob/master/app/src/test/java/io/appium/uiautomator2/utils/UiAutomatorParserTests.java)\n- [UiScrollableParserTests.java](https://github.com/appium/appium-uiautomator2-server/blob/master/app/src/test/java/io/appium/uiautomator2/utils/UiScrollableParserTests.java)\n- [UiSelectorParserTests.java](https://github.com/appium/appium-uiautomator2-server/blob/master/app/src/test/java/io/appium/uiautomator2/utils/UiSelectorParserTests.java)","metadata":{"loc":{"lines":{"from":45,"to":51}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/uiautomator-uiselector.md","filename":"uiautomator-uiselector.md","relativePath":"appium-uiautomator2-driver/uiautomator-uiselector.md"}},{"pageContent":"# Unlock\n\nUiAutomator2 driver allows dealing with the Android lock screen using various APIs.\nThis article describes available APIs and their options.\n\n## Unlock On Session Startup\n\nUiAutomator2 provides the following [capabilities](../../README.md#device-locking) to deal\nwith the system lock screen:\n\n- appium:unlockStrategy\n- appium:unlockSuccessTimeout\n- appium:skipUnlock\n- appium:unlockType\n- appium:unlockKey\n\nThese capabilities could be used to unlock the device under test during the driver session initialization\nas well as deal with different lock screen types.\n\n### appium:unlockStrategy\n\nEither `locksettings` (default since Android 8/API level 26) or `uiautomator` (legacy).\n\nThe `locksettings` strategy uses `adb shell locksettings` CLI to deal with different\ntypes of device lock screens. It is fast, reliable, but has one downside: the actual\npin, pattern or password must be temporarily removed in order to unlock the device and restored afterwards.","metadata":{"loc":{"lines":{"from":1,"to":26}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/unlock/main.md","filename":"main.md","relativePath":"appium-uiautomator2-driver/unlock/main.md"}},{"pageContent":"Setting the strategy to `uiautomator` will enforce the driver to use UiAutomator framework in order\nto interact with the device's lock screen for various unlock types. It might be slower and less stable in comparison\nto the `locksettings` strategy, although there is no other alternative if tests are being executed on an older Android version\nor the application under test requires the device to constantly maintain display lock settings.\n\n### appium:unlockSuccessTimeout\n\nMaximum number of milliseconds to wait until the device is unlocked. `2000` ms by default\n\n### appium:skipUnlock","metadata":{"loc":{"lines":{"from":28,"to":37}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/unlock/main.md","filename":"main.md","relativePath":"appium-uiautomator2-driver/unlock/main.md"}},{"pageContent":"### appium:unlockSuccessTimeout\n\nMaximum number of milliseconds to wait until the device is unlocked. `2000` ms by default\n\n### appium:skipUnlock\n\nThe `appium:skipUnlock` capability is enabled by default and makes the driver to detect and handle the lock screen\nupon session startup _if it is present_. If the lock screen cannot be detected upon session startup then nothing will be\ndone. By default, it is assumed the device has a \"simple\" lock screen, which could be removed by waking up the device.\nIn case the device has a different type of the lock screen configured in its settings then the information about it\nmust be provided in the below capability values.\n\n### appium:unlockType and appium:unlockKey\n\nThis capability supports the following possible values:\n\n#### pin\n\nAssumes the device is protected with a PIN code. Expects the `appium:unlockKey` to contain a valid pin consisting\nof digits in range 0-9, for example `1111`.\n\n#### pinWithKeyEvent","metadata":{"loc":{"lines":{"from":33,"to":54}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/unlock/main.md","filename":"main.md","relativePath":"appium-uiautomator2-driver/unlock/main.md"}},{"pageContent":"#### pin\n\nAssumes the device is protected with a PIN code. Expects the `appium:unlockKey` to contain a valid pin consisting\nof digits in range 0-9, for example `1111`.\n\n#### pinWithKeyEvent\n\nSame as [pin](#pin), but uses ADB instead of UiAutomator framework to enter the actual pin value.\n\n#### password\n\nAssumes the device is protected with a password. Expects the `appium:unlockKey` to contain a valid password consisting\nof latin characters, for example `abcd1234`.\n\n#### pattern\n\nAssumes the device is protected with a secret pattern. Check the example below for more details on the `appium:unlockKey`\nvalue for this particular unlock type.\n\n##### Example\n\nLet say you have a device that is locked with a pattern similar to the one on the image below,\nand you want to run a test over that device.\n\n<img src=\"./screen1.png\" />\n\nWe treat the pattern pins similarly to numbers on a digital phone dial. So, in this case the *unlockKey* is `729854163`\n\n<img src=\"./screen2.png\" />","metadata":{"loc":{"lines":{"from":49,"to":77}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/unlock/main.md","filename":"main.md","relativePath":"appium-uiautomator2-driver/unlock/main.md"}},{"pageContent":"<img src=\"./screen1.png\" />\n\nWe treat the pattern pins similarly to numbers on a digital phone dial. So, in this case the *unlockKey* is `729854163`\n\n<img src=\"./screen2.png\" />\n\nand capabilities are:\n\n```json\n{\n \"appium:unlockType\": \"pattern\",\n \"appium:unlockKey\": \"729854163\"\n}\n```\n\n## Mid-Session Unlock\n\nThere is also a possibility to interact with the device's lock screen while the test session is running.\nUse the following mobile extensions for this purpose:\n\n- [mobile: lock](../../README.md#mobile-lock)\n- [mobile: unlock](../../README.md#mobile-unlock)\n- [mobile: isLocked](../../README.md#mobile-islocked)","metadata":{"loc":{"lines":{"from":73,"to":95}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-uiautomator2-driver/unlock/main.md","filename":"main.md","relativePath":"appium-uiautomator2-driver/unlock/main.md"}},{"pageContent":"## WebDriverAgent JSONWP Endpoints\n\n### Session-less commands\n\n| method | endpoint | req params | opt params |\n| ------ | -------------------------------------- | ---------- | ---------- |\n| POST | /wda/homescreen | | |\n| GET | /source | | accessible |\n| GET | /inspector | | |\n| GET | /inspector.js | | |\n| GET | /screenshot | | |\n| POST | /session | desiredCapabilities\n| GET | /status | | |\n| GET | /* | ** | |\n| POST | /* | ** | |\n| PUT | /* | ** | |\n| DELETE | /* | ** | |\n\n\n### Session commands","metadata":{"loc":{"lines":{"from":1,"to":20}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/endpoints-wda.md","filename":"endpoints-wda.md","relativePath":"appium-xcuitest-driver/endpoints-wda.md"}},{"pageContent":"| method | endpoint | req params | opt params |\n| ------ | -------------------------------------- | ---------- | ---------- |\n| GET | /alert/text | | |\n| POST | /alert/accept | | |\n| POST | /alert/dismiss | | |\n| POST | /wda/deactivateApp | | duration |\n| POST | /timeouts | * | |\n| GET | /source | | accessible |\n| GET | /element/:uuid/enabled | | |\n| GET | /element/:uuid/rect | | |\n| GET | /element/:uuid/attribute/:name | | |\n| GET | /element/:uuid/text | | |\n| GET | /element/:uuid/displayed | | |\n| GET | /wda/element/:uuid/accessible | | |\n| GET | /element/:uuid/name | | |\n| POST | /element/:uuid/value | value | |","metadata":{"loc":{"lines":{"from":22,"to":37}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/endpoints-wda.md","filename":"endpoints-wda.md","relativePath":"appium-xcuitest-driver/endpoints-wda.md"}},{"pageContent":"| GET | /wda/element/:uuid/accessible | | |\n| GET | /element/:uuid/name | | |\n| POST | /element/:uuid/value | value | |\n| POST | /element/:uuid/click | | |\n| POST | /element/:uuid/clear | | |\n| POST | /wda/element/:uuid/doubleTap | | |\n| POST | /wda/element/:uuid/touchAndHold | duration | |\n| POST | /wda/element/:uuid/scroll | | name, direction, predicateString, toVisible |\n| POST | /uiaElement/:uuid/value | value | |\n| POST | /wda/element/:uuid/dragfromtoforduration | fromX, fromY, toX, toY, duration | |\n| POST | /wda/tap/:uuid | x, y | |\n| POST | /wda/keys | value | |\n| GET | /window/size | | |\n| POST | /element | using, value | |\n| POST | /elements | using, value | |","metadata":{"loc":{"lines":{"from":35,"to":49}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/endpoints-wda.md","filename":"endpoints-wda.md","relativePath":"appium-xcuitest-driver/endpoints-wda.md"}},{"pageContent":"| GET | /window/size | | |\n| POST | /element | using, value | |\n| POST | /elements | using, value | |\n| GET | /wda/uiaElement/:uuid/getVisibleCells | | |\n| POST | /element/:uuid/element | using, value | |\n| POST | /element/:uuid/elements | using, value | |\n| GET | /orientation | | |\n| POST | /orientation | orientation | |\n| GET | /screenshot | | |\n| POST | /wda/touch_id | match | |","metadata":{"loc":{"lines":{"from":47,"to":56}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/endpoints-wda.md","filename":"endpoints-wda.md","relativePath":"appium-xcuitest-driver/endpoints-wda.md"}},{"pageContent":"\\* implemented but intentionally not supported\n\n** not implemented handlers","metadata":{"loc":{"lines":{"from":59,"to":61}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/endpoints-wda.md","filename":"endpoints-wda.md","relativePath":"appium-xcuitest-driver/endpoints-wda.md"}},{"pageContent":"## Appium iOS JSONWP Endpoints\n\n### Session-less commands\n\n| method | endpoint | req params | opt params |\n| ------ | ---------------------------------------- | ---------- | ---------- |\n| GET | /status | | |\n| POST | /session | desiredCapabilities | requiredCapabilities |\n| GET | /sessions | | |\n\n\n### Session commands","metadata":{"loc":{"lines":{"from":1,"to":12}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/endpoints.md","filename":"endpoints.md","relativePath":"appium-xcuitest-driver/endpoints.md"}},{"pageContent":"| method | endpoint | req params | opt params |\n| ------ | ---------------------------------------- | ---------- | ---------- |\n| GET | /:sessionId | | |\n| DELETE | /:sessionId | | |\n| POST | /timeouts | type, ms | |\n| POST | /timeouts/async_script | ms | |\n| POST | /timeouts/implicit_wait | ms | |\n| GET | /window_handle | | |\n| GET | /window_handles | | |\n| GET | /url | | |\n| POST | /url | url | |\n| POST | /forward | none | |\n| POST | /back | none | |\n| POST | /refresh | none | |\n| POST | /execute | script, args | |","metadata":{"loc":{"lines":{"from":14,"to":28}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/endpoints.md","filename":"endpoints.md","relativePath":"appium-xcuitest-driver/endpoints.md"}},{"pageContent":"| POST | /back | none | |\n| POST | /refresh | none | |\n| POST | /execute | script, args | |\n| POST | /execute_async | script, args | |\n| GET | /screenshot | | |\n| POST | /frame | id | |\n| POST | /window | name | |\n| DELETE | /window | | |\n| GET | /window/:windowhandle/size | | |\n| GET | /cookie | | |\n| POST | /cookie | cookie | |\n| DELETE | /cookie | | | | |\n| DELETE | /cookie/:name | | |\n| GET | /source | | |\n| GET | /title | | |\n| POST | /element | using, value | |","metadata":{"loc":{"lines":{"from":26,"to":41}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/endpoints.md","filename":"endpoints.md","relativePath":"appium-xcuitest-driver/endpoints.md"}},{"pageContent":"| GET | /source | | |\n| GET | /title | | |\n| POST | /element | using, value | |\n| POST | /elements | using, value | |\n| POST | /element/active | none | |\n| POST | /element/:elementId/element | using, value | |\n| POST | /element/:elementId/elements | using, value | |\n| POST | /element/:elementId/click | none | |\n| POST | /element/:elementId/submit | none | |\n| GET | /element/:elementId/text | none | |\n| POST | /element/:elementId/value | value | |\n| POST | /keys | value | |\n| GET | /element/:elementId/name | | |\n| POST | /element/:elementId/clear | none | |\n| GET | /element/:elementId/selected | | |","metadata":{"loc":{"lines":{"from":39,"to":53}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/endpoints.md","filename":"endpoints.md","relativePath":"appium-xcuitest-driver/endpoints.md"}},{"pageContent":"| GET | /element/:elementId/name | | |\n| POST | /element/:elementId/clear | none | |\n| GET | /element/:elementId/selected | | |\n| GET | /element/:elementId/enabled | | |\n| GET | /element/:elementId/attribute/:name | | |\n| GET | /element/:elementId/equals/:otherId | | |\n| GET | /element/:elementId/displayed | | |\n| GET | /element/:elementId/location | | |\n| GET | /element/:elementId/location_in_view | | |\n| GET | /element/:elementId/size | | |\n| GET | /element/:elementId/css/:propertyName | | |\n| GET | /orientation | | |\n| POST | /orientation | orientation | |\n| GET | /alert_text | | |\n| POST | /alert_text | text | |\n| POST | /accept_alert | none | |","metadata":{"loc":{"lines":{"from":51,"to":66}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/endpoints.md","filename":"endpoints.md","relativePath":"appium-xcuitest-driver/endpoints.md"}},{"pageContent":"| GET | /alert_text | | |\n| POST | /alert_text | text | |\n| POST | /accept_alert | none | |\n| POST | /dismiss_alert | none | |\n| POST | /click | | button |\n| GET | /location | | |\n| POST | /location | location | |\n| POST | /log | type | |\n| GET | /log/types | | |\n| GET | /context | | |\n| POST | /context | name | |\n| GET | /contexts | | |\n| POST | /receive_async_response | status, value | |","metadata":{"loc":{"lines":{"from":64,"to":76}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/endpoints.md","filename":"endpoints.md","relativePath":"appium-xcuitest-driver/endpoints.md"}},{"pageContent":"### Appium-specific commands","metadata":{"loc":{"lines":{"from":79,"to":79}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/endpoints.md","filename":"endpoints.md","relativePath":"appium-xcuitest-driver/endpoints.md"}},{"pageContent":"| method | endpoint | req params | opt params |\n| ------ | ---------------------------------------- | ---------- | ---------- |\n| POST | /appium/device/shake | none | |\n| GET | /appium/device/system_time | | |\n| POST | /appium/device/lock | | seconds |\n| POST | /appium/device/rotate | x, y, radius, rotation, touchCount, duration | element |\n| POST | /appium/device/remove_app | appId or bundleId | |\n| POST | /appium/device/hide_keyboard | | strategy, key, keyCode, keyName |\n| POST | /appium/device/push_file | path, data | |\n| POST | /appium/device/pull_file | path | |\n| POST | /appium/device/pull_folder | path | |\n| POST | /appium/simulator/touch_id | match | |\n| POST | /appium/app/launch | none | |","metadata":{"loc":{"lines":{"from":81,"to":93}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/endpoints.md","filename":"endpoints.md","relativePath":"appium-xcuitest-driver/endpoints.md"}},{"pageContent":"| POST | /appium/device/pull_folder | path | |\n| POST | /appium/simulator/touch_id | match | |\n| POST | /appium/app/launch | none | |\n| POST | /appium/app/close | none | |\n| POST | /appium/app/background | seconds | |\n| POST | /appium/app/strings | | language, stringFile |\n| POST | /appium/element/:elementId/value | value | |\n| POST | /appium/receive_async_response | response | |","metadata":{"loc":{"lines":{"from":91,"to":98}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/endpoints.md","filename":"endpoints.md","relativePath":"appium-xcuitest-driver/endpoints.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Attach to a Running WebDriverAgent\n---\n\nThe XCUITest driver provides the __`appium:webDriverAgentUrl`__ capability to attach to a running\nWebDriverAgent (WDA) application. This works for real devices and simulators, but the primary usage\nis for real devices.\n\n## Usage\n\n1. Start a WebDriverAgent application on a device\n2. Start an XCUITest driver session with `appium:webDriverAgentUrl` capability\n\nPlease read [Manage WebDriverAgent by Yourself](./wda-custom-server.md) and\n[Real Device Configuration](../preparation/real-device-config.md) about how to prepare WDA for a\nreal device.\n\nThe `appium:webDriverAgentUrl` value should be the WDA URL: `http://<reachable ip address for the device>:8100`.\nIf the environment has port-forward to the connected device, it can be `http://localhost:8100`.","metadata":{"loc":{"lines":{"from":1,"to":22}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/attach-to-running-wda.md","filename":"attach-to-running-wda.md","relativePath":"appium-xcuitest-driver/guides/attach-to-running-wda.md"}},{"pageContent":"```json\n{\n \"platformName\": \"ios\",\n \"appium:automationName\": \"xcuitest\",\n \"appium:platformVersion\": \"15.5\",\n \"appium:udid\": \"<device udid>\",\n \"appium:deviceName\": \"iPhone\",\n \"appium:webDriverAgentUrl\": \"http://<reachable ip address for the device>:8100\"\n}\n```\n\nThis method allows you to manage the WDA process by yourself. The XCUITest driver then simply\nattaches to the WDA process, which may improve the application performance.\n\nSome XCUITest driver APIs (for example,\n[mobile: calibrateWebToRealCoordinatesTranslation](../reference/execute-methods.md#mobile-calibratewebtorealcoordinatestranslation))\nmight still require the port number of the remote device if it is a real device. Providing the\n`appium:webDriverAgentUrl` capability might not be sufficient to recognize the remote port number,\nin case it is different from the local one. Consider settings the `appium:wdaRemotePort` capability\nin such cases, to supply the driver with the appropriate data.","metadata":{"loc":{"lines":{"from":24,"to":43}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/attach-to-running-wda.md","filename":"attach-to-running-wda.md","relativePath":"appium-xcuitest-driver/guides/attach-to-running-wda.md"}},{"pageContent":"---\ntitle: Audio Capture\n---\n\n\nAppium XCUITest driver provides a possibility to record iOS audio stream and save it to a file,\nwhich could be then retrieved on the client side. Apple does not provide any API to directly\nretrieve the audio stream from a Simulator or a real device, but it is possible to redirect that\nstream to the host machine, where it could be captured.\n\n* [`mobile: startAudioRecording`](../reference/execute-methods.md#mobile-startaudiorecording)\n* [`mobile: stopAudioRecording`](../reference//execute-methods.md#mobile-stopaudiorecording)\n\n## Server Requirements\n\n- The host machine must have [`ffmpeg`](https://www.ffmpeg.org/download.html) installed and added to PATH.\n It can be installed via [`brew`](https://brew.sh/): `brew install ffmpeg`.\n- For macOS 10.15+, applications recording Microphone audio need to be explicitly granted this permission.\n This can be done in the following settings menu:","metadata":{"loc":{"lines":{"from":1,"to":19}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/audio-capture.md","filename":"audio-capture.md","relativePath":"appium-xcuitest-driver/guides/audio-capture.md"}},{"pageContent":"- macOS < 13: _System Preferences -> Security & Privacy -> Privacy -> Microphone_\n - macOS 13+: _System Settings -> Privacy & Security -> Microphone_\n\n Ensure that either `ffmpeg` itself or the parent Appium process (e.g. Terminal) is present in that list.\n\n- As this is a potentially insecure feature, it must be explicitly allowed on the server side. See\n [the Appium documentation on Security](https://appium.io/docs/en/latest/guides/security/) for more details.\n The feature name is `audio_record`.\n\n## Simulator Setup\n\nThe following steps are necessary to setup iOS Simulator audio capture:","metadata":{"loc":{"lines":{"from":21,"to":32}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/audio-capture.md","filename":"audio-capture.md","relativePath":"appium-xcuitest-driver/guides/audio-capture.md"}},{"pageContent":"## Simulator Setup\n\nThe following steps are necessary to setup iOS Simulator audio capture:\n\n* Install [Soundflower](https://github.com/mattingalls/Soundflower/releases)\n* Redirect Simulator audio output to Soundflower: from the main Simulator menu, select\n _I/O -> Audio Output -> Soundflower (2ch)_\n* In terminal, run `ffmpeg -f avfoundation -list_devices true -i \"\"` to get the identifier of the\n `Soundflower (2ch)` device. This identifier prefixed with `:` will be then used as `audioInput`\n argument to `mobile: startAudioRecording` call\n* Test that your setup works as expected. Run any audio playback in Simulator and execute the\n following command in Terminal, replacing the `-i` argument value with the one you got from the\n previous step:\n ```\n ffmpeg -t 5 -f avfoundation -i \":1\" -c:a aac -b:a 128k -ac 2 -ar 44100 -y ~/Desktop/out.mp4\n ```\n After 5 seconds, a file named `out.mp4` should be created on your desktop, containing the recorded\n audio stream.","metadata":{"loc":{"lines":{"from":30,"to":47}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/audio-capture.md","filename":"audio-capture.md","relativePath":"appium-xcuitest-driver/guides/audio-capture.md"}},{"pageContent":"## Real Device Setup\n\nThe following steps are necessary to setup iOS Real Device audio capture:","metadata":{"loc":{"lines":{"from":49,"to":51}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/audio-capture.md","filename":"audio-capture.md","relativePath":"appium-xcuitest-driver/guides/audio-capture.md"}},{"pageContent":"* Connect your device to the Mac host with a cable\n* Open the _Audio MIDI Setup_ application\n * Via Finder: _Applications -> Utilities -> Audio MIDI Setup_\n * Via terminal: `open -a /System/Applications/Utilities/Audio\\ MIDI\\ Setup.app`\n* Find your phone in the list of devices there and click `Enable` next to it\n* In terminal, run `ffmpeg -f avfoundation -list_devices true -i \"\"` to get the identifier of your\n device in the `AVFoundation audio devices` list. This identifier prefixed with `:` will be then\n used as `audioInput` argument to `mobile: startAudioRecording` call\n* Test that your setup works as expected. Run any audio playback on the device and execute the\n following command in Terminal, replacing the `-i` argument value with the value you got from the\n previous step:\n ```\n ffmpeg -t 5 -f avfoundation -i \":1\" -c:a aac -b:a 128k -ac 2 -ar 44100 -y ~/Desktop/out.mp4\n ```","metadata":{"loc":{"lines":{"from":53,"to":66}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/audio-capture.md","filename":"audio-capture.md","relativePath":"appium-xcuitest-driver/guides/audio-capture.md"}},{"pageContent":"previous step:\n ```\n ffmpeg -t 5 -f avfoundation -i \":1\" -c:a aac -b:a 128k -ac 2 -ar 44100 -y ~/Desktop/out.mp4\n ```\n After 5 seconds, a file named `out.mp4` should be created on your desktop, containing the recorded\n audio stream.","metadata":{"loc":{"lines":{"from":63,"to":68}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/audio-capture.md","filename":"audio-capture.md","relativePath":"appium-xcuitest-driver/guides/audio-capture.md"}},{"pageContent":"!!! note\n\n Apple does not allow phone calls to be redirected this way. You can only record application or system sounds.\n\n## Further Reading\n\n* <https://github.com/appium/appium-xcuitest-driver/pull/1207>\n* <https://www.macobserver.com/tips/quick-tip/iphone-audio-input-mac/>\n* <http://www.lorisware.com/blog/2012/04/28/recording-iphone-emulator-video-with-sound/>","metadata":{"loc":{"lines":{"from":70,"to":78}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/audio-capture.md","filename":"audio-capture.md","relativePath":"appium-xcuitest-driver/guides/audio-capture.md"}},{"pageContent":"---\ntitle: Basic Examples of Session Capability Sets\n---\n\nThis article describes necessary capabilities that must be provided in order\nto implement some common automation testing scenarios.\nIt only describes very minimum sets of capabilities required to\nbe included. For refined setups more of them might need to be provided. Check the\n[Capabilities](../reference/capabilities.md) article for more details\non each option available for the fine-tuning of XCUITest driver sessions.\n\n### Application File (Real Device)\n\n```json\n{\n \"platformName\": \"iOS\",\n \"appium:automationName\": \"XCUITest\",\n \"appium:platformVersion\": \"<iOS_Version>\",\n \"appium:udid\": \"<Phone_UUID>\",\n \"appium:app\": \"/path/to/local/package.ipa\"\n}\n```\n\n`appium:app` could also be a remote app or an archive:\n\n```\n \"appium:app\": \"https://example.com/package.ipa\"\n \"appium:app\": \"https://example.com/package.zip\"\n```","metadata":{"loc":{"lines":{"from":1,"to":29}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/capability-sets.md","filename":"capability-sets.md","relativePath":"appium-xcuitest-driver/guides/capability-sets.md"}},{"pageContent":"`appium:app` could also be a remote app or an archive:\n\n```\n \"appium:app\": \"https://example.com/package.ipa\"\n \"appium:app\": \"https://example.com/package.zip\"\n```\n\n`appium:udid` could also be set to `auto` in order to select the first matched device\nconnected to the host (or a single one if only one is connected):\n\n```\n \"appium:udid\": \"auto\"\n```\n\n### Application File (Simulator)\n\n```json\n{\n \"platformName\": \"iOS\",\n \"appium:automationName\": \"XCUITest\",\n \"appium:deviceName\": \"<Simulator_Name>\",\n \"appium:platformVersion\": \"<iOS_Version>\",\n \"appium:app\": \"/path/to/local/package.app\"\n}\n```\n\n`appium:app` could also be an archive:\n\n```\n \"appium:app\": \"https://example.com/package.zip\"\n \"appium:app\": \"/path/to/local/package.zip\"\n```\n\n### Safari (Real Device)\n\n```json\n{\n \"platformName\": \"iOS\",\n \"appium:automationName\": \"XCUITest\",\n \"browserName\": \"Safari\",\n \"appium:platformVersion\": \"<iOS_Version>\",\n \"appium:udid\": \"<Phone_UUID>\"\n}\n```","metadata":{"loc":{"lines":{"from":24,"to":67}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/capability-sets.md","filename":"capability-sets.md","relativePath":"appium-xcuitest-driver/guides/capability-sets.md"}},{"pageContent":"```json\n{\n \"platformName\": \"iOS\",\n \"appium:automationName\": \"XCUITest\",\n \"browserName\": \"Safari\",\n \"appium:platformVersion\": \"<iOS_Version>\",\n \"appium:udid\": \"<Phone_UUID>\"\n}\n```\n\nYou may also provide `appium:safariInitialUrl` capability value to navigate\nto the desired page during the session startup:\n\n```\n \"appium:safariInitialUrl\": \"https://server.com/page\"\n```\n\n### Safari (Simulator)\n\n```json\n{\n \"platformName\": \"iOS\",\n \"appium:automationName\": \"XCUITest\",\n \"browserName\": \"Safari\",\n \"appium:deviceName\": \"<Simulator_Name>\",\n \"appium:platformVersion\": \"<iOS_Version>\"\n}\n```\n\n### Pre-Installed App (Real Device)\n\n```json\n{\n \"platformName\": \"iOS\",\n \"appium:automationName\": \"XCUITest\",\n \"appium:platformVersion\": \"<iOS_Version>\",\n \"appium:udid\": \"<Phone_UUID>\",\n \"appium:bundleId\": \"<Bundle_ID_Of_Preinstalled_App>\",\n \"appium:noReset\": true\n}\n```","metadata":{"loc":{"lines":{"from":59,"to":99}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/capability-sets.md","filename":"capability-sets.md","relativePath":"appium-xcuitest-driver/guides/capability-sets.md"}},{"pageContent":"The `appium:noReset` capability is set to `true` in order to tell the driver\nthe app identified by `appium:bundleId` is already preinstalled and must not be reset.\n\n### Pre-Installed App (Simulator)\n\n```json\n{\n \"platformName\": \"iOS\",\n \"appium:automationName\": \"XCUITest\",\n \"appium:deviceName\": \"<Simulator_Name>\",\n \"appium:platformVersion\": \"<iOS_Version>\",\n \"appium:bundleId\": \"<Bundle_ID_Of_Preinstalled_App>\",\n \"appium:noReset\": true\n}\n```\n\n### Deeplink (Real Device running iOS 17+)\n\n```json\n{\n \"platformName\": \"iOS\",\n \"appium:automationName\": \"XCUITest\",\n \"appium:platformVersion\": \"<iOS_Version>\",\n \"appium:udid\": \"<Phone_UUID>\",\n \"appium:initialDeeplinkUrl\": \"<Deeplink_Url>\"\n}\n```\n\n### Deeplink (Simulator running iOS 17+)\n\n```json\n{\n \"platformName\": \"iOS\",\n \"appium:automationName\": \"XCUITest\",\n \"appium:deviceName\": \"<Simulator_Name>\",\n \"appium:platformVersion\": \"<iOS_Version>\",\n \"appium:initialDeeplinkUrl\": \"<Deeplink_Url>\"\n}\n```\n\n### Custom Launch (Real Device)","metadata":{"loc":{"lines":{"from":101,"to":141}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/capability-sets.md","filename":"capability-sets.md","relativePath":"appium-xcuitest-driver/guides/capability-sets.md"}},{"pageContent":"### Custom Launch (Real Device)\n\n```json\n{\n \"platformName\": \"iOS\",\n \"appium:automationName\": \"XCUITest\",\n \"appium:platformVersion\": \"<iOS_Version>\",\n \"appium:udid\": \"<Phone_UUID>\",\n}\n```\n\nThis will start your test at the Home screen.\nAfterwards you may use any of the application management\nmethods, like [mobile: installApp](../reference//execute-methods.md#mobile-installapp)\nor [mobile: activateApp](../reference//execute-methods.md#mobile-activateapp)\nto manage the life cycle of your app or switch between contexts to\nmanage web pages. Check the full list of\n[mobile: execute methods](../reference/execute-methods.md) for more details.\n\n### Custom Launch (Simulator)\n\n```json\n{\n \"platformName\": \"iOS\",\n \"appium:automationName\": \"XCUITest\",\n \"appium:deviceName\": \"<Simulator_Name>\",\n \"appium:platformVersion\": \"<iOS_Version>\"\n}\n```","metadata":{"loc":{"lines":{"from":141,"to":169}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/capability-sets.md","filename":"capability-sets.md","relativePath":"appium-xcuitest-driver/guides/capability-sets.md"}},{"pageContent":"---\ntitle: Continuous Integration\n---\n\nSetting up the XCUITest driver in an automated environment brings a few challenges with it. Any scenario\nwhere user interaction is required must be automated or avoided altogether. For real device setup,\nyou should first follow the [Real Device Configuration tutorial](../preparation/real-device-config.md).\n\n### Keychains\n\nOne common scenario is a prompt asking for a keychain to be unlocked in order to sign the WebDriverAgent.\nThere are multiple possible solutions for this:","metadata":{"loc":{"lines":{"from":1,"to":12}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/ci-setup.md","filename":"ci-setup.md","relativePath":"appium-xcuitest-driver/guides/ci-setup.md"}},{"pageContent":"1. Keychains can be set to have no timeout and be unlocked manually once. This can be done using the\n keychain access application. Sometimes keychains still lock themselves though and this approach\n is not recommended.\n2. [It is possible to create a second keychain](../guides/troubleshooting.md#real-device-security-settings),\n which just stores the required certificate to sign the WebDriverAgent. The issue with this\n approach is that Codesign wants to unlock all listed keychains regardless of the specified\n keychain, thus leading to a password prompt. This can be avoided by setting the default keychain\n and basically hiding the login keychain at the start of the build.\n [See this Stackoverflow article](https://stackoverflow.com/questions/16550594/jenkins-xcode-build-works-codesign-fails)\n for how to utilize this approach. It is impractical when running other build jobs simultaneously.","metadata":{"loc":{"lines":{"from":14,"to":23}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/ci-setup.md","filename":"ci-setup.md","relativePath":"appium-xcuitest-driver/guides/ci-setup.md"}},{"pageContent":"for how to utilize this approach. It is impractical when running other build jobs simultaneously.\n3. Stick with the existing keychains as in approach 1, but explicitly call unlock keychain before\n **each** build. This can be done using [fastlane unlock_keychain](https://docs.fastlane.tools/actions/unlock_keychain/)\n or by using [security unlock-keychain](https://www.unix.com/man-page/osx/1/security/) directly.\n The password can be saved as a CI variable/secret or on the machine itself.","metadata":{"loc":{"lines":{"from":23,"to":27}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/ci-setup.md","filename":"ci-setup.md","relativePath":"appium-xcuitest-driver/guides/ci-setup.md"}},{"pageContent":"It is recommended to go with the second or third option. The third one is the easiest and most\nreliable one to set up, at the cost of having to set the keychain password as an environment variable.\n\n### Xcode\n\nWhen setting up a new machine as a CI server, you are probably going to install Xcode, without\nexecuting it once, because you are not going to use it for development. Make sure to start Xcode at\nleast once and do the initial set up and install the suggested extensions.\n\n### Linking Apple Account\n\nThis only applies for real device set up. Make sure to link your 'Apple Developer Account' in the\nmachine's system wide \"Account Panel\" when using the \"Basic Automatic Configuration\" described\n[here](../preparation/prov-profile-basic-auto.md).\n\n### Troubleshooting\n\nEnable the `appium:showXcodeLog` [capability](../reference/capabilities.md#webdriveragent) and\ncheck the Appium server output.","metadata":{"loc":{"lines":{"from":29,"to":47}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/ci-setup.md","filename":"ci-setup.md","relativePath":"appium-xcuitest-driver/guides/ci-setup.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Get/Set Clipboard\n---\n\nWorking with the clipboard on real devices has an Apple security limitation, where the\nWebDriverAgentRunner application must be in foreground in order for the action to work. Otherwise\nan empty string is always returned, or it could raise an exception like\n[this issue](https://github.com/appium/appium/issues/18730).\n\nConsider using [`mobile: activateApp`](../reference/execute-methods.md/#mobile-activateapp)\nand [`mobile: backgroundApp`](../reference/execute-methods.md/#mobile-backgroundapp) to change the\nforeground application.\n\n## Get Clipboard\n\nApplies to iOS 13+ real devices. You can also use\n[`mobile: getPasteboard`](../reference/execute-methods.md#mobile-getpasteboard) for simulators.\n\n```ruby\n# Ruby","metadata":{"loc":{"lines":{"from":1,"to":23}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/clipboard.md","filename":"clipboard.md","relativePath":"appium-xcuitest-driver/guides/clipboard.md"}},{"pageContent":"## Get Clipboard\n\nApplies to iOS 13+ real devices. You can also use\n[`mobile: getPasteboard`](../reference/execute-methods.md#mobile-getpasteboard) for simulators.\n\n```ruby\n# Ruby\n\n# Bring the WebDriverAgent foreground. The bundle id depends on configuration such as \"appium:updatedWDABundleId\" for real devices.\ndriver.execute_script 'mobile: activateApp', {bundleId: 'com.facebook.WebDriverAgentRunner.xctrunner'}\n# Get the clipboard content\ndriver.get_clipboard\n# Go back to the application under test\ndriver.execute_script 'mobile: activateApp', {bundleId: '<bundle id of the test app>'}\n```\n\n## Set Clipboard\n\nApplies to iOS 15+ real devices. You can also use\n[`mobile: setPasteboard`](../reference/execute-methods.md#mobile-setpasteboard) for simulators.\n\n```ruby\n# Ruby","metadata":{"loc":{"lines":{"from":17,"to":39}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/clipboard.md","filename":"clipboard.md","relativePath":"appium-xcuitest-driver/guides/clipboard.md"}},{"pageContent":"## Set Clipboard\n\nApplies to iOS 15+ real devices. You can also use\n[`mobile: setPasteboard`](../reference/execute-methods.md#mobile-setpasteboard) for simulators.\n\n```ruby\n# Ruby\n\n# Bring the WebDriverAgent foreground. The bundle id depends on configuration such as \"appium:updatedWDABundleId\" for real devices.\ndriver.execute_script 'mobile: activateApp', {bundleId: 'com.facebook.WebDriverAgentRunner.xctrunner'}\n# Set the clipboard content\ndriver.set_clipboard(content: 'happy testing')\n# Go back to the application under test\ndriver.execute_script 'mobile: activateApp', {bundleId: '<bundle id of the test app>'}\n```","metadata":{"loc":{"lines":{"from":33,"to":47}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/clipboard.md","filename":"clipboard.md","relativePath":"appium-xcuitest-driver/guides/clipboard.md"}},{"pageContent":"---\ntitle: Elements Lookup Troubleshooting\n---\n\nThis article helps to resolve possible issues that may pop up while looking up for elements with XCUITest driver,\nwhere the desired element is either not found or not visible in the page source at all.\n\nSince there might be multiple reasons to why an element cannot be found the topic is divided into sections where\neach section contains visible symptoms with the list of their possible resolutions.\n\n\n## Symptom #1\n\nThe desired element is shown as part of a bigger container and is not distinguishable in the page source tree.\nSometimes the whole application view with all elements in it is visible as one single container.\n\n## Resolutions To Symptom #1\n\n### Make sure the application under test is accessible","metadata":{"loc":{"lines":{"from":1,"to":19}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md","filename":"elements-lookup-troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md"}},{"pageContent":"The XCUITest driver is based on Apple's XCTest framework. And the latter uses the information provided by the system\naccessibility framework to interact with on-screen elements, and to distinguish them. The same approach is used by\nvarious screen readers, VoiceOver, etc. You may start your journey into what Accessibility is and how to deal\nwith it in your applications from the official\n[Apple's accessibility guideline](https://developer.apple.com/design/human-interface-guidelines/accessibility).\nBear in mind, that this tutorial only describes apps based on official Apple frameworks, like UIKit or SwiftUI. If you\nuse a different framework to build the application's user interface, for example\n[React Native](https://reactnative.dev/), then consider looking for framework-specific accessibility guidelines.\nIt is also possible that the source tree displayed in Xcode accessibility inspector differs from the tree generated","metadata":{"loc":{"lines":{"from":21,"to":29}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md","filename":"elements-lookup-troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md"}},{"pageContent":"It is also possible that the source tree displayed in Xcode accessibility inspector differs from the tree generated\nby XCTest. The best possible way to verify the page source generated by the latter is to check the output of the\n[debugDescription](https://developer.apple.com/documentation/xctest/xcuielement/1500909-debugdescription) attribute\nof the corresponding XCUIApplication element. XCUITest driver allows to perform a direct forwarding for this API by\nusing the [mobile: source](../reference/execute-methods.md#mobile-source) execute method with `format` set\nto `description`.","metadata":{"loc":{"lines":{"from":29,"to":34}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md","filename":"elements-lookup-troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md"}},{"pageContent":"### Check if this is a hybrid application\n\nHybrid applications are applications that use\n[web views](https://developer.apple.com/design/human-interface-guidelines/web-views) in order to represent\ntheir whole user interface or portions of it.\nWeb views is the technology that allows to seamlessly integrate web pages browsing experience\ninto native mobile applications. Applications might contain native views mixed with web views, or the whole\napplication UI might be just a single web view. And while the built-in web view engine allows limited accessibility\ninteractions via [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) attributes, consider\nswitching a driver context instead in order to get full native access to the page DOM.\nRead [Automating Hybrid Apps](./hybrid.md) for more details there.\n\n### Make sure the application accessibility tree is not too deep","metadata":{"loc":{"lines":{"from":36,"to":48}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md","filename":"elements-lookup-troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md"}},{"pageContent":"Apple's XCTest represents the page source as hierarchical structure (a tree), where each UI element has ancestor and\ndescendant relationships to other elements. There are applications having complex UI structure with deeply nested\nviews. Such deep structures are known to create problems for XCTest as the latter is unable to work with tree elements\nwhose nesting level is deeper than `62`. This limitation has to do with how `NSDictionary` works and cannot be worked\naround. The default maximum nesting level for the XCUITest driver is set to `50` and could be customized by the\n[snapshotMaxDepth](../reference/settings.md) setting.\n[React Native](https://reactnative.dev/) is known to create\nsuch deep hierarchies and the only viable solution for now is to fix the application\nunder test by flattening nested views. Check the corresponding [issue](https://github.com/appium/appium/issues/14825)\nfor more details.","metadata":{"loc":{"lines":{"from":50,"to":59}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md","filename":"elements-lookup-troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md"}},{"pageContent":"under test by flattening nested views. Check the corresponding [issue](https://github.com/appium/appium/issues/14825)\nfor more details.\nDeeply nested hierarchies might also be the reason for the element lookup slowness. Read the [Diagnosing WebDriverAgent Slowness](./wda-slowness.md) article to troubleshoot the latter.","metadata":{"loc":{"lines":{"from":58,"to":60}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md","filename":"elements-lookup-troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md"}},{"pageContent":"### Make sure a valid active application is selected in WebDriverAgent\n\nSometimes, even if visually it looks like UI elements belong to the same application, they are referenced by\nabsolutely different apps. Moreover, the operating system\nmay change elements ownership in different versions. In the UI inspector it looks like visually the element\nis visible, but no \"real\" accessibility control relies on it. Most frequent candidates for such behavior are:\n- System alerts, for example camera or geolocation permission requests\n- Quick access toolbars, for example the one where Wi-Fi or Bluetooth state could be changed\n- Various RPC sheets, for example the Share To collection","metadata":{"loc":{"lines":{"from":62,"to":70}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md","filename":"elements-lookup-troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md"}},{"pageContent":"WebDriverAgent is designed the way it only interacts with a single app hierarchy at the particular\nmoment of time. Such application is called `active`.\nIt is possible to switch between applications in runtime using\n[mobile: activateApp](../reference/execute-methods.md#mobile-activateapp) API or\nto provide a hint for WebDriverAgent on which application to prefer if multiple apps are running\nusing the [defaultActiveApplication setting](../reference/settings.md).\nCheck the [Troubleshooting guide](./troubleshooting.md) and/or\n[Switching Between iOS Apps During a Test](https://appiumpro.com/editions/13-switching-between-ios-apps-during-a-test)\narticle for more details on how to make such elements available.\n\n## Symptom #2\n\nThe desired element is shown in the page tree, but cannot be found if looked up from an automated test.\n\n## Resolutions To Symptom #2\n\n### Make sure there is no race condition","metadata":{"loc":{"lines":{"from":72,"to":88}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md","filename":"elements-lookup-troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md"}},{"pageContent":"Sometimes the automation might too fast or too slow depending on in which state the UI is while the lookup is being\nexecuted. If it is too fast then consider using lookup timers, e.g. repeat the `findElement` more than once until\neither the element is found or the timeout occurs. All clients have convenience wrappers for such timers in form of\nexpected conditions.\nIf the automation is too slow, e.g. the desired element disappears faster than `findElement` could detect its presence\nthen make sure your script is optimized for the maximum performance, e.g. optimal/fast element locators are used,\nthe application itself and driver settings are [adjusted](./wda-slowness.md) to perform optimally, etc.\nThere might be situations where the automation framework is already optimized, although the desired element is\na short-living one, for example some notification popup that only appears for a second and then is immediately hidden.","metadata":{"loc":{"lines":{"from":90,"to":98}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md","filename":"elements-lookup-troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md"}},{"pageContent":"a short-living one, for example some notification popup that only appears for a second and then is immediately hidden.\nFor such \"special\" elements consider using approaches different from `findElement`, for example post-test video recording analysis (video FPS should usually be enough to catch all short-living elements), or introducing special\napplication debug settings to change the behavior for such elements and make them stay visible for longer time, or\nusing non-UI-related assertions, like logs analysis or direct API calls.","metadata":{"loc":{"lines":{"from":98,"to":101}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md","filename":"elements-lookup-troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md"}},{"pageContent":"### Make sure the debug environment matches to the testing one\n\nThere are known cases where application interface/behavior might differ in simulators and real devices. It might even differ\nif the screen size or device model/OS version/system setting differs. That is why always make sure your debug\nenvironment, for example one where Appium Inspector is used,\nis as close as possible to the environment where automated tests are being executed.\n\n\n## Symptom #3\n\nThe desired element is shown in the page tree, but its property value is not as expected, for example, it\nis shown as visible while one does not see it in the application interface or vice versa.\n\n## Resolutions To Symptom #3\n\n### XCUITest driver has minimum influence to attribute values","metadata":{"loc":{"lines":{"from":103,"to":118}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md","filename":"elements-lookup-troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md"}},{"pageContent":"This is a simple and at the same time complicated topic. Since XCUITest driver is based on Apple's XCTest,\nall attribute values are retrieved from the latter. Standard attributes provided by XCTest could be found in\n[XCUIElementAttributes](https://developer.apple.com/documentation/xctest/xcuielementattributes?language=objc)\nprotocol reference. The full list of attributes supported by XCUITest driver's WebElement\ncould be found in the [Element Attributes](../reference/element-attributes.md) document.\nMost of the above attributes are simple compilations of standard attributes, for example, `elementType` is\ntranslated to `type` by matching the corresponding\n[enum](https://developer.apple.com/documentation/xctest/xcuielementtype?language=objc) value to a string representation, `name` is compiled from original element's identifier and label depending on what is\npresent first. The full list of mapping rules between standard and XCUITest attribute values could be found in","metadata":{"loc":{"lines":{"from":120,"to":128}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md","filename":"elements-lookup-troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md"}},{"pageContent":"present first. The full list of mapping rules between standard and XCUITest attribute values could be found in\n[WebDriverAgent sources](https://github.com/appium/WebDriverAgent/blob/master/WebDriverAgentLib/Categories/XCUIElement%2BFBWebDriverAttributes.m).\nAlthough, some attributes there, like `visible` or `accessible` have no direct mapping in XCTest\nand are retrieved directly from the accessibility framework ~~using dark magic~~.\nThis means the actual value of these attributes only depends on accessibility internals and is there\nmostly due to ~~legacy~~ convenience purposes, as the original XCTest does not even expose them.\nWe'd love to deprecate and remove this legacy burden and only rely on officially supported attributes,\nalthough historically many people rely on them, so we keep it, even though their values might\nbe not reliable and there is no good way to debug this behavior or somehow influence it.\nThe final recommendation there would be:","metadata":{"loc":{"lines":{"from":128,"to":137}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md","filename":"elements-lookup-troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md"}},{"pageContent":"be not reliable and there is no good way to debug this behavior or somehow influence it.\nThe final recommendation there would be:\n- If the value of an attribute that directly or indirectly relies on a public XCUIElement attribute\n is different from what you expect then run a vanilla XCTest with the same app and make sure\n it's not the same as you see in the XCUITest driver. If it is then the only place to complain\n would be the Apple support forum or a XCTest bug tracker. If you can confirm the issue lies in\n WebDriverAgent's mapping logic then feel free to raise an\n [issue](https://github.com/appium/WebDriverAgent/issues) to its maintainers.\n- If the value of an attribute that is a \"custom\" XCUITest attribute, like `visible` or `accessible`,\n is different from what you expect then we, most likely, won't be able to help you. You may try\n to improve the corresponding WebDriverAgent sources, but keep in mind there are many automation","metadata":{"loc":{"lines":{"from":136,"to":146}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md","filename":"elements-lookup-troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md"}},{"pageContent":"is different from what you expect then we, most likely, won't be able to help you. You may try\n to improve the corresponding WebDriverAgent sources, but keep in mind there are many automation\n tests around that rely on the current way these attributes are calculated, and we probably don't\n want to break them.","metadata":{"loc":{"lines":{"from":145,"to":148}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md","filename":"elements-lookup-troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md"}},{"pageContent":"## Symptom #4\n\nThe desired element is shown in the page tree, but the content of its `value` property is cut off. For example, the actual size of the element's `value` attribute is above 512 bytes, while the size in the XML page source is always limited to 512 bytes.\n\n## Resolutions To Symptom #4\n\nRetrieve the element's `value` using the corresponding API ([Get Element Attribute](https://www.w3.org/TR/webdriver1/#get-element-attribute) / [Get Element Text](https://www.w3.org/TR/webdriver1/#dfn-get-element-text)) to get the full/uncut content. Please see [this issue](https://github.com/appium/appium-xcuitest-driver/issues/2552) and [this PR](https://github.com/appium/WebDriverAgent/pull/1007) for more details.","metadata":{"loc":{"lines":{"from":150,"to":156}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md","filename":"elements-lookup-troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md"}},{"pageContent":"XCTest framework cuts off long element values in snapshots to achieve the best performance and to reduce the memory footprint. If an element was inspected via [debugDescription](https://developer.apple.com/documentation/xctest/xcuielement/1500909-debugdescription) in XCTest for UI (not Appium XCUITest driver), it prints the value partially while the [value](https://developer.apple.com/documentation/xctest/xcuielementattributes/value) attribute like `element.value` prints the entire value.","metadata":{"loc":{"lines":{"from":158,"to":158}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md","filename":"elements-lookup-troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/elements-lookup-troubleshooting.md"}},{"pageContent":"---\ntitle: File Transfer\n---\n\nThe XCUITest driver provides several [extension commands](../reference/execute-methods.md) for file transfer:\n\n* [`mobile: pullFolder`](../reference/execute-methods.md#mobile-pullfolder)\n* [`mobile: pullFile`](../reference/execute-methods.md#mobile-pullfile)\n* [`mobile: pushFile`](../reference/execute-methods.md#mobile-pushfile)\n* [`mobile: deleteFolder`](../reference/execute-methods.md#mobile-deletefolder)\n* [`mobile: deleteFile`](../reference/execute-methods.md#mobile-deletefile)\n\nThis documentation aims to help to understand how they work on iOS.\n\n## Formats\n\nAll commands require a parameter with a path to the file/folder on the target device. There are 3\npossible formats this path can take:\n\n### Format 1\n\n```\n@<app-bundle-id>:<container-type>/<path-to-file-or-folder>\n```","metadata":{"loc":{"lines":{"from":1,"to":24}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/file-transfer.md","filename":"file-transfer.md","relativePath":"appium-xcuitest-driver/guides/file-transfer.md"}},{"pageContent":"### Format 1\n\n```\n@<app-bundle-id>:<container-type>/<path-to-file-or-folder>\n```\n\n* `@<app-bundle-id>` is the application bundle identifier\n* `<container-type>` is the container type\n * On simulators, common values are `app`, `data`, `groups`, but a custom one can also be provided\n * On real devices, the only accepted value is `documents`. All others are treated as Format 2\n * This value can only be specified for apps that have the `UIFileSharingEnabled` flag set to\n `true`. You can use the [`mobile: listApps`](../reference/execute-methods.md#mobile-listapps)\n extension to identify such apps.\n * By assigning the `skipDocumentsContainerCheck` [Settings API](https://appium.io/docs/en/latest/guides/settings/) to `true`, you may skip the above limitation for certain apps.","metadata":{"loc":{"lines":{"from":20,"to":33}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/file-transfer.md","filename":"file-transfer.md","relativePath":"appium-xcuitest-driver/guides/file-transfer.md"}},{"pageContent":"* `<path-to-file-or-folder>` is the target file or folder\n * On real devices, if `<container-type>` is set to `documents`, this path will be mapped to\n `On My iPhone/<app name>` in the _Files_ app\n\n### Format 2\n\n```\n@<app-bundle-id>/<path-to-file-or-folder>\n```\n\n* On simulators, the implicit `<container-type>` is set to `app`.\n* On real device, only apps with the `UIFileSharingEnabled` flag set to `true` in their `info.plist`\n can be mounted. You can use the [`mobile: listApps`](../reference/execute-methods.md#mobile-listapps)\n extension to identify such apps.\n\n### Format 3\n\n```\n<path-to-file-or-folder>\n```","metadata":{"loc":{"lines":{"from":35,"to":54}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/file-transfer.md","filename":"file-transfer.md","relativePath":"appium-xcuitest-driver/guides/file-transfer.md"}},{"pageContent":"### Format 3\n\n```\n<path-to-file-or-folder>\n```\n\nThis format is only supported on simulators. The implicit `<container-type>` is set to `app`.\nEventually the whole simulator file system is\n[available](https://stackoverflow.com/questions/6480607/is-there-any-way-to-see-the-file-system-on-the-ios-simulator)\ndirectly from the macOS Finder, so you may pull any file from there by providing a path to it\nrelatively to the simulator's file system root.\n\n## Examples\n\n### `pullFile`\n\nThis example pulls a file present in _Files -> On My iPhone -> Keynote_:\n\n|Top | On My iPhone | Keynote |\n|:----:|:----:|:----:|\n|![](./assets/images/ios-xctest-file-movement/top_files.png)|![](./assets/images/ios-xctest-file-movement/on_my_iphone.png)|![](./assets/images/ios-xctest-file-movement/keynote.png)|\n\n=== \"JS (WebdriverIO)\"","metadata":{"loc":{"lines":{"from":50,"to":72}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/file-transfer.md","filename":"file-transfer.md","relativePath":"appium-xcuitest-driver/guides/file-transfer.md"}},{"pageContent":"=== \"JS (WebdriverIO)\"\n\n ```javascript\n let data = driver.pullFile('@com.apple.Keynote:documents/Presentation.key');\n await fs.writeFile('presentation.key', Buffer.from(data, 'base64'), 'binary');\n ```\n\n=== \"Ruby\"\n\n ```ruby\n file = @driver.pull_file '@com.apple.Keynote:documents/Presentation.key'\n File.open('presentation.key', 'wb') { |f| f<< file }\n ```\n\nIf the file is in deeper place like _Keynote/Dir1/Dir2_, then the path changes:\n\n=== \"JS (WebdriverIO)\"\n\n ```javascript\n let data = driver.pullFile('@com.apple.Keynote:documents/Dir1/Dir2/Presentation.key');\n await fs.writeFile('presentation.key', Buffer.from(data, 'base64'), 'binary');\n ```\n\n=== \"Ruby\"\n\n ```ruby\n file = @driver.pull_file '@com.apple.Keynote:documents/Dir1/Dir2/Presentation.key'\n File.open('presentation.key', 'wb') { |f| f<< file }\n ```\n\nExample for a simulator using Format 3:","metadata":{"loc":{"lines":{"from":72,"to":102}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/file-transfer.md","filename":"file-transfer.md","relativePath":"appium-xcuitest-driver/guides/file-transfer.md"}},{"pageContent":"Example for a simulator using Format 3:\n\n```java\n// Java\n// Get AddressBook.sqlitedb in test app package ('app' container)\nbyte[] fileContent = driver.pullFile(\"Library/AddressBook/AddressBook.sqlitedb\");\nPath dstPath = Paths.get(new File(\"/local/path/AddressBook.sqlitedb\"));\nFiles.write(dstPath, fileContent);\n```\n\n### `pullFolder`\n\nYou can pull folders similarly to files, but the path must end with a forward slash (`/`).\n\n=== \"JS (WebdriverIO)\"\n\n ```javascript\n let data = driver.pullFolder('@com.apple.Keynote:documents/');\n await fs.writeFile('documents.zip', Buffer.from(data, 'base64'), 'binary');\n ```\n\n=== \"Ruby\"\n\n ```ruby\n file = @driver.pull_folder '@com.apple.Keynote:documents/'\n File.open('documents.zip', 'wb') { |f| f<< file }\n ```\n\n### `pushFile`\n\n=== \"JS (WebdriverIO)\"\n\n ```javascript\n driver.pushFile('@com.apple.Keynote:documents/text.txt', new Buffer(\"Hello World\").toString('base64'));\n ```\n\n=== \"Ruby\"","metadata":{"loc":{"lines":{"from":102,"to":138}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/file-transfer.md","filename":"file-transfer.md","relativePath":"appium-xcuitest-driver/guides/file-transfer.md"}},{"pageContent":"### `pushFile`\n\n=== \"JS (WebdriverIO)\"\n\n ```javascript\n driver.pushFile('@com.apple.Keynote:documents/text.txt', new Buffer(\"Hello World\").toString('base64'));\n ```\n\n=== \"Ruby\"\n\n ```ruby\n @driver.push_file '@com.apple.Keynote:documents/text.txt', (File.read 'path/to/file')\n ```\n\n## References\n- <https://stackoverflow.com/questions/1108076/where-does-the-iphone-simulator-store-its-data>\n- <https://stackoverflow.com/questions/48884248/how-can-i-add-files-to-the-ios-simulator>\n- <https://apple.stackexchange.com/questions/299413/how-to-allow-the-files-app-to-save-to-on-my-iphone-or-to-on-my-ipad-in-ios/299565#299565>","metadata":{"loc":{"lines":{"from":130,"to":147}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/file-transfer.md","filename":"file-transfer.md","relativePath":"appium-xcuitest-driver/guides/file-transfer.md"}},{"pageContent":"---\ntitle: Gestures\n---\n\nThe XCUITest driver provides multiple options for touch gestures automation.\nFor simple gestures, like tap by coordinates, long tap, multi-finger tap, double/triple tap,\nswipe, drag, rotate, scroll or pinch use the below gesture shortcuts:","metadata":{"loc":{"lines":{"from":1,"to":7}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/gestures.md","filename":"gestures.md","relativePath":"appium-xcuitest-driver/guides/gestures.md"}},{"pageContent":"- [mobile: tap](../reference/execute-methods.md#mobile-tap)\n- [mobile: doubleTap](../reference/execute-methods.md#mobile-doubletap)\n- [mobile: touchAndHold](../reference/execute-methods.md#mobile-touchandhold)\n- [mobile: twoFingerTap](../reference/execute-methods.md#mobile-twofingertap)\n- [mobile: dragFromToForDuration](../reference/execute-methods.md#mobile-dragfromtoforduration)\n- [mobile: dragFromToWithVelocity](../reference/execute-methods.md#mobile-dragfromtowithvelocity)\n- [mobile: rotateElement](../reference/execute-methods.md#mobile-rotateelement)\n- [mobile: tapWithNumberOfTaps](../reference/execute-methods.md#mobile-tapwithnumberoftaps)\n- [mobile: forcePress](../reference/execute-methods.md#mobile-forcepress)\n- [mobile: scrollToElement](../reference/execute-methods.md#mobile-scrolltoelement)\n- [mobile: scroll](../reference/execute-methods.md#mobile-scroll)\n- [mobile: pinch](../reference/execute-methods.md#mobile-pinch)","metadata":{"loc":{"lines":{"from":9,"to":20}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/gestures.md","filename":"gestures.md","relativePath":"appium-xcuitest-driver/guides/gestures.md"}},{"pageContent":"For more sophisticated gestures\nconsider using [W3C actions](https://w3c.github.io/webdriver/#actions).\n\nMake sure you don't use deprecated JSONWP TouchActions APIs. They have been\nremoved from the XCUITest driver since version 7.\n\nIf the action code in the client source looks good and satisfies the above requirements,\nbut its execution still does not deliver the expected result then the following debugging\nmeasures might be applied:","metadata":{"loc":{"lines":{"from":22,"to":30}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/gestures.md","filename":"gestures.md","relativePath":"appium-xcuitest-driver/guides/gestures.md"}},{"pageContent":"- Make sure the gesture has valid coordinates and respects pauses between pointer state changes.\n For example, it is always mandatory to provide a valid element or valid `absolute` coordinates\n to any gesture at the beginning. iOS only registers\n a long touch/click if the pointer has been depressed for longer than 500ms. For shorter actions\n a simple click is registered instead.\n- If your tests run on Simulator then it is possible to activate pointer tracing by enabling\n the [appium:simulatorTracePointer](../reference/capabilities.md#simulator) capability or by enabling\n `Visual Indicators` items from Simulator settings. After running\n your automation code with this feature enabled you would be able to see the exact pointer trace path\n and check the velocity of the gesture. Compare the trace\n to how the same gesture is usually done manually and apply the necessary updates to your code.","metadata":{"loc":{"lines":{"from":32,"to":42}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/gestures.md","filename":"gestures.md","relativePath":"appium-xcuitest-driver/guides/gestures.md"}},{"pageContent":"and check the velocity of the gesture. Compare the trace\n to how the same gesture is usually done manually and apply the necessary updates to your code.\n- Do not mix webview and native elements in actions arguments. It simply won't work. Native\n actions could only consume native elements. A single possibility to perform a native action\n on a web element would be to translate its coordinates into the native context and pass these\n coordinates as native action arguments.","metadata":{"loc":{"lines":{"from":41,"to":46}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/gestures.md","filename":"gestures.md","relativePath":"appium-xcuitest-driver/guides/gestures.md"}},{"pageContent":"Check the below tutorials for more details on how to build reliable action chains:\n\n- [Automating Complex Gestures with the W3C Actions API](https://appiumpro.com/editions/29-automating-complex-gestures-with-the-w3c-actions-api)\n- [Swiping your way through Appium by Wim Selles #AppiumConf2021](https://www.youtube.com/watch?v=oAJ7jwMNFVU)\n- [About iOS Input Events](./input-events.md)","metadata":{"loc":{"lines":{"from":48,"to":52}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/gestures.md","filename":"gestures.md","relativePath":"appium-xcuitest-driver/guides/gestures.md"}},{"pageContent":"---\ntitle: Automating Hybrid Apps\n---\n\nOne of the core principles of XCUITest driver is that you shouldn't have to change your\napp to test it. In line with that methodology, it is possible to test hybrid\napps the same way you can with Selenium for web apps. There is a bit of technical\ncomplexity required so that XCUITest driver knows whether you want to automate the native\naspects of the app or the web views. But, thankfully, we can stay within the\nSelenium WebDriver protocol for everything.\n\nOnce the test is in a web view context the command set that is available is the\nfull [Selenium](http://www.seleniumhq.org/) [WebDriver API](https://www.w3.org/TR/webdriver/).\n\n### Requirements","metadata":{"loc":{"lines":{"from":1,"to":15}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/hybrid.md","filename":"hybrid.md","relativePath":"appium-xcuitest-driver/guides/hybrid.md"}},{"pageContent":"Once the test is in a web view context the command set that is available is the\nfull [Selenium](http://www.seleniumhq.org/) [WebDriver API](https://www.w3.org/TR/webdriver/).\n\n### Requirements\n\nTo interact with a web view XCUITest driver establishes a connection using a custom\n[remote debugger](https://github.com/appium/appium-remote-debugger).\nThis debugger can connect directly to any WebKit debugger socket exposed by the system.\nThe protocol used for the communication there is a proprietary Apple's JSON RPC similar\nto Chrome's [Devtools Protocol](https://chromedevtools.github.io/devtools-protocol/).\nNot all web views expose debugger web sockets by default thus making them invisible\nfor the XCUITest driver and not showing in the available contexts list.\nMake sure the following prerequisites are satisfied if you are unsure about whether\nthe particular web view is debuggable or not:","metadata":{"loc":{"lines":{"from":12,"to":25}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/hybrid.md","filename":"hybrid.md","relativePath":"appium-xcuitest-driver/guides/hybrid.md"}},{"pageContent":"- If you use real devices then make sure the Settings→Safari→Advanced→Web Inspector\n checkbox is turned on.\n- If your app's web view is based on WKWebView then make sure the\n [isInspectable](https://developer.apple.com/documentation/webkit/wkwebview/4111163-inspectable?language=objc) property of it set to `true`. Note, that you must have access to the application sources in order\n to ensure that!\n- Make sure you see the corresponding web view in Safari's\n [remote debugger](https://help.salesforce.com/s/articleView?id=000391692&type=1) list.\n\nIf all the above requirements have been satisfied, but the desired web view is still not present in the\nXCUITest driver's context list then there is probably an issue in the driver itself, which must be reported\nto driver maintainers.\n\n### Entering the web view context\n\nHere are the steps required to talk to a web view in your XCUITest driver test:","metadata":{"loc":{"lines":{"from":27,"to":41}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/hybrid.md","filename":"hybrid.md","relativePath":"appium-xcuitest-driver/guides/hybrid.md"}},{"pageContent":"1. Navigate to a portion of your app where a web view is active\n2. Retrieve the currently available contexts\n * This returns a list of contexts we can access, like `'NATIVE_APP'` or `'WEBVIEW_1'`\n3. Set the id of the context you want to access\n * This puts your XCUITest session into a mode where all commands are\n interpreted as being intended for automating the web view, rather than the\n native portion of the app. For example, if you run `findElement`, it\n will operate on the DOM of the web view, rather than return native elements.\n Of course, certain WebDriver methods only make sense in one context or\n another, so in the wrong context you will receive an error message.\n4. To stop automating in the web view context and go back to automating the\n native portion of the app, simply set the context\n again with the native context id (generally `'NATIVE_APP'`) to leave the web\n context and once again access the native commands.","metadata":{"loc":{"lines":{"from":43,"to":56}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/hybrid.md","filename":"hybrid.md","relativePath":"appium-xcuitest-driver/guides/hybrid.md"}},{"pageContent":"### Automatically entering the web view context on session start\n\nIf your application begins in a web view, and you do not want to automate the\nnative application before entering it, you can have XCUITest driver automatically enter\nthe web view context on session initialization by setting the `autoWebview`\n[capability](../reference/capabilities.md) to `true`.\n\n\n### Examples\n\n=== \"Java\"\n ```java\n // java\n // assuming we have a set of capabilities\n driver = new AppiumDriver(new URL(\"http://127.0.0.1:4723/\"), options);\n\n Set<String> contextNames = driver.getContextHandles();\n for (String contextName : contextNames) {\n System.out.println(contextName); //prints out something like NATIVE_APP \\n WEBVIEW_1\n }\n driver.context(contextNames.toArray()[1]); // set context to WEBVIEW_1\n\n //do some web testing\n String myText = driver.findElement(By.cssSelector(\".green_button\")).click();\n\n driver.context(\"NATIVE_APP\");\n\n // do more native testing if we want","metadata":{"loc":{"lines":{"from":58,"to":85}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/hybrid.md","filename":"hybrid.md","relativePath":"appium-xcuitest-driver/guides/hybrid.md"}},{"pageContent":"//do some web testing\n String myText = driver.findElement(By.cssSelector(\".green_button\")).click();\n\n driver.context(\"NATIVE_APP\");\n\n // do more native testing if we want\n\n driver.quit();\n ```\n \n=== \"Ruby\"\n ```ruby\n # ruby_lib_core\n # assuming we have a set of capabilities\n @driver = Appium::Core.for(url: SERVER_URL, desired_capabilities: capabilities).start_driver\n # ruby_lib\n # opts = { caps: capabilities, appium_lib: { custom_url: SERVER_URL }}\n # @driver = Appium::Driver.new(opts, true).start_driver\n\n # I switch to the last context because its always the webview in our case, in other cases you may need to specify a context\n # View the appium logs while running @driver.contexts to figure out which context is the one you want and find the associated ID\n # Then switch to it using @driver.switch_to.context(\"WEBVIEW_6\")","metadata":{"loc":{"lines":{"from":80,"to":101}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/hybrid.md","filename":"hybrid.md","relativePath":"appium-xcuitest-driver/guides/hybrid.md"}},{"pageContent":"Given(/^I switch to webview$/) do\n webview = @driver.available_contexts.last\n @driver.switch_to.context(webview)\n end\n\n Given(/^I switch out of webview$/) do\n @driver.switch_to.context(@driver.contexts.first)\n end\n\n # Now you can use CSS to select an element inside your webview\n\n And(/^I click a webview button $/) do\n @driver.find_element(:css, \".green_button\").click\n end\n ```\n\n=== \"Python\"\n ```python\n # python\n # assuming we have an initialized `driver` object for an app\n\n # switch to webview\n webview = driver.contexts.last\n driver.switch_to.context(webview)\n\n # do some webby stuff\n driver.find_element(By.CSS, \".green_button\").click\n\n # switch back to native view\n driver.switch_to.context(driver.contexts.first)\n\n # do more native testing if we want\n\n driver.quit()\n ```","metadata":{"loc":{"lines":{"from":103,"to":137}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/hybrid.md","filename":"hybrid.md","relativePath":"appium-xcuitest-driver/guides/hybrid.md"}},{"pageContent":"---\ntitle: About iOS Input Events\n---\n\n## What Are Input Events\n\niOS uses the Events concept to handle signals received from different input devices. An Event is an\nobject generated in response to a signal from an input device. These objects are then delivered to\nthe corresponding kernel subsystem, which processes them and notifies all listening processes about\ntaps, key presses, swipes, etc. This means that in order to emulate a signal generated by an external\ndevice, such as a touch screen, it is necessary to just send Event objects with the same properties\nand in the same sequence as they would be generated by a real device.\n\n## Simulating a Single Tap\n\nThe Events API itself is a part of Apple private API, and it is neither open sourced nor documented.\nThe XCTest framework also does not expose any _public_ APIs for input events generation, although\nthere is a possibility to perform events generation via XCTest _private_ undocumented APIs.","metadata":{"loc":{"lines":{"from":1,"to":18}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/input-events.md","filename":"input-events.md","relativePath":"appium-xcuitest-driver/guides/input-events.md"}},{"pageContent":"In particular, we are interested in the\n[`XCPointerEventPath`](https://github.com/appium/WebDriverAgent/blob/master/PrivateHeaders/XCTest/XCPointerEventPath.h)\nand [`XCSynthesizedEventRecord`](https://github.com/appium/WebDriverAgent/blob/master/PrivateHeaders/XCTest/XCSynthesizedEventRecord.h)\ninterfaces. These APIs allow to create chains of input events and supply them to the system kernel\nfor execution.\n\nIn order to synthesize a single tap, it is necessary to:\n\n- Create a new `XCPointerEventPath` instance and initialize it for touch at the starting point\n- Add a new `liftUp` event at `0.125s` offset using `liftUpAtOffset:` method\n- Add the generated event path object to `XCSynthesizedEventRecord` instance using\n `addPointerEventPath:` method\n- Execute the events using `synthesizeWithError:` method of `XCSynthesizedEventRecord` instance and\n control the returned error\n\nThere are several limitations to these APIs:","metadata":{"loc":{"lines":{"from":20,"to":35}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/input-events.md","filename":"input-events.md","relativePath":"appium-xcuitest-driver/guides/input-events.md"}},{"pageContent":"There are several limitations to these APIs:\n\n- Each `XCPointerEventPath` instance can only be executed for a single action. If one tries to add,\n for example, two taps to a single path, then these are effectively ignored\n- Each `XCPointerEventPath` instance can only be initialized for a particular pointer type: touch,\n mouse (since Xcode 10.2) or keyboard (since Xcode 10.2)\n- Events can only be added with increasing offset values to an existing `XCPointerEventPath` instance\n\n## More Complicated Actions\n\nUnfortunately, because the API is private and has zero documentation, one can only figure out what\nit can do by playing with it and trying different input combinations.\n\nIt is known that providing multiple `XCPointerEventPath` instances with overlapping timeouts will\ngenerate a multitouch action with the amount of fingers equal to the amount of the supplied event\npaths. So, in order to generate two-finger symmetric swipe we need to supply the following events:","metadata":{"loc":{"lines":{"from":35,"to":50}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/input-events.md","filename":"input-events.md","relativePath":"appium-xcuitest-driver/guides/input-events.md"}},{"pageContent":"- Create a two `XCPointerEventPath` instances and init them for touch at the starting point\n- Add a `moveToPoint` event at `0.525s` offset using `moveToPoint:` method to each path\n- Add a `liftUp` eventa at `0.525s` offset using `liftUpAtOffset:` method to each path\n- Add the generated event paths to `XCSynthesizedEventRecord` instance using `addPointerEventPath:` method\n- Execute the events using `synthesizeWithError:` method of `XCSynthesizedEventRecord` instance and\n control the returned error\n\n## Further Reading\n\nUnfortunately, there is no information on this topic at all (private API `¯\\_(ツ)_/¯`). Consider\nvisiting the following resources:","metadata":{"loc":{"lines":{"from":52,"to":62}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/input-events.md","filename":"input-events.md","relativePath":"appium-xcuitest-driver/guides/input-events.md"}},{"pageContent":"## Further Reading\n\nUnfortunately, there is no information on this topic at all (private API `¯\\_(ツ)_/¯`). Consider\nvisiting the following resources:\n\n* <https://github.com/appium/WebDriverAgent/tree/master/PrivateHeaders/XCTest>\n* <https://github.com/appium/WebDriverAgent/blob/master/WebDriverAgentTests/IntegrationTests/FBW3CTouchActionsIntegrationTests.m>\n* <https://github.com/appium/WebDriverAgent/blob/master/WebDriverAgentTests/IntegrationTests/FBW3CMultiTouchActionsIntegrationTests.m>\n* <https://github.com/appium/WebDriverAgent/blob/master/WebDriverAgentLib/Utilities/FBW3CActionsSynthesizer.m>","metadata":{"loc":{"lines":{"from":59,"to":67}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/input-events.md","filename":"input-events.md","relativePath":"appium-xcuitest-driver/guides/input-events.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Self-Signed Certificates\n---\n\nUnfortunately, Apple does not provide any command line options which can help to install self-signed\ncertificate on a real device or simulator. However, there is\n[over-the-air](https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/iPhoneOTAConfiguration/Introduction/Introduction.html)\nenrollment technology, which allows the deployment of several entity types, including such\ncertificates, by simply downloading specially prepared configuration files with the built-in web\nbrowser. After the configuration is downloaded it can be installed and trusted by going through\nseveral simple wizard steps.\n\nYou can use the following extension methods to assist with this:\n\n* [`mobile: installCertificate`](../reference/execute-methods.md#mobile-installcertificate)\n* [`mobile: removeCertificate`](../reference/execute-methods.md#mobile-removecertificate)","metadata":{"loc":{"lines":{"from":1,"to":19}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/install-certificate.md","filename":"install-certificate.md","relativePath":"appium-xcuitest-driver/guides/install-certificate.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Managing Multiple Xcodes\n---\n\nIf you have multiple Xcode installations, you may choose which toolset Appium should use with one\nof two ways:\n\n### `xcode-select` tool\nOnly available with `sudo` privileges, affects the whole system.\n\nAssuming you want to choose `/Applications/Xcode13.app`:\n\n1. Set the default Xcode\n ```\n sudo xcode-select -s /Applications/Xcode13.app/Contents/Developer\n ```\n2. Run Appium\n ```\n appium\n ```\n\n### Environment variable\nNo privileges needed, affects only the current shell, so Appium should be started within that shell.\n\nAssuming you want to choose `/Applications/Xcode12.app`:\n\n1. Set the `DEVELOPER_DIR` environment variable\n ```\n export DEVELOPER_DIR=/Applications/Xcode12.app/Contents/Developer\n ```\n2. Run Appium\n ```\n appium\n ```","metadata":{"loc":{"lines":{"from":1,"to":37}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/multiple-xcode-versions.md","filename":"multiple-xcode-versions.md","relativePath":"appium-xcuitest-driver/guides/multiple-xcode-versions.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Testing in Parallel\n---\n\nIt is possible to execute tests in parallel using XCUITest driver. Appium allows to do this on a\nper-process (multiple server processes running on different ports managing single session) or a\nper-request basis (single server process managing multiple sessions, more preferable, uses less\nresources and ensures better control over running sessions).\n\n!!! note\n\n If you are _not_ going to run your tests in parallel, consider enabling the `--session-override`\n Appium server argument. It forces the server to close all pending sessions before a new one\n could be opened, which allows you to avoid possible issues with such sessions silently\n running/expiring in the background.\n\n### Important Real Device Capabilities","metadata":{"loc":{"lines":{"from":1,"to":20}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/parallel-tests.md","filename":"parallel-tests.md","relativePath":"appium-xcuitest-driver/guides/parallel-tests.md"}},{"pageContent":"### Important Real Device Capabilities\n\n- `udid` must be a unique device UDID for each parallel session.\n- `wdaLocalPort` must be a unique port number for each parallel session. The default value is `8100`.\n- `derivedDataPath` set the unique derived data path root for each driver instance. This will help\n to avoid possible conflicts and to speed up the parallel execution.\n- `mjpegServerPort` must be a unique port number for each parallel session if you are going to\n record a video stream from it. The default value is `9100`.\n\n### Important Simulator Capabilities","metadata":{"loc":{"lines":{"from":20,"to":29}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/parallel-tests.md","filename":"parallel-tests.md","relativePath":"appium-xcuitest-driver/guides/parallel-tests.md"}},{"pageContent":"### Important Simulator Capabilities\n\n- Either `udid`, which is the unique simulator UDID for each parallel session (it could be retrieved\n from `xcrun simctl list` command output), or a unique combination of `deviceName` and\n `platformVersion` capabilities to identify the appropriate simulator with the given name and\n version number for each parallel session.\n- `wdaLocalPort` must be a unique port number for each parallel session. The default value is `8100`.\n- `derivedDataPath` set the unique derived data path root for each driver instance. This will help\n to avoid possible conflicts and to speed up the parallel execution.\n- `mjpegServerPort` must be a unique port number for each parallel session if you are going to\n record a video stream from it. The default value is `9100`.","metadata":{"loc":{"lines":{"from":29,"to":39}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/parallel-tests.md","filename":"parallel-tests.md","relativePath":"appium-xcuitest-driver/guides/parallel-tests.md"}},{"pageContent":"---\ntitle: Run Prebuilt WebDriverAgentRunner\n---\n\nThe XCUITest driver runs `xcodebuild` to build and install the WebDriverAgentRunner (WDA) app on the\ntarget device. You can manually run a modified version of this command in order to prebuild the WDA.\n\n## How `xcodebuild` Works\n\nBy default, `xcodebuild` is run with two commands: `build-for-testing` and `test-without-building`.\n`build-for-testing` builds a test bundle package, whereas `test-without-building` actually runs it.\n\nFor instance, XCUITest driver issues an `xcodebuild` command like so:\n\n```\nxcodebuild build-for-testing test-without-building \\\n -project WebDriverAgent.xcodeproj \\\n -derivedDataPath wda_build \\\n -scheme WebDriverAgentRunner \\\n -destination \"platform=iOS Simulator,name=iPhone 14 Pro\" \\\n CODE_SIGNING_ALLOWED=NO\n```\n\nThis translates to `xcodebuild` building `WebDriverAgent.xcodeproj` and running the resulting\npackage on the specified device.","metadata":{"loc":{"lines":{"from":1,"to":25}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/run-prebuilt-wda.md","filename":"run-prebuilt-wda.md","relativePath":"appium-xcuitest-driver/guides/run-prebuilt-wda.md"}},{"pageContent":"This translates to `xcodebuild` building `WebDriverAgent.xcodeproj` and running the resulting\npackage on the specified device.\n\nThe command can be split into `build-for-testing` and `test-without-building` parts as follows:\n\n```\nxcodebuild build-for-testing \\\n -project WebDriverAgent.xcodeproj \\\n -derivedDataPath wda_build \\\n -scheme WebDriverAgentRunner \\\n -destination \"platform=iOS Simulator,name=iPhone 14 Pro\" \\\n CODE_SIGNING_ALLOWED=NO\n```\n\n```\nxcodebuild test-without-building \\\n -xctestrun wda_build/Build/Products/WebDriverAgentRunner_iphonesimulator16.2-arm64.xctestrun \\\n -destination \"platform=iOS Simulator,name=iPhone 14 Pro\"\n```\n\n* The `build-for-testing` command generates two files: an `.app` package and an `.xctestrun` file, e.g.:\n\n ```\n wda_build/Build/Products/Debug-iphonesimulator/WebDriverAgentRunner-Runner.app\n wda_build/Build/Products/WebDriverAgentRunner_iphonesimulator16.2-arm64.xctestrun\n ```","metadata":{"loc":{"lines":{"from":24,"to":49}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/run-prebuilt-wda.md","filename":"run-prebuilt-wda.md","relativePath":"appium-xcuitest-driver/guides/run-prebuilt-wda.md"}},{"pageContent":"```\n wda_build/Build/Products/Debug-iphonesimulator/WebDriverAgentRunner-Runner.app\n wda_build/Build/Products/WebDriverAgentRunner_iphonesimulator16.2-arm64.xctestrun\n ```\n\n The `.xctestrun` file name depends on the `-destination` preference. The file contains metadata\n about the package (the `DependentProductPaths` key).\n\n* The `test-without-building` command starts the WDA application for testing by referencing the\n provided `.xctestrun` file. Once this is done, `http://localhost:8100` will be able to receive\n commands for the target device.\n\n## Capabilities for Prebuilt WDA with `appium:useXctestrunFile`, `appium:usePrebuiltWDA` or `appium:prebuildWDA`\n\nThe XCUITest driver provides two capabilities that allow skipping the `build-for-testing` command,\nand executing only the `test-without-building` command: __`appium:useXctestrunFile`__ and\n__`appium:bootstrapPath`__ (see [Capabilities](../reference/capabilities.md#webdriveragent)).\n\n!!! note","metadata":{"loc":{"lines":{"from":46,"to":64}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/run-prebuilt-wda.md","filename":"run-prebuilt-wda.md","relativePath":"appium-xcuitest-driver/guides/run-prebuilt-wda.md"}},{"pageContent":"!!! note\n\n These capabilities expect that the WDA files are already prebuild, so make sure to first run\n `xcodebuild` to create the files.\n\nThis method can be used on both real devices and simulators, but real devices requires proper\nsigning as described in [Run Preinstalled WebDriverAgentRunner](./run-preinstalled-wda.md).\nWe recommend using this method for real devices.\n\nThe capabilities can be used as follows:\n\n```json\n{\n \"platformName\": \"ios\",\n \"appium:automationName\": \"xcuitest\",\n \"appium:platformVersion\": \"15.5\",\n \"appium:deviceName\": \"iPhone 12\",\n \"appium:useXctestrunFile\": true,\n \"appium:bootstrapPath\": \"/path/to/wda_build/Build/Products\"\n}\n```\n\nNot all combinations have been tested, but the target device can probably be anything.\n\nThe same thing can be achieved with the __`appium:derivedDataPath`__ and __`appium:usePrebuiltWDA`__\ncapabilities, but this may fail if `xcodebuild` cannot find or handle the `.xctestrun` file\nproperly. The stability depends on Xcode.","metadata":{"loc":{"lines":{"from":64,"to":90}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/run-prebuilt-wda.md","filename":"run-prebuilt-wda.md","relativePath":"appium-xcuitest-driver/guides/run-prebuilt-wda.md"}},{"pageContent":"__`appium:prebuildWDA`__ lets the XCUITest driver build the WDA before running it, then the session\nwill be handled with `appium:usePrebuiltWDA`.\nIt might have additional building steps than with `appium:derivedDataPath` and `appium:usePrebuiltWDA`\ncombination, but it could help `appium:usePrebuiltWDA` to not manage the WDA project.\n\n## Capabilities for Prebuilt WDA with `appium:prebuiltWDAPath`\n\n[Run Preinstalled WebDriverAgentRunner](./run-preinstalled-wda.md) provides `appium:prebuiltWDAPath` capability.\nIt also achieves the same thing, but the `appium:prebuiltWDAPath` does not use `xcodebuild`.\nPlease check the link for more details.\n\n## Download Prebuilt WDA\n\n[The Appium WebDriverAgent GitHub page](https://github.com/appium/WebDriverAgent/releases) provides\ndownloads for WebDriverAgent packages for real devices. They do not have embedded XCTest frameworks.","metadata":{"loc":{"lines":{"from":92,"to":106}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/run-prebuilt-wda.md","filename":"run-prebuilt-wda.md","relativePath":"appium-xcuitest-driver/guides/run-prebuilt-wda.md"}},{"pageContent":"The [Release](https://github.com/appium/appium-xcuitest-driver/actions/workflows/publish.js.yml) and\n[Building WebDriverAgent](https://github.com/appium/WebDriverAgent/actions/workflows/wda-package.yml)\nworkflows may help with validating the build script.\n\nFor simulator environment, the prebuilt packages available on [Building WebDriverAgent](https://github.com/appium/WebDriverAgent/actions/workflows/wda-package.yml)\nmay not work for all environment as different building environment.\nWe recommend preparing the `Build` directory, which is generated by `-derivedDataPath` `xcodebuild` argument,\non your test running environment and re-use it.","metadata":{"loc":{"lines":{"from":108,"to":115}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/run-prebuilt-wda.md","filename":"run-prebuilt-wda.md","relativePath":"appium-xcuitest-driver/guides/run-prebuilt-wda.md"}},{"pageContent":"---\ntitle: Run Preinstalled WebDriverAgentRunner\n---\n\nThe XCUITest driver can be configured to launch an already-installed `WebDriverAgentRunner-Runner`\napplication (WDA) on a real device and a simulator. This allows you to start a session without the `xcodebuild`\ncommand execution, improving the session startup performance.\n\n!!! warning\n\n iOS/tvOS 17+ specific:\n\n This method currently works over `devicectl` for iOS 17+ with Xcode 15+ environment since XCUITest driver v7.5.0.\n This may not work for tvOS 17+.\n iOS/tvOS 16 and lower ones work over [appium-ios-device](https://github.com/appium/appium-ios-device) directly.\n\n## Capabilities","metadata":{"loc":{"lines":{"from":1,"to":17}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/run-preinstalled-wda.md","filename":"run-preinstalled-wda.md","relativePath":"appium-xcuitest-driver/guides/run-preinstalled-wda.md"}},{"pageContent":"## Capabilities\n\n- Required\n - [`appium:usePreinstalledWDA`](../reference/capabilities.md#webdriveragent)\n- Optional\n - [`appium:updatedWDABundleId`](../reference/capabilities.md#webdriveragent)\n - [`appium:updatedWDABundleIdSuffix`](../reference/capabilities.md#webdriveragent)\n - Since XCUITest driver v7.6.0\n - [`appium:prebuiltWDAPath`](../reference/capabilities.md#webdriveragent)\n\n## Install WebDriverAgent\n\n### Using Xcode\n\nRunning a test for the WDA package in Xcode is the easiest way to prepare the device environment:\n\n1. Open WebDriverAgent project in Xcode\n - You can run `appium driver run xcuitest open-wda` if using XCUITest driver 4.13 or newer\n2. Select the _WebDriverAgentRunner_ scheme\n3. Select the scheme as _Product -> Scheme -> WebDriverAgentRunner_ (or _WebDriverAgentRunner\\_tvOS_ for tvOS)\n4. Select your device in _Product -> Destination_\n5. Select _Product -> Test_ to build and install the WDA app","metadata":{"loc":{"lines":{"from":17,"to":38}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/run-preinstalled-wda.md","filename":"run-preinstalled-wda.md","relativePath":"appium-xcuitest-driver/guides/run-preinstalled-wda.md"}},{"pageContent":"If using a real device, you may need to change your bundle ID. Please check the\n[Full Manual Provisioning Profile setup](../preparation/prov-profile-full-manual.md) for details.\n\n### Using 3rd Party Tools\n\nSome 3rd party tools such as [pymobiledevice3](https://github.com/doronz88/pymobiledevice3),\n[ios-deploy](https://github.com/ios-control/ios-deploy), [go-ios](https://github.com/danielpaulus/go-ios) and\n[tidevice](https://github.com/alibaba/taobao-iphone-device), [ios-app-signer](https://github.com/DanTheMan827/ios-app-signer)\ncan install the WebDriverAgent package.","metadata":{"loc":{"lines":{"from":40,"to":48}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/run-preinstalled-wda.md","filename":"run-preinstalled-wda.md","relativePath":"appium-xcuitest-driver/guides/run-preinstalled-wda.md"}},{"pageContent":"Some tools let you set an arbitrary bundle identifier (`CFBundleIdentifier` for the `Info.plist`) and sign it with the bundle identifier.\nIt may not have `.xctrunner` as the bundle identifier.\nXCUITest driver automatically adds the `.xctrunner` suffix to the provided bundle identifier unless a different suffix is specified by the `appium:updatedWDABundleIdSuffix` capability.\nIf the value is an empty string, then no suffix will be added to the provided bundle identifier.\n\nThe WDA app package (`WebDriverAgentRunner-Runner.app`) can be generated in the _derivedDataPath_\ndirectory, as explained in [Manual Configuration for a Generic Device](../preparation/prov-profile-generic-manual.md).\nThe app can then be installed without `xcodebuild` using the 3rd party tools.\n\n### Additional requirement for iOS 17+/tvOS17+\n\nTo launch the WebDriverAgentRunner package with `xcrun devicectl device process launch` for real devices it should not have `Frameworks/XC**` files.","metadata":{"loc":{"lines":{"from":50,"to":61}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/run-preinstalled-wda.md","filename":"run-preinstalled-wda.md","relativePath":"appium-xcuitest-driver/guides/run-preinstalled-wda.md"}},{"pageContent":"### Additional requirement for iOS 17+/tvOS17+\n\nTo launch the WebDriverAgentRunner package with `xcrun devicectl device process launch` for real devices it should not have `Frameworks/XC**` files.\n\nFor example, after building the WebDriverAgent with Xcode with proper sign, it generates `/Users/<user>/Library/Developer/Xcode/DerivedData/WebDriverAgent-ezumztihszjoxgacuhatrhxoklbh/Build/Products/Debug-appletvos/WebDriverAgentRunner-Runner.app`.\nThen you can remove `Frameworks/XC**` in `WebDriverAgentRunner-Runner.app` like `rm Frameworks/WebDriverAgentRunner-Runner.app/XC**`.\n\nConfiguring `appium:prebuiltWDAPath` to the `/Users/<user>/Library/Developer/Xcode/DerivedData/WebDriverAgent-ezumztihszjoxgacuhatrhxoklbh/Build/Products/Debug-appletvos/WebDriverAgentRunner-Runner.app` would install the `WebDriverAgentRunner-Runner.app`, which has no `Frameworks/XC**` to the target device and launch it with `devicectl` command as part of `appium:usePreinstalledWDA` functionality.\n\n!!! note","metadata":{"loc":{"lines":{"from":59,"to":68}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/run-preinstalled-wda.md","filename":"run-preinstalled-wda.md","relativePath":"appium-xcuitest-driver/guides/run-preinstalled-wda.md"}},{"pageContent":"!!! note\n\n You can also remove `Frameworks/Testing.framework` and `Frameworks/libXCTestSwiftSupport.dylib` to reduce the package size\n because WebDriverAgent doesn't need both. Then, the total size of the WebDriverAgent runner app can be 3MB or less.\n `Testing.framework` is almost 6MB and `libXCTestSwiftSupport.dylib` is 2.6MB with Xcode 16 build.\n \n\n## Launch the Session\n\nAfter installing the `WebDriverAgentRunner-Runner` application, you can start the Appium server\nand launch an XCUITest driver session with the specified capabilities:\n\n```\nappium\n```\n\n```ruby\n# Ruby\ncapabilities: {\n \"platformName\": \"ios\",\n \"appium:automationName\": \"xcuitest\",\n \"appium:udid\": \"<udid>\",\n \"appium:usePreinstalledWDA\": true,\n \"appium:updatedWDABundleId\": \"com.appium.WebDriverAgentRunner\"\n}\n@core = Appium::Core.for capabilities: capabilities\ndriver = @core.start_driver\n# do something\ndriver.quit\n```","metadata":{"loc":{"lines":{"from":68,"to":97}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/run-preinstalled-wda.md","filename":"run-preinstalled-wda.md","relativePath":"appium-xcuitest-driver/guides/run-preinstalled-wda.md"}},{"pageContent":"If the `<udid>` device has a WebDriverAgent package with `com.appium.WebDriverAgentRunner.xctrunner`\nbundle ID, the session will launch the WebDriverAgent process without `xcodebuild`.\n\n!!! note\n\n Please ensure that the WDA application is launchable before starting an XCUITest driver session.\n For example, check whether the provisioning profile is trusted.\n\n\n```ruby\n# Ruby\ncapabilities: {\n \"platformName\": \"ios\",\n \"appium:automationName\": \"xcuitest\",\n \"appium:udid\": \"<udid>\",\n \"appium:usePreinstalledWDA\": true,\n \"appium:updatedWDABundleId\": \"io.appium.wda\"\n \"appium:updatedWDABundleIdSuffix\": \"\"\n}\n@core = Appium::Core.for capabilities: capabilities\ndriver = @core.start_driver\n# do something\ndriver.quit\n```\n\nIf the `<udid>` device has a WebDriverAgent package with `io.appium.wda` bundle ID (it does not have `.xctrunner`),\nthe session will launch the WebDriverAgent process without `xcodebuild`.\n\n## Set `appium:prebuiltWDAPath`","metadata":{"loc":{"lines":{"from":99,"to":127}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/run-preinstalled-wda.md","filename":"run-preinstalled-wda.md","relativePath":"appium-xcuitest-driver/guides/run-preinstalled-wda.md"}},{"pageContent":"## Set `appium:prebuiltWDAPath`\n\nIf the `appium:prebuiltWDAPath` capability is provided with a `WebDriverAgentRunner-Runner.app` test bundle,\nthe XCUITest driver will install the application and launch it every test session.\nTest bundles cannot be versioned using `CFBundleVersion` as vanilla applications do usually,\nwhich is why it is necessary to (re)install them for every test session.\nThe test bundle should be signed properly for real devices.\n\nUsually you can find the WDA application bundle at the below location if you use Xcode to build it.\n\n```\n~/Library/Developer/Xcode/DerivedData/WebDriverAgent-<random string>/Build/Products/Debug-iphoneos/WebDriverAgentRunner-Runner.app\n```\n\nYou can then set your Appium capabilities as follows:","metadata":{"loc":{"lines":{"from":127,"to":141}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/run-preinstalled-wda.md","filename":"run-preinstalled-wda.md","relativePath":"appium-xcuitest-driver/guides/run-preinstalled-wda.md"}},{"pageContent":"```\n~/Library/Developer/Xcode/DerivedData/WebDriverAgent-<random string>/Build/Products/Debug-iphoneos/WebDriverAgentRunner-Runner.app\n```\n\nYou can then set your Appium capabilities as follows:\n\n```ruby\n# Ruby\ncapabilities: {\n \"platformName\": \"ios\",\n \"appium:automationName\": \"xcuitest\",\n \"appium:udid\": \"<udid>\",\n \"appium:usePreinstalledWDA\": true,\n \"appium:prebuiltWDAPath\": \"/path/to/Library/Developer/Xcode/DerivedData/WebDriverAgent-<random string>/Build/Products/Debug-iphoneos/WebDriverAgentRunner-Runner.app\"\n}\n@core = Appium::Core.for capabilities: capabilities\ndriver = @core.start_driver\n# do something\ndriver.quit\n```\n\n!!! note\n\n As of iOS 17, the testmanagerd service name has changed from `com.apple.testmanagerd` to\n `com.apple.dt.testmanagerd.runner`. It causes an unexpected WDA process crash with embedded\n XCTest frameworks while running a single WebDriverAgent package on various OS environments\n without `xcodebuild`.","metadata":{"loc":{"lines":{"from":137,"to":163}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/run-preinstalled-wda.md","filename":"run-preinstalled-wda.md","relativePath":"appium-xcuitest-driver/guides/run-preinstalled-wda.md"}},{"pageContent":"Since WDA v5.10.0, the module can refer to the device's local XCTest frameworks. It lets the\n Appium/WebDriverAgent package use proper dependencies for the device with a single prebuilt\n WebDriverAgent package. To set this up, you should remove the package internal frameworks from\n `WebDriverAgentRunner-Runner.app` with `rm -rf WebDriverAgentRunner-Runner.app/Frameworks/XC*.framework`.\n The WDA package itself is available from <https://github.com/appium/WebDriverAgent>.","metadata":{"loc":{"lines":{"from":165,"to":169}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/run-preinstalled-wda.md","filename":"run-preinstalled-wda.md","relativePath":"appium-xcuitest-driver/guides/run-preinstalled-wda.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Touch ID\n---\n\nThe XCUITest driver has the capability to simulate [Touch ID](https://support.apple.com/en-ca/HT201371).\n\n!!! note\n\n This functionality is only supported on simulators.\n\n## Configuration\n\nTo use Touch ID, the application that Appium launches from (Terminal, iTerm, etc.) must be added to\nthe accessibility preferences on your Mac. Navigate to _System Preferences -> Privacy & Security ->\nAccessibility_ and under _Allow the apps below to control your computer_ add the application.\n\nWhy this is needed: The only way Appium can enable enrollment and toggling of Touch ID is to use\nsystem-level accessibility APIs to simulate mouse clicks on the simulator menus via AppleScript.\n\n## Usage","metadata":{"loc":{"lines":{"from":1,"to":23}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/touch-id.md","filename":"touch-id.md","relativePath":"appium-xcuitest-driver/guides/touch-id.md"}},{"pageContent":"## Usage\n\n* Set the capability `appium:allowTouchIdEnroll` to `true`.\n* When the Simulator starts, Touch ID enrollment will be enabled by default\n* You can toggle Touch ID enrollment by calling the\n [`mobile: enrollBiometric`](../reference/execute-methods.md#mobile-enrollbiometric) extension\n\n!!! note\n\n Remember that not all iOS devices have Touch ID, so your tests should handle cases where\n Touch ID is not supported.","metadata":{"loc":{"lines":{"from":23,"to":33}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/touch-id.md","filename":"touch-id.md","relativePath":"appium-xcuitest-driver/guides/touch-id.md"}},{"pageContent":"---\ntitle: Troubleshooting\n---\n\n## Known Problems\n\n* Real devices with iOS/iPadOS 15+ show an overlay with the text `Automation Running Hold both\n volume buttons to stop` while WebDriverAgent is running. This is a known limitation of the XCTest\n framework. Note that screenshotting functionality is not affected (i.e. the overlay is not visible\n on taken screenshots).\n* Real devices with iOS/iPadOS 15+ [require passcode or Touch ID](https://github.com/appium/appium/issues/15898#issuecomment-927340411)\n when starting a new session. A workaround for this is to disable passcode/Touch ID on the device.\n* After many failures on a real device, it could transition to a state where connections are no\n longer being accepted. Rebooting the device can help remedy this problem. Please read\n [this issue](https://github.com/facebook/WebDriverAgent/issues/507) for more details.\n* `shake` is implemented via AppleScript and works only on Simulator due to lack of support from Apple","metadata":{"loc":{"lines":{"from":1,"to":16}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/troubleshooting.md","filename":"troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/troubleshooting.md"}},{"pageContent":"## Interact with dialogs managed by `com.apple.springboard`\n\nSystem dialogs, such as permission dialogs, might not be interactable directly when the active application is not `com.apple.springboard`.\nDespite a similar look, dialogs belonging to the active session application (e.g. initially passed as `appium:app` or `appium:bundleId` capability value)\ndo not require such adjustment.\n\nXCUITest driver offers a couple of approaches to handle them:","metadata":{"loc":{"lines":{"from":18,"to":24}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/troubleshooting.md","filename":"troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/troubleshooting.md"}},{"pageContent":"- Set the [respectSystemAlerts setting](../reference/settings.md) to `true`. It enforces the active application\n detection algorithm to check a presence of system alerts and to return the Springboard app if this check succeeds.\n Such approach emulates the driver behavior prior to version 6 of XCUITest driver, although it might slightly\n slow down your scripts because each attempt to detect an active app would require to also query for alerts\n presence.","metadata":{"loc":{"lines":{"from":26,"to":30}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/troubleshooting.md","filename":"troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/troubleshooting.md"}},{"pageContent":"slow down your scripts because each attempt to detect an active app would require to also query for alerts\n presence.\n- Start a session without `appium:app` nor `appium:bundleId`. Then XCUITest driver attempts to get the current active application. This requires you to start an application after a new session request with [`mobile: installApp`](../reference/execute-methods.md#mobile-installapp) to install an app if needed and [`mobile: launchApp`](../reference/execute-methods.md#mobile-launchapp)/[`mobile: activateApp`](../reference/execute-methods.md#mobile-activateapp), but it could automatically change the active application with `com.apple.springboard` or activate an application at the foreground. (Note that the automatic app detection might be lengthy, thus each action could take more time.)\n - When a permission alert exists at the foreground, it could select the `com.apple.springboard`","metadata":{"loc":{"lines":{"from":29,"to":32}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/troubleshooting.md","filename":"troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/troubleshooting.md"}},{"pageContent":"- When a permission alert exists at the foreground, it could select the `com.apple.springboard`\n - When another application is at the foreground by accepting/denying the system alert, or [`mobile: activateApp`](../reference/execute-methods.md#mobile-activateapp), the application would be selected as an active application.\n- [`mobile: alert`](../reference/execute-methods.md#mobile-alert)\n- `defaultActiveApplication` setting in [Settings](../reference/settings.md).\n - e.g. With the [Appium Ruby client](https://github.com/appium/ruby_lib_core)\n ```ruby\n # Interacting with the test target\n driver.settings.update({defaultActiveApplication: \"com.apple.springboard\"})\n # to accept the alert\n driver.find_element(\"accessibility_id\", \"Allow Once\").click\n driver.settings.update({defaultActiveApplication: \"auto\"})\n # keep interacting with the test target\n ```","metadata":{"loc":{"lines":{"from":32,"to":44}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/troubleshooting.md","filename":"troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/troubleshooting.md"}},{"pageContent":"driver.find_element(\"accessibility_id\", \"Allow Once\").click\n driver.settings.update({defaultActiveApplication: \"auto\"})\n # keep interacting with the test target\n ```\n- Enable `appium:autoAcceptAlerts`/`appium:autoDismissAlerts`, or interact with alerts via [User Prompts](https://www.w3.org/TR/webdriver1/#user-prompts) in WebDriver endpoints\n - e.g. `driver.switch_to.alert.accept` with the [Appium Ruby client](https://github.com/appium/ruby_lib_core)\n - It might be necessary to coordinate element selection via `acceptAlertButtonSelector`/`dismissAlertButtonSelector` settings in [Settings](../reference/settings.md)\n- Activate `com.apple.springboard` with [`mobile: activateApp`](../reference/execute-methods.md#mobile-activateapp) before interacting with dialogs","metadata":{"loc":{"lines":{"from":41,"to":48}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/troubleshooting.md","filename":"troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/troubleshooting.md"}},{"pageContent":"[`mobile: activeAppInfo`](../reference/execute-methods.md#mobile-activateappinfo) helps to understand what application (bundleId) is considered as active for the XCUITest driver.\n\n## Interact with dialogs managed by `com.apple.ContactsUI.LimitedAccessPromptView`\n\niOS 18 introduced a new process named `com.apple.ContactsUI.LimitedAccessPromptView`. See [this issue](https://github.com/appium/appium/issues/20591) for more details.\nAs of XCUITest driver v7.26.4, the only workaround to interact with views available through the process is the below method:","metadata":{"loc":{"lines":{"from":50,"to":55}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/troubleshooting.md","filename":"troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/troubleshooting.md"}},{"pageContent":"- `defaultActiveApplication` setting in [Settings](../reference/settings.md).\n - e.g. With the [Appium Ruby client](https://github.com/appium/ruby_lib_core)\n ```ruby\n # Interacting with the test target\n driver.settings.update({defaultActiveApplication: \"com.apple.ContactsUI.LimitedAccessPromptView\"})\n # to accept the alert\n driver.find_element(\"accessibility_id\", \"Select Contacts\").click\n driver.settings.update({defaultActiveApplication: \"auto\"})\n # keep interacting with the test target\n ```\n\nThe `com.apple.ContactsUI.LimitedAccessPromptView` process can get elements available through `com.apple.springboard`, such as several system permission dialogs.\niOS 18+ devices may be possible to use `com.apple.ContactsUI.LimitedAccessPromptView` to interact with elements managed either by `com.apple.ContactsUI.LimitedAccessPromptView` or `com.apple.springboard`.\n\n## Leftover Application Data on Real Devices","metadata":{"loc":{"lines":{"from":57,"to":71}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/troubleshooting.md","filename":"troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/troubleshooting.md"}},{"pageContent":"## Leftover Application Data on Real Devices\n\nThere might be a situation where application data is present on the real device, even if the\napplication itself is not installed. This could happen if:\n\n- The app is in an [offloaded state](https://discussions.apple.com/thread/254887240)\n- The application state is cached\n- There was an unexpected failure while installing the app. An example of such failure is the\n `ApplicationVerificationFailed` which happens while installing an app signed with an invalid provisioning profile.\n\nIn the above cases, the application identifier will not be listed in the output of\n[`mobile: listApps`](../reference/execute-methods.md#mobile-listapps), and it will not be detected\nby [`mobile: isAppInstalled`](../reference/execute-methods.md#mobile-isappinstalled). Setting\n`appium:fullReset` or `appium:enforceAppInstall` capabilities to `true` also will not help clear this data.","metadata":{"loc":{"lines":{"from":71,"to":84}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/troubleshooting.md","filename":"troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/troubleshooting.md"}},{"pageContent":"The only way to completely get rid of the cached application data is to call the\n[`mobile: removeApp`](../reference/execute-methods.md#mobile-removeapp) command with the appropriate\nbundle identifier.\n\nThe driver does automatically try to resolve application installs that failed because of the\n`MismatchedApplicationIdentifierEntitlement` error. However, in cases when the previously installed\napplication's provisioning profile is different from what currently the driver is trying to\ninstall, and if you explicitly set the driver to _not_ perform application uninstall, then consider\ncalling [`mobile: removeApp`](../reference/execute-methods.md#mobile-removeapp) before the\n`MismatchedApplicationIdentifierEntitlement` error occurs. Example steps can be as follows:","metadata":{"loc":{"lines":{"from":86,"to":95}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/troubleshooting.md","filename":"troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/troubleshooting.md"}},{"pageContent":"1. Start a session without `appium:app` and `appium:bundleId` capabilities\n2. Call [`mobile: removeApp`](../reference/execute-methods.md#mobile-removeapp) for the target\n application's bundle id\n3. Install the test target with [`mobile: installApp`](../reference/execute-methods.md#mobile-installapp)\n4. Launch the application with [`mobile: launchApp`](../reference/execute-methods.md#mobile-launchapp)\n or [`mobile: activateApp`](../reference/execute-methods.md#mobile-activateapp)\n\n\n!!! note\n\n We observed that iOS 18+ environments can retain the permission preference even after reinstallation.\n Please refer to [this issue](https://github.com/appium/appium-xcuitest-driver/issues/2572) for more information about this behavior.\n \n\n## Weird State\n\n### Real Device Stops Responding\n\nRunning tests on a real device is particularly flakey. If things stop responding, the only recourse\nis, most often, to restart the device. Logs in the form of the following _may_ start to occur:","metadata":{"loc":{"lines":{"from":97,"to":116}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/troubleshooting.md","filename":"troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/troubleshooting.md"}},{"pageContent":"Running tests on a real device is particularly flakey. If things stop responding, the only recourse\nis, most often, to restart the device. Logs in the form of the following _may_ start to occur:\n\n```shell\ninfo JSONWP Proxy Proxying [POST /session] to [POST http://10.35.4.122:8100/session] with body: {\"desiredCapabilities\":{\"ap...\"\ndbug WebDriverAgent Device: Jul 26 13:20:42 iamPhone XCTRunner[240] <Warning>: Listening on USB\ndbug WebDriverAgent Device: Jul 26 13:21:42 iamPhone XCTRunner[240] <Warning>: Enqueue Failure: UI Testing Failure - Unable to update application state promptly. <unknown> 0 1\ndbug WebDriverAgent Device: Jul 26 13:21:57 iamPhone XCTRunner[240] <Warning>: Enqueue Failure: UI Testing Failure - Failed to get screenshot within 15s <unknown> 0 1\ndbug WebDriverAgent Device: Jul 26 13:22:57 iamPhone XCTRunner[240] <Warning>: Enqueue Failure: UI Testing Failure - App state of (null) is still unknown <unknown> 0 1\n```\n\n### Command Takes 60+ Seconds","metadata":{"loc":{"lines":{"from":115,"to":126}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/troubleshooting.md","filename":"troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/troubleshooting.md"}},{"pageContent":"### Command Takes 60+ Seconds\n\nSometimes it is possible to encounter slowdowns for an additional 60 seconds for a command that\nusually should not take long. This may be caused by a crash in the `testmanagerd` process on the\ndevice under test. In such a case, the OS tries to restore the process, then wait for the resurrected\ndaemon to connect to the target process, which causes the aforementioned delay.\n\nThis can be fixed by terminating the target application process. For example, if this behavior\noccurs while calling `mobile: queryAppState`, you can terminate the application once, or restart the\ndevice entirely. Please check [this pull request](https://github.com/appium/WebDriverAgent/pull/774)\nfor more details.\n\n## Real Device Security Settings","metadata":{"loc":{"lines":{"from":126,"to":138}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/troubleshooting.md","filename":"troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/troubleshooting.md"}},{"pageContent":"## Real Device Security Settings\n\nOn some systems, especially CI ones, where tests are executed by command line agents, macOS\nAccessibility restrictions result in the WebDriverAgent process being unable to retrieve the\ndevelopment keys from the system keychain. This usually manifests by `xcodebuild` returning error\ncode `65`. One workaround for this is to use a private key that is not stored on the system\nkeychain. See [this issue](https://github.com/appium/appium/issues/6955) and\n[this Stack Exchange post](http://stackoverflow.com/questions/16550594/jenkins-xcode-build-works-codesign-fails).\n\nTo export the key, use\n\n```\nsecurity create-keychain -p [keychain_password] MyKeychain.keychain\nsecurity import MyPrivateKey.p12 -t agg -k MyKeychain.keychain -P [p12_Password] -A\n```\n\nwhere `MyPrivateKey.p12` is the private development key exported from the system keychain.","metadata":{"loc":{"lines":{"from":138,"to":154}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/troubleshooting.md","filename":"troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/troubleshooting.md"}},{"pageContent":"where `MyPrivateKey.p12` is the private development key exported from the system keychain.\n\nYou can then use the [`appium:keychainPath`](../reference/capabilities.md#webdriveragent) and\n[`appium:keychainPassword`](../reference/capabilities.md#webdriveragent) capabilities to pass this\nkeychain to WebDriverAgent.\n\n## Simulator Resetting\n\nWhen testing on simulators, the driver tries to leave the simulator state as it found it:\n\n* If no `udid` is provided, the driver will create a new iOS simulator, run tests on it, and then\n delete the simulator\n* If a specific `udid` is provided for a simulator that _is not_ running, the driver will boot the\n specified simulator, run tests on it, and then shut the simulator down\n* If a specific `udid` is provided for a simulator that _is_ running, the driver will connect to the\n existing simulator, run tests, and then leave the simulator running","metadata":{"loc":{"lines":{"from":154,"to":169}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/troubleshooting.md","filename":"troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/troubleshooting.md"}},{"pageContent":"You can use the `appium:noReset` capability to adjust this behavior: setting it to `true` will\nleave the simulator running at the end of a test session.\n\n## Caching Issues During Build\n\nTesting on iOS generates files that can sometimes get large. These include logs, temporary files,\nand derived data from Xcode runs, all of which are safe to delete if any issues arise. The files are\nusually found in the following locations, should they need to be deleted:\n\n```\n$HOME/Library/Logs/CoreSimulator/*\n$HOME/Library/Developer/Xcode/DerivedData/*\n```\n\n## Frequent `Disconnecting from remote debugger` error in iOS 17\n\nPlease try out iOS 17.6 or a newer version which includes [a possible fix by Apple](https://developer.apple.com/documentation/safari-release-notes/safari-17_6-release-notes#Web-Inspector).","metadata":{"loc":{"lines":{"from":171,"to":187}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/troubleshooting.md","filename":"troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/troubleshooting.md"}},{"pageContent":"Please try out iOS 17.6 or a newer version which includes [a possible fix by Apple](https://developer.apple.com/documentation/safari-release-notes/safari-17_6-release-notes#Web-Inspector).\n\nFrequent Web Inspector debugger disconnection started since iOS 17.2 (or iOS 17.0), that eventually caused `Disconnecting from remote debugger` error.\nIt could be improved since iOS 17.6.\nPlease check [the corresponding pull request](https://github.com/appium/appium-xcuitest-driver/pull/2334) for more details.","metadata":{"loc":{"lines":{"from":187,"to":191}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/troubleshooting.md","filename":"troubleshooting.md","relativePath":"appium-xcuitest-driver/guides/troubleshooting.md"}},{"pageContent":"---\ntitle: tvOS Support\n---\n\nThe XCUITest driver supports automation of the tvOS platform.\n\n<img src=\"https://user-images.githubusercontent.com/5511591/55161297-876e0200-51a8-11e9-8313-8d9f15a0db9d.gif\" width=50%>\n\n!!! warning\n\n Apple TV 4K is not supported. This is because [`appium-ios-device`](https://github.com/appium/appium-ios-device),\n which is used to support low-level communication with devices, only supports devices connected via USB.\n\n## Setup\n\nYou can run tests for tvOS by setting the `platformName` capability to `tvOS`:\n\n```json\n{\n \"platformName\": \"tvOS\", // here\n \"appium:automationName\": \"XCUITest\",\n \"appium:platformVersion\": \"12.2\",\n \"appium:deviceName\": \"Apple TV\",\n ...\n}\n```\n\n!!! note\n\n If using a simulator, make sure the tvOS simulator exists in your simulator list. You can run\n `xcrun simctl list | grep \"com.apple.CoreSimulator.SimRuntime.tvOS\"` to verify this.\n\n## Basic Actions","metadata":{"loc":{"lines":{"from":1,"to":33}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/tvos.md","filename":"tvos.md","relativePath":"appium-xcuitest-driver/guides/tvos.md"}},{"pageContent":"## Basic Actions\n\ntvOS provides [remote controller](https://developer.apple.com/design/human-interface-guidelines/tvos/remote-and-controllers/remote/)\nbased actions. The XCUITest driver implements these actions using the\n[`mobile: pressButton`](../reference/execute-methods.md#mobile-pressbutton) extension, with the\nfollowing button values: `menu`, `up/down/left/right`, `home`, `playpause` and `select`.\n\nAll actions are performed on the _focused_ element (which has the `focus` attribute set). The\nfocused element is automatically changed after using `mobile: pressButton`.\n\nIt is also possible to use the standard `findElement` and `click` methods. The XCUITest driver will\nautomatically calculate the necessary sequence of `up/down/left/right` and `select` button presses,\nso you should not care about which keys should be pressed to reach an arbitrary element every time.\n\n=== \"Java\"","metadata":{"loc":{"lines":{"from":33,"to":47}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/tvos.md","filename":"tvos.md","relativePath":"appium-xcuitest-driver/guides/tvos.md"}},{"pageContent":"=== \"Java\"\n\n ```java\n WebElement element = driver.findElementByAccessibilityId(\"element on the app\");\n element.getAttribute(\"focused\"); // => 'true'\n // Appium moves the focus to the element by pressing the corresponding keys and clicking the element\n element.click();\n driver.queryAppState(\"test.package.name\"); // => :running_in_foreground\n driver.executeScript(\"mobile: pressButton\", ImmutableMap.of(\"name\", \"Home\"));\n driver.executeScript(\"mobile: pressButton\", ImmutableMap.of(\"name\", \"Up\"));\n element = driver.switchTo().activeElement();\n element.getAttribute(\"label\");\n ```\n\n=== \"JS (WebdriverIO)\"\n\n ```javascript\n const element = $('~SomeAccessibilityId');\n element.getAttribute('focused');\n element.click();\n driver.execute('mobile: pressButton', {name: 'Home'});\n driver.execute('mobile: pressButton', {name: 'Up'});\n const activeElement = driver.getActiveElement();\n activeElement.getAttribute('label');\n ```\n\n=== \"Python\"","metadata":{"loc":{"lines":{"from":47,"to":73}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/tvos.md","filename":"tvos.md","relativePath":"appium-xcuitest-driver/guides/tvos.md"}},{"pageContent":"=== \"Python\"\n\n ```Python\n element = driver.find_element_by_accessibility_id('element on the app')\n element.get_attribute('focused')\n element.click()\n driver.query_app_state('test.package.name')\n driver.execute_script('mobile: pressButton', { 'name': 'Home' })\n driver.execute_script('mobile: pressButton', { 'name': 'Up' })\n element = driver.switch_to.active_element\n element.get_attribute('label')\n ```\n\n=== \"Ruby\"\n\n ```ruby\n element = @driver.find_element :accessibility_id, 'element on the app'\n element.focused\n element.click\n @driver.app_state('test.package.name')\n @driver.execute_script 'mobile: pressButton', { name: 'Home' }\n @driver.execute_script 'mobile: pressButton', { name: 'Up' }\n element = @driver.switch_to.active_element\n element.label\n ```\n\n## More Actions\n\n* Consider using `wait` methods, since tvOS also has animation\n* The `menu` button works as _back_ for iOS context in tvOS\n\n## Known Limitations","metadata":{"loc":{"lines":{"from":73,"to":104}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/tvos.md","filename":"tvos.md","relativePath":"appium-xcuitest-driver/guides/tvos.md"}},{"pageContent":"## More Actions\n\n* Consider using `wait` methods, since tvOS also has animation\n* The `menu` button works as _back_ for iOS context in tvOS\n\n## Known Limitations\n\n* Gesture commands do not work for tvOS. Some commands such as pasteboard do not work as well.\n\n## Related Tickets\n\n* <https://github.com/appium/appium/pull/12401>\n* <https://github.com/appium/appium-xcuitest-driver/pull/911>\n* <https://github.com/appium/appium-xcuitest-driver/pull/931>\n* <https://github.com/appium/appium-xcuitest-driver/pull/939>\n* <https://github.com/appium/WebDriverAgent/pull/163>","metadata":{"loc":{"lines":{"from":99,"to":114}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/tvos.md","filename":"tvos.md","relativePath":"appium-xcuitest-driver/guides/tvos.md"}},{"pageContent":"---\ntitle: Manage WebDriverAgent by Yourself\n---\n\nThe XCUITest driver uses [WebDriverAgent](https://github.com/appium/WebDriverAgent) (WDA) as the\nautomation backend. This backend is based on Apple's XCTest framework and shares all the known\nproblems that are present in XCTest. For some of them we have workarounds, but there are some that\nare hardly possible to workaround ([here is one example](https://github.com/facebookarchive/WebDriverAgent/issues/507)).\nThe approach described in this article enables you to have full control over how WDA is built,\nmanaged, and run on the device. This way you may fine-tune your automated tests in a CI environment\nand make them more stable inlong-running perspective.\n\n!!! note","metadata":{"loc":{"lines":{"from":1,"to":13}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"!!! note\n\n * The steps below are not necessary if default Appium capabilities are used. The server will do\n everything for you, however, you will not have so much control over WDA.\n * It is mandatory to have SSH or physical access to the machine to which the device under test\n is connected.\n\n\n### WDA Setup\n\nIn order to setup and launch WDA, please check the provided steps in the\n[Run Preinstalled WDA](./run-preinstalled-wda.md#using-xcode) documentation.\n\n### WDA Startup via Code","metadata":{"loc":{"lines":{"from":13,"to":26}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"### WDA Setup\n\nIn order to setup and launch WDA, please check the provided steps in the\n[Run Preinstalled WDA](./run-preinstalled-wda.md#using-xcode) documentation.\n\n### WDA Startup via Code\n\nWebDriverAgent application acts as a REST server, which proxies external API requests to native\nXCTest calls for your application under test. The server address will be `localhost` if you run your\ntests on a simulator, or the actual phone IP address in case of real device. Appium uses\n[`appium-ios-device`](https://github.com/appium/appium-ios-device) to route network requests to a\nreal device from `localhost` via USB, which means one can use this tool to unify the WDA network\naddresses for a simulator and real device.","metadata":{"loc":{"lines":{"from":21,"to":33}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"You can use `appium-ios-device` to connect to a remote device by requiring the module from your\nJavaScript code. Alternatively, you can use [`iproxy`](https://github.com/libimobiledevice/libusbmuxd#iproxy),\n[`go-ios`](https://github.com/danielpaulus/go-ios) or [`tidevice`](https://github.com/alibaba/taobao-iphone-device)\nto handle the WDA process outside Appium, by installing and launching the WDA package. For instance,\n`iproxy` can be installed using `npm`: `npm install -g iproxy`.\n\nThis helper class written in Java illustrates the main implementation details with `iproxy`:\n\n```java\npublic class WDAServer {\n private static final Logger log = ZLogger.getLog(WDAServer.class.getSimpleName());\n\n private static final int MAX_REAL_DEVICE_RESTART_RETRIES = 1;\n private static final Timedelta REAL_DEVICE_RUNNING_TIMEOUT = Timedelta.ofMinutes(4);\n private static final Timedelta RESTART_TIMEOUT = Timedelta.ofMinutes(1);","metadata":{"loc":{"lines":{"from":35,"to":49}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"// These settings are needed to properly sign WDA for real device tests\n // See https://github.com/appium/appium-xcuitest-driver for more details\n private static final File KEYCHAIN = new File(String.format(\"%s/%s\",\n System.getProperty(\"user.home\"), \"/Library/Keychains/MyKeychain.keychain\"));\n private static final String KEYCHAIN_PASSWORD = \"******\";","metadata":{"loc":{"lines":{"from":51,"to":55}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"private static final File IPROXY_EXECUTABLE = new File(\"/usr/local/bin/iproxy\");\n private static final File XCODEBUILD_EXECUTABLE = new File(\"/usr/bin/xcodebuild\");\n private static final File WDA_PROJECT =\n new File(\"~/.appium/node_modules/appium-xcuitest-driver/node_modules/appium-webdriveragent\" +\n \"/WebDriverAgent.xcodeproj\");\n private static final String WDA_SCHEME = \"WebDriverAgentRunner\";\n private static final String WDA_CONFIGURATION = \"Debug\";\n private static final File XCODEBUILD_LOG = new File(\"/usr/local/var/log/appium/build.log\");\n private static final File IPROXY_LOG = new File(\"/usr/local/var/log/appium/iproxy.log\");\n\n private static final int PORT = 8100;\n public static final String SERVER_URL = String.format(\"http://127.0.0.1:%d\", PORT);","metadata":{"loc":{"lines":{"from":57,"to":68}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"private static final int PORT = 8100;\n public static final String SERVER_URL = String.format(\"http://127.0.0.1:%d\", PORT);\n\n private static final String[] IPROXY_CMDLINE = new String[]{\n IPROXY_EXECUTABLE.getAbsolutePath(),\n Integer.toString(PORT),\n Integer.toString(PORT),\n String.format(\"> %s 2>&1 &\", IPROXY_LOG.getAbsolutePath())\n };\n\n private static WDAServer instance = null;\n private final boolean isRealDevice;\n private final String deviceId;\n private final String platformVersion;\n private int failedRestartRetriesCount = 0;","metadata":{"loc":{"lines":{"from":67,"to":81}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"private WDAServer() {\n try {\n this.isRealDevice = !getIsSimulatorFromConfig(getClass());\n final String udid;\n if (isRealDevice) {\n udid = IOSRealDeviceHelpers.getUDID();\n } else {\n udid = IOSSimulatorHelpers.getId();\n }\n this.deviceId = udid;\n this.platformVersion = getPlatformVersionFromConfig(getClass());\n } catch (Exception e) {\n throw new RuntimeException(e);\n }\n ensureToolsExistence();\n ensureParentDirExistence();\n }\n\n public synchronized static WDAServer getInstance() {\n if (instance == null) {\n instance = new WDAServer();\n }\n return instance;\n }","metadata":{"loc":{"lines":{"from":83,"to":106}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"public synchronized static WDAServer getInstance() {\n if (instance == null) {\n instance = new WDAServer();\n }\n return instance;\n }\n\n private boolean waitUntilIsRunning(Timedelta timeout) throws Exception {\n final URL status = new URL(SERVER_URL + \"/status\");\n try {\n if (timeout.asSeconds() > 5) {\n log.debug(String.format(\"Waiting max %s until WDA server starts responding...\", timeout));\n }\n new UrlChecker().waitUntilAvailable(timeout.asMillis(), TimeUnit.MILLISECONDS, status);\n return true;\n } catch (UrlChecker.TimeoutException e) {\n return false;\n }\n }","metadata":{"loc":{"lines":{"from":101,"to":119}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"private static void ensureParentDirExistence() {\n if (!XCODEBUILD_LOG.getParentFile().exists()) {\n if (!XCODEBUILD_LOG.getParentFile().mkdirs()) {\n throw new IllegalStateException(String.format(\n \"The script has failed to create '%s' folder for Appium logs. \" +\n \"Please make sure your account has correct access permissions on the parent folder(s)\",\n XCODEBUILD_LOG.getParentFile().getAbsolutePath()));\n }\n }\n }","metadata":{"loc":{"lines":{"from":121,"to":130}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"private void ensureToolsExistence() {\n if (isRealDevice && !IPROXY_EXECUTABLE.exists()) {\n throw new IllegalStateException(String.format(\"%s tool is expected to be installed (`npm install -g iproxy`)\",\n IPROXY_EXECUTABLE.getAbsolutePath()));\n }\n if (!XCODEBUILD_EXECUTABLE.exists()) {\n throw new IllegalStateException(String.format(\"xcodebuild tool is not detected on the current system at %s\",\n XCODEBUILD_EXECUTABLE.getAbsolutePath()));\n }\n if (!WDA_PROJECT.exists()) {\n throw new IllegalStateException(String.format(\"WDA project is expected to exist at %s\",\n WDA_PROJECT.getAbsolutePath()));\n }\n }","metadata":{"loc":{"lines":{"from":132,"to":145}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"private List<String> generateXcodebuildCmdline() {\n final List<String> result = new ArrayList<>();\n result.add(XCODEBUILD_EXECUTABLE.getAbsolutePath());\n result.add(\"clean build-for-testing test-without-building\");\n result.add(String.format(\"-project %s\", WDA_PROJECT.getAbsolutePath()));\n result.add(String.format(\"-scheme %s\", WDA_SCHEME));\n result.add(String.format(\"-destination id=%s\", deviceId));\n result.add(String.format(\"-configuration %s\", WDA_CONFIGURATION));\n result.add(String.format(\"IPHONEOS_DEPLOYMENT_TARGET=%s\", platformVersion));\n result.add(String.format(\"> %s 2>&1 &\", XCODEBUILD_LOG.getAbsolutePath()));\n return result;\n }","metadata":{"loc":{"lines":{"from":147,"to":158}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"private static List<String> generateKeychainUnlockCmdlines() throws Exception {\n final List<String> result = new ArrayList<>();\n result.add(String.format(\"/usr/bin/security -v list-keychains -s %s\", KEYCHAIN.getAbsolutePath()));\n result.add(String.format(\"/usr/bin/security -v unlock-keychain -p %s %s\",\n KEYCHAIN_PASSWORD, KEYCHAIN.getAbsolutePath()));\n result.add(String.format(\"/usr/bin/security set-keychain-settings -t 3600 %s\", KEYCHAIN.getAbsolutePath()));\n return result;\n }\n\n public synchronized void restart() throws Exception {\n if (isRealDevice && failedRestartRetriesCount >= MAX_REAL_DEVICE_RESTART_RETRIES) {\n throw new IllegalStateException(String.format(\n \"WDA server cannot start on the connected device with udid %s after %s retries. \" +\n \"Reboot the device manually and try again\", deviceId, MAX_REAL_DEVICE_RESTART_RETRIES));\n }","metadata":{"loc":{"lines":{"from":160,"to":174}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"final String hostname = InetAddress.getLocalHost().getHostName();\n log.info(String.format(\"Trying to (re)start WDA server on %s:%s...\", hostname, PORT));\n UnixProcessHelpers.killProcessesGracefully(IPROXY_EXECUTABLE.getName(), XCODEBUILD_EXECUTABLE.getName());","metadata":{"loc":{"lines":{"from":176,"to":178}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"final File scriptFile = File.createTempFile(\"script\", \".sh\");\n try {\n final List<String> scriptContent = new ArrayList<>();\n scriptContent.add(\"#!/bin/bash\");\n if (isRealDevice && isRunningInJenkinsNetwork()) {\n scriptContent.add(String.join(\"\\n\", generateKeychainUnlockCmdlines()));\n }\n if (isRealDevice) {\n scriptContent.add(String.join(\" \", IPROXY_CMDLINE));\n }\n final String wdaBuildCmdline = String.join(\" \", generateXcodebuildCmdline());\n log.debug(String.format(\"Building WDA with command line:\\n%s\\n\", wdaBuildCmdline));\n scriptContent.add(wdaBuildCmdline);\n try (Writer output = new BufferedWriter(new FileWriter(scriptFile))) {\n output.write(String.join(\"\\n\", scriptContent));\n }\n new ProcessBuilder(\"/bin/chmod\", \"u+x\", scriptFile.getCanonicalPath())","metadata":{"loc":{"lines":{"from":180,"to":196}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"output.write(String.join(\"\\n\", scriptContent));\n }\n new ProcessBuilder(\"/bin/chmod\", \"u+x\", scriptFile.getCanonicalPath())\n .redirectErrorStream(true).start().waitFor(5, TimeUnit.SECONDS);\n final ProcessBuilder pb = new ProcessBuilder(\"/bin/bash\", scriptFile.getCanonicalPath());\n final Map<String, String> env = pb.environment();\n // This is needed for Jenkins\n env.put(\"BUILD_ID\", \"dontKillMe\");\n // This line is important. If USE_PORT environment variable is not set then WDA\n // takes port number zero by default and won't accept any incoming requests\n env.put(\"USE_PORT\", Integer.toString(PORT));\n log.info(String.format(\"Waiting max %s for WDA to be (re)started on %s:%s...\", RESTART_TIMEOUT.toString(),\n hostname, PORT));\n final Timedelta started = Timedelta.now();","metadata":{"loc":{"lines":{"from":194,"to":207}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"hostname, PORT));\n final Timedelta started = Timedelta.now();\n pb.redirectErrorStream(true).start().waitFor(RESTART_TIMEOUT.asMillis(), TimeUnit.MILLISECONDS);\n if (!waitUntilIsRunning(RESTART_TIMEOUT)) {\n ++failedRestartRetriesCount;\n throw new IllegalStateException(\n String.format(\"WDA server has failed to start after %s timeout on server '%s'.\\n\"\n + \"Please make sure that iDevice is properly connected and you can build \"\n + \"WDA manually from XCode.\\n\"\n + \"Xcodebuild logs:\\n\\n%s\\n\\n\\niproxy logs:\\n\\n%s\\n\\n\\n\",\n RESTART_TIMEOUT, hostname,\n getLog(XCODEBUILD_LOG).orElse(\"EMPTY\"), getLog(IPROXY_LOG).orElse(\"EMPTY\"))\n );\n }","metadata":{"loc":{"lines":{"from":206,"to":219}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"log.info(String.format(\"WDA server has been successfully (re)started after %s \" +\n \"and now is listening on %s:%s\", Timedelta.now().diff(started).toString(), hostname, PORT));\n } finally {\n scriptFile.delete();\n }\n }\n\n public boolean isRunning() throws Exception {\n if (!isProcessRunning(XCODEBUILD_EXECUTABLE.getName())\n || (isRealDevice && !isProcessRunning(IPROXY_EXECUTABLE.getName()))) {\n return false;\n }\n return waitUntilIsRunning(isRealDevice ? REAL_DEVICE_RUNNING_TIMEOUT : Timedelta.ofSeconds(3));\n }\n\n public Optional<String> getLog(File logFile) {\n if (logFile.exists()) {\n try {\n return Optional.of(new String(Files.readAllBytes(logFile.toPath()), Charset.forName(\"UTF-8\")));\n } catch (IOException e) {\n e.printStackTrace();\n }\n }\n return Optional.empty();\n }\n}\n```","metadata":{"loc":{"lines":{"from":221,"to":247}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"The following piece of code should then be called before starting the XCUITest driver:\n\n```java\nif (!WDAServer.getInstance().isRunning()) {\n WDAServer.getInstance().restart();\n}\n```\n\nIt is important to set the `appium:webDriverAgentUrl` capability for the driver to let it know\nthat WDA is ready for use:\n\n```java\ncapabilities.setCapability(\"webDriverAgentUrl\", WDAServer.SERVER_URL);\n```\n\n### Important Notes","metadata":{"loc":{"lines":{"from":249,"to":264}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"* The process does not have direct access to keychain if it is executed by a continuous integration\n agent, so the keychain must be prepared before compiling WDA for real device, otherwise\n codesigning will fail. Check the [CI Setup](./ci-setup.md) documentation for details.\n* The `xcodebuild` and `iproxy` processes are killed before restart to make sure compilation\n succeeds, in case the processes are frozen\n* A dedicated `bash` script is used to detach the `iproxy`/`xcodebuild` processes, so they can\n continue running in background even after the actual code execution is finished. This is extremely\n important if multiple tests/suites are executed on the same machine/node in automation lab, which\n requires minimum human interaction\n* The value of the `BUILD_ID` environment variable is changed to avoid the CI agent killing the\n background process after the job is finished\n* The `isRunning` check is done by verifying the actual network endpoint","metadata":{"loc":{"lines":{"from":266,"to":277}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"background process after the job is finished\n* The `isRunning` check is done by verifying the actual network endpoint\n* The output of daemonized processes is logged, so it is possible to track errors and unexpected\n failures. The content of the log files is automatically added to the actual error message if the\n server fails to (re)start.\n* Real device id can be parsed from `system_profiler SPUSBDataType` output\n* Simulator id can be parsed from `xcrun simctl list` output\n* The `UrlChecker` class is imported from the `org.openqa.selenium.net` package","metadata":{"loc":{"lines":{"from":276,"to":283}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-custom-server.md","filename":"wda-custom-server.md","relativePath":"appium-xcuitest-driver/guides/wda-custom-server.md"}},{"pageContent":"---\ntitle: Diagnosing WebDriverAgent Slowness\n---\n\nThe XCUITest driver is based on Apple's [XCTest](https://developer.apple.com/documentation/xctest)\ntest automation framework and thus inherits most (if not all) properties and features this framework\nprovides. The purpose of this article is to help with optimization of automation scenarios that\ndon't perform well and/or to explain possible causes of such behavior.\n\n## \"Slowness\" could be different\n\nFirst, it is important to figure out what exactly is slow.\nThe Appium ecosystem is complicated and\nconsists of multiple layers, where each layer could influence the overall duration.\nFor example, when an API call is invoked from a client script, it must go through the following stages:","metadata":{"loc":{"lines":{"from":1,"to":15}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-slowness.md","filename":"wda-slowness.md","relativePath":"appium-xcuitest-driver/guides/wda-slowness.md"}},{"pageContent":"Your automation script (Java, Python, C#, etc; runs on your machine)\n--> Appium Client Lib (Java, Python, C#, etc; runs on your machine)\n--> Appium Server (Node.js HTTP server; runs on your machine or a remote one)\n--> XCUITest Driver and/or Plugin (Node.js HTTP handler; runs on your machine or a remote one)\n--> WDA Server (ObjectiveC HTTP Server; runs on the remote mobile device)\n\nThe example above is the simplest flow. If you run your scripts using cloud providers\ninfrastructure then the amount of intermediate components in this chain may be much greater.\nLike it was mentioned above, it is very important to know on which stage(s)\n(or between them) the bottleneck is observed.\n\nThis particular article focuses only on the last stage: the WDA Server one.\n\n## WebDriverAgent (WDA) Server","metadata":{"loc":{"lines":{"from":17,"to":30}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-slowness.md","filename":"wda-slowness.md","relativePath":"appium-xcuitest-driver/guides/wda-slowness.md"}},{"pageContent":"This particular article focuses only on the last stage: the WDA Server one.\n\n## WebDriverAgent (WDA) Server\n\nWDA source code is located in the separate [repository](https://github.com/appium/WebDriverAgent/tree/master).\nThe content of this repository is published as [appium-webdriveragent](https://www.npmjs.com/package/appium-webdriveragent)\nNPM package and contains several helper Node.js modules along with the WDA source code itself.\nThis source code is compiled into an .xctrunner bundle, which is a special application type\nthat contains tests (also it has some higher privileges in comparison to vanilla apps).\nWebDriverAgent project itself consists of three main parts:\n\n- Vendor Libs\n- WebDriverAgentLib\n- WebDriverAgentRunner","metadata":{"loc":{"lines":{"from":28,"to":41}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-slowness.md","filename":"wda-slowness.md","relativePath":"appium-xcuitest-driver/guides/wda-slowness.md"}},{"pageContent":"- Vendor Libs\n- WebDriverAgentLib\n- WebDriverAgentRunner\n\nVendor libs, like RoutingHTTPServer, ensure the support for low-level HTTP- and TCP-server APIs.\nWebDriverAgentLib defines handlers for [W3C WebDriver](https://www.w3.org/TR/webdriver/) endpoints\nand implements all the heavy-lifting procedures related to Apple's XCTest communication\nand some more custom stuff specific for the XCUITest driver.\nWebDriverAgentRunner is actually one long test, whose main purpose\nis to run the HTTP server implemented by the WebDriverAgentLib.\n\nImportant conclusions from the above information:\n\n- WDA is an HTTP server, which executes API commands by invoking HTTP response handlers\n- WDA uses Apple's XCTest APIs with various custom additions\n\n## How to confirm my script's bottleneck is WDA","metadata":{"loc":{"lines":{"from":39,"to":55}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-slowness.md","filename":"wda-slowness.md","relativePath":"appium-xcuitest-driver/guides/wda-slowness.md"}},{"pageContent":"- WDA is an HTTP server, which executes API commands by invoking HTTP response handlers\n- WDA uses Apple's XCTest APIs with various custom additions\n\n## How to confirm my script's bottleneck is WDA\n\nCheck the server logs in order to verify how long it takes for the XCUITest driver to receive a\nresponse from WDA. The log line that is written before an HTTP request is proxied to WDA looks\nlike `Proxying [X] to [Y]`. Also consider enabling server timestamps by providing the\n`--log-timestamp` command line parameter. If you observe timestamps between the above log line and the\nnext one differ too much and the difference is an anomaly (e.g. the same step is (much) faster\nfor other apps/environments/parameter combinations) then it might serve as a confirmation of a\nsuspicious slowness.\n\n## Patterns lookup","metadata":{"loc":{"lines":{"from":52,"to":65}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-slowness.md","filename":"wda-slowness.md","relativePath":"appium-xcuitest-driver/guides/wda-slowness.md"}},{"pageContent":"## Patterns lookup\n\nAfter the slowness is confirmed it is important to determine behavior patterns, e.g. under which\ncircumstances does it happen, if it is always reproducible, etc. This article only targets specific\npatterns that the author knows of or dealt with. If your pattern is not present here then try to\nlook for possible occurrences in existing [issues](https://github.com/appium/appium/issues),\n[Appium forum](https://discuss.appium.io) or just search the internet.\n\n## Pattern: Application startup is slow\n\n### Symptoms\n\nYou observe timeouts or unusual slowness (in comparison to manual execution performance)\nof the application startup on session init (if it also includes app startup)\nor mid-session app startup.\n\n### Causes","metadata":{"loc":{"lines":{"from":65,"to":81}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-slowness.md","filename":"wda-slowness.md","relativePath":"appium-xcuitest-driver/guides/wda-slowness.md"}},{"pageContent":"### Causes\n\nWhen XCTest starts an app it ensures the accessibility layer of it is ready for interactions.\nTo check that the framework verifies the application is idling (e.g. does not perform any actions\non the main thread) as well as all animations have been finished. If this check times out\nan exception is thrown or WDA may try to continue without any guarantees the app could be\ninteracted with (a.k.a. best effort strategy).\n\n### Solutions\n\nI was observing applications that were constantly running something on the main thread in an endless loop.\nMost likely such apps are not automatable at all or hardly automatable without fixing the app\nsource code itself.\nYou may still try to tune the following capabilities and settings to influence the above timeout:\n\n- [appium:waitForIdleTimeout](../reference/capabilities.md)\n- [waitForIdleTimeout](../reference/settings.md)\n- [animationCoolOffTimeout](../reference/settings.md)\n\n## Pattern: Element location with XPath is slow\n\n### Symptoms","metadata":{"loc":{"lines":{"from":81,"to":102}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-slowness.md","filename":"wda-slowness.md","relativePath":"appium-xcuitest-driver/guides/wda-slowness.md"}},{"pageContent":"## Pattern: Element location with XPath is slow\n\n### Symptoms\n\nYou observe timeouts or unusual slowness (in comparison to other location strategies)\nof XPath locators.\n\n### Causes","metadata":{"loc":{"lines":{"from":100,"to":107}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-slowness.md","filename":"wda-slowness.md","relativePath":"appium-xcuitest-driver/guides/wda-slowness.md"}},{"pageContent":"You observe timeouts or unusual slowness (in comparison to other location strategies)\nof XPath locators.\n\n### Causes\n\nThe [XPath](../reference/locator-strategies.md) location strategy\nis not natively supported by XCTest. It's a custom addition\nwhich is only available in WDA. Such locators have more features than others, but the price\nfor it is the observed slowness as we cannot rely on native XCTest location APIs\nwhile looking for elements using XPath.\nIn order to perform XPath lookup WDA needs to take a snapshot of the whole accessibility\nhierarchy with all element attributes resolved, which is a time-expensive operation.\nLocation slowness might be observed if:\n- The current app hierarchy is too large (e.g. has hundreds of elements). This is a known\n XCTest limitation.\n- The app is not idling/has active animations\n- It takes too long to determine each element's `visible` or `accessible` attributes, which are custom\n ones and are not present in the original XCTest implementation","metadata":{"loc":{"lines":{"from":104,"to":121}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-slowness.md","filename":"wda-slowness.md","relativePath":"appium-xcuitest-driver/guides/wda-slowness.md"}},{"pageContent":"### Solutions","metadata":{"loc":{"lines":{"from":123,"to":123}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-slowness.md","filename":"wda-slowness.md","relativePath":"appium-xcuitest-driver/guides/wda-slowness.md"}},{"pageContent":"Depending on the actual cause there might be different applicable solutions. In general, the common\nadvice would be to avoid XPath locators where possible and use locators that are natively\nsupported by XCTest (like predicates or ids) and have better speed ranking.\nIf the usage of an XPath locators is a single available option then you may try to apply the following\nsuggestions:\n- Reduce the size of the app hierarchy using the [snapshotMaxDepth setting](../reference/settings.md).\n This might not help if the destination element is deeply nested -\n it won't be found if the value of this setting is lower than its nesting level.\n- Exclude the `visible` and/or `accessible` attributes from your query. These are\n custom attributes exclusive to WDA and their calculation is expensive in comparison\n to other native attributes.\n- Reduce various timeouts similarly to how it's advised in the\n [Application startup is slow](#pattern-application-startup-is-slow) pattern","metadata":{"loc":{"lines":{"from":125,"to":137}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-slowness.md","filename":"wda-slowness.md","relativePath":"appium-xcuitest-driver/guides/wda-slowness.md"}},{"pageContent":"to other native attributes.\n- Reduce various timeouts similarly to how it's advised in the\n [Application startup is slow](#pattern-application-startup-is-slow) pattern\n- Fix the source code of the application under test to reduce the amount of accessible elements\n on a single screen\n- Fix the source code of the application under test to avoid running long operations\n or animations on the main thread","metadata":{"loc":{"lines":{"from":135,"to":141}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-slowness.md","filename":"wda-slowness.md","relativePath":"appium-xcuitest-driver/guides/wda-slowness.md"}},{"pageContent":"## Pattern: Element location with non-XPath is slow\n\n### Symptoms\n\nYou observe timeouts or unusual slowness with various non-XPath locators.\n\n### Causes\n\nLocation slowness might be observed if:\n- The current app hierarchy is too large (e.g. has hundreds of elements). This is a known\n XCTest limitation.\n- The app is not idling/has active animations\n- It takes too long to determine each element's `visible` or `accessible` attributes, which are custom\n ones and are not present in the original XCTest implementation (only applicable to predicate and class chain locators)\n\n### Solutions","metadata":{"loc":{"lines":{"from":143,"to":158}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-slowness.md","filename":"wda-slowness.md","relativePath":"appium-xcuitest-driver/guides/wda-slowness.md"}},{"pageContent":"### Solutions\n\n- Reduce the size of the app hierarchy using the [snapshotMaxDepth setting](../reference/settings.md).\n This might not help if the destination element is deeply nested -\n it won't be found if the value of this setting is lower than its nesting level.\n- Exclude the `visible` and/or `accessible` attributes from your query\n (only applicable to predicate and class chain locators). These are\n custom attributes exclusive to WDA and their calculation is expensive in comparison\n to other native attributes.\n- Reduce various timeouts similarly to how it's advised in the\n [Application startup is slow](#pattern-application-startup-is-slow) pattern\n- Fix the source code of the application under test to reduce the amount of accessible elements\n on a single screen\n- Fix the source code of the application under test to avoid running long operations\n or animations on the main thread\n\n## Pattern: Various element interactions are slow\n\n### Symptoms","metadata":{"loc":{"lines":{"from":158,"to":176}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-slowness.md","filename":"wda-slowness.md","relativePath":"appium-xcuitest-driver/guides/wda-slowness.md"}},{"pageContent":"## Pattern: Various element interactions are slow\n\n### Symptoms\n\nYou observe timeouts or unusual slowness while clicking elements or performing other\nactions on them.\n\n### Causes\n\n- The current app hierarchy is too large (e.g. has hundreds of elements). This is a known\n XCTest limitation.\n- The app is not idling/has active animations\n\n### Solutions\n\n- Reduce various timeouts similarly to how it's advised in the\n [Application startup is slow](#pattern-application-startup-is-slow) pattern\n- Fix the source code of the application under test to reduce the amount of accessible elements\n on a single screen\n- Fix the source code of the application under test to avoid running long operations\n or animations on the main thread\n\n## Pattern: Page source retrieval slow\n\n### Symptoms\n\nYou observe timeouts or unusual slowness while retrieving the page of the app.\n\n### Causes","metadata":{"loc":{"lines":{"from":174,"to":202}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-slowness.md","filename":"wda-slowness.md","relativePath":"appium-xcuitest-driver/guides/wda-slowness.md"}},{"pageContent":"## Pattern: Page source retrieval slow\n\n### Symptoms\n\nYou observe timeouts or unusual slowness while retrieving the page of the app.\n\n### Causes\n\nIn order to retrieve the page source WDA needs to take a snapshot of the whole accessibility\nhierarchy with all element attributes resolved, which is a time-expensive operation.\nPage source retrieval slowness might be observed if:\n- The current app hierarchy is too large (e.g. has hundreds of elements). This is a known\n XCTest limitation.\n- The app is not idling/has active animations\n- It takes too long to determine each element's `visible` or `accessible` attributes, which are custom\n ones and are not present in the original XCTest implementation\n\n### Solutions","metadata":{"loc":{"lines":{"from":196,"to":213}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-slowness.md","filename":"wda-slowness.md","relativePath":"appium-xcuitest-driver/guides/wda-slowness.md"}},{"pageContent":"- Reduce the size of the app hierarchy using the [snapshotMaxDepth setting](../reference/settings.md).\n Note that you won't see nested elements in the source tree whose nesting level is greater than\n the given size.\n- Retrieve the page source without \"expensive\" attributes using the\n [mobile: source](../reference/execute-methods.md#mobile-source) method with\n the appropriate `excludedAttributes` argument value or add such attribute names into\n the [pageSourceExcludedAttributes setting](../reference/settings.md).\n- Retrieve the native XCTest page source using the\n [mobile: source](../reference/execute-methods.md#mobile-source) method with\n the `format=description` argument value. The returned page source is a poorly-formatted text,\n although its retrieval should be fast (at least not slower than XCTest does that).\n- Reduce various timeouts similarly to how it's advised in the\n [Application startup is slow](#pattern-application-startup-is-slow) pattern","metadata":{"loc":{"lines":{"from":215,"to":227}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-slowness.md","filename":"wda-slowness.md","relativePath":"appium-xcuitest-driver/guides/wda-slowness.md"}},{"pageContent":"- Reduce various timeouts similarly to how it's advised in the\n [Application startup is slow](#pattern-application-startup-is-slow) pattern\n- Fix the source code of the application under test to reduce the amount of accessible elements\n on a single screen\n- Fix the source code of the application under test to avoid running long operations\n or animations on the main thread","metadata":{"loc":{"lines":{"from":226,"to":231}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/guides/wda-slowness.md","filename":"wda-slowness.md","relativePath":"appium-xcuitest-driver/guides/wda-slowness.md"}},{"pageContent":"---\nhide:\n - navigation\n - toc\n\ntitle: Welcome\n---\n<style>\n .md-typeset h1 {\n display: none;\n }\n</style>\n\n<div style=\"text-align: center\">\n <img src=\"assets/images/appium-plus-xctest.png\" style=\"max-width: 500px;\" />\n</div>\n\nWelcome to the Appium XCUITest Driver documentation! The XCUITest driver is a test automation\nframework for iOS, iPadOS and tvOS devices, enabling automated black-box testing of native, hybrid\nand WebKit web apps, on both emulators and real devices. \n\nThe XCUITest driver is part of the Appium test automation tool. For information on Appium itself,\nplease visit [the Appium documentation](https://appium.io).\n\n## Explore the Documentation\n\n<div class=\"grid cards\" markdown>","metadata":{"loc":{"lines":{"from":1,"to":27}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/index.md","filename":"index.md","relativePath":"appium-xcuitest-driver/index.md"}},{"pageContent":"## Explore the Documentation\n\n<div class=\"grid cards\" markdown>\n\n- Check out the [__Overview__](./overview.md) to learn how the driver works\n- Go through the [__Installation__](./installation/index.md) steps to get set up\n- Follow the [__Device Preparation__](./preparation/index.md) instructions to configure your test device\n- Browse the [__Reference__](./reference/scripts.md) documentation for everything exposed by the driver\n- Read the different [__Guides__](./guides/parallel-tests.md) for a variety of instructions, tips and tricks\n- For contributions to the driver, refer to the [__Contributing__](./contributing.md) page\n\n</div>","metadata":{"loc":{"lines":{"from":25,"to":36}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/index.md","filename":"index.md","relativePath":"appium-xcuitest-driver/index.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Installation\n---\n\n!!! info\n\n Before installing, make sure to check the [System Requirements](./requirements.md).\n\nUse the Appium [extension CLI](https://appium.io/docs/en/latest/cli/extensions/) to\nadd this driver to your Appium install:\n\n```bash\nappium driver install xcuitest\n```\n\nAlternatively, if you are running a Node.js project, you can include `appium-xcuitest-driver` as\none of your dependencies.\n\nTo activate the driver, simply launch the Appium server. By default, Appium will load all the\ninstalled drivers:\n\n```bash\nappium\n```\n\nYou should see some output that includes a line like this:\n\n```\n[Appium] XCUITestDriver has been successfully loaded in 0.789s\n```\n\nOnce you have installed the driver and confirmed it works, you should continue with\n[device preparation](../preparation/index.md).","metadata":{"loc":{"lines":{"from":1,"to":36}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/installation/index.md","filename":"index.md","relativePath":"appium-xcuitest-driver/installation/index.md"}},{"pageContent":"---\ntitle: System Requirements\n---\n\n## Main Dependencies\n\nLike all Appium drivers, the XCUITest driver requires Appium to be installed. Refer to the\n[Appium documentation](https://appium.io/docs/en/latest/quickstart/install/) for its requirements\nand prerequisites.\n\n!!! note\n\n Since version 4.0.0, the XCUITest driver has dropped support for Appium 1, and is only compatible\n with Appium 2.\n\nIn addition to Appium system requirements, the XCUITest driver expects the following prerequisites:","metadata":{"loc":{"lines":{"from":1,"to":16}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/installation/requirements.md","filename":"requirements.md","relativePath":"appium-xcuitest-driver/installation/requirements.md"}},{"pageContent":"In addition to Appium system requirements, the XCUITest driver expects the following prerequisites:\n\n- Only macOS is supported as the host platform\n- Xcode and Xcode Developer Tools must be installed\n - The Appium team usually needs some time to add support for the most recent Xcode/iOS versions,\n especially beta versions (check the [Xcode/iOS version support](#xcodeios-version-support) section)\n- If automating real devices, additional manual configuration is required. Please check the\n [Real Device Configuration](../preparation/real-device-config.md) document for more details.\n- Webviews must be debuggable in order to test them. If it is not possible to connect to your\n webview(s) using [Safari remote debugger](https://appletoolbox.com/use-web-inspector-debug-mobile-safari/),\n then the driver will not be able to identify them.\n\n## Optional Dependencies","metadata":{"loc":{"lines":{"from":16,"to":28}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/installation/requirements.md","filename":"requirements.md","relativePath":"appium-xcuitest-driver/installation/requirements.md"}},{"pageContent":"## Optional Dependencies\n\n- [`xcpretty`](https://github.com/supermarin/xcpretty) can be used to make Xcode output easier to\n read. It can be installed by running `gem install xcpretty`.\n- [`ffmpeg`](https://ffmpeg.org/) is used for test video recording. It can be installed using\n [`brew`](https://brew.sh/): `brew install ffmpeg`\n- [`idb`](https://github.com/facebook/idb), [`go-ios`](https://github.com/danielpaulus/go-ios) and\n [`tidevice`](https://github.com/alibaba/taobao-iphone-device) can be used to improve device interactions\n- [WIX AppleSimulatorUtils](https://github.com/wix/AppleSimulatorUtils) can be used to improve some\n Simulator interactions\n- [`py-ios-device`](https://github.com/YueChen-C/py-ios-device) is required in several `mobile:`\n extensions, and can improve the general testing experience for real devices\n\n## Validate Dependencies Using Doctor","metadata":{"loc":{"lines":{"from":28,"to":41}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/installation/requirements.md","filename":"requirements.md","relativePath":"appium-xcuitest-driver/installation/requirements.md"}},{"pageContent":"## Validate Dependencies Using Doctor\n\nSince driver version 5.13.0, you can automate the validation for the most of the above requirements\nas well as various optional ones needed by driver extensions by running the\n`appium driver doctor xcuitest` command.\n\n## Xcode/iOS Version Support\n\nThe XCUITest driver functionality [relies on the XCTest framework](../overview.md), and changes in\nthe XCTest API are published in new Xcode and iOS versions. Many major and even some minor Xcode/iOS\nversions include breaking changes in this API, which require updating the driver code. Similarly,\nmaintaining compatibility with older Xcode/iOS versions often requires workarounds, which are\neventually dropped in order to simplify the code and use newer XCTest features.\n\nGenerally, the driver aims to support at least _two_ latest major Xcode and iOS versions.\n\nThe following table lists the minimum driver versions required for specific Xcode/iOS versions:","metadata":{"loc":{"lines":{"from":41,"to":57}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/installation/requirements.md","filename":"requirements.md","relativePath":"appium-xcuitest-driver/installation/requirements.md"}},{"pageContent":"Generally, the driver aims to support at least _two_ latest major Xcode and iOS versions.\n\nThe following table lists the minimum driver versions required for specific Xcode/iOS versions:\n\n| Xcode/iOS version | Minimum required XCUITest driver version |\n| --- | --- |\n| Xcode 13 / iOS 15 | 3.48.0 |\n| Xcode 14-beta.3 / iOS 16 Beta | 4.7.4 |\n| Xcode 14.3 / iOS 16.4 | 4.21.7 |\n| Xcode 15 / iOS 17 | 4.35.0 |\n| Xcode 16-beta.5 / iOS 18 | 7.24.15 |\n\nThe following table lists the last driver versions that are compatible with older Xcode versions:\n\n| Xcode version | Last supported XCUITest driver version |\n| --- | --- |\n| Xcode 8 | 2.95.0 |\n| Xcode 9 | 2.133.1 |\n| Xcode 10-10.1 | 3.31.1 |\n| Xcode 10.2 | 3.56.3 |\n| Xcode 11 | 4.3.2 |\n| Xcode 12 | 4.27.2 |\n\nThe following table lists the last driver versions that are compatible with older iOS versions:\n\n| iOS version | Last supported XCUITest driver version |\n| --- | --- |\n| iOS < 15 | 4.27.2 |","metadata":{"loc":{"lines":{"from":55,"to":82}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/installation/requirements.md","filename":"requirements.md","relativePath":"appium-xcuitest-driver/installation/requirements.md"}},{"pageContent":"---\nhide:\n - navigation\n - toc\n\ntitle: Overview\n---\n\nThe XCUITest driver combines several different technologies to achieve its functionality:","metadata":{"loc":{"lines":{"from":1,"to":9}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/overview.md","filename":"overview.md","relativePath":"appium-xcuitest-driver/overview.md"}},{"pageContent":"- Native testing is based on Apple's [XCTest](https://developer.apple.com/documentation/xctest) framework\n and Appium's fork of Facebook's [WebDriverAgent](https://github.com/appium/WebDriverAgent) server\n (the [original](https://github.com/facebookarchive/WebDriverAgent) project is not supported anymore)\n - In native mode, the driver operates in scope of [WebDriver W3C protocol](https://w3c.github.io/webdriver)\n with several platform-specific extensions\n- Webview communication is done via [Webkit remote debugger protocol](https://github.com/appium/appium-remote-debugger)\n - In webview mode, the driver can only operate in scope of the obsolete [JSONWP protocol](https://webdriver.io/docs/api/jsonwp.html)\n- Real device communication is provided by the [`appium-ios-device`](https://github.com/appium/appium-ios-device) library\n- Simulator communication is provided by the [`appium-ios-simulator`](https://github.com/appium/appium-ios-simulator) library","metadata":{"loc":{"lines":{"from":11,"to":19}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/overview.md","filename":"overview.md","relativePath":"appium-xcuitest-driver/overview.md"}},{"pageContent":"---\ntitle: Device Preparation\n---\n\nBefore using the XCUITest driver with a simulator or real device, some device preparation is required.\n\n## Automatic Adjustments\n\nThe XCUITest driver automatically adjusts some device preferences for testing purposes.\n\n### Keyboard Configuration\n\nSome keyboard preferences are changed in order to make test runs more stable. You can change some\nof them via the [Settings API](https://appium.io/docs/en/latest/guides/settings/).\n\n- _Settings -> General -> Keyboard -> Auto-Correction_ is turned OFF\n- _Settings -> General -> Keyboard -> Predictive Text_ is turned OFF\n- The keyboard tutorial is marked as complete\n- (Simulator Only) Software keyboard is turned ON\n\n## Manual Adjustments\n\nUnfortunately, not all configuration can be done automatically, and some changes must be applied manually.\n\n### Accessibility Settings","metadata":{"loc":{"lines":{"from":1,"to":25}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/index.md","filename":"index.md","relativePath":"appium-xcuitest-driver/preparation/index.md"}},{"pageContent":"## Manual Adjustments\n\nUnfortunately, not all configuration can be done automatically, and some changes must be applied manually.\n\n### Accessibility Settings\n\n- To avoid miscalculation of element coordinates, please make sure the zoom preference is turned off\n in _Settings -> Accessibility -> Zoom_.\n- Some accessibility settings may expose additional view elements. Appium does not modify these\n settings automatically, since they could affect the way your application under test performs.\n Please change them manually if needed. Note that the available accessibility content depends on\n the OS version.\n - _Settings -> Accessibility -> Spoken Content -> Speak Selection_\n\n### Webview Testing","metadata":{"loc":{"lines":{"from":21,"to":35}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/index.md","filename":"index.md","relativePath":"appium-xcuitest-driver/preparation/index.md"}},{"pageContent":"- Webviews on iOS/iPadOS 16.4 or above may require additional configuration from the application developer.\n Specifically, the destination `WKWebView` and/or `JSContext` component must have the\n [`isInspectable`](https://developer.apple.com/documentation/webkit/wkwebview/4111163-isinspectable)\n property set to `true`. Please read [the WebKit documentation page](https://webkit.org/blog/13936/enabling-the-inspection-of-web-content-in-apps/)\n for more details on this property.\n - WebViews on iOS/iPadOS below version 16.4 must have the [`get-task-allow` entitlement](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_debugger) present as `true` in the application manifest.\n- Starting from iOS/iPadOS 16.4, the Google Chrome browser also supports webview testing. This feature\n requires Chrome version 115 or newer. Please read\n [the Chrome Developer documentation page](https://developer.chrome.com/blog/debugging-chrome-on-ios/)","metadata":{"loc":{"lines":{"from":37,"to":45}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/index.md","filename":"index.md","relativePath":"appium-xcuitest-driver/preparation/index.md"}},{"pageContent":"requires Chrome version 115 or newer. Please read\n [the Chrome Developer documentation page](https://developer.chrome.com/blog/debugging-chrome-on-ios/)\n for details on the necessary configuration.","metadata":{"loc":{"lines":{"from":44,"to":46}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/index.md","filename":"index.md","relativePath":"appium-xcuitest-driver/preparation/index.md"}},{"pageContent":"### Real Devices\n\nSome settings are enabled by default on simulators, but need to be manually changed for real devices.\nSee the [Real Device Configuration](./real-device-config.md) document for details.","metadata":{"loc":{"lines":{"from":48,"to":51}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/index.md","filename":"index.md","relativePath":"appium-xcuitest-driver/preparation/index.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Basic Automatic Configuration\n---\n\nIf you have a paid Apple Developer account, the easiest way to create the provisioning profile is\nto use the automatic configuration strategy. There are two ways to do this:\n\n* Use the `xcodeOrgId` and `xcodeSigningId` [capabilities](../reference/capabilities.md):\n ```json\n {\n \"appium:xcodeOrgId\": \"<Team ID>\",\n \"appium:xcodeSigningId\": \"Apple Developer\",\n \"appium:updatedWDABundleId\": \"<bundle id your provisioning profile can accept>\"\n }\n ```\n* Create a `.xcconfig` file somewhere on your file system and add the following to it:\n ```ini\n DEVELOPMENT_TEAM = <Team ID>\n CODE_SIGN_IDENTITY = Apple Developer\n ```\n Then use the `xcodeConfigFile` capability to specify the path to this file:\n ```json\n {\n \"appium:xcodeConfigFile\": \"/path/to/xcconfig/file\"\n }\n ```","metadata":{"loc":{"lines":{"from":1,"to":29}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/prov-profile-basic-auto.md","filename":"prov-profile-basic-auto.md","relativePath":"appium-xcuitest-driver/preparation/prov-profile-basic-auto.md"}},{"pageContent":"Note that these are mutually exclusive strategies; use _either_ the `appium:xcodeConfigFile` capability\n_or_ the combination of `appium:xcodeOrgId` and `appium:xcodeSigningId`.","metadata":{"loc":{"lines":{"from":31,"to":32}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/prov-profile-basic-auto.md","filename":"prov-profile-basic-auto.md","relativePath":"appium-xcuitest-driver/preparation/prov-profile-basic-auto.md"}},{"pageContent":"* `appium:xcodeOrgId` / `DEVELOPMENT_TEAM` is a unique 10-character string generated by Apple that is\n assigned to your team.\n * To find this string (your Team ID), sign in to [developer.apple.com/account](https://developer.apple.com/account),\n and click Membership in the sidebar. Your Team ID appears in the Membership Information\n section under the team name. You can also find your Team ID listed under the \"Organizational\n Unit\" field in your iPhone Developer certificate in your keychain.\n* `appium:xcodeSigningId` / `CODE_SIGN_IDENTITY` is usually either `Apple Developer` or `iPhone Developer`.\n* `appium:updatedWDABundleId` is the bundle id you would like to use for the built WebDriverAgent.\n * Appium replaces the existing placeholder of `com.facebook.WebDriverAgentRunner` in `WebDriverAgent.xcodeproj` with the given capability value.","metadata":{"loc":{"lines":{"from":34,"to":42}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/prov-profile-basic-auto.md","filename":"prov-profile-basic-auto.md","relativePath":"appium-xcuitest-driver/preparation/prov-profile-basic-auto.md"}},{"pageContent":"* Appium replaces the existing placeholder of `com.facebook.WebDriverAgentRunner` in `WebDriverAgent.xcodeproj` with the given capability value.\n * `xcodebuild` adds `.xctrunner` automatically for XCTest package. Thus, the provisioning profile you're using should have the suffix explicitly, or it can be for bundle id which has `*`.\n * For instance, when the `appium:updatedWDABundleId` is `io.appium.WebDriverAgentRunner`, the given provisioning profile should be for `io.appium.WebDriverAgentRunner.xctrunner`, `io.appium.WebDriverAgentRunner.*` or `*`.\n * `appium:allowProvisioningDeviceRegistration` lets XCUITest driver set `-allowProvisioningUpdates` and `-allowProvisioningDeviceRegistration` flags for the `xcodebuild` command. They will help register the target device to the matched provisioning profile if it still doesn't have the device. Please check `man xcodebuild` output for more details.","metadata":{"loc":{"lines":{"from":42,"to":45}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/prov-profile-basic-auto.md","filename":"prov-profile-basic-auto.md","relativePath":"appium-xcuitest-driver/preparation/prov-profile-basic-auto.md"}},{"pageContent":"Once this configuration is done, you should specify your real device UDID with the `udid` desired\ncapability, after which you should be able to start your test. Proceed with\n[Validating the WDA Install](./real-device-config.md#validating-the-wda-install) for the next steps.","metadata":{"loc":{"lines":{"from":47,"to":49}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/prov-profile-basic-auto.md","filename":"prov-profile-basic-auto.md","relativePath":"appium-xcuitest-driver/preparation/prov-profile-basic-auto.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Basic Manual Configuration\n---\n\nThere are many cases in which the basic automatic configuration is not enough. Often this happens\nwhen the development account being used is a \"Free\" one, in which case it is not possible to create\na wildcard provisioning profile.\n\nYou can confirm this by opening the WDA project in Xcode. The issue will manifest as something like\nan error that Xcode failed to create provisioning profile:\n\n![No provisioning profile](./assets/images/no-prov-prof.png)\n\nThe easiest way around this is to create a new project:\n\n![Create new project](./assets/images/create-new-project.png)\n\nThe type does not matter, other than it being \"iOS\". \"Single View Application\" is the easiest:\n\n![Create single page](./assets/images/create-single-page.png)\n\nThe important part is to use a unique \"Product Name\" and \"Organization Name\". Also, at this point,\nspecify your \"Team\".\n\n![Setup bundle](./assets/images/set-up-bundle.png)","metadata":{"loc":{"lines":{"from":1,"to":28}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/prov-profile-basic-manual.md","filename":"prov-profile-basic-manual.md","relativePath":"appium-xcuitest-driver/preparation/prov-profile-basic-manual.md"}},{"pageContent":"The important part is to use a unique \"Product Name\" and \"Organization Name\". Also, at this point,\nspecify your \"Team\".\n\n![Setup bundle](./assets/images/set-up-bundle.png)\n\nYou can confirm that the provisioning profile was created by looking at the \"Project\" tab:\n\n![Project pane](./assets/images/project-prov-prof.png)\n\nOr by going into your account preferences and seeing the provisioning profile:\n\n![Check provisioning profile](./assets/images/check-prov-prof.png)\n\nAt this point you have a valid provisioning profile. Make note of the bundle identifier\nyou associated with it, and add that in the `updatedWDABundleId` capability for your tests.\nThen follow the [initial instructions for automatic configuration](./prov-profile-basic-auto.md).","metadata":{"loc":{"lines":{"from":25,"to":40}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/prov-profile-basic-manual.md","filename":"prov-profile-basic-manual.md","relativePath":"appium-xcuitest-driver/preparation/prov-profile-basic-manual.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Full Manual Configuration\n---\n\nThe provisioning profile can also be manually associated with the WDA project. Keep in mind that\nthis will have to be done each time WDA is updated (such as when updating the XCUITest driver),\nand is _not_ recommended:\n\n* In the terminal, open the directory where WDA is located. Run the following to set the project up:\n ```bash\n mkdir -p Resources/WebDriverAgent.bundle\n ```\n* Open `WebDriverAgent.xcodeproj` in Xcode. This will likely open a screen with an empty editor.\n* In the file browser on the left side, select the root _WebDriverAgent_ project, which will open\n it in the editor. Then, under _Targets_, select _WebDriverAgentRunner_ (or\n _WebDriverAgentRunner\\_tvOS_ for tvOS), and switch to the _Signing & Capabilities_ tab.\n* Check _Automatically manage signing_, and then select your _Team_ (you may need to first sign\n into Xcode). The outcome should be similar to the following:","metadata":{"loc":{"lines":{"from":1,"to":21}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/prov-profile-full-manual.md","filename":"prov-profile-full-manual.md","relativePath":"appium-xcuitest-driver/preparation/prov-profile-full-manual.md"}},{"pageContent":"![WebDriverAgent in Xcode project](./assets/images/xcode-config.png)\n\n* Xcode will likely fail to create a provisioning profile due to an invalid bundle identifier:\n\n ![Xcode provisioning fail](./assets/images/xcode-facebook-fail.png)\n\n* Change the _Bundle Identifier_ from `com.facebook.WebDriverAgentRunner` to something that Xcode\n will accept. You can also do this in the _Build Settings_ tab:\n\n ![Xcode bundle id](./assets/images/xcode-bundle-id.png)\n \n!!! note\n\n Versions of Xcode older than 11 have a different naming convention. This feature may not work\n for a package which is built by Xcode versions below 12.\n\n* If your bundle identifier is accepted, you should see that Xcode has created a provisioning\n profile and all is well:\n\n ![Xcode provisioning profile](./assets/images/xcode-facebook-succeed.png)","metadata":{"loc":{"lines":{"from":23,"to":42}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/prov-profile-full-manual.md","filename":"prov-profile-full-manual.md","relativePath":"appium-xcuitest-driver/preparation/prov-profile-full-manual.md"}},{"pageContent":"![Xcode provisioning profile](./assets/images/xcode-facebook-succeed.png)\n\n* Finally, you can verify that everything works:\n * Select the scheme as _Product -> Scheme -> WebDriverAgentRunner_\n * Select your real device in _Product -> Destination_\n * Select _Product -> Test_ to build and install the WDA app\n\nProceed with [Validating the WDA Install](./real-device-config.md#validating-the-wda-install) for\nthe next steps!","metadata":{"loc":{"lines":{"from":42,"to":50}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/prov-profile-full-manual.md","filename":"prov-profile-full-manual.md","relativePath":"appium-xcuitest-driver/preparation/prov-profile-full-manual.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Manual Configuration for a Generic Device\n---\n\nIt is possible to build `WebDriverAgentRunner` for a generic iOS/iPadOS/tvOS device, and install the\ngenerated `.app` package to a real device.\n\n```bash\n# iOS/iPadOS\n$ xcodebuild clean build-for-testing -project WebDriverAgent.xcodeproj -derivedDataPath appium_wda_ios -scheme WebDriverAgentRunner -destination generic/platform=iOS CODE_SIGNING_ALLOWED=YES\n\n# tvOS\n$ xcodebuild clean build-for-testing -project WebDriverAgent.xcodeproj -derivedDataPath appium_wda_tvos -scheme WebDriverAgentRunner_tvOS -destination generic/platform=tvOS CODE_SIGNING_ALLOWED=YES\n```\n\nOn successful completion the resulting package `WebDriverAgentRunner-Runner.app` should be located\nin the `Build/Products/Debug-iphoneos/` subfolder under WebDriverAgent sources root, or in the path\nprovided as `derivedDataPath` argument.\n\n!!! note","metadata":{"loc":{"lines":{"from":1,"to":23}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/prov-profile-generic-manual.md","filename":"prov-profile-generic-manual.md","relativePath":"appium-xcuitest-driver/preparation/prov-profile-generic-manual.md"}},{"pageContent":"!!! note\n\n If the build fails, please make sure `WebDriverAgent.xcodeproj` has codesigning properties\n configured properly. For example, you may need to change the bundle id for the provisioning profile.\n\nThe `WebDriverAgentRunner-Runner.app` can now be installed to any real device as allowed by the\nprovisioning profile.\n\nYou can install the package with 3rd party tools and manage it separately as explained in\n[How To Set Up And Customize WebDriverAgent Server](../guides/wda-custom-server.md). Note that if\nthe codesigning was not correct, the installation will fail.\n\nAs a more advanced method, you can generate the package with `CODE_SIGNING_ALLOWED=NO` and do\n[`codesign`](https://developer.apple.com/documentation/xcode/using-the-latest-code-signature-format)\nby yourself. This would make the device management more flexible, but you would need to know about\nadvanced codesign usage scenarios.\n\n!!! note","metadata":{"loc":{"lines":{"from":23,"to":40}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/prov-profile-generic-manual.md","filename":"prov-profile-generic-manual.md","relativePath":"appium-xcuitest-driver/preparation/prov-profile-generic-manual.md"}},{"pageContent":"!!! note\n\n The Appium team distributes generic builds with `CODE_SIGNING_ALLOWED=NO` at\n [WebDriverAgent package releases](https://github.com/appium/WebDriverAgent/releases).\n It is recommended to sign packages with a wildcard (`*`) provisioning profile,\n although such profiles require a paid Apple Developer account.\n For example, if you're preparing such a provisioning profile for `io.appium.WebDriverAgentRunner.xctrunner`, it will be for `io.appium.*`, `io.appium.WebDriverAgentRunner.*` or `*`.\n In case of a free account, you may need to update the bundle id before building\n the WebDriverAgent package to prepare a properly signed WebDriverAgent package\n by `xcodebuild`.","metadata":{"loc":{"lines":{"from":40,"to":49}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/prov-profile-generic-manual.md","filename":"prov-profile-generic-manual.md","relativePath":"appium-xcuitest-driver/preparation/prov-profile-generic-manual.md"}},{"pageContent":"---\ntitle: Real Device Configuration\n---\n\nIn order to communicate with the device under test, the XCUITest driver automatically installs the\n`WebDriverAgentRunner-Runner` (WDA) application on it, using Xcode's command-line utility `xcodebuild`.\nUnlike simulators, real devices have several security restrictions that need to be manually\nconfigured, before this can work:","metadata":{"loc":{"lines":{"from":1,"to":8}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/real-device-config.md","filename":"real-device-config.md","relativePath":"appium-xcuitest-driver/preparation/real-device-config.md"}},{"pageContent":"- Devices need to be trusted. This can be done by opening Xcode and afterwards physically connecting\n the device under test to the computer. The device should have a popup asking to trust the computer,\n which you should accept.\n- Devices using iOS/iPadOS 16 or above require enabling Developer Mode. Please read\n [Apple's documentation on Developer Mode](https://developer.apple.com/documentation/xcode/enabling-developer-mode-on-a-device)\n for more details. `devmodectl streaming` CLI on macOS 13+ and installing development signed apps\n also help enabling the mode.\n- After enabling Developer Mode (if applicable), please turn on _Settings -> Developer -> Enable UI Automation_\n- Webviews will not be testable unless the Safari Inspector is enabled. Please turn it on in\n _Settings -> Safari -> Advanced -> Web Inspector_. Similarly, you may want to turn on the adjacent\n option _Settings -> Safari -> Advanced -> Remote Automation_.","metadata":{"loc":{"lines":{"from":10,"to":20}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/real-device-config.md","filename":"real-device-config.md","relativePath":"appium-xcuitest-driver/preparation/real-device-config.md"}},{"pageContent":"Finally, the WDA application must have a valid provisioning profile, which includes signing the app\nand linking it to a development team.\n\n## Provisioning Profile Setup\n\nGenerally, unless your device under test [already has WDA installed](../guides/run-preinstalled-wda.md),\nor you already have [a prebuilt WDA](../guides/run-prebuilt-wda.md) on your local system, you will\nneed an Apple ID to be able to sign the app.\n\nOnce you have an Apple ID, there are several approaches you can take.\n\n* [__Basic Automatic Configuration__](./prov-profile-basic-auto.md): the easiest approach, but\n requires you to have a paid Apple Developer account\n\nIf the automatic configuration did not work or does not apply to you, you will need to follow one of\nthe manual configuration approaches. All of these involve the WDA Xcode project, so at the very\nleast, you must know the local path to the project file - `WebDriverAgent.xcodeproj`:","metadata":{"loc":{"lines":{"from":22,"to":38}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/real-device-config.md","filename":"real-device-config.md","relativePath":"appium-xcuitest-driver/preparation/real-device-config.md"}},{"pageContent":"* The WDA project is included in `appium-webdriveragent`, which is installed as a dependency of the\n XCUITest driver. You can therefore find the project file in\n `/path/to/xcuitest/driver/node_modules/appium-webdriveragent/WebDriverAgent.xcodeproj`.\n By default, drivers are installed in `~/.appium`, so the project would be located at\n `~/.appium/node_modules/appium-xcuitest-driver/node_modules/appium-webdriveragent/WebDriverAgent.xcodeproj`.\n* If using XCUITest driver v4.13.0 or newer, you can run the `appium driver run xcuitest open-wda`\n [driver script](../reference/scripts.md) to directly open `WebDriverAgent.xcodeproj` in Xcode.\n\nThe WDA project file can now be used in the manual configuration approaches:","metadata":{"loc":{"lines":{"from":40,"to":48}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/real-device-config.md","filename":"real-device-config.md","relativePath":"appium-xcuitest-driver/preparation/real-device-config.md"}},{"pageContent":"The WDA project file can now be used in the manual configuration approaches:\n\n* [__Basic Manual Configuration__](./prov-profile-basic-manual.md): create a new project, then use\n its provisioning profile and bundle ID\n* [__Full Manual Configuration__](./prov-profile-full-manual.md): associate the provisioning profile\n directly with the WDA project\n* [__Manual Configuration for a Generic Device__](./prov-profile-generic-manual.md): manually run\n `xcodebuild` to build WDA, then manually install it\n\n### Validating the WDA Install\n\nOnce you have configured the WDA project or have the app ready, you can try installing it. It is\npossible that you may encounter some errors:\n\n* `xcodebuild exited with code '65' and signal 'null'`\n\n This usually happens when attempting the automatic configuration, and it means that the necessary\n code signing is not set up correctly. Follow the steps in any of the manual configuration\n approaches to fix this.","metadata":{"loc":{"lines":{"from":48,"to":66}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/real-device-config.md","filename":"real-device-config.md","relativePath":"appium-xcuitest-driver/preparation/real-device-config.md"}},{"pageContent":"* `Unable to launch <your-bundle-id>.WebDriverAgentRunner-Runner because it has an invalid code\n signature, inadequate entitlements or its profile has not been explicitly trusted by the user.`\n\n This means that the developer is not trusted on the device. If you manually try to open the WDA\n app on the device, you will see a popup message:\n\n ![Untrusted developer](./assets/images/untrusted-dev.png)\n\n To fix this, you need to open _Settings -> General -> VPN & Device Management_ on the device, then\n select your development team and trust it. Afterwards you should be able to open/launch the app.\n See [Apple documentation for more information](https://support.apple.com/en-us/HT204460).\n\n* For other issues, please refer to the [Troubleshooting](../guides/troubleshooting.md) page\n\n\n### Create an Offline Provisioning Profile","metadata":{"loc":{"lines":{"from":68,"to":83}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/real-device-config.md","filename":"real-device-config.md","relativePath":"appium-xcuitest-driver/preparation/real-device-config.md"}},{"pageContent":"* For other issues, please refer to the [Troubleshooting](../guides/troubleshooting.md) page\n\n\n### Create an Offline Provisioning Profile\n\nSince iOS 16, Apple requires a device to have a live internet connection for validating the code\nsigning. It is possible to set up an offline enabled provisioning profile, which allows you to avoid\nthe limitation. Please read [this issue](https://github.com/appium/appium/issues/18378#issuecomment-1482678074)\nregarding detailed configuration steps.\n\n## Tune WebDriverAgent to improve session startup performance\n\nRunning `xcodebuild` every time takes much longer time to complete a session startup.\nXCUITest driver offers a few methods to improve the performance with, or without using `xcodebuild`.\n\nSome might require deeper understanding of iOS development environment,\nbut they help to improve speedup your test execution speed.","metadata":{"loc":{"lines":{"from":80,"to":96}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/real-device-config.md","filename":"real-device-config.md","relativePath":"appium-xcuitest-driver/preparation/real-device-config.md"}},{"pageContent":"Some might require deeper understanding of iOS development environment,\nbut they help to improve speedup your test execution speed.\n\n- [Run Preinstalled WebDriverAgentRunner](./../guides/run-preinstalled-wda.md)\n- [Run Prebuilt WebDriverAgentRunner](./../guides/run-prebuilt-wda.md)\n- [Attach to a Running WebDriverAgent](./../guides/attach-to-running-wda.md)","metadata":{"loc":{"lines":{"from":95,"to":100}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/preparation/real-device-config.md","filename":"real-device-config.md","relativePath":"appium-xcuitest-driver/preparation/real-device-config.md"}},{"pageContent":"---\ntitle: BiDi Protocol Support\n---\n\nXCUITest driver has partial support of the [BiDi Protocol](https://w3c.github.io/webdriver-bidi/) since version 7.26.0.\nOnly events and commands mentioned below are supported.\nAll other entities described in the spec throw not implemented errors.\n\n# Supported Events\n\n## log.entryAdded\n\nThis event is emitted if the driver retrieves a new entry for any of the below log types. Logs collection might be disabled by the `appium:skipLogCapture` capability.\n\n### crashlog\n\nEvents are emitted for both emulator and real devices. The latter only works if [py-ios-device](https://github.com/YueChen-C/py-ios-device) is installed on the server host. Each event contains a particular device crash report entry.\nEvents are always emitted with the `NATIVE_APP` context.\n\n### syslog\n\nEvents are emitted for both emulator and real devices. Each event contains a single device system log line.\nEvents are always emitted with the `NATIVE_APP` context.\n\n### safariConsole","metadata":{"loc":{"lines":{"from":1,"to":25}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/bidi.md","filename":"bidi.md","relativePath":"appium-xcuitest-driver/reference/bidi.md"}},{"pageContent":"### syslog\n\nEvents are emitted for both emulator and real devices. Each event contains a single device system log line.\nEvents are always emitted with the `NATIVE_APP` context.\n\n### safariConsole\n\nEvents are emitted for both emulator and real devices. Each event contains a single Safari console log line.\nEvents are always emitted with the appropriate web context name from which they were generated.\nEvents are only emitted if the `appium:showSafariConsoleLog` capability value is provided.\n\n### safariNetwork\n\nEvents are emitted for both emulator and real devices. Each event contains a single Safari network log line.\nEvents are always emitted with the appropriate web context name from which they were generated.\nEvents are only emitted if the `appium:showSafariNetworkLog` capability value is provided.\n\n### performance","metadata":{"loc":{"lines":{"from":20,"to":37}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/bidi.md","filename":"bidi.md","relativePath":"appium-xcuitest-driver/reference/bidi.md"}},{"pageContent":"### performance\n\nEvents are emitted for both emulator and real devices. Each event contains a single Safari performance log line.\nEvents are always emitted with the appropriate web context name from which they were generated.\nEvents are only emitted if the `appium:enablePerformanceLogging` capability value is provided.\n\n### server\n\nEvents are emitted for both emulator and real devices. Each event contains a single Appium server log line.\nEvents are always emitted with the `NATIVE_APP` context.\nEvents are only emitted if the `get_server_logs` server security feature is enabled.\n\n## appium:xcuitest.contextUpdate\n\nThis event is emitted upon the context change, either explicit or implicit.\nThe event is always emitted upon new session initialization.\nSee the [GitHub feature ticket](https://github.com/appium/appium/issues/20741) for more details.\n\n### CDDL","metadata":{"loc":{"lines":{"from":37,"to":55}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/bidi.md","filename":"bidi.md","relativePath":"appium-xcuitest-driver/reference/bidi.md"}},{"pageContent":"### CDDL\n\n```cddl\nappium:xcuitest.contextUpdated = {\n method: \"appium:xcuitest.contextUpdated\",\n params: {\n name: text,\n type: \"NATIVE\" / \"WEB\",\n },\n}\n```\n\nThe event contains the following params:\n\n### name\n\nContains the actual name of the new context, for example `NATIVE_APP`.\n\n### type\n\nEither `NATIVE` or `WEB` depending on which context is currently active in the driver session.","metadata":{"loc":{"lines":{"from":55,"to":75}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/bidi.md","filename":"bidi.md","relativePath":"appium-xcuitest-driver/reference/bidi.md"}},{"pageContent":"---\ntitle: Capabilities\n---\n\nThis page lists various capabilities used and implemented by the XCUITest driver. To learn more\nabout capabilities, refer to the [Appium documentation](https://appium.io/docs/en/latest/guides/caps/).\n\n### General","metadata":{"loc":{"lines":{"from":1,"to":8}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"| <div style=\"width:10em\">Capability</div> | Description |\n| --- | --- |\n| `platformName` | Could be set to `ios`. Appium itself is not strict about this capability value if `automationName` is provided, so feel free to assign it to any supported platform name if this is needed, for example, to make Selenium Grid working. |\n| `browserName` | The name of the browser to run the test on. If this capability is provided then the driver will try to start the test in Web context mode (Native mode is applied by default). Read [Automating hybrid apps](../guides/hybrid.md) for more details. Usually equals to `safari`. |\n| `appium:automationName` | Must always be set to `xcuitest`. Values of `automationName` are compared case-insensitively. |\n| `appium:deviceName` | The name of the device under test. Consider setting `udid` for real devices and use this one for Simulator selection instead |","metadata":{"loc":{"lines":{"from":10,"to":15}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"| `appium:deviceName` | The name of the device under test. Consider setting `udid` for real devices and use this one for Simulator selection instead |\n| `appium:platformVersion` | The platform version of an emulator or a real device. This capability is used for device autodetection if `udid` is not provided |\n| `appium:udid` | UDID of the device to be tested. Could be retrieved from Xcode->Window->Devices and Simulators window. Always set this capability if you run parallel tests or use a real device to run your tests. |\n| `appium:noReset` | Prevents the device to be reset before the session startup if set to `true`. This means that the application under test is not going to be terminated neither its data cleaned. `false` by default |","metadata":{"loc":{"lines":{"from":15,"to":18}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"| `appium:fullReset` | Being set to `true` always enforces the application under test to be fully uninstalled before starting a new session. The application data might be cached on real devices under particular circumstances. Please check [troubleshooting](../guides/troubleshooting.md#leftover-application-data-on-real-devices) for more details regarding obsolete application data cleanup on real devices. `false` by default |\n| `appium:printPageSourceOnFindFailure` | Enforces the server to dump the actual XML page source into the log if any error happens. `false` by default. |","metadata":{"loc":{"lines":{"from":19,"to":20}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"| `appium:printPageSourceOnFindFailure` | Enforces the server to dump the actual XML page source into the log if any error happens. `false` by default. |\n| `appium:includeDeviceCapsToSessionInfo` | Whether to include screen information as the result of [Get Session Capabilities](https://appium.io/docs/en/latest/commands/base-driver/#getsession/). It includes `pixelRatio`, `statBarHeight` and `viewportRect`, but it causes an extra API call to WDA which may increase the response time like [this issue](https://github.com/appium/appium/issues/15101). Defaults to `true`. **This capability has no effect since driver version 5** |\n| `appium:resetLocationService` | Whether reset the location service in the session deletion on real device. Defaults to `false`. |","metadata":{"loc":{"lines":{"from":20,"to":22}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"| `appium:resetLocationService` | Whether reset the location service in the session deletion on real device. Defaults to `false`. |\n| `appium:customSSLCert` | Adds a root SSL certificate to IOS Simulators and real devices. Real devices only work if [py-ios-device](https://github.com/YueChen-C/py-ios-device) tool is available on the server machine. The certificate content must be provided in [PEM](https://knowledge.digicert.com/quovadis/ssl-certificates/ssl-general-topics/what-is-pem-format.html) format, e.g. ```-----BEGIN CERTIFICATE-----MIIFWjCCBEKg...-----END CERTIFICATE-----``` |","metadata":{"loc":{"lines":{"from":22,"to":23}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"### App","metadata":{"loc":{"lines":{"from":25,"to":25}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"| <div style=\"width:10em\">Capability</div> | Description |\n| --- | --- |\n| `appium:bundleId` | Bundle identifier of the app under test, for example `com.mycompany.myapp`. The capability value is calculated automatically if `app` is provided. If neither `app` or `bundleId` capability is provided then XCUITest driver starts from the Home screen. |\n| `appium:initialDeeplinkUrl` | A deeplink URL used to run either the application assigned to `appium:bundleId`, or the default application assigned to handle the particular deeplink protocol if `appium:bundleId` is not set. If provided in combination with `browserName=safari` then makes Safari to start with the given URL preloaded, which speeds up the session startup. The value of `appium:initialSafariUrl` capability is ignored in such case. An error is thrown on session init if either the value of the capability is not a valid URL, or XCTest was not able to associate it with any existing app, or the actual iOS version is below *16.4* |","metadata":{"loc":{"lines":{"from":27,"to":30}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"| `appium:app` | Full path to the application to be tested (the app must be located on the same machine where the server is running). `.ipa` and `.app` application extensions are supported. Zipped `.app` bundles are supported as well. Could also be an URL to a remote location. If neither of the `app` or `bundleId` capabilities are provided then the driver starts from the Home screen and expects the test to know what to do next. Do not provide both `app` and `browserName` capabilities at once. |","metadata":{"loc":{"lines":{"from":31,"to":31}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"| `appium:enforceAppInstall` | If set to `false` it will make xcuitest driver to verify whether the app version currently installed on the device under test is older than the one, which is provided as `appium:app` value. No app reinstall is going to happen if the candidate app has the same or older version number than the already installed copy of it. The version number used for comparison must be provided as [CFBundleVersion](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion) [Semantic Versioning](https://semver.org/)-compatible value in the application's Info.plist. No validation is performed by default, e.g. the provided app is always (re)installed, which could potentially slow down your test suites. The application data might be cached on real devices under particular circumstances when `appium:enforceAppInstall` is `true` if the application under test remained on the device under a certain situation. Please check","metadata":{"loc":{"lines":{"from":32,"to":32}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"might be cached on real devices under particular circumstances when `appium:enforceAppInstall` is `true` if the application under test remained on the device under a certain situation. Please check [troubleshooting](../guides/troubleshooting.md#leftover-application-data-on-real-devices) for more details regarding obsolete application data cleanup on real devices. Available since XCUITest driver 4.19.0. | false |","metadata":{"loc":{"lines":{"from":32,"to":32}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"| `appium:localizableStringsDir` | Where to look for localizable strings in the application bundle. Defaults to `en.lproj` |\n| `appium:otherApps` | App or list of apps (as a JSON array) to install prior to running tests. For example: `[\"http://appium.github.io/appium/assets/TestApp9.4.app.zip\", \"/path/to/app-b.app\"]` |\n| `appium:language` | Language to set for iOS app, for example `fr`. Please read [Language IDs](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/LanguageandLocaleIDs/LanguageandLocaleIDs.html) to get more details about available values for this capability. If a test is executed on a Simulator then UI language is changed as well. You can also change Simulator language in runtime using [mobile: configureLocalization](./execute-methods.md#mobile-configurelocalization) extension. |","metadata":{"loc":{"lines":{"from":33,"to":35}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"| `appium:locale` | Locale to set for iOS app, for example `fr_CA`. Please read [Locale IDs](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/LanguageandLocaleIDs/LanguageandLocaleIDs.html#//apple_ref/doc/uid/10000171i-CH15-SW9) to get more details about available values for this capability. If a test is executed on a Simulator then UI locale is changed as well. You can also change Simulator locale in runtime using [mobile: configureLocalization](./execute-methods.md#mobile-configurelocalization) extension. |\n| `appium:calendarFormat` | Calendar format to set for iOS Simulator, for example `gregorian` or `persian`. Can only be set in conjunction with `appium:locale`. |\n| `appium:appPushTimeout` | The timeout for an application install/upgrade in milliseconds. Works for real devices only. The default value is `480000` ms (8 minutes) |","metadata":{"loc":{"lines":{"from":36,"to":38}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"| `appium:appPushTimeout` | The timeout for an application install/upgrade in milliseconds. Works for real devices only. The default value is `480000` ms (8 minutes) |\n| **Deprecated** **Not used since v7.15.0** `appium:appInstallStrategy` | Select application installation strategy for real devices. The following strategies are supported:<br>`serial` (default) - pushes app files to the device in a sequential order; this is the least performant strategy, although the most reliable<br>`parallel` - pushes app files simultaneously; this is usually the the most performant strategy, but sometimes could not be very stable<br>`ios-deploy` - tells the driver to use a third-party tool [ios-deploy](https://www.npmjs.com/package/ios-deploy) to install the app; obviously the tool must be installed separately first and must be present in PATH before it could be used. |","metadata":{"loc":{"lines":{"from":38,"to":39}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"| `appium:appTimeZone` | Defines the custom time zone override for the application under test. You can use UTC, PST, EST, as well as place-based timezone names such as America/Los_Angeles. The application must be (re)launched for the capability to take effect. See the [List of tz database time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) for more details. The same behavior could be achieved by providing a custom value to the [TZ](https://developer.apple.com/forums/thread/86951#263395) environment variable via the `appium:processArguments` capability | UTC |","metadata":{"loc":{"lines":{"from":40,"to":40}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"### WebDriverAgent","metadata":{"loc":{"lines":{"from":42,"to":42}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|<div style=\"width:10em\">Capability</div>|Description|<div style=\"width:6em\">Example</div>|\n|----------|-----------|------|\n|`appium:xcodeOrgId`|Apple developer team identifier string. Must be used in conjunction with `xcodeSigningId` to take effect.|`JWL241K123`|\n|`appium:xcodeSigningId`|String representing a signing certificate. Must be used in conjunction with `xcodeOrgId`. This is usually just `Apple Development` or `iPhone Developer`, so the default (if not included) is `iPhone Developer`|`Apple Developer`|\n|`appium:xcodeConfigFile`|Full path to an optional Xcode configuration file that specifies the code signing identity and team for running the `WebDriverAgent` on the real device.|`/path/to/myconfig.xcconfig`|\n|`appium:updatedWDABundleId`|Bundle id to update WDA to before building and launching it. This bundle id _must_ be associated with a valid provisioning profile. The default value is `com.facebook.WebDriverAgentRunner`. |`io.appium.WebDriverAgentRunner`|","metadata":{"loc":{"lines":{"from":44,"to":49}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:keychainPath`|Full path to the private development key exported from the system keychain. Used in conjunction with `keychainPassword` when testing on real devices.|`/path/to/MyPrivateKey.p12`|\n|`appium:keychainPassword`|Password for unlocking keychain specified in `keychainPath`.|`super awesome password`|","metadata":{"loc":{"lines":{"from":50,"to":51}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:keychainPassword`|Password for unlocking keychain specified in `keychainPath`.|`super awesome password`|\n|`appium:derivedDataPath`|Overrides the folder that should be used for derived data when performing a source building with xCode. xCode stores all build and test artifacts under this file system root. Use this capability to set a unique path while running [parallel tests](../guides/parallel-tests.md) or to have more control over built artifacts, for example if you'd like to use [preinstalled](../guides/run-preinstalled-wda.md) or [prebuilt](../guides/run-prebuilt-wda.md) WDA to reduce the session startup time. If the capability is not set then Xcode will store the derived data in the default root taken from preferences (usually a subfolder of `/Users/<username>/Library/Developer/Xcode/DerivedData`).|`/tmp/wda-861563ec`|","metadata":{"loc":{"lines":{"from":51,"to":52}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:webDriverAgentUrl`|If provided, Appium will connect to an existing `WebDriverAgent` instance at this URL instead of starting a new one.|`http://localhost:8100`|","metadata":{"loc":{"lines":{"from":53,"to":53}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:useNewWDA`|If `true`, forces uninstall of any existing `WebDriverAgent` app on device. Set it to `true` if you want to apply different startup options for `WebDriverAgent` for each session. Although, it is only guaranteed to work stable on Simulator. Real devices require `WebDriverAgent` client to run for as long as possible without reinstall/restart to avoid issues like https://github.com/facebook/WebDriverAgent/issues/507. The `false` value (the default behaviour since driver version 2.35.0) will try to detect currently running WDA listener executed by previous testing session(s) and reuse it if possible, which is highly recommended for real device testing and to speed up suites of multiple tests in general. A new WDA session will be triggered at the default URL (http://localhost:8100) if WDA is not listening and `webDriverAgentUrl` capability is not set. The negative/unset value of `useNewWDA` capability has no effect prior to xcuitest driver version 2.35.0.|`true`|","metadata":{"loc":{"lines":{"from":54,"to":54}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:wdaLaunchTimeout`|Time, in ms, to wait for `WebDriverAgent` to be pingable. Defaults to 60000ms.|`30000`|\n|`appium:wdaConnectionTimeout`|Timeout, in ms, for waiting for a response from `WebDriverAgent`. Defaults to 240000ms.|`1000`|\n|`appium:wdaStartupRetries`|Number of times to try to build and launch `WebDriverAgent` onto the device by `xcodebuild`. It does not work for `webDriverAgentUrl` and `usePreinstalledWDA` capabilities since they handle `WebDriverAgent` without the `xcodebuild`. Defaults to 2 for simulators and 1 for real devices. |`4`|\n|`appium:wdaStartupRetryInterval`|Time, in ms, to wait between tries to build and launch `WebDriverAgent`. Defaults to 10000ms.|`20000`|\n|`appium:wdaLocalPort`|This value if specified, will be used to forward traffic from Mac host to real ios devices over USB. Default value is same as port number used by WDA on device.|`8100`|","metadata":{"loc":{"lines":{"from":55,"to":59}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:wdaLocalPort`|This value if specified, will be used to forward traffic from Mac host to real ios devices over USB. Default value is same as port number used by WDA on device.|`8100`|\n|`appium:wdaRemotePort`|This value if specified, will be used as the port number to start WDA HTTP server on the remote device. This is only relevant for real devices, because Simulator shares ports with its host. If `webDriverAgentUrl` is provided then it might be used to provide a hint for the remote port number if it differs from the default one. Default value is 8100.|`8100`|\n|`appium:wdaBaseUrl`| This value if specified, will be used as a prefix to build a custom `WebDriverAgent` url. It is different from `webDriverAgentUrl`, because if the latter is set then it expects `WebDriverAgent` to be already listening and skips the building phase. Defaults to `http://localhost` | `http://192.168.1.100`|","metadata":{"loc":{"lines":{"from":59,"to":61}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:showXcodeLog`|Whether to display the output of the Xcode command used to run the tests. If this is `true`, there will be **lots** of extra logging at startup. Defaults to `false`|`true`|\n|`appium:iosInstallPause`|Time in milliseconds to pause between installing the application and starting `WebDriverAgent` on the device. Used particularly for larger applications. Defaults to `0`|`8000`|\n|`appium:prebuildWDA`|Enables prebuilding if the WebDriverAgentRunner application before running the WDA app. With this capability, XCUITest driver builds the WDA project first, then it handles the session as `appium:usePrebuiltWDA` `true` behavior. Defaults to `false`.|`true`|\n|`appium:usePrebuiltWDA`|Skips the build phase of running the WDA app. Building is then the responsibility of the user. `appium:derivedDataPath` let the session use the path as `-derivedDataPath` argument for `xcodebuild` command. Defaults to `false`.|`true`|","metadata":{"loc":{"lines":{"from":62,"to":65}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:prebuiltWDAPath`| The full path to the prebuilt WebDriverAgent-Runner application package to be installed if `appium:usePreinstalledWDA` capability is enabled. The package's bundle identifier could be customized via `appium:updatedWDABundleId` capability. |`/path/to/WebDriverAgentRunner-Runner.app`|","metadata":{"loc":{"lines":{"from":66,"to":66}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:usePreinstalledWDA`| Whether to launch a preinstalled WebDriverAgentRunner application using a custom XCTest API client (via `com.apple.instruments` service) instead of running `xcodebuild` for real devices or simulators via simctl tool (since driver version 7.4.0). If `appium:prebuiltWDAPath` is provided, XCUITest driver will install WebDriverAgent-Runner app from the given path before launching the application. The preinstalled WebDriverAgent package must be built by Xcode 12+. The default target bundle identifier is `com.facebook.WebDriverAgentRunner.xctrunner`, although it could be customized by providing the `appium:updatedWDABundleId` capability value (the `.xctrunner` suffix is added automatically). Please read [Run Preinstalled WebDriverAgentRunner](../guides/run-preinstalled-wda.md) for more details. Defaults to `false`. |`true` or `false`|","metadata":{"loc":{"lines":{"from":67,"to":67}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:updatedWDABundleIdSuffix`| Add suffix for the bundle id provided by the `appium:updatedWDABundleId` capability value in `appium:usePreinstalledWDA` capability usage since XCUITest driver v7.6.0. This is for an advanced usage that sets an arbitrary `CFBundleIdentifier` for prebuilt WebDriverAgent package to sign with the bundle identifier's certificate. For example, if you would need to sign a WebDriverAgent package with `io.appium.wda` bundle identifier's certificate, the WebDriverAgent's package must have the same bundle identifier as `CFBundleIdentifier`. Then, the WebDriverAgent package can be launched by `io.appium.wda`, which does not have `.xctrunner`. Then `\"appium:updatedWDABundleIdSuffix\": \"\"` (an empty string) helps. Please read [Run Preinstalled WebDriverAgentRunner](../guides/run-preinstalled-wda.md) for more details. Defaults to `.xctrunner`. | `\"\"`, `\".customsuffix\"` |","metadata":{"loc":{"lines":{"from":68,"to":68}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:shouldUseSingletonTestManager`|Use default proxy for test management within `WebDriverAgent`. Setting this to `false` sometimes helps with socket hangup problems. Defaults to `true`.|`false`|\n|`appium:waitForIdleTimeout`|The amount of time in float seconds to wait until the application under test is idling. XCTest requires the app's main thread to be idling in order to execute any action on it, so WDA might not even start/freeze if the app under test is constantly hogging the main thread. The default value is `10` (seconds). Setting it to zero disables idling checks completely (not recommended) and has the same effect as setting `waitForQuiescence` to `false`. Available since Appium 1.20.0. |`1`|","metadata":{"loc":{"lines":{"from":69,"to":70}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:useXctestrunFile`|Use Xctestrun file to launch WDA. It will search for such file in `bootstrapPath`. Expected name of file is `WebDriverAgentRunner_iphoneos<sdkVersion>-arm64.xctestrun` for real device and `WebDriverAgentRunner_iphonesimulator<sdkVersion>-x86_64.xctestrun` for simulator. One can do `build-for-testing` for `WebDriverAgent` project for simulator and real device and then you will see [Product Folder like this](./assets/images/useXctestrunFile.png) and you need to copy content of this folder at `bootstrapPath` location. Since this capability expects that you have already built `WDA` project, it neither checks whether you have necessary dependencies to build `WDA` nor will it try to build project. Defaults to `false`. _Tips: `Xcodebuild` builds for the target platform version. We'd recommend you to build with minimal OS version which you'd like to run as the original WDA module. e.g. If you build WDA for 12.2, the module cannot run on iOS 11.4 because of loading","metadata":{"loc":{"lines":{"from":71,"to":71}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"version. We'd recommend you to build with minimal OS version which you'd like to run as the original WDA module. e.g. If you build WDA for 12.2, the module cannot run on iOS 11.4 because of loading some module error on simulator. A module built with 11.4 can work on iOS 12.2. (This is xcodebuild's expected behaviour.)_ |`true`|","metadata":{"loc":{"lines":{"from":71,"to":71}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"| **Deprecated** `appium:useSimpleBuildTest`| Build with `build` and run test with `test` in xcodebuild for all Xcode version if this is `true`, or build with `build-for-testing` and run tests with `test-without-building` for over Xcode 8 if this is `false`. Defaults to `false`. | `true` or `false` |\n|`appium:wdaEventloopIdleDelay`|Delays the invocation of `-[XCUIApplicationProcess setEventLoopHasIdled:]` by the number of seconds specified with this capability. This can help quiescence apps that fail to do so for no obvious reason (and creating a session fails for that reason). This increases the time for session creation because `-[XCUIApplicationProcess setEventLoopHasIdled:]` is called multiple times. If you enable this capability start with at least `3` seconds and try increasing it, if creating the session still fails. Defaults to `0`. |`5`|","metadata":{"loc":{"lines":{"from":72,"to":73}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:processArguments`|Process arguments and environment which will be sent to the `WebDriverAgent` server in a new session request. Please use [mobile: launchApp](./execute-methods.md#mobile-launchapp) to launch an application with process arguments in the middle of a session. |`{ args: [\"a\", \"b\", \"c\"] , env: { \"a\": \"b\", \"c\": \"d\" } }` or `'{\"args\": [\"a\", \"b\", \"c\"], \"env\": { \"a\": \"b\", \"c\": \"d\" }}'`|\n|`appium:autoLaunch`|When set to `false`, prevents the application under test from being launched automatically as a part of the new session startup process. The launch become the responsibility of the user. Defaults to `true`.|`true` or `false`|\n|`appium:allowProvisioningDeviceRegistration`|Allow `xcodebuild` to register your destination device on the developer portal if necessary. Requires a developer account to have been added in Xcode's Accounts preference pane. Defaults to `false`.|`true` or `false`|","metadata":{"loc":{"lines":{"from":74,"to":76}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:resultBundlePath`| Specify the path to the result bundle path as `xcodebuild` argument for `WebDriverAgent` build under a security flag (Please check _Opt-in Features_ section below). `WebDriverAgent` process must start/stop every time to pick up changed value of this property. Specifying `useNewWDA` to `true` may help there. Please read `man xcodebuild` for more details. | `/path/to/resultbundle` |\n|`appium:resultBundleVersion`| Specify the version of result bundle as `xcodebuild` argument for `WebDriverAgent` build. The default value depends on your Xcode version. Please read `man xcodebuild` for more details. | `/path/to/resultbundle` |\n|`appium:maxTypingFrequency`|Maximum frequency of keystrokes for typing and clear. If your tests are failing because of typing errors, you may want to adjust this. Defaults to 60 keystrokes per minute.|`30`|","metadata":{"loc":{"lines":{"from":77,"to":79}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:simpleIsVisibleCheck`|Use native methods for determining visibility of elements. In some cases this takes a long time. Setting this capability to `false` will cause the system to use the position and size of elements to make sure they are visible on the screen. This can, however, lead to false results in some situations. Defaults to `false`. | `true`, `false`|\n| **Deprecated** `appium:waitForQuiescence`| It allows to turn on/off waiting for application quiescence in `WebDriverAgent`, while performing queries. The default value is `true`. You can avoid [this kind of issues](https://github.com/appium/appium/issues/11132) if you turn it off. Consider using `waitForIdleTimeout` capability instead for this purpose since Appium 1.20.0 | `false` |","metadata":{"loc":{"lines":{"from":80,"to":81}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:mjpegServerPort`|The port number on which WDA broadcasts screenshots stream encoded into MJPEG format from the device under test. It might be necessary to change this value if the default port is busy because of other tests running in parallel. Default value: `9100`|`12000`|\n|`appium:mjpegScreenshotUrl` | The URL of a service that provides realtime device screenshots in MJPEG format. If provided then the actual command to retrieve a screenshot will be requesting pictures from this service rather than directly from the server. Appium does not handle port forward etc to the URL. | `http://<ip address to the device>:9100` |","metadata":{"loc":{"lines":{"from":82,"to":83}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:screenshotQuality`| Changes the initial quality of display screenshots. This capability affects the screenshoting speed and the actual quality of resulting screenshots. Before version 5.4.0 of WebDriverAgent possible values were: `0`, `1` (default), `2`, where `0` abbreviates lossless PNG, `1` is a high-quality JPEG and `2` is a low-quality JPEG. In the version 5.4.0 one more mode has been added (`3`), which is now the default one. It abbreviates lossless HEIC with fallback to PNG if the device does not support hardware-accelerated HEIC encoding. You can also change the value of screenshotQuality in [settings](settings.md). | `2` |\n|`appium:autoAcceptAlerts`| Accept all iOS alerts automatically if they pop up. This includes privacy access permission alerts (location, contacts, photos). Default is `false`. |`true` or `false`|","metadata":{"loc":{"lines":{"from":84,"to":85}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:autoAcceptAlerts`| Accept all iOS alerts automatically if they pop up. This includes privacy access permission alerts (location, contacts, photos). Default is `false`. |`true` or `false`|\n|`appium:autoDismissAlerts`| Dismiss all iOS alerts automatically if they pop up. This includes privacy access permission alerts (location, contacts, photos). Default is `false`. |`true` or `false`|\n|`appium:disableAutomaticScreenshots`| Disable automatic screenshots taken by XCTest at every interaction. Default is up to `WebDriverAgent`'s config to decide, which currently defaults to `true`. |`true` or `false`|\n|`appium:shouldTerminateApp`| Specify if the app should be terminated on session end. This capability only has an effect if an application identifier has been passed to the test session (either explicitly, by setting bundleId, or implicitly, by providing app). Default is `true` unless `noReset` capability is set to `true`. |`true` or `false`|","metadata":{"loc":{"lines":{"from":85,"to":88}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:forceAppLaunch`| Specify if the app should be forcefully restarted if it is already running on session startup. This capability only has an effect if an application identifier has been passed to the test session (either explicitly, by setting bundleId, or implicitly, by providing app). Default is `true` unless `noReset` capability is set to `true`. |`true` or `false`|\n|`appium:useNativeCachingStrategy`| Set this capability to `false` in order to use the custom elements caching strategy. This might help to avoid stale element exception on property change. By default the native XCTest cache resolution is used (`true`) for all native locators (e.g. all, but xpath). Check the corresponding [WebDriverAgent pull request](https://github.com/appium/WebDriverAgent/pull/516) for more details. |`true` or `false`|","metadata":{"loc":{"lines":{"from":89,"to":90}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:appLaunchStateTimeoutSec`|Allows to set the timeout in float seconds for the application state change on the session startup in range (0, 240) exclusively. The default value for it in XCTest is 60 seconds, which means WDA would throw an exception if the application under test is not ready for accessibility interactions in 60s after its process has started. **Important**: The fact the application's user interface is visible does not necessarily mean it could be immediately interacted with by XCTest. The latter must ensure the app's main thread is also idling. Setting this capability to a lower value might help to avoid prolonged test startup with problematic apps taking too much time to be ready and fail fast. It is not advised to increase the capability value above 60 seconds, rather consider fixing the affected application itself. Too low values though may cause unexpected app startup failures. The capability does not have an effect if the app under test is not (re)started","metadata":{"loc":{"lines":{"from":91,"to":91}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"consider fixing the affected application itself. Too low values though may cause unexpected app startup failures. The capability does not have an effect if the app under test is not (re)started at the beginning of the session. | `10.5` |","metadata":{"loc":{"lines":{"from":91,"to":91}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"### Simulator","metadata":{"loc":{"lines":{"from":93,"to":93}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|<div style=\"width:10em\">Capability</div>|Description|<div style=\"width:7em\">Example</div>|\n|----------|-----------|------|\n|`appium:orientation`|Start a test session in a certain orientation. Note, that Simulator may ignore this capability if the simulated device itself does not support orientation change in its current state. For example, iPhones only allow orientation change to landscape if an app that declares landscape support in its manifest is running. Thus changing the orientation from portrait to something else being on home screen won't have any effect.|`LANDSCAPE` or `PORTRAIT`|\n|`appium:scaleFactor`|Simulator scale factor. This is useful to have if the default resolution of simulated device is greater than the actual display resolution, so you can scale the simulator to see the whole device screen without scrolling. Must be a string containing a positive float value.|`'2.0'`|","metadata":{"loc":{"lines":{"from":95,"to":98}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:connectHardwareKeyboard`|Set this option to `true` in order to enable hardware keyboard in Simulator. The preference works only when XCUITest driver launches a simulator instance with this value. It is set to `false` by default, because this helps to workaround some XCTest bugs. `connectHardwareKeyboard: true` makes `forceSimulatorSoftwareKeyboardPresence: false` if no explicit value is set for `forceSimulatorSoftwareKeyboardPresence` capability since Appium 1.22.0. |`true` or `false`|","metadata":{"loc":{"lines":{"from":99,"to":99}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:forceSimulatorSoftwareKeyboardPresence`|Set this option to `true` in order to turn software keyboard on and turn hardware keyboard off in Simulator since Appium 1.22.0. This option helps to avoid `Keyboard is not present` error. It is set to `true` by default. XCUITest driver respects preset simulator software/hardware keyboard preference when this value is `false`, so `connectHardwareKeyboard: false` and `forceSimulatorSoftwareKeyboardPresence: false` means for XCUITest driver to keep the current Simulator keyboard preferences. This option has priority over `connectHardwareKeyboard`. |`true` or `false`|\n|`appium:skipSyncUiDialogTranslation`|Set this option to `true` in order to skip synchronizing UI dialogs translation. While this option might leave some system UI alerts untranslated, it helps to avoid unexpected side effects (see [this issue](https://github.com/appium/appium/issues/19440) for more details). It is set to `false` by default. |`true` or `false`|","metadata":{"loc":{"lines":{"from":100,"to":101}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"| **Deprecated** `appium:calendarAccessAuthorized`|This capability is obsolete. Please use `appium:permissions` one instead with the `calendar` key.|`true` or `false`|\n|`appium:isHeadless`|Set this capability to `true` if automated tests are running on Simulator and the device display is not needed to be visible. This only has an effect since Xcode9 and only for simulators. All running instances of Simulator UI are going to be automatically terminated if headless test is started. `false` is the default value.|`true`|\n|`appium:simulatorWindowCenter`|Allows to explicitly set the coordinates of Simulator window center for Xcode9+ SDK. This capability only has an effect if Simulator window has not been opened yet for the current session before it started. Must be a tuple containing floats or integers, with no spaces.|`{-100.0,100.0}`|","metadata":{"loc":{"lines":{"from":102,"to":104}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:simulatorStartupTimeout`|Allows to change the default timeout for Simulator startup. By default this value is set to 120000ms (2 minutes), although the startup could take longer on a weak hardware or if other concurrent processes use much system resources during the boot up procedure.|`300000`|\n|`appium:simulatorTracePointer`|Whether to highlight pointer moves in the Simulator window. The Simulator UI client must be shut down before the session startup in order for this capability to be applied properly. `false` by default.|`true`|","metadata":{"loc":{"lines":{"from":105,"to":106}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:shutdownOtherSimulators`|If this capability set to `true` and the current device under test is an iOS Simulator then Appium will try to shutdown all the other running Simulators before to start a new session. This might be useful while executing webview tests on different devices, since only one device can be debugged remotely at once due to an Apple bug. The capability only has an effect if `--relaxed-security` command line argument is provided to the server. Defaults to `false`.|`true`|\n|`appium:enforceFreshSimulatorCreation`| Creates a new simulator in session creation and deletes it in session deletion. Defaults to `false`. | `true` or `false` |\n|`appium:keepKeyChains`|Set the capability to `true` in order to preserve Simulator keychains folder after full reset. This feature has no effect on real devices. Defaults to `false`|`true`|","metadata":{"loc":{"lines":{"from":107,"to":109}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:keepKeyChains`|Set the capability to `true` in order to preserve Simulator keychains folder after full reset. This feature has no effect on real devices. Defaults to `false`|`true`|\n|`appium:keychainsExcludePatterns`|This capability accepts comma-separated path patterns, which are going to be excluded from keychains restore while full reset is being performed on Simulator. It might be useful if you want to exclude only particular keychain types from being restored, like the applications keychain. This feature has no effect on real devices.|`*keychain*.db*`|\n|`appium:reduceMotion`| It allows to turn on/off reduce motion accessibility preference. Setting reduceMotion `on` helps to reduce flakiness during tests. Only on simulators | `true` |\n|`appium:reduceTransparency`| It allows you to turn on/off reduce transparency accessibility preference. Setting reduceTransparency `on` helps to reduce screenshot image distortion during tests. Only on simulators | `true` |","metadata":{"loc":{"lines":{"from":109,"to":112}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:autoFillPasswords`| It allows you to turn on/off autofill passwords function when text field is foccused. Works only with iOS16.4+ simulators | `true` |\n|`appium:permissions`| Allows to set permissions for the specified application bundle on Simulator only. The capability value is expected to be a valid JSON string with `{\"<bundleId1>\": {\"<serviceName1>\": \"<serviceStatus1>\", ...}, ...}` format. Since Xcode SDK 11.4 Apple provides native APIs to interact with application settings. Check the output of `xcrun simctl privacy booted` command to get the list of available permission names. Use `yes`, `no` and `unset` as values in order to `grant`, `revoke` or `reset` the corresponding permission. Below Xcode SDK 11.4 it is required that `applesimutils` package is installed and available in PATH. The list of available service names and statuses can be found at https://github.com/wix/AppleSimulatorUtils. | `{\"com.apple.mobilecal\": {\"calendar\": \"YES\"}}` |","metadata":{"loc":{"lines":{"from":113,"to":114}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:iosSimulatorLogsPredicate`|Set the `--predicate` flag in the ios simulator logs|`'process != \"locationd\" AND process != \"DTServiceHub\"' AND process != \"mobileassetd\"`|\n|`appium:simulatorLogLevel`|Allows to customize the minimum log level for logs collected from simulators. Possible values are `default` (the default value), `info` and `debug`| `debug` |\n|`appium:simulatorPasteboardAutomaticSync`| Handle the `-PasteboardAutomaticSync` flag when simulator process launches. It could improve launching simulator performance not to sync pasteboard with the system when this value is `off`. `on` forces the flag enabled. `system` does not provide the flag to the launching command. `on`, `off`, or `system` is available. They are case insensitive. Defaults to `off` | `system` |","metadata":{"loc":{"lines":{"from":115,"to":117}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:simulatorDevicesSetPath`| This capability allows to set an alternative path to the simulator devices set in case you have multiple sets deployed on your local system. Such feature could be useful if you, for example, would like to save disk space on the main system volume. | `/MyVolume/Devices` |\n|`appium:safariGlobalPreferences`| Allows changing of Mobile Safari's preferences at the session startup. Check the documentation on arguments of [mobile: updateSafariPreferences](./execute-methods.md#mobile-updatesafaripreferences) extension to get more details on the value type requirements. Only available on real devices since driver version 7.9.0. A new Safari instance must be launched upon test startup for this capability to take effect on real devices. | `{ ShowTabBar: 0, WarnAboutFraudulentWebsites: 0 }` |","metadata":{"loc":{"lines":{"from":118,"to":119}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"### Web Context","metadata":{"loc":{"lines":{"from":121,"to":121}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|<div style=\"width:10em\">Capability</div>|Description|<div style=\"width:7em\">Example</div>|\n|----------|-----------|------|\n|`pageLoadStrategy` | One of the available page load strategies. See https://www.w3.org/TR/webdriver/#capabilities. Default `normal`. | `eager` |\n|`appium:absoluteWebLocations`|This capability will direct the `Get Element Location` command, when used within webviews, to return coordinates which are relative to the origin of the page, rather than relative to the current scroll offset. This capability has no effect outside of webviews. Default `false`.|`true`|\n|`appium:safariGarbageCollect`|Turns on/off Web Inspector garbage collection when executing scripts on Safari. Turning on may improve performance. Defaults to `false`.|`true` or `false`|","metadata":{"loc":{"lines":{"from":123,"to":127}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:safariGarbageCollect`|Turns on/off Web Inspector garbage collection when executing scripts on Safari. Turning on may improve performance. Defaults to `false`.|`true` or `false`|\n|`appium:includeSafariInWebviews`|Add Safari web contexts to the list of contexts available during a native/webview app test. This is useful if the test opens Safari and needs to be able to interact with it. Defaults to `false`.|`true` or `false`|\n|`appium:safariLogAllCommunication`|Log all plists sent to and received from the Web Inspector, as plain text. For some operations this can be a lot of data, so it is recommended to be used only when necessary. Defaults to `false`.|`true` or `false`|","metadata":{"loc":{"lines":{"from":127,"to":129}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:safariLogAllCommunicationHexDump`|Log all communication sent to and received from the Web Inspector, as raw hex dump and printable characters. This logging is done _before_ any data manipulation, and so can elucidate some communication issues. Like `appium:safariLogAllCommunication`, this can produce a lot of data in some cases, so it is recommended to be used only when necessary. Defaults to `false`.|`true` or `false`|\n|`appium:safariSocketChunkSize`|The size, in _bytes_, of the data to be sent to the Web Inspector on iOS 11+ real devices. Some devices hang when sending large amounts of data to the Web Inspector, and breaking them into smaller parts can be helpful in those cases. Defaults to `16384` (also the maximum possible)|`1000`|","metadata":{"loc":{"lines":{"from":130,"to":131}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:safariWebInspectorMaxFrameLength`| The maximum size in bytes of a single data frame for the Web Inspector. Too high values could introduce slowness and/or memory leaks. Too low values could introduce possible buffer overflow exceptions. Defaults to 20MB (`20*1024*1024`) |`1024`, `100*1024*1024` |\n|`appium:additionalWebviewBundleIds`|Array (or JSON array) of possible bundle identifiers for webviews. This is sometimes necessary if the Web Inspector is found to be returning a modified bundle identifier for the app. If the value includes `*`, XCUITest driver will return all available webview contexts on the device. Defaults to `[]`|`[\"io.appium.modifiedId', 'ABCDEF\"]`, `[\"*\"]`|\n|`appium:webviewAtomWaitTimeout`|The time to wait, in `ms`, for each atom execution timeout of webviews in MobileSafari or hybrid apps. Defaults to `120000`. If the value was zero or less, the timeout keeps the default value. |`20000`|","metadata":{"loc":{"lines":{"from":132,"to":134}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:safariIgnoreWebHostnames`| Provide a list of hostnames (comma-separated) that the Safari automation tools should ignore. This is to provide a workaround to prevent a webkit bug where the web context is unintentionally changed to a 3rd party website and the test gets stuck. The common culprits are search engines (yahoo, bing, google) and `about:blank` |`'www.yahoo.com, www.bing.com, www.google.com, about:blank'`|\n|`appium:nativeWebTap`| Enable native, non-javascript-based taps being in web context mode. Defaults to `false`. Warning: sometimes the preciseness of native taps could be broken, because there is no reliable way to map web element coordinates to native ones. | `true` |","metadata":{"loc":{"lines":{"from":135,"to":136}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:nativeWebTapStrict`| Enabling this capability would skip the additional logic that tries to match web view elements to native ones by using their textual descriptions. Depending on the actual web view content this algorithm might sometimes be not very reliable and will slow down each click as we anyway fallback to the usual coordinates transformation flow if it fails. It is advised to enable strict tap if you use [mobile: calibrateWebToRealCoordinatesTranslation](./execute-methods.md#mobile-calibratewebtorealcoordinatestranslation) extension. Only applicable if `nativeWebTap` is enabled. `false` by default | `true` |\n|`appium:safariInitialUrl`| Initial safari url, default is a local welcome page. Setting it to an empty string will skip the initial navigation. | `https://www.github.com` |","metadata":{"loc":{"lines":{"from":137,"to":138}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:safariInitialUrl`| Initial safari url, default is a local welcome page. Setting it to an empty string will skip the initial navigation. | `https://www.github.com` |\n|`appium:safariAllowPopups`| Allow javascript to open new windows in Safari. Default keeps the current setting. Only available on real devices since driver version 7.9.0. A new Safari instance must be launched upon test startup on real devices for this capability to take effect. |`true` or `false`|\n|`appium:safariIgnoreFraudWarning`| Prevent Safari from showing a fraudulent website warning. Default keeps the current setting. Only available on real devices since driver version 7.9.0. A new Safari instance must be launched upon test startup on real devices for this capability to take effect. |`true` or `false`|","metadata":{"loc":{"lines":{"from":138,"to":140}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:safariOpenLinksInBackground`| Whether Safari should allow links to open in new windows. Default keeps the current sim setting. Only available on real devices since driver version 7.9.0. A new Safari instance must be launched upon test startup on real devices for this capability to take effect. |`true` or `false`|\n|`appium:webviewConnectRetries`| The maximum number of retries before giving up on web view pages detection. Under the hood the remote debugger waits until webkit delivers the list of connected applications pages (`_rpc_applicationSentListing`). The delay between each retry is 500ms, which creates a minimum 10s of waiting time with the default retries amount of `20`. |`10`|","metadata":{"loc":{"lines":{"from":141,"to":142}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:webviewConnectTimeout`| The time to wait, in `ms`, for the presence of webviews in MobileSafari or hybrid apps. Under the hood the remote debugger waits until webkit delivers the list of connected applications (`_rpc_reportConnectedApplicationList`) after sending a request for setting the connection key (`_rpc_reportIdentifier`). For better stability it might be necessary to increase this value if you run tests on Simulator and the host does not perform fast enough, for example in the continuous integration environment. `5000` ms by default. |`10000`|\n|`appium:enableAsyncExecuteFromHttps`| Capability to allow simulators to execute asynchronous JavaScript on pages using HTTPS. Defaults to `false` | `true` or `false` |","metadata":{"loc":{"lines":{"from":143,"to":144}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:enableAsyncExecuteFromHttps`| Capability to allow simulators to execute asynchronous JavaScript on pages using HTTPS. Defaults to `false` | `true` or `false` |\n|`appium:fullContextList` | Returns the detailed information on contexts for the [Get Contexts](https://appium.io/docs/en/latest/guides/context/) command. If this capability is enabled, then each item in the returned contexts list would additionally include WebView title, full URL and the bundle identifier. Defaults to `false`. | `true` or `false` |\n|`appium:enablePerformanceLogging`| Enable Safari's performance logging (default `false`)| `true`, `false`|\n|`appium:autoWebview`| Move directly into Webview context if available. Default `false`|`true`, `false`|","metadata":{"loc":{"lines":{"from":144,"to":147}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:autoWebview`| Move directly into Webview context if available. Default `false`|`true`, `false`|\n|`appium:skipTriggerInputEventAfterSendkeys`| If this capability is set to `true`, then whenever you call the Send Keys method in a web context, the driver will not fire an additional `input` event on the input field used for the call. This event, turned on by default, helps in situations where JS frameworks (like React) do not respond to the input events that occur by default when the underlying Selenium atom is executed. Default `false`|`true`, `false`|","metadata":{"loc":{"lines":{"from":147,"to":148}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:sendKeyStrategy`| If this capability is set to `oneByOne`, then whenever you call the Send Keys method in a web context, the driver will type each character the given string consists of in serial order to the element. This strategy helps in situations where JS frameworks (like React) update the view for each input. If `appium:skipTriggerInputEventAfterSendkeys` capability is `true`, it will affect every type. For example, when you are going to type the word `appium` with `oneByOne` strategy and `appium:skipTriggerInputEventAfterSendkeys` is enabled, the `appium:skipTriggerInputEventAfterSendkeys` option affects each typing action: `a`, `p`, `p`,`i`, `u` and `m`. Suppose any other value or no value has been provided to the `appium:sendKeyStrategy` capability. In that case, the driver types the given string in the destination input element. `appium` Send Keys input types `appium` if `oneByOne` was not set. |`oneByOne`|","metadata":{"loc":{"lines":{"from":149,"to":149}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:showSafariConsoleLog`| Adds Safari JavaScript console events to Appium server logs (`true`) and writes fully serialized events into the `safariConsole` logs bucket (both `true` and `false`). If unset then no console events are being collected, which helps to save CPU and memory resources. Before the driver version 7.22 the default behavior was to always collect console logs if the capability is not set. Setting the value to `false` mimics that legacy behavior. |`true`, `false`|\n|`appium:showSafariNetworkLog`| Adds Safari network events to Appium server logs (`true`) and writes fully serialized events into the `safariNetwork` logs bucket (both `true` and `false`). If unset then no network events are being collected, which helps to save CPU and memory resources. Before the driver version 7.22 the default behavior was to always collect network logs if the capability is not set. Setting the value to `false` mimics that legacy behavior. |`true`, `false`|","metadata":{"loc":{"lines":{"from":150,"to":151}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"### Other","metadata":{"loc":{"lines":{"from":153,"to":153}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|<div style=\"width:10em\">Capability</div>|Description|<div style=\"width:6em\">Example</div>|\n|----------|-----------|------|\n|`appium:resetOnSessionStartOnly`|Whether to perform reset on test session finish (`false`) or not (`true`). Keeping this variable set to `true` and Simulator running (the default behaviour since version 1.6.4) may significantly shorten the duration of test session initialization. Defaults to `true`|`true` or `false`|","metadata":{"loc":{"lines":{"from":155,"to":157}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:commandTimeouts`|Custom timeout(s) in milliseconds for WDA backend commands execution. This might be useful if WDA backend freezes unexpectedly or requires too much time to fail and blocks automated test execution. The value is expected to be of type string and can either contain max milliseconds to wait for each WDA command to be executed before terminating the session forcefully or a valid JSON string, where keys are internal Appium command names (you can find these in logs, look for \"Executing command 'command_name'\" records) and values are timeouts in milliseconds. You can also set the 'default' key to assign the timeout for all other commands not explicitly enumerated as JSON keys.|`'120000'`, `'{\"findElement\": 40000, \"findElements\": 40000, \"setValue\": 20000, \"default\": 120000}'`|\n|`appium:useJSONSource`|Get JSON source from WDA and transform it to XML on the Appium server side. Defaults to `false`.|`true`|","metadata":{"loc":{"lines":{"from":158,"to":159}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:useJSONSource`|Get JSON source from WDA and transform it to XML on the Appium server side. Defaults to `false`.|`true`|\n|`appium:skipLogCapture`|Skips to start capturing logs such as crash, system, safari console and safari network. It might improve performance such as network. Log related commands will not work. Defaults to `false`. |`true` or `false`|\n|`appium:launchWithIDB`| Launch WebDriverAgentRunner with [idb](https://github.com/facebook/idb) instead of xcodebuild. This could save a significant amount of time by skipping the xcodebuild process, although the idb might not be very reliable, especially with fresh Xcode SDKs. Check the [idb repository](https://github.com/facebook/idb/issues) for more details on possible compatibility issues. Defaults to `false` |`true` or `false`|\n|`appium:showIOSLog`| Whether to show any logs captured from a device in the appium logs. Default `false`|`true` or `false`|","metadata":{"loc":{"lines":{"from":159,"to":162}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"|`appium:showIOSLog`| Whether to show any logs captured from a device in the appium logs. Default `false`|`true` or `false`|\n|`appium:clearSystemFiles`|Whether to clean temporary XCTest files (for example logs) when a testing session is closed. `false` by default| `true` or `false`\n|`appium:newCommandTimeout`|How long (in seconds) the driver should wait for a new command from the client before assuming the client has stopped sending requests. After the timeout the session is going to be deleted. `60` seconds by default. Setting it to zero disables the timer. |`100`|","metadata":{"loc":{"lines":{"from":162,"to":164}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/capabilities.md","filename":"capabilities.md","relativePath":"appium-xcuitest-driver/reference/capabilities.md"}},{"pageContent":"---\ntitle: Commands\n---\n\nThe driver comes with a set of many available commands, in addition to the commands included in the\nAppium base driver. Refer to the documentation of your Appium client for the exact syntax to call\nthese commands.\n\nPlease note that most of the driver-specific functionality is available using\n[Execute Methods](./execute-methods.md) instead.\n\n!!! info\n\n Check the [Appium base driver documentation](https://appium.io/docs/en/latest/reference/commands/base-driver/)\n for commands inherited by the XCUITest driver\n\n### `getClipboard`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please use the [`mobile: getClipboard`](./execute-methods.md#mobile-getclipboard) extension instead\n\n`POST` **`/session/:sessionId/appium/device/get_clipboard`**\n\nGets the content of the primary clipboard on the device under test.\nSee [Get/Set Clipboard](../guides/clipboard.md) for more details\n\n#### Arguments\n\n| Name | Type |\n| :------ | :------ |\n| `contentType?` | `any` |","metadata":{"loc":{"lines":{"from":1,"to":32}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/commands.md","filename":"commands.md","relativePath":"appium-xcuitest-driver/reference/commands.md"}},{"pageContent":"#### Arguments\n\n| Name | Type |\n| :------ | :------ |\n| `contentType?` | `any` |\n\n#### Returned Result\n\n`string`\n\nThe actual clipboard content encoded into base64 string. An empty string is returned if the\nclipboard contains no data.\n\n### `setClipboard`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please use the [`mobile: setClipboard`](./execute-methods.md#mobile-setclipboard) extension instead\n\n`POST` **`/session/:sessionId/appium/device/set_clipboard`**\n\nSets the primary clipboard's content on the device under test.\nSee [Get/Set Clipboard](../guides/clipboard.md) for more details\n\n#### Arguments\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `content` | `any` | - |\n| `contentType?` | `any` | - |\n| `label?` | `string` | The content to be set as base64 encoded string. |\n\n#### Returned Result\n\n``null``\n\n### `getGeoLocation`\n\n`GET` **`/session/:sessionId/location`**","metadata":{"loc":{"lines":{"from":28,"to":66}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/commands.md","filename":"commands.md","relativePath":"appium-xcuitest-driver/reference/commands.md"}},{"pageContent":"#### Returned Result\n\n``null``\n\n### `getGeoLocation`\n\n`GET` **`/session/:sessionId/location`**\n\nReturns the location of the device under test. Location Services for WebDriverAgent must be set to\n'Always' to get the location data correctly.\n\nThe 'latitude', 'longitude' and 'altitude' could be zero even if the Location Services are set to\n'Always', because the device may need some time to update the location data.\n\nFor iOS 17+ simulators and real devices, this method will return the result of\n[`mobile: getSimulatedLocation`](./execute-methods.md#mobile-getsimulatedlocation) extension\nif the simulated location was previously set by [`mobile: setSimulatedLocation`](./execute-methods.md#mobile-setsimulatedlocation).\n\n**`Throws`**\n\nIf the device under test returns an error message. i.e.: tvOS returns unsupported error\n\n#### Returned Result\n\n`Promise`<`altitude`: `number`, `latitude`: `number`, `longitude`: `number`\\>\n\n### `setGeoLocation`\n\n`POST` **`/session/:sessionId/location`**","metadata":{"loc":{"lines":{"from":60,"to":88}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/commands.md","filename":"commands.md","relativePath":"appium-xcuitest-driver/reference/commands.md"}},{"pageContent":"#### Returned Result\n\n`Promise`<`altitude`: `number`, `latitude`: `number`, `longitude`: `number`\\>\n\n### `setGeoLocation`\n\n`POST` **`/session/:sessionId/location`**\n\nSet location of the device under test.\n\nFor iOS 17+ real devices, this method will call the\n[`mobile: setSimulatedLocation`](./execute-methods.md#mobile-setsimulatedlocation) extension.\n\n#### Arguments\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `location` | `Location` | An object with `latitude` and `longitude` values |\n\n#### Returned Result\n\n`Promise`<`altitude`: `number`, `latitude`: `number`, `longitude`: `number`\\>\n\n### `startRecordingScreen`\n\n`POST` **`/session/:sessionId/appium/start_recording_screen`**\n\nStart recording the device screen. This functionality is available in the iOS Simulator since\nXcode 9, and in real devices since iOS 11.","metadata":{"loc":{"lines":{"from":82,"to":110}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/commands.md","filename":"commands.md","relativePath":"appium-xcuitest-driver/reference/commands.md"}},{"pageContent":"Start recording the device screen. This functionality is available in the iOS Simulator since\nXcode 9, and in real devices since iOS 11.\n\nScreen activity is recorded to an MPEG-4 file. Note that audio is not recorded with the video file.\nIf the screen recording has already been started, this command will force stop it and start a new\nrecording. The previously recorded video file will also be deleted.\n\n!!! info\n\n This command requires the `ffmpeg` utility to be installed (`brew install ffmpeg`)\n\n**`Throws`**\n\nIf the screen recording has failed to start.\n\n#### Arguments\n\n| Name | Type |\n| :------ | :------ |\n| `options?` | `any` |\n\n#### Returned Result\n\n`string`\n\nBase64-encoded content of the recorded media file if any screen recording is currently running,\nor an empty string.\n\n### `stopRecordingScreen`\n\n`POST` **`/session/:sessionId/appium/stop_recording_screen`**","metadata":{"loc":{"lines":{"from":109,"to":139}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/commands.md","filename":"commands.md","relativePath":"appium-xcuitest-driver/reference/commands.md"}},{"pageContent":"### `stopRecordingScreen`\n\n`POST` **`/session/:sessionId/appium/stop_recording_screen`**\n\nStop an ongoing screen recording and return the video. This functionality is available in the iOS\nSimulator since Xcode 9, and in real devices since iOS 11.\n\n\nIf no screen recording process is running, the command will attempt to retrieve the most recently\nrecorded file. If no previously recorded file is found, the method will return an empty string.\n\n**`Throws`**\n\nIf there was an error while getting the name of a media file, or the file content cannot be uploaded\nto the remote location.\n\n#### Arguments\n\n| Name | Type |\n| :------ | :------ |\n| `options?` | `any` |\n\n#### Returned Result\n\n``null`` \\| `string`\n\nBase64-encoded content of the recorded media file if `remotePath` parameter is empty or null,\nor an empty string.\n\n### `getSize`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please refer to the [Get Element Rect][https://www.w3.org/TR/webdriver1/#dfn-get-element-rect] instead","metadata":{"loc":{"lines":{"from":137,"to":170}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/commands.md","filename":"commands.md","relativePath":"appium-xcuitest-driver/reference/commands.md"}},{"pageContent":"### `getSize`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please refer to the [Get Element Rect][https://www.w3.org/TR/webdriver1/#dfn-get-element-rect] instead\n\n`GET` **`/session/:sessionId/element/:elementId/size`**\n\nGet the size of an element\n\n#### Returned Result\n\n`Size`\n\nThe positions of the element\n\n### `submit`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please click the submit button instead\n\n`POST` **`/session/:sessionId/element/:elementId/submit`**\n\nSubmit the form an element is in\n\n#### Returned Result\n\n``null``\n\n### `background`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please use the [`mobile: backgroundApp`](./execute-methods.md#mobile-backgroundapp) extension instead\n\n`POST` **`/session/:sessionId/appium/app/background`**\n\nClose app (simulate device home button). It is possible to restore\nthe app after the timeout or keep it minimized based on the parameter value.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":166,"to":207}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/commands.md","filename":"commands.md","relativePath":"appium-xcuitest-driver/reference/commands.md"}},{"pageContent":"Close app (simulate device home button). It is possible to restore\nthe app after the timeout or keep it minimized based on the parameter value.\n\n#### Arguments\n\n| Name | Type |\n| :------ | :------ |\n| `seconds` | `any` |\n\n#### Returned Result\n\n`unknown`\n\n### `queryAppState`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please use the [`mobile: queryAppState`](./execute-methods.md#mobile-queryappstate) extension instead\n\n`POST` **`/session/:sessionId/appium/device/app_state`**\n\nGet the running state of an app\n\n#### Returned Result\n\n`AppState`\n\nA number representing the state. `0` means not installed, `1` means not running, `2`\nmeans running in background but suspended, `3` means running in the background, and `4` means\nrunning in the foreground\n\n### `isLocked`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please use the [`mobile: isLocked`](./execute-methods.md#mobile-islocked) extension instead\n\n`POST` **`/session/:sessionId/appium/device/is_locked`**","metadata":{"loc":{"lines":{"from":204,"to":241}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/commands.md","filename":"commands.md","relativePath":"appium-xcuitest-driver/reference/commands.md"}},{"pageContent":"This method is deprecated. Please use the [`mobile: isLocked`](./execute-methods.md#mobile-islocked) extension instead\n\n`POST` **`/session/:sessionId/appium/device/is_locked`**\n\nDetermine whether the device is locked\n\n#### Returned Result\n\n`boolean`\n\n`true` if the device is locked, `false` otherwise\n\n### `lock`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please use the [`mobile: lock`](./execute-methods.md#mobile-lock) extension instead\n\n`POST` **`/session/:sessionId/appium/device/lock`**\n\nLock the device (and optionally unlock the device after a certain amount of time)\n\n**`Default Value`**\n\n0\n\n#### Arguments\n\n| Name | Type |\n| :------ | :------ |\n| `seconds?` | `any` |\n\n#### Returned Result\n\n``null``\n\n### `unlock`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please use the [`mobile: unlock`](./execute-methods.md#mobile-unlock) extension instead\n\n`POST` **`/session/:sessionId/appium/device/unlock`**\n\nUnlock the device","metadata":{"loc":{"lines":{"from":239,"to":283}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/commands.md","filename":"commands.md","relativePath":"appium-xcuitest-driver/reference/commands.md"}},{"pageContent":"This method is deprecated. Please use the [`mobile: unlock`](./execute-methods.md#mobile-unlock) extension instead\n\n`POST` **`/session/:sessionId/appium/device/unlock`**\n\nUnlock the device\n\n<!-- comment source: method-signature -->\n\n#### Returned Result\n\n``null``\n\n### `mobileShake`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please use the [`mobile: shake`](./execute-methods.md#mobile-shake) extension instead\n\n`POST` **`/session/:sessionId/appium/device/shake`**\n\nShake the device\n\n#### Returned Result\n\n``null``\n\n### `getStrings`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please use the [`mobile: getAppStrings`](./execute-methods.md#mobile-getappstrings) extension instead\n\n`POST` **`/session/:sessionId/appium/app/strings`**\n\nReturn the language-specific strings for an app\n\n#### Arguments","metadata":{"loc":{"lines":{"from":279,"to":315}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/commands.md","filename":"commands.md","relativePath":"appium-xcuitest-driver/reference/commands.md"}},{"pageContent":"`POST` **`/session/:sessionId/appium/app/strings`**\n\nReturn the language-specific strings for an app\n\n#### Arguments\n\n| Name | Type | Default value | Description |\n| :------ | :------ | :------ | :------ |\n| `language?` | `any` | `undefined` | - |\n| `stringFile?` | `string` | `null` | The language abbreviation to fetch app strings mapping for. If no language is provided then strings for the 'en language would be returned |\n\n#### Returned Result\n\n`StringRecord`<`string`\\>\n\nA record of localized keys to localized text\n\n### `setValueImmediate`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated\n\n`POST` **`/session/:sessionId/appium/element/:elementId/value`**\n\n#### Arguments\n\n| Name | Type |\n| :------ | :------ |\n| `text` | `any` |\n\n#### Returned Result\n\n``null``\n\n### `keys`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please use `setValue` instead\n\n`POST` **`/session/:sessionId/keys`**\n\nSend keys to the app\n\n#### Arguments","metadata":{"loc":{"lines":{"from":311,"to":356}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/commands.md","filename":"commands.md","relativePath":"appium-xcuitest-driver/reference/commands.md"}},{"pageContent":"``null``\n\n### `keys`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please use `setValue` instead\n\n`POST` **`/session/:sessionId/keys`**\n\nSend keys to the app\n\n#### Arguments\n\n| Name | Type |\n| :------ | :------ |\n| `value` | `any` |\n\n#### Returned Result\n\n``null``\n\n### `receiveAsyncResponse`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please use the [Execute Async Script](https://www.w3.org/TR/webdriver1/#dfn-execute-async-script) instead\n\n`POST` **`/session/:sessionId/appium/receive_async_response`**\n\nCollect the response of an async script execution\n\n#### Arguments\n\n| Name | Type |\n| :------ | :------ |\n| `response` | `any` |\n\n#### Returned Result\n\n``null``\n\n### `toggleEnrollTouchId`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please use the [`mobile: enrollBiometric`](./execute-methods.md#mobile-enrollbiometric) extension instead\n\n`POST` **`/session/:sessionId/appium/simulator/toggle_touch_id_enrollment`**","metadata":{"loc":{"lines":{"from":344,"to":392}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/commands.md","filename":"commands.md","relativePath":"appium-xcuitest-driver/reference/commands.md"}},{"pageContent":"`POST` **`/session/:sessionId/appium/simulator/toggle_touch_id_enrollment`**\n\nToggle whether the device is enrolled in the touch ID program\n\n#### Arguments\n\n| Name | Type | Default value |\n| :------ | :------ | :------ |\n| `enabled?` | `any` | `true` |\n\n#### Returned Result\n\n``null``\n\n### `touchId`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please use the [`mobile: sendBiometricMatch`](./execute-methods.md#mobile-sendbiometricmatch) extension instead\n\n`POST` **`/session/:sessionId/appium/simulator/touch_id`**\n\nTrigger a touch/fingerprint match or match failure\n\n#### Arguments\n\n| Name | Type | Default value |\n| :------ | :------ | :------ |\n| `match` | `any` | `true` |\n\n#### Returned Result\n\n``null``\n\n### `asyncScriptTimeout`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please use `scriptTimeoutW3C` instead\n\n`POST` **`/session/:sessionId/timeouts/async_script`**\n\nAlias for XCUITestDriver.scriptTimeoutW3C.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":392,"to":436}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/commands.md","filename":"commands.md","relativePath":"appium-xcuitest-driver/reference/commands.md"}},{"pageContent":"This method is deprecated. Please use `scriptTimeoutW3C` instead\n\n`POST` **`/session/:sessionId/timeouts/async_script`**\n\nAlias for XCUITestDriver.scriptTimeoutW3C.\n\n#### Arguments\n\n| Name | Type |\n| :------ | :------ |\n| `ms` | `any` |\n\n#### Returned Result\n\n``null``\n\n### `getLocation`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please use `getElementRect` instead\n\n`GET` **`/session/:sessionId/element/:elementId/location`**\n\nGet the position of an element on screen\n\n#### Returned Result\n\n`Position`\n\nThe position of the element\n\n### `getLocationInView`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please use `getElementRect` instead\n\n`GET` **`/session/:sessionId/element/:elementId/location_in_view`**\n\nAlias for `getLocation`\n\n#### Returned Result\n\n`Position`\n\nThe position of the element\n\n### `getWindowSize`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please use `getElementRect` instead","metadata":{"loc":{"lines":{"from":430,"to":482}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/commands.md","filename":"commands.md","relativePath":"appium-xcuitest-driver/reference/commands.md"}},{"pageContent":"#### Returned Result\n\n`Position`\n\nThe position of the element\n\n### `getWindowSize`\n\n!!! warning \"Deprecated\"\n\n This method is deprecated. Please use `getElementRect` instead\n\n`GET` **`/session/:sessionId/window/:windowhandle/size`**\n\nGet the window size\n\n#### Returned Result\n\n`any`","metadata":{"loc":{"lines":{"from":472,"to":490}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/commands.md","filename":"commands.md","relativePath":"appium-xcuitest-driver/reference/commands.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Element Attributes\n---\n\nThe XCUITest driver supports the following element attributes:","metadata":{"loc":{"lines":{"from":1,"to":8}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/element-attributes.md","filename":"element-attributes.md","relativePath":"appium-xcuitest-driver/reference/element-attributes.md"}},{"pageContent":"| <div style=\"width:6em\">Name</div> | Description | <div style=\"width:8em\">Example</div> |\n| --- | --- | --- |","metadata":{"loc":{"lines":{"from":10,"to":11}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/element-attributes.md","filename":"element-attributes.md","relativePath":"appium-xcuitest-driver/reference/element-attributes.md"}},{"pageContent":"| --- | --- | --- |\n| `name` | Could contain either element's [identifier](https://developer.apple.com/documentation/xctest/xcuielementattributes/1500981-identifier?language=objc) or its [label](https://developer.apple.com/documentation/xctest/xcuielementattributes/1500692-label?language=objc), depending on which one is available first. Could also be `null`. It is recommended to prefer the usage of [accessibilityIdentifier](https://developer.apple.com/documentation/uikit/uiaccessibilityidentification/1623132-accessibilityidentifier) over [accessibilityLabel](https://developer.apple.com/documentation/objectivec/nsobject/1615181-accessibilitylabel) for automation purposes, since the `identifier` property is supposed to stay constant under different locales and does not affect accessibility services such as VoiceOver. In applications written using [ReactNative](https://reactnative.dev/) framework this attribute reflects the value of the `testID` property. | `hello` |","metadata":{"loc":{"lines":{"from":11,"to":12}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/element-attributes.md","filename":"element-attributes.md","relativePath":"appium-xcuitest-driver/reference/element-attributes.md"}},{"pageContent":"| `label` | Element's [label](https://developer.apple.com/documentation/xctest/xcuielementattributes/1500692-label?language=objc) value. Could be `null`. Since XCUITest driver 4.7.3 (WebDriverAgent 4.8.0), the behavior of this value was better aligned with XCTest, so it could include line breaks (`\\n`). Before this version, line breaks were replaced by spaces. | `hello`, `hello\\nworld` |\n| `type` | Element's [type](https://developer.apple.com/documentation/xctest/xcuielementattributes/1500614-elementtype?language=objc) name | `XCUIElementTypeButton` |\n| `visible` | Whether the element is visible. This value is not available in the \"vanilla\" XCTest and is read directly from the accessibility layer | `false` |\n| `focused` | Whether the element is [focused](https://developer.apple.com/documentation/xctest/xcuielementattributes/1627636-hasfocus?language=objc). Before driver version 4.25.4, this was only available for tvOS. | `true` |","metadata":{"loc":{"lines":{"from":13,"to":16}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/element-attributes.md","filename":"element-attributes.md","relativePath":"appium-xcuitest-driver/reference/element-attributes.md"}},{"pageContent":"| `accessible` | Whether the element is accessible. This value is not available in the \"vanilla\" XCTest and is read directly from the accessibility layer | `true` |\n| `enabled` | Whether the element is [enabled](https://developer.apple.com/documentation/xctest/xcuielementattributes/1500330-enabled?language=objc). | `false` |\n| `selected` | Whether the element is [selected](https://developer.apple.com/documentation/xctest/xcuielementattributes/1500581-selected?language=objc) | `false` |\n| `index` | Element's index in the hierarchy relatively to its parent. Only available since Appium 1.20.0. Indexing starts from `0`. | `2` |\n| `rect` | Element's rectangle. The actual data of this attribute is based on element's [frame](https://developer.apple.com/documentation/xctest/xcuielementattributes/1500911-frame?language=objc). | `{'x': 0, 'y': 0, 'width': 100, 'height': 100}` |","metadata":{"loc":{"lines":{"from":17,"to":21}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/element-attributes.md","filename":"element-attributes.md","relativePath":"appium-xcuitest-driver/reference/element-attributes.md"}},{"pageContent":"| `value` | Element's value. This is a complex attribute, whose calculation algorithm depends on the actual element type. Check [WebDriverAgent sources](https://github.com/appium/WebDriverAgent/blob/master/WebDriverAgentLib/Categories/XCUIElement%2BFBWebDriverAttributes.m) to know more about how it is compiled (method `- (NSString *)wdValue`). Could be `null` | `hello` |","metadata":{"loc":{"lines":{"from":22,"to":22}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/element-attributes.md","filename":"element-attributes.md","relativePath":"appium-xcuitest-driver/reference/element-attributes.md"}},{"pageContent":"| `hittable` | Whether the element is [hittable](https://developer.apple.com/documentation/xctest/xcuielement/1500561-hittable). Note that XCTest hittable requires an element to have the [isAccessibilityElement](https://developer.apple.com/documentation/objectivec/nsobject-swift.class/isaccessibilityelement) property enabled. It means if the element is on screen, but it sets [accessibilityElementsHidden](https://developer.apple.com/documentation/objectivec/nsobject-swift.class/accessibilityelementshidden) to `false`, the hittable attribute will be `false`. This attribute is not included into the XML page source due to performance reasons, although you can use it in element locators or fetch its value using [getAttribute](https://www.w3.org/TR/webdriver2/#get-element-attribute) API. | `true` |\n|`placeholderValue` | Element's [placeolderValue](https://developer.apple.com/documentation/xctest/xcuielementattributes/placeholdervalue) value. | `Placeholder text`|","metadata":{"loc":{"lines":{"from":23,"to":24}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/element-attributes.md","filename":"element-attributes.md","relativePath":"appium-xcuitest-driver/reference/element-attributes.md"}},{"pageContent":"|`placeholderValue` | Element's [placeolderValue](https://developer.apple.com/documentation/xctest/xcuielementattributes/placeholdervalue) value. | `Placeholder text`|\n|`traits` | Element's [traits](https://developer.apple.com/documentation/uikit/uiaccessibilitytraits?language=objc) value. This attribute returns a comma-separated string of accessibility traits. This attribute is not included into the XML page source, it may only be retrieved via [getAttribute](https://www.w3.org/TR/webdriver2/#get-element-attribute) API.| `Button, Adjustable`, `Button` |","metadata":{"loc":{"lines":{"from":24,"to":25}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/element-attributes.md","filename":"element-attributes.md","relativePath":"appium-xcuitest-driver/reference/element-attributes.md"}},{"pageContent":"---\ntitle: Execute Methods\n---\n\nIn addition to standard W3C APIs, the driver provides many custom command extensions for executing\nplatform-specific scenarios. Use the following examples in order to invoke them from your client code:\n\n=== \"Java\"\n\n ```java\n var result = driver.executeScript(\"mobile: <methodName>\", Map.ofEntries(\n Map.entry(\"arg1\", \"value1\"),\n Map.entry(\"arg2\", \"value2\")\n // you may add more pairs if needed or skip providing the map completely\n // if all arguments are defined as optional\n ));\n ```\n\n=== \"JS (WebdriverIO)\"\n\n ```js\n const result = await driver.executeScript('mobile: <methodName>', [{\n arg1: \"value1\",\n arg2: \"value2\",\n }]);\n ```\n\n=== \"Python\"\n\n ```python\n result = driver.execute_script('mobile: <methodName>', {\n 'arg1': 'value1',\n 'arg2': 'value2',\n })\n ```\n\n=== \"Ruby\"","metadata":{"loc":{"lines":{"from":1,"to":37}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"=== \"Python\"\n\n ```python\n result = driver.execute_script('mobile: <methodName>', {\n 'arg1': 'value1',\n 'arg2': 'value2',\n })\n ```\n\n=== \"Ruby\"\n\n ```ruby\n result = @driver.execute_script 'mobile: <methodName>', {\n arg1: 'value1',\n arg2: 'value2',\n }\n ```\n\n=== \"C#\"\n\n ```csharp\n object result = driver.ExecuteScript(\"mobile: <methodName>\", new Dictionary<string, object>() {\n {\"arg1\", \"value1\"},\n {\"arg2\", \"value2\"}\n }));\n ```\n\n### mobile: selectPickerWheelValue\n\nPerforms selection of the next or previous picker wheel value. This might\nbe useful if these values are populated dynamically, so you don't know which\none to select or value selection suing `sendKeys` API does not work because of an XCTest bug. The method throws an exception if it fails to change the current picker value.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":28,"to":61}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId (`element` before version 1.22) | string | yes | PickerWheel's internal element id (as hexadecimal hash string) to perform value selection on. The element must be of type XCUIElementTypePickerWheel | abcdef12-1111-2222-3333-444444\norder | string | yes | Either `next` to select the value next to the current one from the target picker wheel or `previous` to select the previous one. | next\noffset | number | no | The value in range [0.01, 0.5]. It defines how far from picker wheel's center the click should happen. The actual distance is calculated by multiplying this value to the actual picker wheel height. Too small offset value may not change the picker wheel value and too high value may cause the wheel to switch two or more values at once. Usually the optimal value is located in range [0.15, 0.3]. `0.2` by default | 0.15","metadata":{"loc":{"lines":{"from":63,"to":67}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"value | string | no | If provided WDA will try to automatically scroll in the given direction until the actual picker value reaches the expected one or the amount of scrolling attempts is exceeded. | myvalue\nmaxAttempts | number | no | The maximum number of scrolling attempts to reach `value` before an error will be thrown. Only makes sense in combination with `value`. 25 by default | 50","metadata":{"loc":{"lines":{"from":68,"to":69}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: sendMemoryWarning\n\nSimulates sending of Low Memory warning to the target application.\nIt might be useful to verify the\n[didReceiveMemoryWarning](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621409-didreceivememorywarning?language=objc)\nAPI in the application under test.\nThis feature only works on real devices running iOS 17+ with Xcode 15+ SDK.\nThe target application must be running while this API is called.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nbundleId | string | yes | Bundle identifier of the app to simulate the warning for | com.great.app\n\n### mobile: alert\n\nTries to apply the given action to the currently visible alert.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":71,"to":90}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: alert\n\nTries to apply the given action to the currently visible alert.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\naction | string | yes | The actual action to apply. Could be either: `accept`, `dismiss` or `getButtons` | accept\nbuttonLabel | string | no | The name of the button used to perform the chosen alert action. Only makes sense if the action is `accept` or `dismiss` | Accept\n\n#### Returned Result\n\nThe list of alert button names if the selected action is `getButtons`\n\n### mobile: setPasteboard\n\nSets the Simulator's pasteboard content to the given value. Does not work for real devices.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ncontent | string | yes | The content to set | hello\nencoding | string | no | The content's encoding. `utf8` by default | ascii\n\n### mobile: getPasteboard\n\nGets the Simulator's pasteboard content. Does not work for real devices.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":86,"to":116}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: getPasteboard\n\nGets the Simulator's pasteboard content. Does not work for real devices.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nencoding | string | no | The expected encoding of the returned string. `utf8` by default | ascii\n\n#### Returned Result\n\nThe pasteboard content string.\n\n### mobile: source\n\nAllows to retrieve the source tree of the current page in different representation formats.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":112,"to":130}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nformat | string | yes | One of possible page tree source representation formats: `xml` (the default value), `description` and `json`. The `xml` format generates the output similar to what `getPageSource` standard API returns. `description` representation is how XCTest \"sees\" the page internally and is the same string as [debugDescription](https://developer.apple.com/documentation/xctest/xcuielement/1500909-debugdescription?language=objc) API would return for the root application element. This source representation format is useful for debugging purposes and is the fastest one to fetch. `json` representation is similar to `xml`, but the tree hierarchy there is represented as JSON elements tree rather than as XML nodes. | description","metadata":{"loc":{"lines":{"from":132,"to":134}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"excludedAttributes | string | no | One or more comma-separated attribute names to be excluded from the XML output, thus only makes sense if `format` is set to `xml`. It might be sometimes helpful to exclude, for example, the `visible` attribute, to significantly speed-up page source retrieval. | visible,accessible","metadata":{"loc":{"lines":{"from":135,"to":135}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Returned Result\n\nThe page source tree formatted according to the given format argument.\n\n### mobile: getContexts\n\nRetrieves the list of available contexts including the extended context information, like urls and page names. This is different from the standard `getContexts` API, because the latter only has web view names without any additional information. In situation where multiple web views are available at once the client code would have to connect to each of them in order to detect the one, which needs to be interacted with. Although, this extra effort is not needed with the information provided by this extension.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nwaitForWebviewMs | number | no | Tells Appium for how long (in milliseconds) to wait for web view(s) to appear. `5000`ms by default | 10000\n\n#### Returned Result\n\nThe list of available context objects along with their properties:","metadata":{"loc":{"lines":{"from":137,"to":153}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Returned Result\n\nThe list of available context objects along with their properties:\n\n- id: The identifier of the context. The native context will be 'NATIVE_APP' and the webviews will be 'WEBVIEW_xxx'\n- title: The title associated with the webview content. Could be `null`\n- url: The url associated with the webview content. Could be `null`\n\n### mobile: installApp\n\nInstalls the given application to the device under test. Make sure the application is built for a correct architecture and is signed with a proper developer signature (for real devices) prior to install it.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":151,"to":163}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\napp | string | yes | See the description of the `appium:app` capability | /path/to/my.app\ntimeoutMs | number | no | The maximum time to wait until app install is finished in milliseconds on real devices. If not provided then the value of `appium:appPushTimeout` capability is used. If the capability is not provided then equals to 240000ms | 500000\n**Deprecated** **Not Used since v7.15.0** strategy | string | no | One of possible app installation strategies on real devices. This argument is ignored on simulators. If not provided then the value of `appium:appInstallStrategy` is used. If the latter is also not provided then `serial` is used. See the description of `appium:appInstallStrategy` capability for more details on available values. | parallel","metadata":{"loc":{"lines":{"from":165,"to":169}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"checkVersion | bool | no | If set to `true`, it will make xcuitest driver to verify whether the app version currently installed on the device under test is older than the one, which is provided as `app` value. No app install is going to happen if the candidate app has the same or older version number than the already installed copy of it. The version number used for comparison must be provided as [CFBundleVersion](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion) [Semantic Versioning](https://semver.org/)-compatible value in the application's `Info.plist`. No validation is performed and the `app` is installed if `checkVersion` was not provided or `false`, which is default behavior. | true","metadata":{"loc":{"lines":{"from":170,"to":170}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: isAppInstalled\n\nChecks whether the given application is installed on the device under test.\n[Offloaded applications](https://discussions.apple.com/thread/254887240) are handled as not installed.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nbundleId | string | yes | The bundle identifier of the application to be checked | com.mycompany.myapp\n\n#### Returned Result\n\nEither `true` or `false`\n\n### mobile: removeApp\n\nRemoves the given application from the device under test.\n[Offloaded application](https://discussions.apple.com/thread/254887240) can also be removed.\n\nFor real devices, please also check [how to explicitly clear the application local data](../guides/troubleshooting.md#leftover-application-data-on-real-devices).\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nbundleId | string | yes | The bundle identifier of the application to be removed | com.mycompany.myapp","metadata":{"loc":{"lines":{"from":172,"to":198}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nbundleId | string | yes | The bundle identifier of the application to be removed | com.mycompany.myapp\n\n#### Returned Result\n\nEither `true` if the application was successfully uninstalled, otherwise `false`\n\n### mobile: launchApp\n\nExecutes the given application on the device under test. If the application is already running then it would be activated.\nIf the application is not installed or cannot be launched then an exception is thrown.\n\nIt accepts `arguments` and `environment` to start an application with them.","metadata":{"loc":{"lines":{"from":194,"to":209}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"It accepts `arguments` and `environment` to start an application with them.\n\nAs an usage example, `arguments` allow you to enforce language and locale for the application to start with.\nXCTest lets you to start an application process by specifying [Language and Locale IDs](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/LanguageandLocaleIDs/LanguageandLocaleIDs.html) via process `arguments` with `-AppleLanguages` and `-AppleLocale`.\nCheck the [Testing Specific Languages and Regions part of the Testing Your Internationalized App](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/TestingYourInternationalApp/TestingYourInternationalApp.html) for more details.\nMake sure to terminate the application before launching it with `arguments` if it is already running.\n\n=== \"Java\"","metadata":{"loc":{"lines":{"from":209,"to":216}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"=== \"Java\"\n\n ```java\n driver.executeScript(\"mobile:launchApp\", Map.of(\n \"bundleId\", \"com.apple.Preferences\",\n \"arguments\", Arrays.asList(\"-AppleLanguages\", \"(ja)\", \"-AppleLocale\", \"ja_JP\")\n ));\n ```\n\n=== \"JS (WebdriverIO)\"\n\n ```js\n await driver.executeScript('mobile:launchApp', [{\n bundleId: 'com.apple.Preferences',\n arguments: ['-AppleLanguages', '(ja)', '-AppleLocale', 'ja_JP']\n }]);\n ```\n\n=== \"Python\"\n\n ```python\n driver.execute_script(\"mobile:launchApp\", {\n \"bundleId\": \"com.apple.Preferences\",\n \"arguments\": [\"-AppleLanguages\", \"(ja)\", \"-AppleLocale\", \"ja_JP\"]\n })\n ```\n\n=== \"Ruby\"\n\n ```ruby\n driver.execute_script \"mobile:launchApp\", {\n \"bundleId\": \"com.apple.Preferences\",\n \"arguments\": [\"-AppleLanguages\", \"(ja)\", \"-AppleLocale\", \"ja_JP\"]\n }\n ```\n\n=== \"C#\"","metadata":{"loc":{"lines":{"from":216,"to":252}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"```ruby\n driver.execute_script \"mobile:launchApp\", {\n \"bundleId\": \"com.apple.Preferences\",\n \"arguments\": [\"-AppleLanguages\", \"(ja)\", \"-AppleLocale\", \"ja_JP\"]\n }\n ```\n\n=== \"C#\"\n\n ```csharp\n driver.ExecuteScript(\"mobile:launchApp\", new Dictionary<string, object>() {\n {\"bundleId\", \"com.apple.Preferences\"},\n {\"arguments\", new List<string>() { \"-AppleLanguages\", \"(ja)\", \"-AppleLocale\", \"ja_JP\" }}\n });\n ```\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nbundleId | string | yes | The bundle identifier of the application to be launched | com.mycompany.myapp\narguments | string&#124;array | no | One or more command line arguments for the app. If the app is already running then this argument is ignored. | ['-s', '-m']\nenvironment | dict | no | Environment variables mapping for the app. If the app is already running then this argument is ignored. | {'var': 'value'}\n\n### mobile: terminateApp","metadata":{"loc":{"lines":{"from":245,"to":269}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: terminateApp\n\nTerminates the given app on the device under test via [XCTest's terminate](https://developer.apple.com/documentation/xctest/xcuiapplication/1500637-terminate) API. If the app is not installed an exception is thrown. If the app is not running then nothing is done.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nbundleId | string | yes | The bundle identifier of the application to be terminated | com.mycompany.myapp\n\n#### Returned Result\n\nEither `true` if the app was successfully terminated, otherwise `false`\n\n### mobile: killApp\n\nKill the given app on the real device under test by instruments service.\nIf the app is not running or failed to kill, then nothing is done.\n\nXCUITest driver 4.4 and higher does not require [py-ios-device](https://github.com/YueChen-C/py-ios-device).\nXCUITest driver 4.3 requires [py-ios-device](https://github.com/YueChen-C/py-ios-device).\n\n#### Arguments","metadata":{"loc":{"lines":{"from":269,"to":291}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nbundleId | string | yes | The bundle identifier of the application to be terminated | com.mycompany.myapp\n\n#### Returned Result\n\nEither `true` if the app was successfully killed, otherwise `false`\n\n### mobile: queryAppState\n\nQueries the state of an installed application from the device under test. An exception will be thrown if the app with given identifier is not installed.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nbundleId | string | yes | The bundle identifier of the application to be queried | com.mycompany.myapp\n\n#### Returned Result\n\nAn integer number is returned, which encodes the application state. Possible values are described in [XCUIApplicationState](https://developer.apple.com/documentation/xctest/xcuiapplicationstate?language=objc) XCTest documentation topic.\n\n### mobile: activateApp","metadata":{"loc":{"lines":{"from":291,"to":315}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: activateApp\n\nPuts the given application to foreground if it is running in the background. An error is thrown if the app is not installed or is not running. Nothing is done if the app is already running in the foreground.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nbundleId | string | yes | The bundle identifier of the application to be activated | com.mycompany.myapp\n\n### mobile: listApps\n\nList applications installed on the real device under test. This extension throws an error if called\nfor a Simulator device.\nOffload applications will not be in the result.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\napplicationType | string | no | The type of applications to list. Either `System` or `User` (the default one) | System\n\n#### Returned Result","metadata":{"loc":{"lines":{"from":315,"to":337}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Returned Result\n\nA list of apps, where each item is a map where keys are bundle identifiers and values are maps of platform-specific app properties. Having `UIFileSharingEnabled` set to `true` in the app properties map means this app supports files upload and download into its `documents` container. Read the [File Transfer](../guides/file-transfer.md) guide for more details.\n\n### mobile: clearApp\n\nDeletes data files from the data container of an installed app,\nso it could start from the clean state next time it is launched.\nThe destination app will be terminated if it is running when this API is invoked.\nSometimes it might also be necessary to invoke the following APIs\nto fully reset the state of an installed app (make sure the app is not running while\ncalling them):\n- [mobile: clearKeychains](#mobile-clearkeychains)\n- [mobile: resetPermission](#mobile-resetpermission)","metadata":{"loc":{"lines":{"from":337,"to":350}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"This API might not be 100% reliable for some apps. The only reliable method to fully\nreset an existing app that Apple supports is to [uninstall](#mobile-removeapp) it and then perform a fresh [install](#mobile-installapp) of the same app.\n\nThis API only works on simulators. An exception is thrown if executed with real devices.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nbundleId | string | yes | The bundle identifier of the application to be cleared | com.mycompany.myapp\n\n#### Returned Result\n\n`true` if at least one item has been successfully deleted from the app data container.\n\n### mobile: startPerfRecord","metadata":{"loc":{"lines":{"from":352,"to":367}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Returned Result\n\n`true` if at least one item has been successfully deleted from the app data container.\n\n### mobile: startPerfRecord\n\nStarts performance profiling for the device under test.\nRelaxing security is mandatory for simulators. It can always work for real devices.\nSince XCode 12 the method tries to use `xctrace` tool to record performance stats.\nThe `instruments` developer utility is used as a fallback for this purpose if `xctrace` is not available. It is possible to record multiple profiles at the same time. Read [Instruments User Guide](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/Recording,Pausing,andStoppingTraces.html) for more details.\nIf the recording for the given profile is already running then nothing is done.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":363,"to":375}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ntimeout | number | no | The maximum count of milliseconds to record the profiling information. It is recommended to always limit the maximum duration of perf record operation, since the resulting logs are pretty huge and may easily exceed the free space on th local storage volume. `300000`ms by default (5 minutes) | `600000`\nprofileName | string | no | The name of existing performance profile to apply. Can also contain the full path to the chosen template on the server file system. Note, that not all profiles are supported on mobile devices. `Activity Monitor` by default. | `Time Profile`\npid | string or number | no | The ID of the process to measure the performance for. Set it to `current` in order to measure the performance of the process, which belongs to the currently active application. All processes running on the device are measured if pid is unset (the default setting). | current","metadata":{"loc":{"lines":{"from":375,"to":381}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: stopPerfRecord\n\nStops the performance recording operation previously started by `mobile: startPerfRecord` call. If the previous call has already been completed due to the timeout then its result is returned immediately. An error is thrown if the performance recording has failed to start and recorded no data.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":383,"to":387}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nprofileName | string | no | The name of existing performance profile to stop the recording for. Multiple recorders for different profile names could be executed at the same time. `Activity Monitor` by default. | `Time Profile`\nremotePath | string | no | The path to the remote location, where the resulting zipped .trace file should be uploaded. The following protocols are supported: http/https, ftp Null or empty string value (the default setting) means the content of resulting file should be zipped, encoded as Base64 and passed as the endpoint response value. An exception will be thrown if the generated file is too big to fit into the available process memory. | https://myserver/upload\nuser | string | no | The name of the user for the remote authentication. Only works if `remotePath` is provided. | myuser","metadata":{"loc":{"lines":{"from":389,"to":393}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"user | string | no | The name of the user for the remote authentication. Only works if `remotePath` is provided. | myuser\npass | string | no | The password for the remote authentication. Only works if `remotePath` is provided. | mypassword\nmethod | string | no | The http multipart upload method name. Only works if `remotePath` is provided. `PUT` by default | POST\nheaders | dict | no | Additional headers mapping for multipart http(s) uploads | {'User-Agent': 'Myserver 1.0'}\nfileFieldName | string | no | The name of the form field, where the file content BLOB should be stored for http(s) uploads. `file` by default | payload\nformFields | dict or array | no | Additional form fields for multipart http(s) uploads | {'field2': 'value2'}","metadata":{"loc":{"lines":{"from":393,"to":398}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Returned Result\n\nThe resulting file in .trace format can be either returned directly as base64-encoded zip archive or uploaded to a remote location (such files could be pretty large), depending on the `remotePath` argument value. Afterwards it is possible to unarchive and open such file with Xcode Developer Tools.\n\n### mobile: installCertificate","metadata":{"loc":{"lines":{"from":400,"to":404}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: installCertificate\n\nInstalls a custom certificate onto the device. Since Xcode SDK 11.4 Apple has added a dedicated simctl subcommand to quickly handle certificates on Simulator over CLI.\nOn real devices the certificate could be installed via CLI if [py-ios-device](https://github.com/YueChen-C/py-ios-device) tool is available on the server machine.\nOn simulators before Xcode 11.4 SDK Apple provides no official way to do it via the command line. In such case (and also as a fallback if CLI setup fails) this method tries to wrap the certificate into .mobileconfig format and then deploys the wrapped file to the internal HTTP server, so one can open it via mobile Safari. Then the algorithm goes through the profile installation procedure by clicking the necessary buttons using WebDriverAgent.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":404,"to":410}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ncontent | string | yes | Base64-encoded content of the public certificate in [PEM](https://knowledge.digicert.com/quovadis/ssl-certificates/ssl-general-topics/what-is-pem-format.html) format | a23234...\ncommonName | string | no | Common name of the certificate. If this is not set then the script will try to parse it from the given certificate content. | com.myorg\nisRoot | boolean | no | This option defines where the certificate should be installed to: either Trusted Root Store (`true`, the default option) or the Keychain (`false`). On environments other than Xcode 11.4+ Simulator this option is ignored. | false\n\n#### Returned Result\n\nThe content of the generated .mobileconfig file as base64-encoded string. This config might be useful for debugging purposes. If the certificate has been successfully set via CLI then nothing is returned.\n\n### mobile: removeCertificate","metadata":{"loc":{"lines":{"from":410,"to":422}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: removeCertificate\n\nRemoves installed certificate for real devices only if [py-ios-device](https://github.com/YueChen-C/py-ios-device) tool is available on the server machine since driver version 4.19.2.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nname | string | yes | Name of the profile | com.orgname.profile.mdmprofile\n\n#### Returned Result\n\nReturns status acknowledgment `{'Status': 'Acknowledged'}` if successfully removed certificate or `None` if unable to remove certificate.\n\n### mobile: listCertificates\n\nLists installed certificates for real devices only if [py-ios-device](https://github.com/YueChen-C/py-ios-device) tool is available on the server machine since driver version 4.10.0.\n\n#### Returned Result\n\nReturns map of certificates installed on the real device. The response looks like:","metadata":{"loc":{"lines":{"from":422,"to":442}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Returned Result\n\nReturns map of certificates installed on the real device. The response looks like:\n\n```json\n{\n 'OrderedIdentifiers': ['com.orgname.profile.mdmprofile'],\n 'ProfileManifest': {\n 'com.orgname.profile.mdmprofile': {\n 'Description': 'MDM Profile',\n 'IsActive': True\n }\n },\n 'ProfileMetadata': {\n 'com.orgname.profile.mdmprofile': {\n 'PayloadDescription': 'MDM Profile for testing,\n 'PayloadDisplayName': 'MDM Profile',\n 'PayloadOrganization': 'My Org, Inc.',\n 'PayloadRemovalDisallowed': False,\n 'PayloadUUID': '9ab3fa27-cc45-4c23-a94a-714686397a86',\n 'PayloadVersion': 1\n }\n },\n 'Status': 'Acknowledged'\n}\n```\n\n### mobile: startLogsBroadcast","metadata":{"loc":{"lines":{"from":440,"to":467}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: startLogsBroadcast\n\nStarts iOS system logs broadcast websocket on the same host and port where Appium server is running at `/ws/session/:sessionId:/appium/syslog` endpoint. The method will return immediately if the web socket is already listening.\nEach connected webcoket listener will receive syslog lines as soon as they are visible to Appium.\nRead [Using Mobile Execution Commands to Continuously Stream Device Logs with Appium](https://appiumpro.com/editions/55-using-mobile-execution-commands-to-continuously-stream-device-logs-with-appium) Appium Pro article for more details on this feature.\n\nConsider using [logs broadcast via BiDi](./bidi.md#logentryadded) over this extension.\n\n### mobile: stopLogsBroadcast\n\nStops the syslog broadcasting wesocket server previously started by `mobile: startLogsBroadcast`. This method will return immediately if no server is running.\n\nConsider using [logs broadcast via BiDi](./bidi.md#logentryadded) over this extension.","metadata":{"loc":{"lines":{"from":467,"to":479}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"Consider using [logs broadcast via BiDi](./bidi.md#logentryadded) over this extension.\n\n### mobile: batteryInfo\n\nReads the battery information from the device under test. This endpoint only returns reliable result on real devices.\n\n#### Returned Result\n\nThe actual battery info map, which consists of the following entries:\n\n- level: Battery level in range [0.0, 1.0], where 1.0 means 100% charge.\n- state: Battery state as an integer number. The following values are possible:\n * UIDeviceBatteryStateUnknown = 0\n * UIDeviceBatteryStateUnplugged = 1 // on battery, discharging\n * UIDeviceBatteryStateCharging = 2 // plugged in, less than 100%\n * UIDeviceBatteryStateFull = 3 // plugged in, at 100%\n\n### mobile: deviceInfo\n\nReturns the miscellaneous information about the device under test.\nIt includes device information via lockdown in a real device since XCUITest driver 4.2.0.\n\n#### Returned Result\n\nThe returned device information map contains the following entries:","metadata":{"loc":{"lines":{"from":479,"to":503}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"Name | Type | Description | Example\n--- | --- | --- | ---\ncurrentLocale | string | Device locale name. See [autoupdatingCurrentLocale](https://developer.apple.com/documentation/foundation/nslocale/1414388-autoupdatingcurrentlocale) for more details. | ja_EN, zh-Hant_US\ntimeZone | string | Device time zone name. See [NSTimeZone](https://developer.apple.com/documentation/foundation/nstimezone?language=objc) documentation for more details. | America/New_York\nname | string | Device name, synonym for model. Prior to iOS 16, user-assigned device name. See [UIDevice.name](https://developer.apple.com/documentation/uikit/uidevice/1620015-name?language=objc) documentation for more details. | iPhone\nmodel | string | The model of the device. See [UIDevice.model](https://developer.apple.com/documentation/uikit/uidevice/1620044-model?language=objc) documentation for more details. | iPod touch","metadata":{"loc":{"lines":{"from":505,"to":510}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"model | string | The model of the device. See [UIDevice.model](https://developer.apple.com/documentation/uikit/uidevice/1620044-model?language=objc) documentation for more details. | iPod touch\nuuid | string | Device [identifier for vendor](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor?language=objc). Could be equal to `unknown` if cannot be retrieved. | 12345abcd\nuserInterfaceIdiom | number | The style of the interface on the current device. Could help to determine the device type (e.g. iPhone vs iPad). See [UIDevice.userInterfaceIdiom](https://developer.apple.com/documentation/uikit/uidevice/1620037-userinterfaceidiom?language=objc) for more details. | 0 (UIUserInterfaceIdiomUnspecified), 1 (UIUserInterfaceIdiomPhone), 2 (UIUserInterfaceIdiomPad), 3 (UIUserInterfaceIdiomTV)","metadata":{"loc":{"lines":{"from":510,"to":512}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"userInterfaceStyle | string | The device's UI [appearance](https://developer.apple.com/documentation/xctest/xcuidevice/4108227-appearance?language=objc) style. Possible values are: `automatic`, `light`, `dark`, `unknown`. | dark\nisSimulator | number | Whether the device is a simulator (1) or a real device (0) | 1\nthermalState | number | Thermal state of the device. See [NSProcessInfoThermalState](https://developer.apple.com/documentation/foundation/nsprocessinfothermalstate) documentation on possible values. | 0 (NSProcessInfoThermalStateNominal), 1 (NSProcessInfoThermalStateFair), 2 (NSProcessInfoThermalStateSerious), 3 (NSProcessInfoThermalStateCritical)","metadata":{"loc":{"lines":{"from":513,"to":515}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: getDeviceTime\n\nReturns the actual device time.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nformat | string | no | The format specifier string. Read [MomentJS documentation](https://momentjs.com/docs/) to get the full list of supported datetime format specifiers. The default format is `YYYY-MM-DDTHH:mm:ssZ`, which complies to ISO-8601 | `YYYY-MM-DD HH:mm:ss`\n\n#### Returned Result\n\nThe retrieved datetime string formatted according to the given format specfier.\n\n### mobile: activeAppInfo\n\nReturns information about the active application.\n\n#### Returned Result\n\nThe API returns a map with the following entries","metadata":{"loc":{"lines":{"from":517,"to":537}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: activeAppInfo\n\nReturns information about the active application.\n\n#### Returned Result\n\nThe API returns a map with the following entries\n\nName | Type | Description | Example\n--- | --- | --- | ---\npid | number | The process identifier of the active application | 1234\nbundleId | string | The bundle identifier of the active application | com.yolo.myapp\nname | string | The name of the active application, if present | Safari\nprocessArguments | map | The map containing actual process arguments. Check the description of the [appium:processArguments capability](./capabilities.md#webdriveragent) for more details on its format. Might be empty if no process arguments have been provided on the app startup. | {\"args\": [\"--help\"], \"env\": {\"PATH\": \"/\"}}\n\n### mobile: pressButton","metadata":{"loc":{"lines":{"from":531,"to":546}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: pressButton\n\nEmulates press action on the given physical device button. iOS is [pressButton:](https://developer.apple.com/documentation/xctest/xcuidevice/1619052-pressbutton), tvOS is [pressButton:](https://developer.apple.com/documentation/xctest/xcuiremote/1627475-pressbutton) or [pressButton:forDuration:](https://developer.apple.com/documentation/xctest/xcuiremote/1627476-pressbutton).\n[mobile: performIoHidEvent](#mobile-performiohidevent) calls a more universal API to perform press with duration on any supported device.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":546,"to":551}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nname | string | yes | The name of the button to be pressed. Supported button names for iOS-based devices are (case-insensitive): `home`, `volumeup`, `volumedown`. For tvOS-based devices (case-insensitive): `home`, `up`, `down`, `left`, `right`, `menu`, `playpause`, `select` | home\ndurationSeconds | number | no | Duration in float seconds for tvOS-based devices since Appium 1.22.0 | 10\n\n### mobile: pushNotification\n\nSimulates push notification delivery to Simulator.\nOnly application remote push notifications are supported. VoIP, Complication, File Provider,\nand other types are not supported. Check the output of `xcrun simctl help push`\ncommand for more details.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":551,"to":565}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nbundleId | string | yes | The bundle identifier of the target application | com.apple.Preferences\npayload | map | yes | Valid Apple Push Notification values. Read the `Create the JSON Payload` topic of the [official Apple documentation](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification?language=objc) for more details on the payload creation. | `{\"aps\": {\"alert\": {\"title\": \"This is a simulated notification!\"}, \"badge\": 3, \"sound\": \"default\"} }`\n\n### mobile: expectNotification","metadata":{"loc":{"lines":{"from":565,"to":572}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: expectNotification\n\nBlocks until the expected notification is delivered.\nIt is a thin wrapper over [XCTNSNotificationExpectation](https://developer.apple.com/documentation/xctest/xctnsnotificationexpectation?language=objc) and\n[XCTDarwinNotificationExpectation](https://developer.apple.com/documentation/xctest/xctdarwinnotificationexpectation?language=objc) entities.\nThe extension call throws [TimeoutError](https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/lib/error_exports_TimeoutError.html) if the expected notification has not been delivered within the given timeout.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":572,"to":579}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nname | string | yes | The name of the notification to expect | com.example.fooAllDone\ntype | string | no | Which notification type to expect. Either `plain` (the default value) to wait for a notification from the *default* notification center or `darwin` to wait for a system notification. | darwin\ntimeoutSeconds | number | no | For how long to wait until the notification is delivered in float seconds. 60 seconds by default | 5.5\n\n### mobile: performIoHidEvent","metadata":{"loc":{"lines":{"from":579,"to":587}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: performIoHidEvent\n\nEmulates triggering of the given low-level IO HID device event. Constants for possible events are defined\nin [HID Usage Tables](https://developer.apple.com/documentation/hiddriverkit/hid_usage_tables).\nFor example, in order to emulate single press on Home button the extension should be called with the following arguments:\n- page: `0x0C` (`kHIDPage_Consumer`, select the `Customer` page)\n- usage: `0x40` (`kHIDUsage_Csmr_Menu`, the `Csmr` prefix here means this usage is dedicated to the `Customer` page)\n- durationSeconds: `0.005` (The event duration should be 5 milliseconds to be recognized as a single press by iOS)\n\nSome popular constants:","metadata":{"loc":{"lines":{"from":587,"to":596}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"Some popular constants:\n\nName | Value | Description\n--- | --- | ---\nkHIDPage_Consumer | 0x0C | The page containing all usages prefixed with `kHIDUsage_Csmr_`\nkHIDUsage_Csmr_VolumeIncrement | 0xE9 | Volume Up\nkHIDUsage_Csmr_VolumeDecrement | 0xEA | Volume Down\nkHIDUsage_Csmr_Menu | 0x40 | Home\nkHIDUsage_Csmr_Power | 0x30 | Power/Lock\nkHIDUsage_Csmr_Snapshot | 0x65 | Power + Home\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\npage | int | yes | The event page identifier. Look for constants perfixed with `kHIDPage_` in the table above | 0x0C\nusage | int | yes | The event usage identifier (usages are defined per-page). Look for constants prefixed with `kHIDUsage_` in the table above | 0x40\ndurationSeconds | number | yes | The event duration in float seconds. XCTest uses `0.005` for a single press event duration | 2.5\n\n### mobile: enrollBiometric\n\nEnrolls biometric authentication on Simulator.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":596,"to":619}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: enrollBiometric\n\nEnrolls biometric authentication on Simulator.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nisEnabled | boolean | no | Whether to enable/disable biometric enrollment. `true` by default. | true\n\n### mobile: sendBiometricMatch\n\nEmulates biometric match/non-match event on Simulator. The biometric feature is expected to be already enrolled before executing that.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ntype | string | no | The biometric feature name. Either `touchId` or `faceId`. `touchId` by default. | faceId\nmatch | boolean | no | Whether to simulate biometric match (`true`, the default value) or non-match (`false`). | true\n\n### mobile: isBiometricEnrolled\n\nChecks whether biometric is currently enrolled or not on a Simulator device.\n\n#### Returned Result\n\nEither `true` or `false`\n\n### mobile: clearKeychains","metadata":{"loc":{"lines":{"from":615,"to":644}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: isBiometricEnrolled\n\nChecks whether biometric is currently enrolled or not on a Simulator device.\n\n#### Returned Result\n\nEither `true` or `false`\n\n### mobile: clearKeychains\n\nClears keychains on Simulator. An exception is thrown for real devices.\n\n### mobile: getPermission\n\nGets application permission state on Simulator. This method requires [WIX applesimutils](https://github.com/wix/AppleSimulatorUtils) to be installed on the host where Appium server is running.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nbundleId | string | yes | The bundle identifier of the destination app. | com.mycompany.myapp\nservice | string | yes | One of available service names. The following services are supported: `calendar`, `camera`, `contacts`, `homekit`, `microphone`, `photos`, `reminders`, `medialibrary`, `motion`, `health`, `siri`, `speech`. | true\n\n#### Returned Result\n\nEither 'yes', 'no', 'unset' or 'limited'\n\n### mobile: setPermission","metadata":{"loc":{"lines":{"from":636,"to":663}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Returned Result\n\nEither 'yes', 'no', 'unset' or 'limited'\n\n### mobile: setPermission\n\nSet application permission state on Simulator.\n\n`location` and `location-always` services are by `xcrun simctl privacy` command since XCUITest driver version 5.11.0.\nThe command will kill the `bundleId` application process if it is running.\n\nOther services such as `contacts` are processed by [WIX applesimutils](https://github.com/wix/AppleSimulatorUtils), which will not kill the `bundleId` application process.\n[WIX applesimutils](https://github.com/wix/AppleSimulatorUtils) needs to be installed on the host where Appium server is running.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":659,"to":673}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nbundleId | string | yes | The bundle identifier of the destination app. | com.mycompany.myapp","metadata":{"loc":{"lines":{"from":675,"to":677}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"bundleId | string | yes | The bundle identifier of the destination app. | com.mycompany.myapp\naccess | map | yes | One or more access rules to set. The following keys are supported: `all` (Apply the action to all services), `calendar` (Allow access to calendar), `contacts-limited` (Allow access to basic contact info), `contacts` (Allow access to full contact details), `location` (Allow access to location services when app is in use), `location-always` (Allow access to location services at all times), `photos-add` (Allow adding photos to the photo library), `photos` (Allow full access to the photo library), `media-library` (Allow access to the media library), `microphone` (Allow access to audio input), `motion` (Allow access to motion and fitness data), `reminders` (Allow access to reminders), `siri` (Allow use of the app with Siri.). The following values are supported: `yes` (To grant the permission), `no` (To revoke the permission), `unset` (To reset the permission) | {'all': 'yes'}","metadata":{"loc":{"lines":{"from":677,"to":678}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: resetPermission\n\nResets the given permission for the active application under test. Works for both Simulator and real devices using Xcode SDK 11.4+\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nservice | string or int | yes | One of available service names. The supported service names are: `calendar`, `camera`, `contacts`, `health`, `homekit`, `keyboardnet`, `location`, `medialibrary`, `microphone`, `photos`, `reminders`, `systemroot`, `userdesktop`, `userdocuments`, `userdownloads`, `bluetooth`. This could also be an integer protected resource identifier taken from [XCUIProtectedResource](https://developer.apple.com/documentation/xctest/xcuiprotectedresource?language=objc) | photos\n\n### mobile: getAppearance\n\nGet the device's UI appearance style.\n\n#### Returned Result\n\nAn object, with the following entries:\n- style: The device's UI appearance value. This could be one of: `light`, `dark`, `unknown`, `unsupported`","metadata":{"loc":{"lines":{"from":680,"to":697}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Returned Result\n\nAn object, with the following entries:\n- style: The device's UI appearance value. This could be one of: `light`, `dark`, `unknown`, `unsupported`\n\n### mobile: setAppearance\n\nSet the device's UI appearance style.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nstyle | string | yes | Either `light` or `dark` | dark\n\n### mobile: getIncreaseContrast\n\nGet the device's \"increase contrast\" accessibility mode.\nThis API only works on simulators. An exception is thrown if executed with real devices.\n\n#### Returned Result\n\nOne of below:\n\n- `enabled`: Increase Contrast is enabled.\n- `disabled`: Increase Contrast is disabled.\n- `unsupported`: The platform or runtime version does not support the Increase Contrast setting.\n- `unknown`: The current setting is unknown or there was an error detecting it.\n\n\n### mobile: setIncreaseContrast","metadata":{"loc":{"lines":{"from":694,"to":724}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: setIncreaseContrast\n\nEnable or disable the device's \"increase contrast\" accessibility mode.\nThis API only works on simulators. An exception is thrown if executed with real devices.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nincreaseContrast | string | yes | Either `enabled` or `disabled` (case insensitive) | 'enabled'\n\n### mobile: contentSize\n\nGet the device's content size.\nThis API only works on simulators. An exception is thrown if executed with real devices.\n\n#### Returned Result\n\nOne of below:\n\n- `extra-small`\n- `small`\n- `medium`\n- `large`\n- `extra-large`\n- `extra-extra-large`\n- `extra-extra-extra-large`\n- `accessibility-medium`\n- `accessibility-large`\n- `accessibility-extra-large`\n- `accessibility-extra-extra-large`\n- `accessibility-extra-extra-extra-large`\n- `unknown`\n- `unsupported`\n\n### mobile: setContentSize","metadata":{"loc":{"lines":{"from":724,"to":759}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: setContentSize\n\nSet the device's content size.\nThis API only works on simulators. An exception is thrown if executed with real devices.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nsize | string | yes | One of the content sizes listed below in case-insensitive. | large\n\n- `extra-small`\n- `small`\n- `medium`\n- `large`\n- `extra-large`\n- `extra-extra-large`\n- `extra-extra-extra-large`\n- `accessibility-medium`\n- `accessibility-large`\n- `accessibility-extra-large`\n- `accessibility-extra-extra-large`\n- `accessibility-extra-extra-extra-large`\n\n### mobile: getClipboard\n\nGets the content of the primary clipboard on the device under test.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ncontentType | string | no | `plaintext` (default), `image` or `url` | image\n\n#### Returned Result","metadata":{"loc":{"lines":{"from":759,"to":793}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ncontentType | string | no | `plaintext` (default), `image` or `url` | image\n\n#### Returned Result\n\nThe actual clipboard content encoded into base64 string.\nAn empty string is returned if the clipboard contains no data.\n\n### mobile: setClipboard\n\nSets the primary clipboard's content on the device under test.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ncontent| string | yes | The content to be set as base64-encoded string. | QXBwaXVt\ncontentType | string | no | `plaintext` (default), `image` or `url` | image\n\n### mobile: siriCommand","metadata":{"loc":{"lines":{"from":787,"to":809}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: siriCommand\n\nPresents the Siri UI, if it is not currently active, and accepts a string which is then processed as if it were recognized speech. Check the documentation on [activateWithVoiceRecognitionText](https://developer.apple.com/documentation/xctest/xcuisiriservice/2852140-activatewithvoicerecognitiontext?language=objc) XCTest method for more details.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ntext | string | yes | The actual command that will be passed to Siri service | Hello Siri\n\n### mobile: pullFile\n\nPulls a remote file from the device.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nremotePath | string | yes | The path to an existing remote file on the device. See the [File Transfer](../guides/file-transfer.md) guide for accepted formats. If the file with the given name does not exist an exception will be thrown. | @com.mycompany.myapp:documents/myfile.txt","metadata":{"loc":{"lines":{"from":809,"to":827}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Returned Result\n\nBase64-encoded string, which represents the content of the remote file.\n\n### mobile: pushFile\n\nPushes a local file to the device.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nremotePath | string | yes | The path on the device to where the payload should be written. The value format is similar to the one used in [pullFile](#mobile-pullfile) extension. If the file with the same name already exists then it will be silently overridden. | @com.mycompany.myapp:documents/myfile.txt\npayload | string | yes | Base64-encoded content of the file to be pushed. | QXBwaXVt\n\n### mobile: pullFolder\n\nPulls a remote folder from the device.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nremotePath | string | yes | Same as for [pullFile](#mobile-pullfile) extension, but should be pointing to a remote folder | @com.mycompany.myapp:documents/myfolder/\n\n#### Returned Result","metadata":{"loc":{"lines":{"from":829,"to":854}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Returned Result\n\nBase64-encoded string, which represents the zipped content of the remote folder.\n\n### mobile: deleteFile\n\nDeletes the given file from the device under test.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nremotePath | string | yes | Same as for [pullFile](#mobile-pullfile) extension | @com.mycompany.myapp:documents/myfile.txt\n\n### mobile: deleteFolder\n\nDeletes the given folder from the device under test.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nremotePath | string | yes | Same value as for `mobile: deleteFile` except of the fact it should be pointing to a folder and should end with a single slash `/` | @com.mycompany.myapp:documents/myfolder/\n\n### mobile: configureLocalization","metadata":{"loc":{"lines":{"from":854,"to":878}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: configureLocalization\n\nChange localization settings on the currently booted Simulator.\nThe changed settings are only applied for the *newly started* applications/activities.\nCurrently running applications will stay unchanged. This means, for example, that the keyboard\nshould be hidden and shown again in order to observe the changed layout, and corresponding\napps must be restarted in order to observe their interface using the newly set locale/language.\nAlso this method might leave some system UI alerts untranslated.\nBe careful while setting the actual arguments since their actual values are not strictly checked.\nThis could lead to an unexpected behavior if an incorrect/unsupported language or locale abbreviation is provided.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":878,"to":889}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nkeyboard | map | no | On-screen keyboard properties. The `name` key is required and should be set to a valid locale abbreviation. The `layout` key is also required. The `hardware` key is optional and could be omitted or set to `Automated`. You could switch the keyboard layout in system preferences of your booted simulator, run `xcrun simctl spawn booted defaults read .GlobalPreferences.plist`, and inspect the value of `AppleKeyboards` to see possible combinations. | `{\"name\": \"de_CH\", \"layout\": \"QWERTZ\", \"hardware\": \"Automated\"}`\nlanguage | map | no | System language properties. The `name` key is required and should be set to a valid language abbreviation. You could switch the system language in preferences of your booted simulator, run `xcrun simctl spawn booted defaults read .GlobalPreferences.plist`, and inspect the value of `AppleLanguages` to see possible combinations. | `{\"name\": \"zh-Hant-CN\"}`","metadata":{"loc":{"lines":{"from":891,"to":894}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"locale | map | no | System locale properties. The `name` key is required and should be set to a valid language abbreviation. The `calendar`key is optional and could be set to a valid calendar format name. You could switch the system locale/calendar format in preferences of your booted simulator, run `xcrun simctl spawn booted defaults read .GlobalPreferences.plist`, and inspect the value of `AppleLocale` to see possible combinations. | `{\"name\": \"uk_UA\", \"calendar\": \"gregorian\"}`","metadata":{"loc":{"lines":{"from":895,"to":895}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Returned Result\n\n`true` if any of settings has been successfully changed.\n\n### mobile: startAudioRecording\n\nRecords the given hardware audio input into an .mp4 file. You must allow the `audio_record` security feature in order to use this extension. Also it is required that [FFMpeg](https://ffmpeg.org/) is installed on the machibe where Appium server is running.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":897,"to":905}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\naudioInput | string or int | yes | The name of the corresponding audio input device to use for the capture. The full list of capture devices could be shown using `ffmpeg -f avfoundation -list_devices true -i \"\"` Terminal command. | 1\naudioCodec | string | no | The name of the audio codec. The Advanced Audio Codec (aac) is used by default. | aac\naudioBitrate | string | no | The bitrate of the resulting audio stream. `128k` by default. | 256k\naudioChannels | string or int | no | The count of audio channels in the resulting stream. Setting it to `1` will create a single channel (mono) audio stream. `2` By default | 1\naudioRate | string or int | no | The sampling rate of the resulting audio stream. 44100 by default | 22050\ntimeLimit | string or int | no | The maximum recording time, in seconds. The default value is `180`, the maximum value is `43200` (12 hours). | 60","metadata":{"loc":{"lines":{"from":907,"to":914}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"timeLimit | string or int | no | The maximum recording time, in seconds. The default value is `180`, the maximum value is `43200` (12 hours). | 60\nforceRestart | boolean | no | Whether to restart audio capture process forcefully when startRecordingAudio is called (`true`) or ignore the call until the current audio recording is completed (`false`, the default value). | true","metadata":{"loc":{"lines":{"from":914,"to":915}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: stopAudioRecording\n\nStops recording of the audio input. If no audio recording process is running then the endpoint will try to get the recently recorded file. If no previously recorded file is found and no active audio recording processes are running then the method returns an empty string.\n\n#### Returned Result\n\nBase64-encoded content of the recorded media file or an empty string if no audio recording has been started before.\n\n### mobile: startPcap\n\nStart mobile device network traffic capture. This extension only works if [py-ios-device](https://github.com/YueChen-C/py-ios-device) utility is installed on the server machine and only supports\nreal iOS devices.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":917,"to":930}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ntimeLimitSec | string or int | no | The maximum recording time, in seconds. The default value is `180`, the maximum value is `43200` (12 hours). | 60\nforceRestart | boolean | no | Whether to restart traffic capture process forcefully when startPcap is called (`true`) or ignore the call until the current traffic capture is completed (`false`, the default value). | true\n\n### mobile: stopPcap\n\nStops network traffic capture. If no traffic capture process is running then the endpoint will try to get the recently recorded file. If no previously recorded file is found and no active traffic capture processes are running then the method returns an empty string.\n\n#### Returned Result\n\nBase64-encoded content of the traffic capture file (.pcap) or an empty string if no traffic capture has been started before. Network capture files could be opened in [Wireshark](https://www.wireshark.org/) application.","metadata":{"loc":{"lines":{"from":930,"to":943}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: runXCTest\n\nRun a native XCTest script. Launches a subprocess that runs the XC Test and blocks until it is completed. Parses the stdout of the process and returns its result as an array. Facebook's [IDB](https://github.com/facebook/idb) tool is required to run such tests.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":945,"to":949}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ntestRunnerBundleId | string | yes | Test app bundle | io.appium.XCTesterAppUITests.xctrunner\nappUnderTestBundleId | string | yes | App-under-test bundle | com.mycompany.myapp\nxcTestBundleID | string | yes | xctest bundle id | io.appium.XCTesterAppUITests\ntestType | string | no | Test type. Either `ui` (the default one), `app` or `logic` | app\nenv | map | no | Environment variables mapping to be passed to the test | {'myvar': 'myvalue'}\nargs | array | no | Launch arguments to start the test with (see https://developer.apple.com/documentation/xctest/xcuiapplication/1500477-launcharguments for reference) | ['-arg1', '--arg2']\ntimeout | string or int | no | Timeout if session doesn't complete after given time (in milliseconds). `360000`ms by default | 120000\n\n#### Returned Result\n\nThe API calls returns a map with the following entries:","metadata":{"loc":{"lines":{"from":949,"to":963}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Returned Result\n\nThe API calls returns a map with the following entries:\n\n- results: The array of test results. Each item in this array conists of the following entries:\n * testName: Name of the test (e.g.: 'XCTesterAppUITests - XCTesterAppUITests.XCTesterAppUITests/testExample')\n * passed: Did the tests pass?\n * crashed: Did the tests crash?\n * status: Test result status (e.g.: 'passed', 'failed', 'crashed')\n * duration: How long did the tests take (in seconds)\n * failureMessage: Failure message (if applicable)\n * location The geolocation of the test (if applicable)\n- code: The exit code of the process. `0` value marks a successful execution.\n- signal: The signal that terminated the process. Could be `null` (e.g.: `SIGTERM`)\n\n### mobile: installXCTestBundle\n\nInstalls an XCTest bundle to the device under test. Facebook's [IDB](https://github.com/facebook/idb) tool is required to for this API to work.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":961,"to":980}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: installXCTestBundle\n\nInstalls an XCTest bundle to the device under test. Facebook's [IDB](https://github.com/facebook/idb) tool is required to for this API to work.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nxctestBundle | string | yes | Path to your xctest .app bundle. Could be an URL | /path/to/my/bundle.app\n\n### mobile: listXCTestBundles\n\nList XCTest bundles that are installed on device. Facebook's [IDB](https://github.com/facebook/idb) tool is required to for this API to work.\n\n#### Returned Result\n\nArray of XCTest bundles (e.g.: [\"XCTesterAppUITests.XCTesterAppUITests/testLaunchPerformance\"])\n\n### mobile: listXCTestsInTestBundle\n\nList XCTests in a test bundle. Facebook's [IDB](https://github.com/facebook/idb) tool is required to for this API to work.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nbundle | string | yes | Bundle ID of the XCTest | 'com.bundle.myapp'","metadata":{"loc":{"lines":{"from":976,"to":1002}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nbundle | string | yes | Bundle ID of the XCTest | 'com.bundle.myapp'\n\n#### Returned Result\n\nArray of xctests in the test bundle (e.g.: `[ 'XCTesterAppUITests.XCTesterAppUITests/testExample', 'XCTesterAppUITests.XCTesterAppUITests/testLaunchPerformance' ]`)\n\n### mobile: viewportRect\n\nRetrieves the viewport dimensions.\nThe viewport is the device's screen size with status bar size subtracted if the latter is present/visible.\n\n#### Returned Result\n\nThe response looks like `{\"value\":{\"left\":0,\"top\":96,\"width\":828,\"height\":1696}}`.\n\n`left` and `top` are distance from the `left` of the screen and the `top` of the screen. [iOS Drawing Concepts](https://developer.apple.com/library/archive/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/GraphicsDrawingOverview/GraphicsDrawingOverview.html) could help about the relationship of coordinate.\n\n`width` and `height` are the screen's width and height.","metadata":{"loc":{"lines":{"from":998,"to":1019}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"`width` and `height` are the screen's width and height.\n\n### mobile: viewportScreenshot\n\nTakes a screenshot of the device viewport (see [`mobile: viewportRect`](#mobile-viewportrect))\n\n!!! warning \"Unreliable\"\n\n This method is unreliable. We recommend using `getScreenshot` instead\n\n#### Returned Result\n\nBase64-encoded string, which represents the viewport screenshot.\n\n### mobile: deviceScreenInfo\n\nGet information about screen.\n\n#### Returned Result\n\nThe response looks like `{\"value\":{\"statusBarSize\":{\"width\":414,\"height\":48},\"scale\":2}}`\n\n`statusBarSize` contains status bar dimensions. It is the result of [status bar](https://developer.apple.com/documentation/xctest/xcuielementtypequeryprovider/1500428-statusbars).\n`scale` is [screen scale](https://developer.apple.com/documentation/uikit/uiscreen/1617836-scale).\n\n### mobile: swipe","metadata":{"loc":{"lines":{"from":1019,"to":1044}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: swipe\n\nThis gesture performs a simple \"swipe\" gesture on the particular screen element or\non the application element, which is usually the whole screen. This method does not\naccept coordinates and simply emulates single swipe with one finger. It might be\nuseful for such cases like album pagination, switching views, etc. More advanced\ncases may require to call [mobile: dragFromToForDuration](#mobile-dragfromtoforduration),\nwhere one can supply coordinates and duration.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1044,"to":1053}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId (\"element\" prior to Appium v 1.22) | string | no | The internal element identifier (as hexadecimal hash string) to swipe on. Application element will be used instead if this argument is not provided | fe50b60b-916d-420b-8728-ee2072ec53eb\ndirection | Either 'up', 'down', 'left' or 'right' | yes | The direction in which to swipe | up\nvelocity | number | no | This argument is optional and is only supported since Appium server version 1.19 and Xcode SDK version 11.4+. The value is measured in pixels per second and same values could behave differently on different devices depending on their display density. Higher values make swipe gesture faster (which usually scrolls larger areas if we apply it to a list) and lower values slow it down. Only values greater than zero have effect. | 250\n\n#### Examples\n\n=== \"Java\"","metadata":{"loc":{"lines":{"from":1053,"to":1063}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Examples\n\n=== \"Java\"\n\n ```java\n RemoteWebElement e = driver.findElement(AppiumBy.accessibilityId(\"target element\"));\n driver.executeScript(\"mobile: swipe\", ImmutableMap.of(\n \"velocity\": 2500,\n \"direction\": \"down\",\n \"elementId\", e.getId()\n ));\n ```\n\n=== \"JS (WebdriverIO)\"\n\n ```js\n const e = await $('~target element');\n await driver.executeScript(\"mobile: swipe\", [{\n velocity: 2500,\n direction: \"down\",\n elementId: e.elementId\n }]);\n\n=== \"Python\"\n\n ```python\n e = driver.find_element(by=AppiumBy.ACCESSIBILITY_ID, value='target element')\n driver.execute_script(\"mobile: swipe\", {\n \"velocity\": 2500,\n \"direction\": \"down\",\n \"elementId\": e.id\n })\n ```\n\n=== \"Ruby\"\n\n ```ruby\n e = driver.find_element :accessibility_id, 'target element'\n driver.execute_script 'mobile: swipe', {\n velocity: 2500,\n direction: 'down',\n elementId: e.ref\n }\n ```\n\n=== \"C#\"","metadata":{"loc":{"lines":{"from":1061,"to":1106}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"=== \"C#\"\n\n ```csharp\n var e = driver.FindElement(By.AccessibilityId(\"target element\"))\n driver.ExecuteScript(\"mobile: swipe\", new Dictionary<string, object>() {\n {\"elementId\", element.Id},\n {\"direction\", \"down\" },\n {\"velocity\", 2500 }\n });\n ```\n\n#### References","metadata":{"loc":{"lines":{"from":1106,"to":1117}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### References\n\n- [swipeDown](https://developer.apple.com/documentation/xctest/xcuielement/1618664-swipedown?language=objc)\n- [swipeDownWithVelocity:](https://developer.apple.com/documentation/xctest/xcuielement/3551694-swipedownwithvelocity?language=objc)\n- [swipeUp](https://developer.apple.com/documentation/xctest/xcuielement/1618667-swipeup?language=objc)\n- [swipeUpWithVelocity:](https://developer.apple.com/documentation/xctest/xcuielement/3551697-swipeupwithvelocity?language=objc)\n- [swipeLeft](https://developer.apple.com/documentation/xctest/xcuielement/1618668-swipeleft?language=objc)\n- [swipeLeftWithVelocity:](https://developer.apple.com/documentation/xctest/xcuielement/3551695-swipeleftwithvelocity?language=objc)\n- [swipeRight](https://developer.apple.com/documentation/xctest/xcuielement/1618674-swiperight?language=objc)\n- [swipeRightWithVelocity:](https://developer.apple.com/documentation/xctest/xcuielement/3551696-swiperightwithvelocity?language=objc)\n\n### mobile: scroll","metadata":{"loc":{"lines":{"from":1117,"to":1128}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: scroll\n\nScrolls the element or the whole screen. Different scrolling strategies are supported.\nArguments define the chosen strategy: either 'name', 'direction', 'predicateString' or\n'toVisible' in that order. All strategies are exclusive and only one strategy\ncan be applied at a single moment of time. Use \"mobile: scroll\" to emulate precise\nscrolling in tables or collection views, where it is already known to which element\nthe scrolling should be performed. Although, there is one known limitation there: in case\nit is necessary to perform too many scroll gestures on parent container to reach the\nnecessary child element (tens of them) then the method call may fail.\n_Important_: The implementation of this extension relies on several undocumented XCTest features, which might not always be reliable. Thus it might *not* always work as expected.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1128,"to":1140}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId (\"element\" prior to Appium v 1.22) | string | no | The internal element identifier (as hexadecimal hash string) to scroll on (e.g. the container). The active application element will be used instead if this parameter is not provided. | fe50b60b-916d-420b-8728-ee2072ec53eb\nname | string | no | The accessibility id of the child element, to which scrolling is performed. The same result can be achieved by setting _predicateString_ argument to 'name == accessibilityId'. Has no effect if _elementId_ is not a container | cell12\ndirection | Either 'up', 'down', 'left' or 'right' | yes | The main difference from [swipe](#mobile-swipe) call with the same argument is that _scroll_ will try to move the current viewport exactly to the next/previous page (the term \"page\" means the content, which fits into a single device screen) | down","metadata":{"loc":{"lines":{"from":1142,"to":1146}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"predicateString | string | no | The NSPredicate locator of the child element, to which the scrolling should be performed. Has no effect if _elementId_ is not a container | label == \"foo\"\ntoVisible | boolean | no | If set to _true_ then asks to scroll to the first visible _elementId_ in the parent container. Has no effect if _elementId_ is not set | true","metadata":{"loc":{"lines":{"from":1147,"to":1148}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Examples\n\n=== \"Java\"\n\n ```java\n driver.executeScript(\"mobile: scroll\", ImmutableMap.of(\n \"direction\", \"down\"\n ));\n ```\n\n=== \"JS (WebdriverIO)\"\n\n ```js\n await driver.executeScript('mobile: scroll', [{\n direction: 'down'\n }]);\n\n=== \"Python\"\n\n ```python\n driver.execute_script(\"mobile: scroll\", {\n \"direction\": \"down\"\n })\n ```\n\n=== \"Ruby\"\n\n ```ruby\n driver.execute_script 'mobile: scroll', {\n direction: 'down'\n }\n ```\n\n=== \"C#\"\n\n ```csharp\n driver.ExecuteScript(\"mobile: scroll\", new Dictionary<string, object>() {\n {\"direction\", \"down\"}\n });\n ```\n\n### mobile: pinch\n\nPerforms pinch gesture on the given element or on the application element.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1150,"to":1195}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: pinch\n\nPerforms pinch gesture on the given element or on the application element.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId (\"element\" prior to Appium v 1.22) | string | no | The internal element identifier (as hexadecimal hash string) to pinch on. The active application element will be used instead if this parameter is not provided. | fe50b60b-916d-420b-8728-ee2072ec53eb\nscale | number | yes | Pinch scale of type float. Use a scale between 0 and 1 to \"pinch close\" or zoom out and a scale greater than 1 to \"pinch open\" or zoom in. | 0.5\nvelocity | number | yes | The velocity of the pinch in scale factor per second (float value) | 2.2\n\n#### Examples\n\n=== \"Java\"\n\n ```java\n RemoteWebElement e = driver.findElement(AppiumBy.accessibilityId(\"target element\"));\n driver.executeScript(\"mobile: pinch\", ImmutableMap.of(\n \"scale\", 0.5,\n \"velocity\", 1.1,\n \"elementId\", e.getId()\n ));\n ```","metadata":{"loc":{"lines":{"from":1191,"to":1214}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"=== \"JS (WebdriverIO)\"\n\n ```js\n const e = await $('~target element');\n await driver.executeScript('mobile: pinch', [{\n scale: 0.5,\n velocity: 1.1,\n elementId: e.elementId\n }]);\n\n=== \"Python\"\n\n ```python\n e = driver.find_element(by=AppiumBy.ACCESSIBILITY_ID, value='target element')\n driver.execute_script(\"mobile: pinch\", {\n \"scale\": 0.5,\n \"velocity\": 1.1,\n \"elementId\": e.id\n })\n ```\n\n=== \"Ruby\"\n\n ```ruby\n e = driver.find_element :accessibility_id, 'target element'\n driver.execute_script 'mobile: pinch', {\n scale: 0.5,\n velocity: 1.1,\n elementId: e.ref\n }\n ```\n\n=== \"C#\"\n\n ```csharp\n var e = driver.FindElement(By.AccessibilityId(\"target element\"))\n driver.ExecuteScript(\"mobile: pinch\", new Dictionary<string, object>() {\n {\"elementId\", element.Id},\n {\"scale\", 0.5 },\n {\"velocity\", 1.1 },\n });\n ```\n\n#### Reference","metadata":{"loc":{"lines":{"from":1216,"to":1259}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Reference\n\n[pinchWithScale:velocity:](https://developer.apple.com/documentation/xctest/xcuielement/1618669-pinchwithscale?language=objc)\n\n### mobile: doubleTap\n\nPerforms double tap gesture on the given element or on the screen.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId (\"element\" prior to Appium v 1.22) | string | no | The internal element identifier (as hexadecimal hash string) to double tap on. The active application element will be used instead if this parameter is not provided. | fe50b60b-916d-420b-8728-ee2072ec53eb\nx | number | no | Horizontal coordinate offset. | 100\ny | number | no | Vertical coordinate offset. | 100\n\n#### Examples\n\n=== \"Java\"\n\n ```java\n RemoteWebElement e = driver.findElement(AppiumBy.accessibilityId(\"target element\"));\n driver.executeScript(\"mobile: doubleTap\", ImmutableMap.of(\n \"elementId\", e.getId()\n ));\n ```\n\n=== \"JS (WebdriverIO)\"","metadata":{"loc":{"lines":{"from":1259,"to":1286}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"=== \"JS (WebdriverIO)\"\n\n ```js\n const e = await $('~target element');\n await driver.executeScript('mobile: doubleTap', [{\n elementId: e.elementId\n }]);\n\n=== \"Python\"\n\n ```python\n e = driver.find_element(by=AppiumBy.ACCESSIBILITY_ID, value='target element')\n driver.execute_script(\"mobile: doubleTap\", {\n \"elementId\": e.id\n })\n ```\n\n=== \"Ruby\"\n\n ```ruby\n e = driver.find_element :accessibility_id, 'target element'\n driver.execute_script 'mobile: doubleTap', {\n elementId: e.ref\n }\n ```\n\n=== \"C#\"\n\n ```csharp\n var e = driver.FindElement(By.AccessibilityId(\"target element\"))\n driver.ExecuteScript(\"mobile: doubleTap\", new Dictionary<string, object>() {\n {\"elementId\", element.Id}\n });\n ```\n\n### mobile: touchAndHold\n\nPerforms long press gesture on the given element or on the screen.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1286,"to":1325}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: touchAndHold\n\nPerforms long press gesture on the given element or on the screen.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId (\"element\" prior to Appium v 1.22) | string | no | The internal element identifier (as hexadecimal hash string) to long tap on. The active application element will be used instead if this parameter is not provided. | fe50b60b-916d-420b-8728-ee2072ec53eb\nduration | number | yes | The float duration of press action in seconds | 1.5\nx | number | no | Horizontal coordinate offset. | 100\ny | number | no | Vertical coordinate offset. | 100\n\n#### Examples\n\n=== \"Java\"\n\n ```java\n RemoteWebElement e = driver.findElement(AppiumBy.accessibilityId(\"target element\"));\n driver.executeScript(\"mobile: touchAndHold\", ImmutableMap.of(\n \"elementId\", e.getId(),\n \"duration\", 2.0\n ));\n ```\n\n=== \"JS (WebdriverIO)\"","metadata":{"loc":{"lines":{"from":1321,"to":1346}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"=== \"JS (WebdriverIO)\"\n\n ```js\n const e = await $('~target element');\n await driver.executeScript('mobile: touchAndHold', [{\n elementId: e.elementId,\n duration: 2.0\n }]);\n\n=== \"Python\"\n\n ```python\n e = driver.find_element(by=AppiumBy.ACCESSIBILITY_ID, value='target element')\n driver.execute_script(\"mobile: touchAndHold\", {\n \"elementId\": e.id,\n \"duration\": 2.0\n })\n ```\n\n=== \"Ruby\"\n\n ```ruby\n e = driver.find_element :accessibility_id, 'target element'\n driver.execute_script 'mobile: touchAndHold', {\n elementId: e.ref,\n duration: 2.0\n }\n ```\n\n=== \"C#\"\n\n ```csharp\n var e = driver.FindElement(By.AccessibilityId(\"target element\"))\n driver.ExecuteScript(\"mobile: touchAndHold\", new Dictionary<string, object>() {\n {\"elementId\", element.Id},\n {\"duration\", 2.0}\n });\n ```\n\n#### Reference","metadata":{"loc":{"lines":{"from":1346,"to":1385}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Reference\n\n[pressForDuration:](https://developer.apple.com/documentation/xctest/xcuielement/1618663-pressforduration?language=objc)\n\n### mobile: twoFingerTap\n\nPerforms two finger tap gesture on the given element or on the application element.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId (\"element\" prior to Appium v 1.22) | string | no | The internal element identifier (as hexadecimal hash string) to tap on. The active application element will be used instead if this parameter is not provided. | fe50b60b-916d-420b-8728-ee2072ec53eb\n\n#### Examples\n\n=== \"Java\"\n\n ```java\n RemoteWebElement e = driver.findElement(AppiumBy.accessibilityId(\"target element\"));\n driver.executeScript(\"mobile: twoFingerTap\", ImmutableMap.of(\n \"elementId\", e.getId()\n ));\n ```\n\n=== \"JS (WebdriverIO)\"","metadata":{"loc":{"lines":{"from":1385,"to":1410}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"=== \"JS (WebdriverIO)\"\n\n ```js\n const e = await $('~target element');\n await driver.executeScript('mobile: twoFingerTap', [{\n elementId: e.elementId\n }]);\n\n=== \"Python\"\n\n ```python\n e = driver.find_element(by=AppiumBy.ACCESSIBILITY_ID, value='target element')\n driver.execute_script(\"mobile: twoFingerTap\", {\n \"elementId\": e.id\n })\n ```\n\n=== \"Ruby\"\n\n ```ruby\n e = driver.find_element :accessibility_id, 'target element'\n driver.execute_script 'mobile: twoFingerTap', {\n elementId: e.ref\n }\n ```\n\n=== \"C#\"\n\n ```csharp\n var e = driver.FindElement(By.AccessibilityId(\"target element\"))\n driver.ExecuteScript(\"mobile: twoFingerTap\", new Dictionary<string, object>() {\n {\"elementId\", element.Id}\n });\n ```\n\n#### Reference\n\n[twoFingerTap](https://developer.apple.com/documentation/xctest/xcuielement/1618675-twofingertap?language=objc)\n\n### mobile: tap","metadata":{"loc":{"lines":{"from":1410,"to":1449}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Reference\n\n[twoFingerTap](https://developer.apple.com/documentation/xctest/xcuielement/1618675-twofingertap?language=objc)\n\n### mobile: tap\n\nPerforms tap gesture by coordinates on the given element or on the screen.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId (\"element\" prior to Appium v 1.22) | string | no | The internal element identifier (as hexadecimal hash string) to tap on. _x_ and _y_ tap coordinates will be calculated relatively to the current element position on the screen if this argument is provided. Otherwise they should be calculated relatively to the active application element. | fe50b60b-916d-420b-8728-ee2072ec53eb\nx | number | yes | Horizontal coordinate offset. | 100\ny | number | yes | Vertical coordinate offset. | 100\n\n### mobile: dragFromToForDuration\n\nPerforms drag and drop gesture by coordinates. This can be done either on an element or\non the screen\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1445,"to":1466}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: dragFromToForDuration\n\nPerforms drag and drop gesture by coordinates. This can be done either on an element or\non the screen\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId (\"element\" prior to Appium v 1.22) | string | no | The internal element identifier (as hexadecimal hash string) to perform drag on. All the coordinates will be calculated relatively this this element position on the screen. Absolute screen coordinates are expected if this argument is not set | fe50b60b-916d-420b-8728-ee2072ec53eb\nduration | number | yes | Float number of seconds in range [0.5, 60]. How long the tap gesture at starting drag point should be before to start dragging | 5.3\nfromX | number | yes | The x coordinate of starting drag point | 100\nfromY | number | yes | The y coordinate of starting drag point | 100\ntoX | number | yes | The x coordinate of ending drag point | 200\ntoY | number | yes | The y coordinate of ending drag point | 200","metadata":{"loc":{"lines":{"from":1461,"to":1475}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Examples\n\n=== \"Java\"\n\n ```java\n RemoteWebElement e = driver.findElement(AppiumBy.accessibilityId(\"target element\"));\n driver.executeScript(\"mobile: dragFromToForDuration\", ImmutableMap.of(\n \"elementId\", e.getId(),\n \"duration\", 1.0,\n \"fromX\", 100,\n \"fromY\", 100,\n \"toX\", 200,\n \"toY\", 200\n ));\n ```\n\n=== \"JS (WebdriverIO)\"\n\n ```js\n const e = await $('~target element');\n await driver.executeScript('mobile: dragFromToForDuration', [{\n elementId: e.elementId,\n duration: 1.0,\n fromX: 100,\n fromY: 100,\n toX: 200,\n toY: 200\n }]);\n\n=== \"Python\"\n\n ```python\n e = driver.find_element(by=AppiumBy.ACCESSIBILITY_ID, value='target element')\n driver.execute_script(\"mobile: dragFromToForDuration\", {\n \"elementId\": e.id,\n \"duration\": 1.0,\n \"fromX\": 100,\n \"fromY\": 100,\n \"toX\": 200,\n \"toY\": 200\n })\n ```\n\n=== \"Ruby\"","metadata":{"loc":{"lines":{"from":1477,"to":1520}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"=== \"Ruby\"\n\n ```ruby\n e = driver.find_element :accessibility_id, 'target element'\n driver.execute_script 'mobile: dragFromToForDuration', {\n elementId: e.ref,\n duration: 1.0,\n fromX: 100,\n fromY: 100,\n toX: 200,\n toY: 200\n }\n ```\n\n=== \"C#\"\n\n ```csharp\n var e = driver.FindElement(By.AccessibilityId(\"target element\"))\n driver.ExecuteScript(\"mobile: dragFromToForDuration\", new Dictionary<string, object>() {\n {\"elementId\", element.Id},\n {\"duration\", 1.0,}\n {\"fromX\", 100},\n {\"fromY\", 100},\n {\"toX\", 200},\n {\"toY\", 200}\n });\n ```\n\n\n#### Reference\n\n[clickForDuration:thenDragToElement:](https://developer.apple.com/documentation/xctest/xcuielement/1500989-clickforduration?language=objc)\n\n### mobile: dragFromToWithVelocity\n\nInitiates a press-and-hold gesture, drags to another coordinate or an element with a velocity you specify, and holds for a duration you specify.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1520,"to":1557}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nfromElementId | string | no | The internal element identifier (as hexadecimal hash string) to start the drag gesture from. Absolute screen coordinates are expected if this argument is not set | fe50b60b-916d-420b-8728-ee2072ec53eb\ntoElementId | string | no | The internal element identifier (as hexadecimal hash string) to end the drag gesture on. This parameter is mandatory if `fromElementId` is provided | fe50b60b-916d-420b-8728-ee2072ec53eb\npressDuration | number | yes | Float number of seconds in range [0, 60]. How long the tap gesture at starting drag point should be before to start dragging | 0.5\nholdDuration | number | yes | Float number of seconds in range [0, 60]. The duration for which to hold over the other coordinate or the given element after dragging | 0.1","metadata":{"loc":{"lines":{"from":1559,"to":1564}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"holdDuration | number | yes | Float number of seconds in range [0, 60]. The duration for which to hold over the other coordinate or the given element after dragging | 0.1\nvelocity | number | yes | The speed at which to move from the initial press position to the other element or coordinate, expressed in pixels per second | 400\nfromX | number | no | The x coordinate of starting drag point. Must be provided if `fromElementId` is not defined | 100\nfromY | number | no | The y coordinate of starting drag point. Must be provided if `fromElementId` is not defined | 100\ntoX | number | no | The x coordinate of ending drag point. Must be provided if `fromElementId` is not defined | 200\ntoY | number | no | The y coordinate of ending drag point. Must be provided if `fromElementId` is not defined | 200","metadata":{"loc":{"lines":{"from":1564,"to":1569}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### References\n\n[pressForDuration:thenDragToElement:withVelocity:thenHoldForDuration:](https://developer.apple.com/documentation/xctest/xcuielement/3551693-pressforduration?language=objc)\n[pressForDuration:thenDragToCoordinate:withVelocity:thenHoldForDuration:](https://developer.apple.com/documentation/xctest/xcuicoordinate/3551692-pressforduration?language=objc)\n\n### mobile: rotateElement\n\nPerforms [rotate](https://developer.apple.com/documentation/xctest/xcuielement/1618665-rotate?language=objc) gesture on the given element.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1571,"to":1580}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: rotateElement\n\nPerforms [rotate](https://developer.apple.com/documentation/xctest/xcuielement/1618665-rotate?language=objc) gesture on the given element.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId (\"element\" prior to Appium v 1.22) | string | no | Internal element id (as hexadecimal hash string) to perform rotation on. The active application element will be used instead if this parameter is not provided. | fe50b60b-916d-420b-8728-ee2072ec53eb\nrotation | number | yes | The rotation of the gesture in radians | Math.PI\nvelocity | number | yes | The velocity of the rotation gesture in radians per second | Math.PI / 4\n\n#### Examples\n\n\n=== \"Java\"","metadata":{"loc":{"lines":{"from":1576,"to":1591}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Examples\n\n\n=== \"Java\"\n\n ```java\n RemoteWebElement e = driver.findElement(AppiumBy.accessibilityId(\"target element\"));\n driver.executeScript(\"mobile: rotateElement\", ImmutableMap.of(\n // rotate clockwise, 90 degrees\n \"rotation\", -Math.PI / 2,\n // in approximately two seconds\n \"velocity\", Math.PI / 4,\n \"elementId\", e.getId()\n ));\n ```\n\n=== \"JS (WebdriverIO)\"\n\n ```js\n const e = await $('~target element');\n await driver.executeScript('mobile: rotateElement', [{\n rotation: -Math.PI / 2,\n velocity: Math.PI / 4,\n elementId: e.elementId\n }]);\n ```\n\n=== \"Python\"\n\n ```python\n e = driver.find_element(by=AppiumBy.ACCESSIBILITY_ID, value='target element')\n driver.execute_script(\"mobile: rotateElement\", {\n \"rotation\": -math.pi / 2,\n \"velocity\": math.pi / 4,\n \"elementId\": e.id\n })\n ```\n\n=== \"Ruby\"","metadata":{"loc":{"lines":{"from":1588,"to":1626}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"=== \"Ruby\"\n\n ```ruby\n e = driver.find_element :accessibility_id, 'target element'\n driver.execute_script 'mobile: rotateElement', {\n elementId: e.ref,\n rotation: PI / 2,\n velocity: PI / 4\n }\n ```\n\n=== \"C#\"\n\n ```csharp\n var e = driver.FindElement(By.AccessibilityId(\"target element\"))\n driver.ExecuteScript(\"mobile: rotateElement\", new Dictionary<string, object>() {\n {\"elementId\", element.Id},\n {\"rotation\", -Math.PI / 2 },\n {\"velocity\", Math.PI / 4 },\n });\n ```\n\n\n#### Reference\n\n[rotate:withVelocity:](https://developer.apple.com/documentation/xctest/xcuielement/1618665-rotate?language=objc)\n\n### mobile: tapWithNumberOfTaps\n\nSends one or more taps with one or more touch points since Appium 1.17.1.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1626,"to":1657}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: tapWithNumberOfTaps\n\nSends one or more taps with one or more touch points since Appium 1.17.1.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId (\"element\" prior to Appium v 1.22) | string | no | The internal element identifier (as hexadecimal hash string) to perform one or more taps. The active application element will be used instead if this parameter is not provided.| fe50b60b-916d-420b-8728-ee2072ec53eb\nnumberOfTaps | number | no | The number of taps. 1 by default | 2\nnumberOfTouches | number | no | The number of touch points. 1 by default | 2\n\n#### Examples\n\n=== \"Java\"\n\n ```java\n RemoteWebElement e = driver.findElement(AppiumBy.accessibilityId(\"target element\"));\n var result = driver.executeScript(\"mobile: tapWithNumberOfTaps\", Map.of(\n \"elementId\", e.getId(),\n \"numberOfTaps\", 2,\n \"numberOfTouches\", 1,\n ));\n ```\n\n=== \"JS (WebdriverIO)\"","metadata":{"loc":{"lines":{"from":1653,"to":1678}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"=== \"JS (WebdriverIO)\"\n\n ```js\n const e = await $('~target element');\n await driver.executeScript('mobile: tapWithNumberOfTaps', [{\n elementId: e.elementId,\n numberOfTaps: 2,\n numberOfTouches: 1\n }]);\n ```\n\n=== \"Python\"\n\n ```python\n e = driver.find_element(by=AppiumBy.ACCESSIBILITY_ID, value='target element')\n driver.execute_script(\"mobile: tapWithNumberOfTaps\", {\n \"elementId\": e.id,\n \"numberOfTaps\": 2,\n \"numberOfTouches\": 1\n })\n ```\n\n=== \"Ruby\"\n\n ```ruby\n e = driver.find_element :accessibility_id, 'target element'\n driver.execute_script 'mobile: tapWithNumberOfTaps', {\n elementId: e.ref,\n numberOfTaps: 2,\n numberOfTouches: 1\n }\n ```\n\n=== \"C#\"","metadata":{"loc":{"lines":{"from":1678,"to":1711}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"=== \"C#\"\n\n ```csharp\n var e = driver.FindElement(By.AccessibilityId(\"target element\"))\n driver.ExecuteScript(\"mobile: touchAndHold\", new Dictionary<string, object>() {\n {\"elementId\", element.Id},\n {\"numberOfTaps\", 2 },\n {\"numberOfTouches\", 1 },\n });\n ```\n\n- numberOfTaps=1, numberOfTouches=1 -> \"vanilla\" single tap\n- numberOfTaps=2, numberOfTouches=1 -> double tap\n- numberOfTaps=3, numberOfTouches=1 -> triple tap\n- numberOfTaps=2, numberOfTouches=2 -> double tap with two fingers\n\n#### Reference\n[tapWithNumberOfTaps:numberOfTouches:](https://developer.apple.com/documentation/xctest/xcuielement/1618671-tapwithnumberoftaps)\n\n### mobile: forcePress\n\nEmulates force press on the given element/coordinates.\nAn error is thrown if the target device does not support force press gesture.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1711,"to":1735}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId | string | no | The internal element identifier (as hexadecimal hash string) to perform one or more taps. It is expected that both x and y are provided if this argument is omitted. If the element identifier is provided without coordinates then the actual element's touch point will be calculated automatically by WebDriverAgent. | fe50b60b-916d-420b-8728-ee2072ec53eb\nx | number | no | x coordinate of the gesture. It is calculated relatively to the given element (if provided). Otherwise the gesture destination point is calculated relatively to the active application. | 100\ny | number | no | y coordinate of the gesture. It is calculated relatively to the given element (if provided). Otherwise the gesture destination point is calculated relatively to the active application | 100","metadata":{"loc":{"lines":{"from":1737,"to":1741}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"duration | number | no | The float number of seconds the force press action would take. If duration is provided then it is also expected that a custom pressure value is provided as well. `0.5` by default. | 2.5\npressure | number | no | The float number defining how much pressure to apply. If pressure is provided then it is also expected that a custom duration value is provided as well. `1.0` by default | 1.5","metadata":{"loc":{"lines":{"from":1742,"to":1743}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: scrollToElement\n\nScrolls the current viewport to the given element. It is expected the destination element is inside a scrollable container and is hittable. The scroll direction is detected automatically.\nThis API uses native XCTest calls, so it performs scrolling pretty fast. The same native call is\nimplicitly performed by a vanilla `click` API if the destination element is out of the current viewport. An exception is thrown if the scrolling action cannot be performed.\nThis extension is available since the driver version 4.7.0.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId | string | yes | The internal element identifier (as hexadecimal hash string) to scroll to. The destination element must be located in a scrollable container and must be hittable. If the element is already present in the current viewport then no action is performed. | fe50b60b-916d-420b-8728-ee2072ec53eb\n\n### mobile: resetLocationService","metadata":{"loc":{"lines":{"from":1745,"to":1758}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: resetLocationService\n\nReset the location service on real device since Appium 1.22.0.\nIt could delay a few seconds to reflect the location by the system.\nIt raises an error if the device is simulator or an error occurred during the reset.\n\n### mobile: enableConditionInducer\n\nImportant: Device conditions are available for real devices running iOS 13.0 and later.\n\nThis API is going to throw an error if it is called while another condition inducer has been already enabled and is not explicitly disabled.\n\n```\nmobile: enableConditionInducer\nmobile: disableConditionInducer\nmobile: listConditionInducers\n```\n\nThe above three extensions are available since the driver version 4.9.0.\n\nYou can create a condition on a connected device to test your app under adverse conditions, such as poor network connectivity or thermal constraints.","metadata":{"loc":{"lines":{"from":1758,"to":1778}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"You can create a condition on a connected device to test your app under adverse conditions, such as poor network connectivity or thermal constraints.\n\nWhen you start a device condition, the operating system on the device behaves as if its environment has changed. The device condition remains active until you stop the device condition or disconnect the device. For example, you can start a device condition, run your app, monitor your app’s energy usage, and then stop the condition.\n\nReference: [Test under adverse device conditions (iOS)](https://help.apple.com/xcode/mac/current/#/dev308429d42)\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nconditionID | string | yes | Get the conditionID parameter through the command `mobile: availableConditionInducer` | SlowNetworkCondition\nprofileID | string | yes | Get the profileID parameter through the command `mobile: availableConditionInducer` | SlowNetwork100PctLoss\n\n#### Returned Result","metadata":{"loc":{"lines":{"from":1778,"to":1789}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Returned Result\n\nEither `true` or `false`, where `true` means enabling of the condition inducer has been successful\n\n### mobile: listConditionInducers\n\nGet all condition inducer configuration profiles\n\n#### Returned Result\n\nThe response looks like","metadata":{"loc":{"lines":{"from":1789,"to":1799}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: listConditionInducers\n\nGet all condition inducer configuration profiles\n\n#### Returned Result\n\nThe response looks like\n\n```\n[{\n \"profiles\": [\n {\n \"name\": \"100% packet loss\",\n \"identifier\": \"SlowNetwork100PctLoss\", // enableConditionInducer profileID\n \"description\": \"Name: 100% Loss Scenario\n Downlink Bandwidth: 0 Mbps\n Downlink Latency: 0 ms\n Downlink Packet Loss Ratio: 100%\n Uplink Bandwidth: 0 Mbps\n Uplink Latency: 0 ms\n Uplink Packet Loss Ratio: 100%\"\n },\n ],\n \"profilesSorted\": true,\n \"identifier\": \"SlowNetworkCondition\", // enableConditionInducer conditionID\n \"isDestructive\": false,\n \"isInternal\": false,\n \"activeProfile\": \"\",\n \"name\": \"Network Link\",\n \"isActive\": false\n}]\n```\n\n### mobile: disableConditionInducer","metadata":{"loc":{"lines":{"from":1793,"to":1826}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: disableConditionInducer\n\nDisable device condition inducer.\n\nUsually a persistent connection is maintained after enable the condition inducer, and this method is only valid for this connection.\n\nIf the connection is disconnected, condition inducer will be automatically disabled\n\n#### Returned Result\n\nEither `true` or `false`, where `true` means disabling of the condition inducer has been successful\n\n### mobile: calibrateWebToRealCoordinatesTranslation\n\nCalibrates web to real coordinates translation.\nThis API can only be called from Safari web context.\nIt must load a custom page to the browser, and then restore\nthe original one, so don't call it if you can potentially\nlose the current web app state.\nThe outcome of this API is then used if `nativeWebTap` capability/setting is enabled.\nThe returned value could also be used to manually transform web coordinates\nto real device ones in client scripts.","metadata":{"loc":{"lines":{"from":1826,"to":1847}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"It is advised to call this API at least once before changing the device orientation\nor device screen layout as the recetly received value is cached for the session lifetime\nand may become obsolete.\n\nIt is advised to enable `nativeWebTapStrict` capability/setting to speed up dynamic coordinates\ntransformation if you use this extension.\n\n#### Returned Result\n\nAn object with three properties used to properly shift Safari web element coordinates into native context:\n- `offsetX`: Webview X offset in real coordinates\n- `offsetY`: Webview Y offset in real coordinates\n- `pixelRatioX`: Webview X pixel ratio\n- `pixelRatioY`: Webview Y pixel ratio\n\nThe following formulas are used for coordinates translation:\n`RealX = offsetX + webviewX * pixelRatioX`\n`RealY = offsetY + webviewY * pixelRatioY`\n\n### mobile: updateSafariPreferences\n\nUpdates preferences of Mobile Safari on Simulator\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1849,"to":1872}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: updateSafariPreferences\n\nUpdates preferences of Mobile Safari on Simulator\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\npreferences | map | yes | An object containing Mobile Safari preferences to be updated. The list of available setting names and their values could be retrieved by changing the corresponding Safari settings under Preferences-&gt;Safari and then inspecting `Library/Preferences/com.apple.mobilesafari.plist` file inside of `com.apple.mobilesafari` app container. The full path to the Mobile Safari's container could be retrieved from `xcrun simctl get_app_container <sim_udid> com.apple.mobilesafari data` command output. Use the `xcrun simctl spawn <sim_udid> defaults read <path_to_plist>` command to print the actual .plist content to the Terminal. | { ShowTabBar: 0, WarnAboutFraudulentWebsites: 0 }\n\n### mobile: deepLink","metadata":{"loc":{"lines":{"from":1868,"to":1878}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: deepLink\n\nOpens the given URL with the default or the given application.\nThis functionality is only available since xcuitest driver version 4.17.\nXcode must be at version 14.3+ and iOS must be at version 16.4+.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nurl | string | yes | The URL to be opened. This parameter is manadatory. | https://apple.com, myscheme:yolo\nbundleId | string | no | The bundle identifier of an application to open the given url with. If not provided then the default application for the given url scheme is going to be used. | com.myapp.yolo\n\n### mobile: getSimulatedLocation\n\nRetrieves simulated geolocation value.\nThis functionality is only available since xcuitest driver version 4.18.\nXcode must be at version 14.3+ and iOS must be at version 16.4+.\n\n#### Returned Result\n\nThis API returns a map with the following entries:","metadata":{"loc":{"lines":{"from":1878,"to":1899}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Returned Result\n\nThis API returns a map with the following entries:\n\nName | Type | Description | Example\n--- | --- | --- | ---\nlatitude | number | Measurement of distance north or south of the Equator. `null` if [mobile: setSimulatedLocation](#mobile-setsimulatedlocation) has not been called before or the simulated geolocation has been reset by [mobile: resetSimulatedLocation](#mobile-resetsimulatedlocation). | 50.08546\nlongitude | number | Measurement of distance east or west of the prime meridian. `null` if [mobile: setSimulatedLocation](#mobile-setsimulatedlocation) has not been called before or the simulated geolocation has been reset by [mobile: resetSimulatedLocation](#mobile-resetsimulatedlocation). | -20.12345\n\n### mobile: setSimulatedLocation\n\nSets simulated geolocation value.\nThis functionality is only available since xcuitest driver version 4.18.\nXcode must be at version 14.3+ and iOS must be at version 16.4+.","metadata":{"loc":{"lines":{"from":1897,"to":1910}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"Sets simulated geolocation value.\nThis functionality is only available since xcuitest driver version 4.18.\nXcode must be at version 14.3+ and iOS must be at version 16.4+.\n\nIt is recommended for iOS 17+ real devices to simulate the device location.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nlatitude | number | yes | Measurement of distance north or south of the Equator. | 50.08546\nlongitude | number | yes | Measurement of distance east or west of the prime meridian. | -20.12345\n\n### mobile: resetSimulatedLocation\n\nResets the previously set simulated geolocation value.\nThis functionality is only available since xcuitest driver version 4.18.\nXcode must be at version 14.3+ and iOS must be at version 16.4+.\n\n> **Warning**\n> Do not forget to reset the simulated geolocation value after your automated test is finished.\n> If the value is not reset explicitly then the simulated one will remain until the next device restart.","metadata":{"loc":{"lines":{"from":1908,"to":1929}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: getAppStrings\n\nRetrieves string resources for the given app language. An error is thrown if strings cannot be fetched or no strings exist\nfor the given language abbreviation\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nlanguage | string | no | The language abbreviation to fetch app strings mapping for. If no language is provided then strings for the 'en language would be returned | fr\nstringFile | string | no | Relative path to the corresponding .strings file starting from the corresponding .lproj folder | base/main.strings\n\n#### Returned Result\n\nApp strings map, where keys are resource identifiers.\n\n### mobile: hideKeyboard","metadata":{"loc":{"lines":{"from":1931,"to":1947}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Returned Result\n\nApp strings map, where keys are resource identifiers.\n\n### mobile: hideKeyboard\n\nTries to hide the on-screen keyboard. Throws an exception if the keyboard cannot be hidden. On non-tablet devices the keyboard might not have an explicit button to hide it. In such case this API won't work and the only way to close the keyboard would be to simulate the same action an app user would do to close it. For example, swipe from top to bottom or tap the screen somewhere at the area not covered by the keyboard.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nkeys | string[] | no | One or more keyboard key names used to close/hide it. On tablet's such button is usually called 'done'.\n\n### mobile: isKeyboardShown\n\nChecks if the system on-screen keyboard is visible.\n\n#### Returned Result\n\n`true` if the keyboard is visible\n\n### mobile: keys","metadata":{"loc":{"lines":{"from":1943,"to":1965}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: isKeyboardShown\n\nChecks if the system on-screen keyboard is visible.\n\n#### Returned Result\n\n`true` if the keyboard is visible\n\n### mobile: keys\n\nSend keys to the given element or to the application under test.\nThis API is only supported since Xcode 15/iOS 17.\nIt is not supported on tvOS.\nThe API only works on iPad. On iOS calling it has no effect.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1957,"to":1972}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nelementId | string | no | Unique identifier of the element to send the keys to. If unset then keys are sent to the current application under test. | 21045BC8-013C-43BD-9B1E-4C6DC7AB0744\nkeys | array | yes | Array of keys to type. Each item could either be a string, that represents a key itself (see the official documentation on XCUIElement's [typeKey:modifierFlags: method](https://developer.apple.com/documentation/xctest/xcuielement/1500604-typekey?language=objc) and on [XCUIKeyboardKey constants](https://developer.apple.com/documentation/xctest/xcuikeyboardkey?language=objc)) or a dictionary with `key` and `modifierFlags` entries, if the key should also be entered with modifiers. | ['h', 'i'] or [{key: 'h', modifierFlags: 1 << 1}, {key: 'i', modifierFlags: 1 << 2}] or ['XCUIKeyboardKeyEscape'] |\n\n!!! note","metadata":{"loc":{"lines":{"from":1972,"to":1979}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"!!! note\n\n The `modifierFlags` argument is of `unsigned long` type and defines the bitmask with depressed modifier keys for the given key.\n XCTest defines the following possible bitmasks for modifier keys:\n\n <pre>\n typedef NS_OPTIONS(NSUInteger, XCUIKeyModifierFlags) {\n XCUIKeyModifierNone = 0,\n XCUIKeyModifierCapsLock = (1UL << 0),\n XCUIKeyModifierShift = (1UL << 1),\n XCUIKeyModifierControl = (1UL << 2),\n XCUIKeyModifierOption = (1UL << 3),\n XCUIKeyModifierCommand = (1UL << 4),\n XCUIKeyModifierFunction = (1UL << 5),\n // These values align with UIKeyModifierFlags and CGEventFlags.\n XCUIKeyModifierAlphaShift = XCUIKeyModifierCapsLock,\n XCUIKeyModifierAlternate = XCUIKeyModifierOption,\n };\n </pre>","metadata":{"loc":{"lines":{"from":1979,"to":1997}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"So, for example, if you want Ctrl and Shift to be depressed while entering your key then `modifierFlags` should be set to\n `(1 << 1) | (1 << 2)`, where the first constant defines `XCUIKeyModifierShift` and the seconds\n one - `XCUIKeyModifierControl`. We apply the [bitwise or](https://www.programiz.com/c-programming/bitwise-operators#or)\n (`|`) operator between them to raise both bitflags\n in the resulting value. The [left bitshift](https://www.programiz.com/c-programming/bitwise-operators#left-shift)\n (`<<`) operator defines the binary bitmask for the given modifier key.\n You may combine more keys using the same approach.\n\n### mobile: lock\n\nLock the device (and optionally unlock it after a certain amount of time). Only simple (e.g. without a password) locks are supported.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":1999,"to":2011}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: lock\n\nLock the device (and optionally unlock it after a certain amount of time). Only simple (e.g. without a password) locks are supported.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nseconds | number|string | no | The number of seconds after which to unlock the device. Set to `0` or leave it empty to require manual unlock (e.g. do not block and automatically unlock afterwards). | 5\n\n### mobile: unlock\n\nUnlocks the previously locked device. Only simple (e.g. without a password) locks are supported.\n\n### mobile: isLocked\n\nDetermine whether the device is locked.\n\n#### Returned Result\n\nEither `true` or `false`\n\n### mobile: shake\n\nShakes the device. This functionality is only supported on simulators.\n\n### mobile: backgroundApp\n\nPuts the app to the background and waits the given number of seconds. Then restores the app\nif necessary. The call is blocking.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":2007,"to":2038}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: backgroundApp\n\nPuts the app to the background and waits the given number of seconds. Then restores the app\nif necessary. The call is blocking.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nseconds | number | no | The amount of seconds to wait between putting the app to background and restoring it. Any negative value means to not restore the app after putting it to background (the default behavior). | 5\n\n### mobile: performAccessibilityAudit\n\nPerforms accessibility audit of the current application according to the given type or multiple types.\nWraps the XCTest's [performAccessibilityAuditWithAuditTypes](https://developer.apple.com/documentation/xctest/xcuiapplication/4190847-performaccessibilityauditwithaud?language=objc) API.\nOnly available since Xcode 15/iOS 17.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":2033,"to":2050}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nauditTypes | string[] | no | One or more type names to perform the audit for. The full list of available names could be found in the official [XCTest API documentation](https://developer.apple.com/documentation/xctest/xcuiaccessibilityaudittype?language=objc). If no type if provided explicitly then `XCUIAccessibilityAuditTypeAll` is assumed. | ['XCUIAccessibilityAuditTypeContrast', 'XCUIAccessibilityAuditTypeElementDetection']\n\n#### Returned Result\n\nList of found issues or an empty list. Each list item is a map consisting of the following items:","metadata":{"loc":{"lines":{"from":2050,"to":2058}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"List of found issues or an empty list. Each list item is a map consisting of the following items:\n\nName | Type | Description | Example\n--- | --- | --- | ---\ndetailedDescription | string | The detailed description of the found accessibility issue. | Some longer issue description\ncompactDescription | string | The compact description of the found accessibility issue. | Some compact issue description\nauditType | string or number | The name of the audit type this issue belongs to. Could be a number if the type name is unknown. | 'XCUIAccessibilityAuditTypeContrast'\nelement | string | The description of the element this issue was found for. | 'Yes' button\nelementDescription | string | The debug description of the element this issue was found for. Available since driver version | A long string describing the element itself and its position in the page tree hierarchy\nelementAttributes | dict | JSON object containing various attributes of the element. | See the example below","metadata":{"loc":{"lines":{"from":2058,"to":2067}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"```json\n\"elementAttributes\":{\n \"isEnabled\":\"1\",\n \"isVisible\":\"1\",\n \"isAccessible\":\"0\",\n \"frame\":\"{{129, 65}, {135, 18}}\",\n \"isFocused\":\"0\",\n \"rect\":{\n \"y\":65,\n \"x\":129,\n \"width\":135,\n \"height\":18\n },\n \"value\":\"Some Button\",\n \"label\":\"Some Button\",\n \"type\":\"StaticText\",\n \"name\":\"Some Button\",\n \"rawIdentifier\":null\n}\n```\n\n### mobile: startXCTestScreenRecording\n\nStart a new screen recording via XCTest.\n\nSince this feature is based on the native implementation provided by Apple\nit provides the best quality for the least performance penalty in comparison\nto alternative implementations.\n\nEven though the feature is available for real devices\nthere is no possibility to delete video files stored on the device yet,\nwhich may lead to internal storage overload.\nThat is why it was put under the `xctest_screen_record` security\nfeature flag if executed from a real device test.","metadata":{"loc":{"lines":{"from":2069,"to":2102}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"If the screen recording is already running this API is a noop.\n\nThe feature is only available since Xcode 15/iOS 17.\n\n#### Arguments\n\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nfps | number | no | The Frames Per Second value for the resulting video. Providing higher values will create video files that are greater in size, but with smoother transitions. It is highly recommended to keep this value is range 1-60. 24 by default | 60\n\n#### Returned Result\n\nThe API response consists of the following entries:\n\nName | Type | Description | Example\n--- | --- | --- | ---\nuuid | string | Unique identifier of the video being recorded | 1D988774-C7E2-4817-829D-3B835DDAA7DF\nfps | number | FPS value | 24\ncodec | number | The magic for the used codec. Value of zero means h264 video codec is being used | 0\nstartedAt | number | The timestamp when the screen recording has started in float seconds since Unix epoch | 1709826124.123\n\n### mobile: getXCTestScreenRecordingInfo","metadata":{"loc":{"lines":{"from":2104,"to":2125}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"### mobile: getXCTestScreenRecordingInfo\n\nRetrieves information about the current running screen recording.\nIf no screen recording is running then `null` is returned.\n\n#### Returned Result\n\nSame as for [mobile: startXCTestScreenRecording](#mobile-startxctestscreenrecording)\n\n### mobile: stopXCTestScreenRecording\n\nStops the current XCTest screen recording previously started by the\n[mobile: startXctestScreenRecording](#mobile-startxctestscreenrecording) API.\n\nAn error is thrown if no screen recording is running.\n\nThe resulting movie is returned as base-64 string or is uploaded to\na remote location if corresponding options have been provided.\n\nThe resulting movie is automatically deleted from the local file system **FOR SIMULATORS ONLY**.\nIn order to clean it up from a real device it is necessary to properly\nshut down XCTest by calling `GET /wda/shutdown` API to the WebDriverAgent server running\non the device directly or by doing device factory reset.\n\n#### Arguments","metadata":{"loc":{"lines":{"from":2125,"to":2149}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"Name | Type | Required | Description | Example\n--- | --- | --- | --- | ---\nremotePath | string | no | The path to the remote location, where the resulting .mov file should be uploaded. The following protocols are supported: http/https, ftp Null or empty string value (the default setting) means the content of resulting file should be encoded as Base64 and passed to the endpoint response value. An exception will be thrown if the generated file is too big to fit into the available process memory. | https://myserver/upload\nuser | string | no | The name of the user for the remote authentication. Only works if `remotePath` is provided. | myuser\npass | string | no | The password for the remote authentication. Only works if `remotePath` is provided. | mypassword\nmethod | string | no | The http multipart upload method name. Only works if `remotePath` is provided. `PUT` by default | POST","metadata":{"loc":{"lines":{"from":2151,"to":2156}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"method | string | no | The http multipart upload method name. Only works if `remotePath` is provided. `PUT` by default | POST\nheaders | dict | no | Additional headers mapping for multipart http(s) uploads | {'User-Agent': 'Myserver 1.0'}\nfileFieldName | string | no | The name of the form field, where the file content BLOB should be stored for http(s) uploads. `file` by default | payload\nformFields | dict or array | no | Additional form fields for multipart http(s) uploads | {'field2': 'value2'}","metadata":{"loc":{"lines":{"from":2156,"to":2159}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Returned Result\n\nSame as for [mobile: startXCTestScreenRecording](#mobile-startxctestscreenrecording) plus the below entry:\n\nName | Type | Description | Example\n--- | --- | --- | ---\npayload | string | Base64-encoded content of the recorded media file if `remotePath` parameter is empty/null or an empty string otherwise. The resulting media is expected to a be a valid QuickTime movie (.mov). | `YXBwaXVt....`\n\n### mobile: simctl\n\nRuns the given command as a subcommand of `xcrun simctl` against the device under test.\nDoes not work for real devices.","metadata":{"loc":{"lines":{"from":2161,"to":2172}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Arguments\nName | Type | Required | Description | Example\n--- | --- | --- | --- | ---\ncommand | string | yes | a subcommand for the `simctl`. Available commands are boot, get_app_container, getenv, icloud_sync, install, install_app_data, io, keychain, launch, location, logverbose, openurl, pbcopy, pbpaste, privacy, push, shutdown, spawn, status_bar, terminate, ui, and uninstall. Please check each usage details with `xcrun simctl help`. | `'getenv'`\nargs | array | no | array of string as arguments for the command after `<device>`. For example `getenv` subcommand accept `simctl getenv <device> <variable name>`. The `<device>` will be filled out automatically. This `args` should be the ` <variable name>` part only. | `['HOME']`\ntimeout | number | no | Command timeout in milliseconds. If the command blocks for longer than this timeout then an exception is going to be thrown. The default timeout is `600000` ms. | `10000`\n\n#### Returned Result","metadata":{"loc":{"lines":{"from":2174,"to":2181}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"#### Returned Result\n\nName | Type | Description | Example\n--- | --- | --- | ---\nstdout | string | The standard output of the command. | `'/Users/user/Library/Developer/CoreSimulator/Devices/60EB8FDB-92E0-4895-B466-0153C6DE7BAE/data\\n'`\nstderr | string | The standard error of the command. | `''` (an empty string)\ncode | string | The status code of the command. | `0`","metadata":{"loc":{"lines":{"from":2181,"to":2187}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/execute-methods.md","filename":"execute-methods.md","relativePath":"appium-xcuitest-driver/reference/execute-methods.md"}},{"pageContent":"---\ntitle: Predicate Locator Strategy\n--- \n\nThe XCUITest driver supports searching elements using the _predicate_ and _class chain_\n[locator search strategies](./locator-strategies.md). They are powered by Apple XCTest, provide\nflexibility and are much faster than XPath. Predicates can be used to restrict a set of elements to\nselect only those for which some condition evaluates to true.\n\n!!! tip\n\n In addition to the examples listed here, make sure to check the links in the\n [More Information](#more-information) section below!\n\n\n### Quick Examples\n\n=== \"Predicate String\"\n\n ```java\n // java\n driver.findElements(AppiumBy.iOSNsPredicateString(\"isVisible == 1\"));\n ```\n\n=== \"Class Chain\"\n\n ```java\n // java\n driver.findElements(AppiumBy.iOSClassChain(\"**/XCUIElementTypeWindow[`label LIKE '*yolo*'`]\"));\n ```","metadata":{"loc":{"lines":{"from":1,"to":30}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/ios-predicate.md","filename":"ios-predicate.md","relativePath":"appium-xcuitest-driver/reference/ios-predicate.md"}},{"pageContent":"=== \"Class Chain\"\n\n ```java\n // java\n driver.findElements(AppiumBy.iOSClassChain(\"**/XCUIElementTypeWindow[`label LIKE '*yolo*'`]\"));\n ```\n\nThe predicate string example would select all visible elements on the page, while the class chain\nexample would find all elements of type `XCUIElementTypeWindow` whose label contains `yolo`. Class\nchain queries allow to create much more complicated search expressions and may contain multiple\npredicates. Check the [More Information](#more-information) section below for how to build such queries.\n\n### Basic Comparisons\n\n* `=` , `==` - The left-hand expression is equal to the right-hand expression:\n ```java\n // java\n driver.findElements(AppiumBy.iOSNsPredicateString(\"label == 'Olivia'\"));\n\n // same in Xpath:\n driver.findElements(AppiumBy.xpath(\"//*[@label = 'Olivia']\"));\n ```\n\n* `>=` , `=>` - The left-hand expression is greater than or equal to the right-hand expression.","metadata":{"loc":{"lines":{"from":25,"to":48}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/ios-predicate.md","filename":"ios-predicate.md","relativePath":"appium-xcuitest-driver/reference/ios-predicate.md"}},{"pageContent":"// same in Xpath:\n driver.findElements(AppiumBy.xpath(\"//*[@label = 'Olivia']\"));\n ```\n\n* `>=` , `=>` - The left-hand expression is greater than or equal to the right-hand expression.\n\n* `<=` , `=<` - The left-hand expression is less than or equal to the right-hand expression.\n\n* `>` - The left-hand expression is greater than the right-hand expression.\n\n* `<` - The left-hand expression is less than the right-hand expression.\n\n* `!=` , `<>` - The left-hand expression is not equal to the right-hand expression.\n\n* `BETWEEN` - The left-hand expression is between, or equal to either of, the values specified in\n the right-hand side. The right-hand side is a two value array (an array is required to specify\n order) giving upper and lower bounds. For example, `1 BETWEEN { 0 , 33 }`, or `$INPUT BETWEEN { $LOWER, $UPPER }`.\n In Objective-C, you could create a `BETWEEN` predicate as shown in the following example:","metadata":{"loc":{"lines":{"from":44,"to":61}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/ios-predicate.md","filename":"ios-predicate.md","relativePath":"appium-xcuitest-driver/reference/ios-predicate.md"}},{"pageContent":"```java\n driver.findElements(AppiumBy.iOSNsPredicateString(\"rect.x BETWEEN { 1, 100 }\"));\n ```\n\n This creates a predicate that matches all elements whole left top coordinate is in range between\n 1 and 100.\n\n### Boolean Value Predicates\n\n* `TRUEPREDICATE` - A predicate that always evaluates to `TRUE` .\n\n* `FALSEPREDICATE` - A predicate that always evaluates to `FALSE`.\n\n### Basic Compound Predicates\n\n* `AND` , `&&` - Logical AND.\n\n* `OR` , `||` - Logical OR.\n\n* `NOT` , `!` - Logical NOT.\n\n### String Comparisons\n\nString comparisons are by default case and diacritic sensitive. You can modify an operator using the\nkey characters `c` and `d` within square braces to specify case and diacritic insensitivity\nrespectively, for example, `value BEGINSWITH[cd] 'bar'`.\n\n* `BEGINSWITH` - The left-hand expression begins with the right-hand expression.","metadata":{"loc":{"lines":{"from":63,"to":90}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/ios-predicate.md","filename":"ios-predicate.md","relativePath":"appium-xcuitest-driver/reference/ios-predicate.md"}},{"pageContent":"* `BEGINSWITH` - The left-hand expression begins with the right-hand expression.\n\n ```java\n driver.findElement(AppiumBy.iOSNsPredicateString(\"type == 'XCUIElementTypeButton' AND name BEGINSWITH 'results toggle'\"));\n\n // same in Xpath:\n driver.findElement(AppiumBy.xpath(\"//XCUIElementTypeButton[starts-with(@name, 'results toggle')]\"));\n ```\n\n* `CONTAINS` - The left-hand expression contains the right-hand expression.\n\n ```java\n driver.findElement(AppiumBy.iOSNsPredicateString(\"type == 'XCUIElementCollectionView' AND name CONTAINS 'opera'\"));\n\n // same in Xpath:\n driver.findElement(AppiumBy.xpath(\"//XCUIElementCollectionView[contains(@name, 'opera')]\"));\n ```\n\n* `ENDSWITH` - The left-hand expression ends with the right-hand expression.","metadata":{"loc":{"lines":{"from":90,"to":108}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/ios-predicate.md","filename":"ios-predicate.md","relativePath":"appium-xcuitest-driver/reference/ios-predicate.md"}},{"pageContent":"* `ENDSWITH` - The left-hand expression ends with the right-hand expression.\n\n* `LIKE` - The left hand expression equals the right-hand expression: `?` and `*` are allowed as\n wildcard characters, where `?` matches 1 character and `*` matches 0 or more characters. In Mac\n OS X v10.4, wildcard characters do not match newline characters.\n\n ```java\n driver.findElement(AppiumBy.iOSNsPredicateString(\"name LIKE '*Total: $*'\"));\n\n // XPath1 does not have an alternative to the above expression\n ```\n\n* `MATCHES` - The left hand expression equals the right hand expression using a regex-style\n comparison according to ICU v3 (for more details see the ICU User Guide for\n [Regular Expressions](http://userguide.icu-project.org/strings/regexp)).\n\n ```java\n driver.findElement(AppiumBy.iOSNsPredicateString(\"value MATCHES '.*of [1-9]'\"));\n\n // XPath1 does not have an alternative to the above expression\n ```\n\n### Aggregate Operations","metadata":{"loc":{"lines":{"from":108,"to":130}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/ios-predicate.md","filename":"ios-predicate.md","relativePath":"appium-xcuitest-driver/reference/ios-predicate.md"}},{"pageContent":"```java\n driver.findElement(AppiumBy.iOSNsPredicateString(\"value MATCHES '.*of [1-9]'\"));\n\n // XPath1 does not have an alternative to the above expression\n ```\n\n### Aggregate Operations\n\n* `IN` - Equivalent to an SQL IN operation, the left-hand side must appear in the collection\n specified by the right-hand side. For example, `name IN { 'Ben', 'Melissa', 'Matthew' }`.\n The collection may be an array, a set, or a dictionary (in the case of a dictionary, its values\n are used).\n\n### Identifiers\n\n* **C style identifier** - Any C style identifier that is not a reserved word.\n\n* **\\#symbol** - Used to escape a reserved word into a user identifier.\n\n* **[\\\\]{octaldigit}{3}** - Used to escape an octal number ( ```\\``` followed by 3 octal digits).\n\n* **[\\\\][xX]{hexdigit}{2}** - Used to escape a hex number ( ```\\x``` or ```\\X``` followed by 2 hex digits).\n\n* **[\\\\][uU]{hexdigit}{4}** - Used to escape a Unicode number ( ```\\u``` or ```\\U``` followed by 4 hex digits).","metadata":{"loc":{"lines":{"from":124,"to":147}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/ios-predicate.md","filename":"ios-predicate.md","relativePath":"appium-xcuitest-driver/reference/ios-predicate.md"}},{"pageContent":"* **[\\\\][uU]{hexdigit}{4}** - Used to escape a Unicode number ( ```\\u``` or ```\\U``` followed by 4 hex digits).\n\n### Literals\n\nSingle and double quotes produce the same result, but they do not terminate each other. For example,\n`\"abc\"` and `'abc'` are identical, whereas `\"a'b'c\"` is equivalent to a space-separated\nconcatenation of `a, 'b', c`.\n\n* `FALSE` , `NO` - Logical false.\n\n* `TRUE` , `YES` - Logical true.\n\n* `NULL` , `NIL` - A null value.\n\n* `SELF` - Represents the object being evaluated.\n\n* `\"text\"` - A character string.\n\n* `'text'` - A character string.\n\n* **Comma-separated literal array** - For example, `{ 'comma', 'separated', 'literal', 'array' }` .\n\n* **Standard integer and fixed-point notations** - For example, `1 , 27 , 2.71828 , 19.75` .\n\n* **Floating-point notation with exponentiation** - For example, `9.2e-5` .\n\n* `0x` - Prefix used to denote a hexadecimal digit sequence.\n\n* `0o` - Prefix used to denote an octal digit sequence.","metadata":{"loc":{"lines":{"from":147,"to":175}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/ios-predicate.md","filename":"ios-predicate.md","relativePath":"appium-xcuitest-driver/reference/ios-predicate.md"}},{"pageContent":"* **Floating-point notation with exponentiation** - For example, `9.2e-5` .\n\n* `0x` - Prefix used to denote a hexadecimal digit sequence.\n\n* `0o` - Prefix used to denote an octal digit sequence.\n\n* `0b` - Prefix used to denote a binary digit sequence.\n\n### Reserved Keywords\n\nThe following keywords are reserved:\n\n`AND, OR, IN, NOT, ALL, ANY, SOME, NONE, LIKE, CASEINSENSITIVE, CI, MATCHES, CONTAINS, BEGINSWITH,\nENDSWITH, BETWEEN, NULL, NIL, SELF, TRUE, YES, FALSE, NO, FIRST, LAST, SIZE, ANYKEY, SUBQUERY,\nCAST, TRUEPREDICATE, FALSEPREDICATE`\n\n### Available Attributes\n\nCheck the [Element Attributes](./element-attributes.md) document to know all element attribute\nnames and types that are available for usage in predicate locators.\n\n### More Information","metadata":{"loc":{"lines":{"from":171,"to":192}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/ios-predicate.md","filename":"ios-predicate.md","relativePath":"appium-xcuitest-driver/reference/ios-predicate.md"}},{"pageContent":"Check the [Element Attributes](./element-attributes.md) document to know all element attribute\nnames and types that are available for usage in predicate locators.\n\n### More Information\n\n* [Apple Developer documentation on Predicates](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Predicates/AdditionalChapters/Introduction.html)\n* [NSPredicate Cheat Sheet](https://academy.realm.io/posts/nspredicate-cheatsheet/)\n* [Class Chain Queries Construction Rules](https://github.com/facebookarchive/WebDriverAgent/wiki/Class-Chain-Queries-Construction-Rules)","metadata":{"loc":{"lines":{"from":189,"to":196}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/ios-predicate.md","filename":"ios-predicate.md","relativePath":"appium-xcuitest-driver/reference/ios-predicate.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Locator Strategies\n---\n\nThe XCUITest driver supports several location strategies in the native context. The following table\nlists them in performance order (the first one is the fastest one):","metadata":{"loc":{"lines":{"from":1,"to":9}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/locator-strategies.md","filename":"locator-strategies.md","relativePath":"appium-xcuitest-driver/reference/locator-strategies.md"}},{"pageContent":"| <div style=\"width:14em\">Name</div> | Description | Speed Ranking | Example |\n| --- | --- | --- | --- |\n| `className` | Performs search by element's `type` [attribute](element-attributes.md). The full list of supported XCUIElement type names could be found in the official XCTest [documentation on XCUIElementType](https://developer.apple.com/documentation/xctest/xcuielementtype) | ⭐⭐⭐⭐⭐ | `XCUIElementTypeButton` |\n| `id`, `name`, `accessibility id` | All these locator types are synonyms and internally get transformed into search by element's `name` [attribute](element-attributes.md). | ⭐⭐⭐⭐⭐ | `my name` |","metadata":{"loc":{"lines":{"from":11,"to":14}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/locator-strategies.md","filename":"locator-strategies.md","relativePath":"appium-xcuitest-driver/reference/locator-strategies.md"}},{"pageContent":"| `id`, `name`, `accessibility id` | All these locator types are synonyms and internally get transformed into search by element's `name` [attribute](element-attributes.md). | ⭐⭐⭐⭐⭐ | `my name` |\n| `-ios predicate string` | This strategy is mapped to the native XCTest predicate locator. Check the [NSPredicate cheat sheet](https://academy.realm.io/posts/nspredicate-cheatsheet/) for more details on how to build effective predicate expressions. All the supported element [attributes](element-attributes.md) could be used in these expressions. | ⭐⭐⭐⭐⭐ | `(name == 'done' OR value == 'done') AND type IN {'XCUIElementTypeButton', 'XCUIElementTypeKey'}` |","metadata":{"loc":{"lines":{"from":14,"to":15}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/locator-strategies.md","filename":"locator-strategies.md","relativePath":"appium-xcuitest-driver/reference/locator-strategies.md"}},{"pageContent":"| `-ios class chain` | This strategy is mapped to the native XCTest predicate locator, but with respect to the actual element tree hierarchy. Such locators are basically a supertype of `-ios predicate string`. Read [Class Chain Queries Construction Rules](https://github.com/facebookarchive/WebDriverAgent/wiki/Class-Chain-Queries-Construction-Rules) for more details on how to build such locators. | ⭐⭐⭐⭐ | ```**/XCUIElementTypeCell[$name == 'done' OR value == 'done'$]/XCUIElementTypeButton[-1]``` |\n| `xpath` | For elements lookup using the Xpath strategy the driver uses the same XML tree that is generated by the page source API. This means such locators are the slowest (sometimes up to 10x slower) in comparison to the ones above, which all depend on native XCTest primitives, but are the most flexible. Use Xpath locators only if there is no other way to locate the given element. Only Xpath 1.0 is supported. | ⭐⭐ | `//XCUIElementTypeButton[@value=\\\"Regular\\\"]/parent::*` |","metadata":{"loc":{"lines":{"from":16,"to":17}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/locator-strategies.md","filename":"locator-strategies.md","relativePath":"appium-xcuitest-driver/reference/locator-strategies.md"}},{"pageContent":"Also, consider checking the [How To Achieve The Best Lookup Performance](https://github.com/facebookarchive/WebDriverAgent/wiki/How-To-Achieve-The-Best-Lookup-Performance) article.","metadata":{"loc":{"lines":{"from":19,"to":19}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/locator-strategies.md","filename":"locator-strategies.md","relativePath":"appium-xcuitest-driver/reference/locator-strategies.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Scripts\n---\n\nAppium drivers can include scripts for executing specific actions. The following table lists the\nscripts bundled with the XCUITest driver. These scripts can be run as follows:\n\n```\nappium driver run xcuitest <script-name>\n```\n\n|Script Name|Description|\n|------------|-----------|\n|`open-wda`|Opens the WebDriverAgent project in Xcode|\n|`build-wda`|Builds the WebDriverAgent project using the first available iPhone simulator and the latest iOS supported by the current Xcode version by default|\n|`build-wda --sdk=17.5 --name=\"iPhone 15\"`|Builds the WebDriverAgent project using the iPhone 15 simulator with iOS 17.5. If `--sdk` and `--name` params are not specified - the latest iOS and the first available iPhone simulator will be used|","metadata":{"loc":{"lines":{"from":1,"to":19}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/scripts.md","filename":"scripts.md","relativePath":"appium-xcuitest-driver/reference/scripts.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Security Feature Flags\n---\n\nSome insecure driver features are disabled by default. They can be enabled upon launching Appium as follows:\n```\nappium --allow-insecure <feature-name>\n```\nor\n```\nappium --relaxed-security\n```\n\n|Feature Name|Description|\n|------------|-----------|\n|`shutdown_other_sims`|Allow any session to use a capability to shutdown any running simulators on the host|\n|`perf_record`|Allow recording the system performance and other metrics of the simulator|\n|`audio_record`|Allow recording of host audio input(s)|\n|`customize_result_bundle_path`|Allow customizing the paths to result bundles, using the `resultBundlePath` capability|","metadata":{"loc":{"lines":{"from":1,"to":22}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/security-flags.md","filename":"security-flags.md","relativePath":"appium-xcuitest-driver/reference/security-flags.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Appium Server Arguments\n---\n\nSome driver arguments can be set when launching the Appium server. This can be done as follows:\n\n```\nappium --driver-xcuitest-[argName]=[argValue]\n```\n\n|Argument|Description|Default|Example|\n|----|-------|-----------|-------|\n| `webdriveragent-port` | Local port used for communicating with WebDriverAgent | `8100` | `--driver-xcuitest-webdriveragent-port=8200` |","metadata":{"loc":{"lines":{"from":1,"to":16}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/server-args.md","filename":"server-args.md","relativePath":"appium-xcuitest-driver/reference/server-args.md"}},{"pageContent":"---\nhide:\n - toc\n\ntitle: Settings\n---\n\nThe XCUITest driver supports Appium's [Settings API](https://appium.io/docs/en/latest/guides/settings/).\nAlong with the common settings, the following driver-specific settings are available:","metadata":{"loc":{"lines":{"from":1,"to":9}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| <div style=\"width:14em\">Name</div> | Type | Description |\n| --- | --- | --- |\n| `elementResponseAttributes` | `string` | Comma-separated list of element attribute names to be included into findElement response. By default only element UUID is present there, but it is also possible to add the following items: `name`, `text`, `rect`, `enabled`, `displayed`, `selected`, `attribute/<element_attribute_name>`. It is required that `shouldUseCompactResponses` setting is set to `false` in order for this one to apply. |\n| `shouldUseCompactResponses` | `boolean` | Used in combination with `elementResponseAttributes` setting. If set to `false` then the findElement response is going to include the items enumerated in `elementResponseAttributes` setting. `true` by default |\n| `screenshotQuality` | `int` | See the description of the corresponding capability. |","metadata":{"loc":{"lines":{"from":11,"to":15}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| `screenshotQuality` | `int` | See the description of the corresponding capability. |\n| `mjpegServerFramerate` | `int` | The maximum count of screenshots per second taken by the MJPEG screenshots broadcaster. Must be in range 1..60. `10` by default |\n| `mjpegScalingFactor` | `float` | The percentage value used to apply downscaling on the screenshots generated by the MJPEG screenshots broadcaster. Must be in range 1..100. `100` is by default, which means that screenshots are not downscaled. |\n| `mjpegServerScreenshotQuality` | `int` | The percentage value used to apply lossy JPEG compression on the screenshots generated by the MJPEG screenshots broadcaster. Must be in range 1..100. `25` is by default, which means that screenshots are compressed to the quarter of their original quality. |","metadata":{"loc":{"lines":{"from":15,"to":18}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| <s>`customSnapshotTimeout`</s> | `float` | *Removed since XCUITest driver v8.0.0*. Set how much time in float seconds is allowed to resolve a single accessibility snapshot with custom attributes. _Snapshots_ are mainly used for page source generation, XML lookup and custom attributes retrieval (these are visibility and accessibility ones). It might be necessary to increase this value if the actual page source is very large and contains hundreds of UI elements. Defaults to 15 seconds. Since Appium 1.19.1 if this timeout expires and no custom snapshot could be made then WDA tries to calculate the missing attributes using its own algorithms, so setting this value to zero might speed up, for example, page source retrieval, but for the cost of preciseness of some element attributes. |\n| `waitForIdleTimeout` | `float` | Has the same meaning as corresponding capability (see above) |","metadata":{"loc":{"lines":{"from":19,"to":20}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| `waitForIdleTimeout` | `float` | Has the same meaning as corresponding capability (see above) |\n| `animationCoolOffTimeout` | `float` | The amount of time in float seconds to wait until the application under test does not have any active animations. This check is usually applied after each automation action that is supposed to change the state of the application under test, like `click` one, and blocks XCTest until the transition of the tested application to a new state completes or the cool off timeout occurs. The default value is `2` (seconds). Setting it to zero disables animation checks completely. |","metadata":{"loc":{"lines":{"from":20,"to":21}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| `snapshotMaxDepth` | `int` | Changes the value of maximum depth for traversing elements source tree. It may help to prevent out of memory or timeout errors while getting the elements source tree, but it might restrict the depth of source tree. Please consider restricting this value if you observed an error like _Timed out snapshotting com.apple.testmanagerd..._ message or _Cannot get 'xml' source of the current application_ in your Appium log since they are possibly timeout related. A part of elements source tree might be lost if the value was too small. Defaults to `50` |\n| `useFirstMatch` | `boolean` | Enabling this setting makes single element lookups faster, but there is the known [problem](https://github.com/appium/appium/issues/10101) related to nested elements lookup. Defaults to `false`. |\n| `reduceMotion` | `boolean` | Changes the 'reduce motion' preference of accessibility feature. Defaults to `false` |","metadata":{"loc":{"lines":{"from":22,"to":24}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| `reduceMotion` | `boolean` | Changes the 'reduce motion' preference of accessibility feature. Defaults to `false` |\n| `defaultActiveApplication` | `string` | Sets the hint for active application selection. This helps WebDriverAgent to select the current application if there are multiple items in the active applications list and the desired one is also one of them. The setting is particularly useful for split-screen apps automation. Defaults to `auto`, which makes WebDriverAgent to select the application whose element is located at `screenPoint` location or a single item from the active apps list if the length of this list is equal to one. |","metadata":{"loc":{"lines":{"from":24,"to":25}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| `activeAppDetectionPoint` | `string` | Defines the coordinates of the current screen point. WebDriverAgent uses this point to detect the active application if multiple application are active on the screen. The format of this value is `x,y`, where x and y are float or integer numbers representing valid screen coordinates. Setting this value to a point outside the actual screen coordinates might corrupt WebDriverAgent functionality. By default the screen point coordinates equal to 20% of the minimum screen dimension each, e.g. `MIN(w, h) * 0.2, MIN(w, h) * 0.2` |","metadata":{"loc":{"lines":{"from":26,"to":26}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| `includeNonModalElements` | `boolean` | Whether returns all of elements including no modal dialogs on iOS 13+. It fixes [cannot find elements on nested modal presentations](https://github.com/appium/appium/issues/13227), but it might make visibility attributes unreliable. You could also enable `shouldUseTestManagerForVisibilityDetection` setting (defaults to `false`) or `simpleIsVisibleCheck` capability to improve the visibility detection. This issue may happen between iOS 13.0 to 13.2 (Xcode 11.0 to 11.2). The query issued in `includeNonModalElements` returns `nil` with newer iOS/Xcode versions and Appium/WDA return proper elements three without this setting being used. Defaults to `false`. |","metadata":{"loc":{"lines":{"from":27,"to":27}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| `acceptAlertButtonSelector` | `string` | Allows to customize accept alert button selector. It helps you to handle an arbitrary element as accept button in `accept alert` command. The selector should be a valid [class chain](https://github.com/facebookarchive/WebDriverAgent/wiki/Class-Chain-Queries-Construction-Rules) expression, where the search root is the alert element itself. The default button location algorithm is used if the provided selector is wrong or does not match any element. Example: ```**/XCUIElementTypeButton[`label CONTAINS[c] 'accept'`]``` |","metadata":{"loc":{"lines":{"from":28,"to":28}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| `dismissAlertButtonSelector` | `string` | Allows to customize dismiss alert button selector. It helps you to handle an arbitrary element as dismiss button in `dismiss alert` command. The selector should be a valid [class chain](https://github.com/facebookarchive/WebDriverAgent/wiki/Class-Chain-Queries-Construction-Rules) expression, where the search root is the alert element itself. The default button location algorithm is used if the provided selector is wrong or does not match any element. Example: ```**/XCUIElementTypeButton[`label CONTAINS[c] 'dismiss'`]``` |","metadata":{"loc":{"lines":{"from":29,"to":29}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| `screenshotOrientation` | `string` | Adjust screenshot orientation for iOS. Appium tries to return a screenshot and adjust its orientation properly using internal heuristics, but sometimes it does not work, especially in landscape mode. The actual screenshot orientation depends on various factors such as OS versions, model versions and whether this is a real or simulator device. This option allows you to enforce the given image orientation. Acceptable values: `auto` (default), `portrait`, `portraitUpsideDown`, `landscapeRight`, `landscapeLeft`. |","metadata":{"loc":{"lines":{"from":30,"to":30}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| `boundElementsByIndex` | `boolean` | Whether to look up elements with [`allElementsBoundByAccessibilityElement`](https://developer.apple.com/documentation/xctest/xcuielementquery/1500816-allelementsboundbyaccessibilitye) (default) or [`allElementsBoundByIndex`](https://developer.apple.com/documentation/xctest/xcuielementquery/1500945-allelementsboundbyindex). [This Stack Overflow topic](https://stackoverflow.com/questions/49307513/meaning-of-allelementsboundbyaccessibilityelement) explains the differences. Defaults to `false`. |\n| `keyboardAutocorrection` | `boolean` | Changes the 'Auto-Correction' preference in _Keyboards_ setting. Defaults to `false`. |\n| `keyboardPrediction` | `boolean` | Changes the 'Predictive' preference in _Keyboards_ setting. Defaults to `false`. |\n| `nativeWebTap` | `boolean` | See the description of the corresponding capability. |\n| `nativeWebTapStrict` | `boolean` | See the description of the corresponding capability. |","metadata":{"loc":{"lines":{"from":31,"to":35}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| `nativeWebTap` | `boolean` | See the description of the corresponding capability. |\n| `nativeWebTapStrict` | `boolean` | See the description of the corresponding capability. |\n| `nativeWebTapTabBarVisibility` | `enum` | Bypass finding whether the existence of the _**tab bar**_ before tapping on the element. It could make native web tap faster. If it's `visible`, tab bar offset will be added without checking the existence of the tab bar. It's `invisible`, the tab bar offset will be `zero`. If you want to leave Appium to check and measure the tab bar offset, unset or set `detect`. Only applicable if `nativeWebTap` and `nativeWebTapStrict` are enabled. Unset by default. |\n| `nativeWebTapSmartAppBannerVisibility` | `enum` | The same as `nativeWebTapTabBarVisibility`, this keyword will bypass finding whether the existence of the _**smart app banner**_. |","metadata":{"loc":{"lines":{"from":34,"to":37}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| `nativeWebTapSmartAppBannerVisibility` | `enum` | The same as `nativeWebTapTabBarVisibility`, this keyword will bypass finding whether the existence of the _**smart app banner**_. |\n| `safariTabBarPosition` | `string` | Handle offset of Safari tab bar in `nativeWebTap` enabled interactions. If `platformVersion` was greater than or equal to 15 and iPhone device, the value is `bottom` by default. Otherwise `top`. When the value is `top`, Appium considers offset as the bar length. iOS 15+ environment can customize the bar position in the settings app, so please adjust the offset with this. Acceptable values: `bottom`, `top` |\n| `useJSONSource` | `boolean` | See the description of the corresponding capability. |","metadata":{"loc":{"lines":{"from":37,"to":39}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| `useJSONSource` | `boolean` | See the description of the corresponding capability. |\n| `pageSourceExcludedAttributes` | `string` | One or more comma-separated attribute names to be excluded from the output. It might be sometimes helpful to exclude, for example, the `visible` attribute, to significantly speed-up page source retrieval. Attributes which can be excluded with `useJSONSource` are frame, enabled, visible, accessible and focused. Defaults to an empty string. Example: `\"visible,accessible\"` |\n| `maxTypingFrequency` | `int` | Maximum frequency of keystrokes for typing and clear. If your tests are failing because of typing errors, you may want to adjust this. Defaults to `60` keystrokes per minute. |","metadata":{"loc":{"lines":{"from":39,"to":41}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| `respectSystemAlerts` | `boolean` | Currently we detect the app under test as active if XCTest returns XCUIApplicationStateRunningForeground state for it. In case the app under test is covered by a system alert from the Springboard app this approach might be confusing as we cannot interact with it unless an alert is properly handled. If this setting is set to true (by default it is false) then it forces WDA to verify the presence of alerts shown by Springboard and return the latter while performing the automated app detection. It affects the performance of active app detection, but might be more convenient for writing test scripts (e.g. eliminates the need of proactive switching between system and custom apps). Also, this behavior emulates the legacy active application detection logic before version 6 of the driver. |","metadata":{"loc":{"lines":{"from":42,"to":42}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| `webScreenshotMode` | `native` or `page` or `viewport` | Defines the screenshoting logic if the current context is set to a web one. The default value is `native`, which makes the driver to take screenshots from WDA, e.g. the whole device screen including status bars. The `page` mode tries to retrieve the screenshot of the whole active web page, while the `viewport` one only retrieves a shot of the visible viewport. |\n| `useClearTextShortcut` | `boolean` | Whether to use the fastest operation (using IOHIDEvent) to clear texts. In headless mode, simulator's keyboard won't show up anymore after clearing texts using this approach in some cases (see [this issue](https://github.com/appium/appium/issues/20727) for more details). Defaults to true |","metadata":{"loc":{"lines":{"from":43,"to":44}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| `limitXPathContextScope` | `boolean` | Due to historical reasons XCUITest driver limits scopes of element context-based searches to the parent element. This means a request like `findElement(By.xpath, \"//XCUIElementTypeButton\").findElement(By.xpath, \"./..\")` would always fail, because the driver only collects descendants of the `XCUIElementTypeButton` element for the destination XML source. The `limitXPathContextScope` setting being set to `false` changes that default behavior, so the collected page source includes the whole page source XML where `XCUIElementTypeButton` node is set as the search context. With that setting disabled the search query above should not fail anymore. Although, you must be careful while building XPath requests for context-based searches with the `limitXPathContextScope` setting being set to `false`. A request like `findElement(By.xpath, \"//XCUIElementTypeAlert\").findElement(By.xpath, \"//XCUIElementTypeButton\")` would ignore the current context and search","metadata":{"loc":{"lines":{"from":45,"to":45}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"setting being set to `false`. A request like `findElement(By.xpath, \"//XCUIElementTypeAlert\").findElement(By.xpath, \"//XCUIElementTypeButton\")` would ignore the current context and search for `XCUIElementTypeButton` through the whole page source. Use `.` notation to correct that behavior and only find `XCUIElementTypeButton` nodes which are descendants of the `XCUIElementTypeAlert` node: `findElement(By.xpath, \"//XCUIElementTypeAlert\").findElement(By.xpath, \".//XCUIElementTypeButton\")`. |","metadata":{"loc":{"lines":{"from":45,"to":45}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| `skipDocumentsContainerCheck` | `boolean` | Whether to apply special handling for the `documents` container type in file management such as pushing/pulling to/from real devices (`false`, the default value), or to treat them in the same way as other container types (`true`). For certain applications having this setting enabled helps to workaround documents upload issues if the `UIFileSharingEnabled` flag is not active in the application manifest.|","metadata":{"loc":{"lines":{"from":46,"to":46}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| `autoClickAlertSelector` | `string` | Allows providing a custom [class chain](./locator-strategies.md) selector, which is used to automatically locate an element inside an alert hierarchy, and click it as soon as a new alert is detected. If the provided locator string is invalid then an error is thrown. Providing an empty string disables the feature. This setting has priority over `autoAcceptAlerts` or `autoDismissAlerts` capabilities, e.g. if both are enabled then the destination element to tap on would be selected only based on the provided selector value. If an alert is active, but no element matches the provided selector, then no click would be performed. If two or more elements match the provided selector then the very first matched element is clicked. The selector lookup is performed starting from the root element of the matched alert hierarchy (usually XCUIElementTypeAlert). |","metadata":{"loc":{"lines":{"from":47,"to":47}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}},{"pageContent":"| `includeHittableInPageSource` | `boolean` | Determines whether the [`hittable`](https://developer.apple.com/documentation/xctest/xcuielement/ishittable) attribute should be included in the page source XML tree. This value reflects whether an element is currently interactive from XCTest’s perspective. Disabled by default due to potential performance impact on large UI hierarchies. Defaults to `false`. |","metadata":{"loc":{"lines":{"from":48,"to":48}},"source":"/Users/srinivasans/Documents/workspace/mcp-appium/src/resources/appium-xcuitest-driver/reference/settings.md","filename":"settings.md","relativePath":"appium-xcuitest-driver/reference/settings.md"}}]