appium-mcp 1.8.14 → 1.8.16

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 (436) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/package.json +3 -1
  3. package/server.json +2 -2
  4. package/src/command.ts +249 -0
  5. package/src/devicemanager/adb-manager.ts +164 -0
  6. package/src/devicemanager/ios-manager.ts +145 -0
  7. package/src/index.ts +45 -0
  8. package/src/locators/element-filter.ts +136 -0
  9. package/src/locators/generate-all-locators.ts +150 -0
  10. package/src/locators/locator-generation.ts +657 -0
  11. package/src/locators/source-parsing.ts +149 -0
  12. package/src/logger.ts +11 -0
  13. package/src/resources/caps.json +697 -0
  14. package/src/resources/index.ts +8 -0
  15. package/src/resources/java/template.ts +83 -0
  16. package/src/resources/submodules/appium/.github/PULL_REQUEST_TEMPLATE.md +28 -0
  17. package/src/resources/submodules/appium/CHANGELOG.md +45 -0
  18. package/src/resources/submodules/appium/CONDUCT.md +48 -0
  19. package/src/resources/submodules/appium/GOVERNANCE.md +185 -0
  20. package/src/resources/submodules/appium/IDEAS.md +16 -0
  21. package/src/resources/submodules/appium/README.md +221 -0
  22. package/src/resources/submodules/appium/ROADMAP.md +30 -0
  23. package/src/resources/submodules/appium/SPONSORS.md +3 -0
  24. package/src/resources/submodules/appium/docs/README.md +6 -0
  25. package/src/resources/submodules/appium/docs/payout.md +35 -0
  26. package/src/resources/submodules/appium/packages/appium/CHANGELOG.md +1437 -0
  27. package/src/resources/submodules/appium/packages/appium/README.md +221 -0
  28. package/src/resources/submodules/appium/packages/appium/docs/en/blog/index.md +2 -0
  29. package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/announcing-appiumconf2024.md +45 -0
  30. package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/announcing-browserstack-as-strategic-partner.md +46 -0
  31. package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/announcing-headspin-as-development-partner.md +47 -0
  32. package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/announcing-lambdatest-as-strategic-partner.md +42 -0
  33. package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/announcing-sauce-labs-as-strategic-partner.md +36 -0
  34. package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/announcing-sponsorship-program.md +48 -0
  35. package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/appium3.md +40 -0
  36. package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/hello-world.md +15 -0
  37. package/src/resources/submodules/appium/packages/appium/docs/en/contributing/index.md +150 -0
  38. package/src/resources/submodules/appium/packages/appium/docs/en/developing/build-docs.md +86 -0
  39. package/src/resources/submodules/appium/packages/appium/docs/en/developing/build-doctor-checks.md +141 -0
  40. package/src/resources/submodules/appium/packages/appium/docs/en/developing/build-drivers.md +860 -0
  41. package/src/resources/submodules/appium/packages/appium/docs/en/developing/build-plugins.md +514 -0
  42. package/src/resources/submodules/appium/packages/appium/docs/en/developing/config-system.md +451 -0
  43. package/src/resources/submodules/appium/packages/appium/docs/en/developing/index.md +18 -0
  44. package/src/resources/submodules/appium/packages/appium/docs/en/developing/sensitive.md +49 -0
  45. package/src/resources/submodules/appium/packages/appium/docs/en/ecosystem/clients.md +132 -0
  46. package/src/resources/submodules/appium/packages/appium/docs/en/ecosystem/drivers.md +207 -0
  47. package/src/resources/submodules/appium/packages/appium/docs/en/ecosystem/index.md +45 -0
  48. package/src/resources/submodules/appium/packages/appium/docs/en/ecosystem/plugins.md +138 -0
  49. package/src/resources/submodules/appium/packages/appium/docs/en/ecosystem/tools.md +83 -0
  50. package/src/resources/submodules/appium/packages/appium/docs/en/guides/branch-testing.md +57 -0
  51. package/src/resources/submodules/appium/packages/appium/docs/en/guides/caching.md +76 -0
  52. package/src/resources/submodules/appium/packages/appium/docs/en/guides/caps.md +275 -0
  53. package/src/resources/submodules/appium/packages/appium/docs/en/guides/config.md +98 -0
  54. package/src/resources/submodules/appium/packages/appium/docs/en/guides/context.md +44 -0
  55. package/src/resources/submodules/appium/packages/appium/docs/en/guides/event-timing.md +73 -0
  56. package/src/resources/submodules/appium/packages/appium/docs/en/guides/execute-methods.md +122 -0
  57. package/src/resources/submodules/appium/packages/appium/docs/en/guides/grid.md +166 -0
  58. package/src/resources/submodules/appium/packages/appium/docs/en/guides/headers.md +17 -0
  59. package/src/resources/submodules/appium/packages/appium/docs/en/guides/log-filters.md +86 -0
  60. package/src/resources/submodules/appium/packages/appium/docs/en/guides/managing-exts.md +87 -0
  61. package/src/resources/submodules/appium/packages/appium/docs/en/guides/migrating-1-to-2.md +368 -0
  62. package/src/resources/submodules/appium/packages/appium/docs/en/guides/migrating-2-to-3.md +464 -0
  63. package/src/resources/submodules/appium/packages/appium/docs/en/guides/security.md +89 -0
  64. package/src/resources/submodules/appium/packages/appium/docs/en/guides/settings.md +68 -0
  65. package/src/resources/submodules/appium/packages/appium/docs/en/guides/tls.md +42 -0
  66. package/src/resources/submodules/appium/packages/appium/docs/en/index.md +59 -0
  67. package/src/resources/submodules/appium/packages/appium/docs/en/intro/appium.md +202 -0
  68. package/src/resources/submodules/appium/packages/appium/docs/en/intro/clients.md +127 -0
  69. package/src/resources/submodules/appium/packages/appium/docs/en/intro/drivers.md +188 -0
  70. package/src/resources/submodules/appium/packages/appium/docs/en/intro/history.md +196 -0
  71. package/src/resources/submodules/appium/packages/appium/docs/en/intro/index.md +39 -0
  72. package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/index.md +29 -0
  73. package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/install.md +50 -0
  74. package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/next-steps.md +23 -0
  75. package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/requirements.md +29 -0
  76. package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/test-dotnet.md +105 -0
  77. package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/test-java.md +23 -0
  78. package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/test-js.md +75 -0
  79. package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/test-py.md +60 -0
  80. package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/test-rb.md +83 -0
  81. package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/uiauto2-driver.md +144 -0
  82. package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/appium.md +394 -0
  83. package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/bidi.md +70 -0
  84. package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/index.md +30 -0
  85. package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/jsonwp.md +214 -0
  86. package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/mjsonwp.md +151 -0
  87. package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/others.md +671 -0
  88. package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/plugins.md +289 -0
  89. package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/webdriver.md +1114 -0
  90. package/src/resources/submodules/appium/packages/appium/docs/en/reference/cli/env-vars.md +31 -0
  91. package/src/resources/submodules/appium/packages/appium/docs/en/reference/cli/extensions.md +239 -0
  92. package/src/resources/submodules/appium/packages/appium/docs/en/reference/cli/index.md +35 -0
  93. package/src/resources/submodules/appium/packages/appium/docs/en/reference/cli/server.md +76 -0
  94. package/src/resources/submodules/appium/packages/appium/docs/en/reference/cli/setup.md +76 -0
  95. package/src/resources/submodules/appium/packages/appium/docs/en/reference/index.md +25 -0
  96. package/src/resources/submodules/appium/packages/appium/docs/en/resources/index.md +28 -0
  97. package/src/resources/submodules/appium/packages/appium/docs/en/sponsors/index.md +64 -0
  98. package/src/resources/submodules/appium/packages/appium/docs/ja/blog/index.md +2 -0
  99. package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/announcing-appiumconf2024.md +45 -0
  100. package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/announcing-browserstack-as-strategic-partner.md +46 -0
  101. package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/announcing-headspin-as-development-partner.md +47 -0
  102. package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/announcing-lambdatest-as-strategic-partner.md +41 -0
  103. package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/announcing-sauce-labs-as-strategic-partner.md +36 -0
  104. package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/announcing-sponsorship-program.md +48 -0
  105. package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/appium3.md +40 -0
  106. package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/hello-world.md +15 -0
  107. package/src/resources/submodules/appium/packages/appium/docs/ja/contributing/index.md +158 -0
  108. package/src/resources/submodules/appium/packages/appium/docs/ja/developing/build-docs.md +86 -0
  109. package/src/resources/submodules/appium/packages/appium/docs/ja/developing/build-doctor-checks.md +141 -0
  110. package/src/resources/submodules/appium/packages/appium/docs/ja/developing/build-drivers.md +866 -0
  111. package/src/resources/submodules/appium/packages/appium/docs/ja/developing/build-plugins.md +520 -0
  112. package/src/resources/submodules/appium/packages/appium/docs/ja/developing/config-system.md +468 -0
  113. package/src/resources/submodules/appium/packages/appium/docs/ja/developing/index.md +18 -0
  114. package/src/resources/submodules/appium/packages/appium/docs/ja/developing/sensitive.md +49 -0
  115. package/src/resources/submodules/appium/packages/appium/docs/ja/ecosystem/clients.md +143 -0
  116. package/src/resources/submodules/appium/packages/appium/docs/ja/ecosystem/drivers.md +219 -0
  117. package/src/resources/submodules/appium/packages/appium/docs/ja/ecosystem/index.md +45 -0
  118. package/src/resources/submodules/appium/packages/appium/docs/ja/ecosystem/plugins.md +140 -0
  119. package/src/resources/submodules/appium/packages/appium/docs/ja/ecosystem/tools.md +87 -0
  120. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/branch-testing.md +57 -0
  121. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/caching.md +78 -0
  122. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/caps.md +259 -0
  123. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/config.md +102 -0
  124. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/context.md +44 -0
  125. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/event-timing.md +75 -0
  126. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/execute-methods.md +142 -0
  127. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/grid.md +166 -0
  128. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/headers.md +17 -0
  129. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/log-filters.md +86 -0
  130. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/managing-exts.md +89 -0
  131. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/migrating-1-to-2.md +402 -0
  132. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/migrating-2-to-3.md +458 -0
  133. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/security.md +89 -0
  134. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/settings.md +70 -0
  135. package/src/resources/submodules/appium/packages/appium/docs/ja/guides/tls.md +43 -0
  136. package/src/resources/submodules/appium/packages/appium/docs/ja/index.md +55 -0
  137. package/src/resources/submodules/appium/packages/appium/docs/ja/intro/appium.md +191 -0
  138. package/src/resources/submodules/appium/packages/appium/docs/ja/intro/clients.md +139 -0
  139. package/src/resources/submodules/appium/packages/appium/docs/ja/intro/drivers.md +188 -0
  140. package/src/resources/submodules/appium/packages/appium/docs/ja/intro/history.md +196 -0
  141. package/src/resources/submodules/appium/packages/appium/docs/ja/intro/index.md +39 -0
  142. package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/index.md +23 -0
  143. package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/install.md +47 -0
  144. package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/next-steps.md +19 -0
  145. package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/requirements.md +29 -0
  146. package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/test-dotnet.md +107 -0
  147. package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/test-java.md +23 -0
  148. package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/test-js.md +77 -0
  149. package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/test-py.md +63 -0
  150. package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/test-rb.md +85 -0
  151. package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/uiauto2-driver.md +148 -0
  152. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/appium.md +395 -0
  153. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/bidi.md +71 -0
  154. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/index.md +30 -0
  155. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/jsonwp.md +215 -0
  156. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/mjsonwp.md +152 -0
  157. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/others.md +672 -0
  158. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/plugins.md +291 -0
  159. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/webdriver.md +1114 -0
  160. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/cli/env-vars.md +31 -0
  161. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/cli/extensions.md +240 -0
  162. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/cli/index.md +35 -0
  163. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/cli/server.md +76 -0
  164. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/cli/setup.md +78 -0
  165. package/src/resources/submodules/appium/packages/appium/docs/ja/reference/index.md +25 -0
  166. package/src/resources/submodules/appium/packages/appium/docs/ja/resources/index.md +28 -0
  167. package/src/resources/submodules/appium/packages/appium/docs/ja/sponsors/index.md +61 -0
  168. package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/appium-logo-horiz-white.png +0 -0
  169. package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/appium-logo-horiz.png +0 -0
  170. package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/appium-logo-white.png +0 -0
  171. package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/appium-logo.png +0 -0
  172. package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/sponsor-logo-browserstack-dark.png +0 -0
  173. package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/sponsor-logo-browserstack-light.png +0 -0
  174. package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/sponsor-logo-lambdatest-dark.png +0 -0
  175. package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/sponsor-logo-lambdatest-light.png +0 -0
  176. package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/sponsor-logo-sauce.png +0 -0
  177. package/src/resources/submodules/appium/packages/appium/docs/zh/blog/index.md +2 -0
  178. package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/announcing-appiumconf2024.md +45 -0
  179. package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/announcing-browserstack-as-strategic-partner.md +46 -0
  180. package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/announcing-headspin-as-development-partner.md +47 -0
  181. package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/announcing-lambdatest-as-strategic-partner.md +41 -0
  182. package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/announcing-sauce-labs-as-strategic-partner.md +36 -0
  183. package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/announcing-sponsorship-program.md +48 -0
  184. package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/appium3.md +40 -0
  185. package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/hello-world.md +15 -0
  186. package/src/resources/submodules/appium/packages/appium/docs/zh/contributing/index.md +132 -0
  187. package/src/resources/submodules/appium/packages/appium/docs/zh/developing/build-docs.md +86 -0
  188. package/src/resources/submodules/appium/packages/appium/docs/zh/developing/build-doctor-checks.md +141 -0
  189. package/src/resources/submodules/appium/packages/appium/docs/zh/developing/build-drivers.md +866 -0
  190. package/src/resources/submodules/appium/packages/appium/docs/zh/developing/build-plugins.md +520 -0
  191. package/src/resources/submodules/appium/packages/appium/docs/zh/developing/config-system.md +468 -0
  192. package/src/resources/submodules/appium/packages/appium/docs/zh/developing/index.md +18 -0
  193. package/src/resources/submodules/appium/packages/appium/docs/zh/developing/sensitive.md +49 -0
  194. package/src/resources/submodules/appium/packages/appium/docs/zh/ecosystem/clients.md +143 -0
  195. package/src/resources/submodules/appium/packages/appium/docs/zh/ecosystem/drivers.md +219 -0
  196. package/src/resources/submodules/appium/packages/appium/docs/zh/ecosystem/index.md +45 -0
  197. package/src/resources/submodules/appium/packages/appium/docs/zh/ecosystem/plugins.md +140 -0
  198. package/src/resources/submodules/appium/packages/appium/docs/zh/ecosystem/tools.md +87 -0
  199. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/branch-testing.md +57 -0
  200. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/caching.md +78 -0
  201. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/caps.md +284 -0
  202. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/config.md +102 -0
  203. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/context.md +44 -0
  204. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/event-timing.md +75 -0
  205. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/execute-methods.md +142 -0
  206. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/grid.md +166 -0
  207. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/headers.md +17 -0
  208. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/log-filters.md +86 -0
  209. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/managing-exts.md +89 -0
  210. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/migrating-1-to-2.md +410 -0
  211. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/migrating-2-to-3.md +459 -0
  212. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/security.md +89 -0
  213. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/settings.md +70 -0
  214. package/src/resources/submodules/appium/packages/appium/docs/zh/guides/tls.md +43 -0
  215. package/src/resources/submodules/appium/packages/appium/docs/zh/index.md +54 -0
  216. package/src/resources/submodules/appium/packages/appium/docs/zh/intro/appium.md +200 -0
  217. package/src/resources/submodules/appium/packages/appium/docs/zh/intro/clients.md +139 -0
  218. package/src/resources/submodules/appium/packages/appium/docs/zh/intro/drivers.md +188 -0
  219. package/src/resources/submodules/appium/packages/appium/docs/zh/intro/history.md +196 -0
  220. package/src/resources/submodules/appium/packages/appium/docs/zh/intro/index.md +39 -0
  221. package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/index.md +23 -0
  222. package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/install.md +47 -0
  223. package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/next-steps.md +19 -0
  224. package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/requirements.md +21 -0
  225. package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/test-dotnet.md +99 -0
  226. package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/test-java.md +20 -0
  227. package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/test-js.md +62 -0
  228. package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/test-py.md +57 -0
  229. package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/test-rb.md +80 -0
  230. package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/uiauto2-driver.md +148 -0
  231. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/appium.md +395 -0
  232. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/bidi.md +71 -0
  233. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/index.md +30 -0
  234. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/jsonwp.md +215 -0
  235. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/mjsonwp.md +152 -0
  236. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/others.md +672 -0
  237. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/plugins.md +291 -0
  238. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/webdriver.md +1114 -0
  239. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/cli/env-vars.md +31 -0
  240. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/cli/extensions.md +240 -0
  241. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/cli/index.md +35 -0
  242. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/cli/server.md +76 -0
  243. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/cli/setup.md +78 -0
  244. package/src/resources/submodules/appium/packages/appium/docs/zh/reference/index.md +25 -0
  245. package/src/resources/submodules/appium/packages/appium/docs/zh/resources/index.md +28 -0
  246. package/src/resources/submodules/appium/packages/appium/docs/zh/sponsors/index.md +61 -0
  247. package/src/resources/submodules/appium/packages/appium/types/manifest/README.md +30 -0
  248. package/src/resources/submodules/appium/packages/base-driver/CHANGELOG.md +1131 -0
  249. package/src/resources/submodules/appium/packages/base-driver/README.md +15 -0
  250. package/src/resources/submodules/appium/packages/base-driver/docs/mjsonwp/errors.md +82 -0
  251. package/src/resources/submodules/appium/packages/base-driver/docs/mjsonwp/protocol-methods.md +182 -0
  252. package/src/resources/submodules/appium/packages/base-driver/static/appium.png +0 -0
  253. package/src/resources/submodules/appium/packages/base-plugin/CHANGELOG.md +672 -0
  254. package/src/resources/submodules/appium/packages/base-plugin/README.md +15 -0
  255. package/src/resources/submodules/appium/packages/docutils/CHANGELOG.md +948 -0
  256. package/src/resources/submodules/appium/packages/docutils/README.md +27 -0
  257. package/src/resources/submodules/appium/packages/driver-test-support/CHANGELOG.md +717 -0
  258. package/src/resources/submodules/appium/packages/driver-test-support/README.md +112 -0
  259. package/src/resources/submodules/appium/packages/eslint-config-appium-ts/CHANGELOG.md +168 -0
  260. package/src/resources/submodules/appium/packages/eslint-config-appium-ts/README.md +33 -0
  261. package/src/resources/submodules/appium/packages/execute-driver-plugin/CHANGELOG.md +603 -0
  262. package/src/resources/submodules/appium/packages/execute-driver-plugin/README.md +42 -0
  263. package/src/resources/submodules/appium/packages/fake-driver/CHANGELOG.md +545 -0
  264. package/src/resources/submodules/appium/packages/fake-driver/README.md +7 -0
  265. package/src/resources/submodules/appium/packages/fake-driver/lib/screen.png +0 -0
  266. package/src/resources/submodules/appium/packages/fake-plugin/CHANGELOG.md +683 -0
  267. package/src/resources/submodules/appium/packages/fake-plugin/README.md +7 -0
  268. package/src/resources/submodules/appium/packages/images-plugin/CHANGELOG.md +602 -0
  269. package/src/resources/submodules/appium/packages/images-plugin/README.md +27 -0
  270. package/src/resources/submodules/appium/packages/images-plugin/docs/find-by-image.md +65 -0
  271. package/src/resources/submodules/appium/packages/images-plugin/docs/image-comparison.md +203 -0
  272. package/src/resources/submodules/appium/packages/images-plugin/test/fixtures/appstore.png +0 -0
  273. package/src/resources/submodules/appium/packages/images-plugin/test/fixtures/img1.png +0 -0
  274. package/src/resources/submodules/appium/packages/images-plugin/test/fixtures/img2.png +0 -0
  275. package/src/resources/submodules/appium/packages/images-plugin/test/fixtures/img2_part.png +0 -0
  276. package/src/resources/submodules/appium/packages/logger/CHANGELOG.md +162 -0
  277. package/src/resources/submodules/appium/packages/logger/README.md +31 -0
  278. package/src/resources/submodules/appium/packages/opencv/CHANGELOG.md +384 -0
  279. package/src/resources/submodules/appium/packages/opencv/README.md +68 -0
  280. package/src/resources/submodules/appium/packages/opencv/test/e2e/images/appium-diagram.jpg +0 -0
  281. package/src/resources/submodules/appium/packages/opencv/test/e2e/images/cc1.png +0 -0
  282. package/src/resources/submodules/appium/packages/opencv/test/e2e/images/cc2.png +0 -0
  283. package/src/resources/submodules/appium/packages/opencv/test/e2e/images/cc_rotated.png +0 -0
  284. package/src/resources/submodules/appium/packages/opencv/test/e2e/images/findwaldo.jpg +0 -0
  285. package/src/resources/submodules/appium/packages/opencv/test/e2e/images/number5.png +0 -0
  286. package/src/resources/submodules/appium/packages/opencv/test/e2e/images/waldo.jpg +0 -0
  287. package/src/resources/submodules/appium/packages/plugin-test-support/CHANGELOG.md +539 -0
  288. package/src/resources/submodules/appium/packages/plugin-test-support/README.md +49 -0
  289. package/src/resources/submodules/appium/packages/relaxed-caps-plugin/CHANGELOG.md +154 -0
  290. package/src/resources/submodules/appium/packages/relaxed-caps-plugin/README.md +35 -0
  291. package/src/resources/submodules/appium/packages/schema/CHANGELOG.md +271 -0
  292. package/src/resources/submodules/appium/packages/schema/README.md +50 -0
  293. package/src/resources/submodules/appium/packages/storage-plugin/CHANGELOG.md +73 -0
  294. package/src/resources/submodules/appium/packages/storage-plugin/README.md +83 -0
  295. package/src/resources/submodules/appium/packages/strongbox/CHANGELOG.md +94 -0
  296. package/src/resources/submodules/appium/packages/strongbox/README.md +96 -0
  297. package/src/resources/submodules/appium/packages/support/CHANGELOG.md +1054 -0
  298. package/src/resources/submodules/appium/packages/support/README.md +161 -0
  299. package/src/resources/submodules/appium/packages/test-support/CHANGELOG.md +712 -0
  300. package/src/resources/submodules/appium/packages/test-support/README.md +61 -0
  301. package/src/resources/submodules/appium/packages/tsconfig/CHANGELOG.md +131 -0
  302. package/src/resources/submodules/appium/packages/tsconfig/README.md +19 -0
  303. package/src/resources/submodules/appium/packages/types/CHANGELOG.md +793 -0
  304. package/src/resources/submodules/appium/packages/types/README.md +21 -0
  305. package/src/resources/submodules/appium/packages/universal-xml-plugin/CHANGELOG.md +435 -0
  306. package/src/resources/submodules/appium/packages/universal-xml-plugin/README.md +53 -0
  307. package/src/resources/submodules/appium/renovate/README.md +63 -0
  308. package/src/resources/submodules/appium-uiautomator2-driver/CHANGELOG.md +1204 -0
  309. package/src/resources/submodules/appium-uiautomator2-driver/README.md +2077 -0
  310. package/src/resources/submodules/appium-uiautomator2-driver/docs/actions.md +72 -0
  311. package/src/resources/submodules/appium-uiautomator2-driver/docs/activity-startup.md +47 -0
  312. package/src/resources/submodules/appium-uiautomator2-driver/docs/android-appbundle.md +69 -0
  313. package/src/resources/submodules/appium-uiautomator2-driver/docs/android-mobile-gestures.md +352 -0
  314. package/src/resources/submodules/appium-uiautomator2-driver/docs/bidi.md +50 -0
  315. package/src/resources/submodules/appium-uiautomator2-driver/docs/capability-sets.md +136 -0
  316. package/src/resources/submodules/appium-uiautomator2-driver/docs/scheduled-actions.md +155 -0
  317. package/src/resources/submodules/appium-uiautomator2-driver/docs/uiautomator-uiselector.md +51 -0
  318. package/src/resources/submodules/appium-uiautomator2-driver/docs/unlock/main.md +95 -0
  319. package/src/resources/submodules/appium-uiautomator2-driver/docs/unlock/screen1.png +0 -0
  320. package/src/resources/submodules/appium-uiautomator2-driver/docs/unlock/screen2.png +0 -0
  321. package/src/resources/submodules/appium-uiautomator2-driver/test/functional/assets/checkered-squares.png +0 -0
  322. package/src/resources/submodules/appium-uiautomator2-driver/test/functional/assets/start-button.png +0 -0
  323. package/src/resources/submodules/appium-uiautomator2-driver/test/functional/assets/stop-button.png +0 -0
  324. package/src/resources/submodules/appium-xcuitest-driver/.github/ISSUE_TEMPLATE.md +4 -0
  325. package/src/resources/submodules/appium-xcuitest-driver/CHANGELOG.md +2594 -0
  326. package/src/resources/submodules/appium-xcuitest-driver/README.md +55 -0
  327. package/src/resources/submodules/appium-xcuitest-driver/docs/assets/images/appium-logo-white.png +0 -0
  328. package/src/resources/submodules/appium-xcuitest-driver/docs/assets/images/appium-logo.png +0 -0
  329. package/src/resources/submodules/appium-xcuitest-driver/docs/assets/images/appium-plus-xctest.png +0 -0
  330. package/src/resources/submodules/appium-xcuitest-driver/docs/contributing.md +45 -0
  331. package/src/resources/submodules/appium-xcuitest-driver/docs/endpoints-wda.md +61 -0
  332. package/src/resources/submodules/appium-xcuitest-driver/docs/endpoints.md +98 -0
  333. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/assets/images/ios-xctest-file-movement/keynote.png +0 -0
  334. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/assets/images/ios-xctest-file-movement/on_my_iphone.png +0 -0
  335. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/assets/images/ios-xctest-file-movement/top_files.png +0 -0
  336. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/attach-to-running-wda.md +43 -0
  337. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/audio-capture.md +78 -0
  338. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/capability-sets.md +169 -0
  339. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/ci-setup.md +47 -0
  340. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/clipboard.md +47 -0
  341. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/elements-lookup-troubleshooting.md +158 -0
  342. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/file-transfer.md +147 -0
  343. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/gestures.md +52 -0
  344. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/hybrid.md +137 -0
  345. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/input-events.md +67 -0
  346. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/install-certificate.md +19 -0
  347. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/multiple-xcode-versions.md +37 -0
  348. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/parallel-tests.md +39 -0
  349. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/run-prebuilt-wda.md +135 -0
  350. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/run-preinstalled-wda.md +178 -0
  351. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/touch-id.md +33 -0
  352. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/troubleshooting.md +191 -0
  353. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/tvos.md +114 -0
  354. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/wda-custom-server.md +283 -0
  355. package/src/resources/submodules/appium-xcuitest-driver/docs/guides/wda-slowness.md +231 -0
  356. package/src/resources/submodules/appium-xcuitest-driver/docs/index.md +36 -0
  357. package/src/resources/submodules/appium-xcuitest-driver/docs/installation/index.md +137 -0
  358. package/src/resources/submodules/appium-xcuitest-driver/docs/overview.md +19 -0
  359. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/check-prov-prof.png +0 -0
  360. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/create-new-project.png +0 -0
  361. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/create-single-page.png +0 -0
  362. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/no-prov-prof.png +0 -0
  363. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/project-prov-prof.png +0 -0
  364. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/set-up-bundle.png +0 -0
  365. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/untrusted-dev.png +0 -0
  366. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/xcode-bundle-id.png +0 -0
  367. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/xcode-config.png +0 -0
  368. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/xcode-facebook-fail.png +0 -0
  369. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/xcode-facebook-succeed.png +0 -0
  370. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/index.md +51 -0
  371. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/prov-profile-basic-auto.md +49 -0
  372. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/prov-profile-basic-manual.md +40 -0
  373. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/prov-profile-full-manual.md +50 -0
  374. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/prov-profile-generic-manual.md +49 -0
  375. package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/real-device-config.md +100 -0
  376. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/assets/images/useXctestrunFile.png +0 -0
  377. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/bidi.md +75 -0
  378. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/capabilities.md +165 -0
  379. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/commands.md +490 -0
  380. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/element-attributes.md +27 -0
  381. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/execute-methods.md +2206 -0
  382. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/ios-predicate.md +196 -0
  383. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/locator-strategies.md +19 -0
  384. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/scripts.md +29 -0
  385. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/security-flags.md +22 -0
  386. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/server-args.md +16 -0
  387. package/src/resources/submodules/appium-xcuitest-driver/docs/reference/settings.md +49 -0
  388. package/src/resources/submodules/appium-xcuitest-driver/test/assets/TestApp-iphonesimulator.app/Default-568h@2x.png +0 -0
  389. package/src/resources/submodules/appium-xcuitest-driver/test/assets/test.png +0 -0
  390. package/src/schema.ts +5 -0
  391. package/src/scripts/simple-index-documentation.ts +93 -0
  392. package/src/scripts/simple-query-documentation.ts +61 -0
  393. package/src/server.ts +40 -0
  394. package/src/session-store.ts +151 -0
  395. package/src/tests/README.md +83 -0
  396. package/src/tests/__mocks__/@appium/support.ts +30 -0
  397. package/src/tests/generate-all-locators.test.ts +178 -0
  398. package/src/tests/screenshot.test.ts +279 -0
  399. package/src/tests/test-setup-wda.ts +255 -0
  400. package/src/tools/README.md +179 -0
  401. package/src/tools/app-management/activate-app.ts +47 -0
  402. package/src/tools/app-management/install-app.ts +46 -0
  403. package/src/tools/app-management/list-apps.ts +87 -0
  404. package/src/tools/app-management/terminate-app.ts +48 -0
  405. package/src/tools/app-management/uninstall-app.ts +48 -0
  406. package/src/tools/context/get-contexts.ts +87 -0
  407. package/src/tools/context/switch-context.ts +101 -0
  408. package/src/tools/documentation/answer-appium.ts +73 -0
  409. package/src/tools/documentation/index.ts +98 -0
  410. package/src/tools/documentation/reasoning-rag.ts +435 -0
  411. package/src/tools/documentation/sentence-transformers-embeddings.ts +144 -0
  412. package/src/tools/documentation/simple-pdf-indexer.ts +508 -0
  413. package/src/tools/documentation/uploads/documents.json +1 -0
  414. package/src/tools/index.ts +159 -0
  415. package/src/tools/interactions/click.ts +48 -0
  416. package/src/tools/interactions/double-tap.ts +96 -0
  417. package/src/tools/interactions/drag-and-drop.ts +236 -0
  418. package/src/tools/interactions/find.ts +58 -0
  419. package/src/tools/interactions/get-page-source.ts +65 -0
  420. package/src/tools/interactions/get-text.ts +48 -0
  421. package/src/tools/interactions/long-press.ts +111 -0
  422. package/src/tools/interactions/screenshot.ts +116 -0
  423. package/src/tools/interactions/set-value.ts +49 -0
  424. package/src/tools/ios/boot-simulator.ts +88 -0
  425. package/src/tools/ios/install-wda.ts +277 -0
  426. package/src/tools/ios/setup-wda.ts +217 -0
  427. package/src/tools/navigations/scroll-to-element.ts +198 -0
  428. package/src/tools/navigations/scroll.ts +101 -0
  429. package/src/tools/navigations/swipe.ts +364 -0
  430. package/src/tools/session/create-session.ts +379 -0
  431. package/src/tools/session/delete-session.ts +56 -0
  432. package/src/tools/session/select-device.ts +326 -0
  433. package/src/tools/session/select-platform.ts +250 -0
  434. package/src/tools/test-generation/generate-tests.ts +48 -0
  435. package/src/tools/test-generation/locators.ts +103 -0
  436. package/src/ui/mcp-ui-utils.ts +1630 -0
@@ -0,0 +1,1630 @@
1
+ /**
2
+ * MCP-UI Utility Functions
3
+ *
4
+ * This module provides utilities for creating UI resources using MCP-UI protocol.
5
+ * It enables interactive UI components to be returned alongside text responses.
6
+ *
7
+ * Reference: https://mcpui.dev/guide/introduction
8
+ */
9
+
10
+ /**
11
+ * Creates a UIResource object following MCP-UI protocol
12
+ * @param uri - Unique identifier using ui:// scheme (e.g., 'ui://appium-mcp/device-picker')
13
+ * @param htmlContent - HTML string to render in the iframe
14
+ * @returns UIResource object ready to be included in MCP response content
15
+ */
16
+ export function createUIResource(
17
+ uri: string,
18
+ htmlContent: string
19
+ ): {
20
+ type: 'resource';
21
+ resource: {
22
+ uri: string;
23
+ mimeType: 'text/html';
24
+ text: string;
25
+ };
26
+ } {
27
+ return {
28
+ type: 'resource',
29
+ resource: {
30
+ uri,
31
+ mimeType: 'text/html',
32
+ text: htmlContent,
33
+ },
34
+ };
35
+ }
36
+
37
+ /**
38
+ * Creates a device picker UI component
39
+ * @param devices - Array of device objects with name, udid, state, etc.
40
+ * @param platform - 'android' or 'ios'
41
+ * @param deviceType - 'simulator' or 'real' for iOS
42
+ * @returns HTML string for device picker UI
43
+ */
44
+ export function createDevicePickerUI(
45
+ devices: Array<{
46
+ name?: string;
47
+ udid: string;
48
+ state?: string;
49
+ type?: string;
50
+ }>,
51
+ platform: 'android' | 'ios',
52
+ deviceType?: 'simulator' | 'real'
53
+ ): string {
54
+ const deviceTypeLabel =
55
+ platform === 'ios' && deviceType
56
+ ? deviceType === 'simulator'
57
+ ? 'iOS Simulators'
58
+ : 'iOS Devices'
59
+ : 'Android Devices';
60
+
61
+ const deviceCards = devices
62
+ .map(
63
+ (device, index) => `
64
+ <div class="device-card" data-udid="${device.udid}" data-index="${index}">
65
+ <div class="device-header">
66
+ <h3>${device.name || device.udid}</h3>
67
+ ${device.state ? `<span class="device-state ${device.state.toLowerCase()}">${device.state}</span>` : ''}
68
+ </div>
69
+ <div class="device-details">
70
+ <p><strong>UDID:</strong> <code>${device.udid}</code></p>
71
+ ${device.type ? `<p><strong>Type:</strong> ${device.type}</p>` : ''}
72
+ </div>
73
+ <button class="select-device-btn" onclick="selectDevice('${device.udid}')">
74
+ Select Device
75
+ </button>
76
+ </div>
77
+ `
78
+ )
79
+ .join('');
80
+
81
+ return `
82
+ <!DOCTYPE html>
83
+ <html lang="en">
84
+ <head>
85
+ <meta charset="UTF-8">
86
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
87
+ <title>Device Picker - ${deviceTypeLabel}</title>
88
+ <style>
89
+ * {
90
+ margin: 0;
91
+ padding: 0;
92
+ box-sizing: border-box;
93
+ }
94
+ body {
95
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
96
+ padding: 20px;
97
+ background: #f5f5f5;
98
+ color: #333;
99
+ }
100
+ .container {
101
+ max-width: 1200px;
102
+ margin: 0 auto;
103
+ }
104
+ .header {
105
+ margin-bottom: 24px;
106
+ }
107
+ .header h1 {
108
+ font-size: 24px;
109
+ margin-bottom: 8px;
110
+ color: #1a1a1a;
111
+ }
112
+ .header p {
113
+ color: #666;
114
+ font-size: 14px;
115
+ }
116
+ .devices-grid {
117
+ display: grid;
118
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
119
+ gap: 16px;
120
+ }
121
+ .device-card {
122
+ background: white;
123
+ border: 1px solid #e0e0e0;
124
+ border-radius: 8px;
125
+ padding: 16px;
126
+ transition: all 0.2s;
127
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
128
+ }
129
+ .device-card:hover {
130
+ border-color: #007AFF;
131
+ box-shadow: 0 4px 12px rgba(0,122,255,0.15);
132
+ transform: translateY(-2px);
133
+ }
134
+ .device-header {
135
+ display: flex;
136
+ justify-content: space-between;
137
+ align-items: center;
138
+ margin-bottom: 12px;
139
+ }
140
+ .device-header h3 {
141
+ font-size: 16px;
142
+ font-weight: 600;
143
+ color: #1a1a1a;
144
+ }
145
+ .device-state {
146
+ padding: 4px 8px;
147
+ border-radius: 4px;
148
+ font-size: 12px;
149
+ font-weight: 500;
150
+ text-transform: uppercase;
151
+ }
152
+ .device-state.booted {
153
+ background: #d4edda;
154
+ color: #155724;
155
+ }
156
+ .device-state.shutdown {
157
+ background: #f8d7da;
158
+ color: #721c24;
159
+ }
160
+ .device-details {
161
+ margin-bottom: 12px;
162
+ font-size: 13px;
163
+ }
164
+ .device-details p {
165
+ margin-bottom: 6px;
166
+ color: #666;
167
+ }
168
+ .device-details code {
169
+ background: #f5f5f5;
170
+ padding: 2px 6px;
171
+ border-radius: 3px;
172
+ font-size: 12px;
173
+ font-family: 'Monaco', 'Menlo', monospace;
174
+ }
175
+ .select-device-btn {
176
+ width: 100%;
177
+ padding: 10px 16px;
178
+ background: #007AFF;
179
+ color: white;
180
+ border: none;
181
+ border-radius: 6px;
182
+ font-size: 14px;
183
+ font-weight: 500;
184
+ cursor: pointer;
185
+ transition: background 0.2s;
186
+ }
187
+ .select-device-btn:hover {
188
+ background: #0056b3;
189
+ }
190
+ .select-device-btn:active {
191
+ transform: scale(0.98);
192
+ }
193
+ .empty-state {
194
+ text-align: center;
195
+ padding: 40px;
196
+ color: #999;
197
+ }
198
+ </style>
199
+ </head>
200
+ <body>
201
+ <div class="container">
202
+ <div class="header">
203
+ <h1>📱 Select ${deviceTypeLabel}</h1>
204
+ <p>Found ${devices.length} device${devices.length !== 1 ? 's' : ''}. Click on a device to select it.</p>
205
+ </div>
206
+ <div class="devices-grid">
207
+ ${devices.length > 0 ? deviceCards : '<div class="empty-state">No devices found</div>'}
208
+ </div>
209
+ </div>
210
+ <script>
211
+ function selectDevice(udid) {
212
+ // Send intent message to parent window
213
+ window.parent.postMessage({
214
+ type: 'intent',
215
+ payload: {
216
+ intent: 'select-device',
217
+ params: {
218
+ platform: '${platform}',
219
+ ${deviceType ? `deviceType: '${deviceType}',` : ''}
220
+ deviceUdid: udid
221
+ }
222
+ }
223
+ }, '*');
224
+ }
225
+
226
+ // Add click handlers for better UX
227
+ document.querySelectorAll('.device-card').forEach(card => {
228
+ card.addEventListener('click', (e) => {
229
+ if (e.target.classList.contains('select-device-btn')) return;
230
+ const udid = card.dataset.udid;
231
+ selectDevice(udid);
232
+ });
233
+ });
234
+ </script>
235
+ </body>
236
+ </html>
237
+ `;
238
+ }
239
+
240
+ /**
241
+ * Creates a screenshot viewer UI component
242
+ * @param screenshotBase64 - Base64 encoded PNG image
243
+ * @param filepath - Path where screenshot was saved
244
+ * @returns HTML string for screenshot viewer
245
+ */
246
+ export function createScreenshotViewerUI(
247
+ screenshotBase64: string,
248
+ filepath: string
249
+ ): string {
250
+ return `
251
+ <!DOCTYPE html>
252
+ <html lang="en">
253
+ <head>
254
+ <meta charset="UTF-8">
255
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
256
+ <title>Screenshot Viewer</title>
257
+ <style>
258
+ * {
259
+ margin: 0;
260
+ padding: 0;
261
+ box-sizing: border-box;
262
+ }
263
+ body {
264
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
265
+ background: #1a1a1a;
266
+ color: #fff;
267
+ padding: 20px;
268
+ overflow: hidden;
269
+ }
270
+ .viewer-container {
271
+ display: flex;
272
+ flex-direction: column;
273
+ height: 100vh;
274
+ max-width: 100%;
275
+ }
276
+ .toolbar {
277
+ display: flex;
278
+ justify-content: space-between;
279
+ align-items: center;
280
+ padding: 12px 16px;
281
+ background: #2a2a2a;
282
+ border-radius: 8px 8px 0 0;
283
+ margin-bottom: 1px;
284
+ }
285
+ .toolbar-left {
286
+ display: flex;
287
+ gap: 8px;
288
+ align-items: center;
289
+ }
290
+ .toolbar-right {
291
+ display: flex;
292
+ gap: 8px;
293
+ }
294
+ .btn {
295
+ padding: 6px 12px;
296
+ background: #007AFF;
297
+ color: white;
298
+ border: none;
299
+ border-radius: 4px;
300
+ font-size: 13px;
301
+ cursor: pointer;
302
+ transition: background 0.2s;
303
+ }
304
+ .btn:hover {
305
+ background: #0056b3;
306
+ }
307
+ .btn-secondary {
308
+ background: #444;
309
+ }
310
+ .btn-secondary:hover {
311
+ background: #555;
312
+ }
313
+ .filepath {
314
+ font-size: 12px;
315
+ color: #999;
316
+ font-family: 'Monaco', 'Menlo', monospace;
317
+ }
318
+ .image-container {
319
+ flex: 1;
320
+ overflow: auto;
321
+ background: #1a1a1a;
322
+ display: flex;
323
+ align-items: center;
324
+ justify-content: center;
325
+ padding: 20px;
326
+ }
327
+ .screenshot-img {
328
+ max-width: 100%;
329
+ max-height: 100%;
330
+ object-fit: contain;
331
+ border-radius: 4px;
332
+ box-shadow: 0 4px 20px rgba(0,0,0,0.5);
333
+ cursor: zoom-in;
334
+ }
335
+ .screenshot-img.zoomed {
336
+ cursor: zoom-out;
337
+ transform: scale(2);
338
+ transition: transform 0.3s;
339
+ }
340
+ .zoom-controls {
341
+ position: absolute;
342
+ bottom: 20px;
343
+ right: 20px;
344
+ display: flex;
345
+ gap: 8px;
346
+ background: rgba(42, 42, 42, 0.9);
347
+ padding: 8px;
348
+ border-radius: 6px;
349
+ }
350
+ .zoom-btn {
351
+ width: 32px;
352
+ height: 32px;
353
+ background: #007AFF;
354
+ color: white;
355
+ border: none;
356
+ border-radius: 4px;
357
+ cursor: pointer;
358
+ font-size: 16px;
359
+ display: flex;
360
+ align-items: center;
361
+ justify-content: center;
362
+ }
363
+ .zoom-btn:hover {
364
+ background: #0056b3;
365
+ }
366
+ </style>
367
+ </head>
368
+ <body>
369
+ <div class="viewer-container">
370
+ <div class="toolbar">
371
+ <div class="toolbar-left">
372
+ <span style="font-size: 14px; font-weight: 500;">📸 Screenshot</span>
373
+ <span class="filepath">${filepath}</span>
374
+ </div>
375
+ <div class="toolbar-right">
376
+ <button class="btn btn-secondary" onclick="downloadScreenshot()">Download</button>
377
+ <button class="btn" onclick="takeNewScreenshot()">Take New</button>
378
+ </div>
379
+ </div>
380
+ <div class="image-container" id="imageContainer">
381
+ <img src="data:image/png;base64,${screenshotBase64}"
382
+ alt="Screenshot"
383
+ class="screenshot-img"
384
+ id="screenshotImg"
385
+ onclick="toggleZoom()">
386
+ </div>
387
+ <div class="zoom-controls">
388
+ <button class="zoom-btn" onclick="zoomIn()">+</button>
389
+ <button class="zoom-btn" onclick="zoomOut()">−</button>
390
+ <button class="zoom-btn" onclick="resetZoom()">⌂</button>
391
+ </div>
392
+ </div>
393
+ <script>
394
+ let currentZoom = 1;
395
+ const img = document.getElementById('screenshotImg');
396
+
397
+ function toggleZoom() {
398
+ if (currentZoom === 1) {
399
+ zoomIn();
400
+ } else {
401
+ resetZoom();
402
+ }
403
+ }
404
+
405
+ function zoomIn() {
406
+ currentZoom = Math.min(currentZoom + 0.5, 4);
407
+ img.style.transform = \`scale(\${currentZoom})\`;
408
+ }
409
+
410
+ function zoomOut() {
411
+ currentZoom = Math.max(currentZoom - 0.5, 0.5);
412
+ img.style.transform = \`scale(\${currentZoom})\`;
413
+ }
414
+
415
+ function resetZoom() {
416
+ currentZoom = 1;
417
+ img.style.transform = 'scale(1)';
418
+ }
419
+
420
+ function downloadScreenshot() {
421
+ const link = document.createElement('a');
422
+ link.href = img.src;
423
+ link.download = '${filepath.split('/').pop() || 'screenshot.png'}';
424
+ link.click();
425
+ }
426
+
427
+ function takeNewScreenshot() {
428
+ window.parent.postMessage({
429
+ type: 'tool',
430
+ payload: {
431
+ toolName: 'appium_screenshot',
432
+ params: {}
433
+ }
434
+ }, '*');
435
+ }
436
+
437
+ // Keyboard shortcuts
438
+ document.addEventListener('keydown', (e) => {
439
+ if (e.key === '+' || e.key === '=') zoomIn();
440
+ if (e.key === '-') zoomOut();
441
+ if (e.key === '0') resetZoom();
442
+ });
443
+ </script>
444
+ </body>
445
+ </html>
446
+ `;
447
+ }
448
+
449
+ /**
450
+ * Creates a session dashboard UI component
451
+ * @param sessionInfo - Session information object
452
+ * @returns HTML string for session dashboard
453
+ */
454
+ export function createSessionDashboardUI(sessionInfo: {
455
+ sessionId: string | any;
456
+ platform: string;
457
+ automationName: string;
458
+ deviceName?: string;
459
+ platformVersion?: string;
460
+ udid?: string;
461
+ }): string {
462
+ // Safely convert sessionId to string
463
+ const sessionIdStr =
464
+ typeof sessionInfo.sessionId === 'string'
465
+ ? sessionInfo.sessionId
466
+ : String(sessionInfo.sessionId || 'Unknown');
467
+
468
+ // Get first 8 characters for display, or full string if shorter
469
+ const sessionIdDisplay =
470
+ sessionIdStr.length > 8
471
+ ? `${sessionIdStr.substring(0, 8)}...`
472
+ : sessionIdStr;
473
+
474
+ return `
475
+ <!DOCTYPE html>
476
+ <html lang="en">
477
+ <head>
478
+ <meta charset="UTF-8">
479
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
480
+ <title>Session Dashboard</title>
481
+ <style>
482
+ * {
483
+ margin: 0;
484
+ padding: 0;
485
+ box-sizing: border-box;
486
+ }
487
+ body {
488
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
489
+ background: #f5f5f5;
490
+ padding: 20px;
491
+ }
492
+ .dashboard {
493
+ max-width: 800px;
494
+ margin: 0 auto;
495
+ background: white;
496
+ border-radius: 12px;
497
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
498
+ overflow: hidden;
499
+ }
500
+ .header {
501
+ background: linear-gradient(135deg, #007AFF 0%, #0056b3 100%);
502
+ color: white;
503
+ padding: 24px;
504
+ }
505
+ .header h1 {
506
+ font-size: 24px;
507
+ margin-bottom: 8px;
508
+ }
509
+ .header .status {
510
+ display: inline-block;
511
+ padding: 4px 12px;
512
+ background: rgba(255,255,255,0.2);
513
+ border-radius: 12px;
514
+ font-size: 12px;
515
+ font-weight: 500;
516
+ }
517
+ .content {
518
+ padding: 24px;
519
+ }
520
+ .info-grid {
521
+ display: grid;
522
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
523
+ gap: 16px;
524
+ margin-bottom: 24px;
525
+ }
526
+ .info-card {
527
+ padding: 16px;
528
+ background: #f8f9fa;
529
+ border-radius: 8px;
530
+ border-left: 3px solid #007AFF;
531
+ }
532
+ .info-card label {
533
+ display: block;
534
+ font-size: 12px;
535
+ color: #666;
536
+ margin-bottom: 4px;
537
+ text-transform: uppercase;
538
+ font-weight: 500;
539
+ }
540
+ .info-card value {
541
+ display: block;
542
+ font-size: 16px;
543
+ color: #1a1a1a;
544
+ font-weight: 600;
545
+ }
546
+ .actions {
547
+ display: flex;
548
+ gap: 12px;
549
+ flex-wrap: wrap;
550
+ }
551
+ .btn {
552
+ padding: 10px 20px;
553
+ border: none;
554
+ border-radius: 6px;
555
+ font-size: 14px;
556
+ font-weight: 500;
557
+ cursor: pointer;
558
+ transition: all 0.2s;
559
+ }
560
+ .btn-primary {
561
+ background: #007AFF;
562
+ color: white;
563
+ }
564
+ .btn-primary:hover {
565
+ background: #0056b3;
566
+ }
567
+ .btn-secondary {
568
+ background: #f0f0f0;
569
+ color: #333;
570
+ }
571
+ .btn-secondary:hover {
572
+ background: #e0e0e0;
573
+ }
574
+ .btn-danger {
575
+ background: #dc3545;
576
+ color: white;
577
+ }
578
+ .btn-danger:hover {
579
+ background: #c82333;
580
+ }
581
+ </style>
582
+ </head>
583
+ <body>
584
+ <div class="dashboard">
585
+ <div class="header">
586
+ <h1>📱 Appium Session Dashboard</h1>
587
+ <span class="status">● Active</span>
588
+ </div>
589
+ <div class="content">
590
+ <div class="info-grid">
591
+ <div class="info-card">
592
+ <label>Session ID</label>
593
+ <value>${sessionIdDisplay}</value>
594
+ </div>
595
+ <div class="info-card">
596
+ <label>Platform</label>
597
+ <value>${sessionInfo.platform}</value>
598
+ </div>
599
+ <div class="info-card">
600
+ <label>Automation</label>
601
+ <value>${sessionInfo.automationName}</value>
602
+ </div>
603
+ ${
604
+ sessionInfo.deviceName
605
+ ? `
606
+ <div class="info-card">
607
+ <label>Device</label>
608
+ <value>${sessionInfo.deviceName}</value>
609
+ </div>
610
+ `
611
+ : ''
612
+ }
613
+ ${
614
+ sessionInfo.platformVersion
615
+ ? `
616
+ <div class="info-card">
617
+ <label>Platform Version</label>
618
+ <value>${sessionInfo.platformVersion}</value>
619
+ </div>
620
+ `
621
+ : ''
622
+ }
623
+ ${
624
+ sessionInfo.udid
625
+ ? `
626
+ <div class="info-card">
627
+ <label>UDID</label>
628
+ <value><code style="font-size: 12px;">${sessionInfo.udid}</code></value>
629
+ </div>
630
+ `
631
+ : ''
632
+ }
633
+ </div>
634
+ <div class="actions">
635
+ <button class="btn btn-primary" onclick="takeScreenshot()">📸 Screenshot</button>
636
+ <button class="btn btn-primary" onclick="getPageSource()">📄 Page Source</button>
637
+ <button class="btn btn-primary" onclick="generateLocators()">🔍 Generate Locators</button>
638
+ <button class="btn btn-secondary" onclick="getContexts()">🌐 Contexts</button>
639
+ <button class="btn btn-danger" onclick="deleteSession()">🗑️ End Session</button>
640
+ </div>
641
+ </div>
642
+ </div>
643
+ <script>
644
+ function takeScreenshot() {
645
+ window.parent.postMessage({
646
+ type: 'tool',
647
+ payload: {
648
+ toolName: 'appium_screenshot',
649
+ params: {}
650
+ }
651
+ }, '*');
652
+ }
653
+
654
+ function getPageSource() {
655
+ window.parent.postMessage({
656
+ type: 'tool',
657
+ payload: {
658
+ toolName: 'appium_get_page_source',
659
+ params: {}
660
+ }
661
+ }, '*');
662
+ }
663
+
664
+ function generateLocators() {
665
+ window.parent.postMessage({
666
+ type: 'tool',
667
+ payload: {
668
+ toolName: 'generate_locators',
669
+ params: {}
670
+ }
671
+ }, '*');
672
+ }
673
+
674
+ function getContexts() {
675
+ window.parent.postMessage({
676
+ type: 'tool',
677
+ payload: {
678
+ toolName: 'appium_get_contexts',
679
+ params: {}
680
+ }
681
+ }, '*');
682
+ }
683
+
684
+ function deleteSession() {
685
+ if (confirm('Are you sure you want to end this session?')) {
686
+ window.parent.postMessage({
687
+ type: 'tool',
688
+ payload: {
689
+ toolName: 'delete_session',
690
+ params: {}
691
+ }
692
+ }, '*');
693
+ }
694
+ }
695
+ </script>
696
+ </body>
697
+ </html>
698
+ `;
699
+ }
700
+
701
+ /**
702
+ * Creates a locator generator UI component
703
+ * @param locators - Array of elements with locators
704
+ * @returns HTML string for locator generator UI
705
+ */
706
+ export function createLocatorGeneratorUI(
707
+ locators: Array<{
708
+ tagName: string;
709
+ locators: Record<string, string>;
710
+ text: string;
711
+ contentDesc: string;
712
+ resourceId: string;
713
+ clickable: boolean;
714
+ enabled: boolean;
715
+ displayed: boolean;
716
+ }>
717
+ ): string {
718
+ const locatorCards = locators
719
+ .map(
720
+ (element, index) => `
721
+ <div class="locator-card" data-index="${index}">
722
+ <div class="locator-header">
723
+ <h3>${element.tagName}</h3>
724
+ <div class="badges">
725
+ ${element.clickable ? '<span class="badge badge-clickable">Clickable</span>' : ''}
726
+ ${element.enabled ? '<span class="badge badge-enabled">Enabled</span>' : ''}
727
+ ${element.displayed ? '<span class="badge badge-displayed">Displayed</span>' : ''}
728
+ </div>
729
+ </div>
730
+ ${element.text ? `<p class="element-text"><strong>Text:</strong> ${element.text}</p>` : ''}
731
+ ${element.contentDesc ? `<p class="element-text"><strong>Content Desc:</strong> ${element.contentDesc}</p>` : ''}
732
+ ${element.resourceId ? `<p class="element-text"><strong>Resource ID:</strong> <code>${element.resourceId}</code></p>` : ''}
733
+ <div class="locators-list">
734
+ ${Object.entries(element.locators)
735
+ .map(
736
+ ([strategy, selector]) => `
737
+ <div class="locator-item">
738
+ <span class="strategy">${strategy}</span>
739
+ <code class="selector">${selector}</code>
740
+ <button class="test-btn" onclick="testLocator('${strategy}', \`${selector.replace(/`/g, '\\`')}\`)">Test</button>
741
+ </div>
742
+ `
743
+ )
744
+ .join('')}
745
+ </div>
746
+ </div>
747
+ `
748
+ )
749
+ .join('');
750
+
751
+ return `
752
+ <!DOCTYPE html>
753
+ <html lang="en">
754
+ <head>
755
+ <meta charset="UTF-8">
756
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
757
+ <title>Locator Generator</title>
758
+ <style>
759
+ * {
760
+ margin: 0;
761
+ padding: 0;
762
+ box-sizing: border-box;
763
+ }
764
+ body {
765
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
766
+ background: #f5f5f5;
767
+ padding: 20px;
768
+ }
769
+ .container {
770
+ max-width: 1200px;
771
+ margin: 0 auto;
772
+ }
773
+ .header {
774
+ margin-bottom: 24px;
775
+ }
776
+ .header h1 {
777
+ font-size: 24px;
778
+ margin-bottom: 8px;
779
+ }
780
+ .locators-grid {
781
+ display: grid;
782
+ gap: 16px;
783
+ }
784
+ .locator-card {
785
+ background: white;
786
+ border: 1px solid #e0e0e0;
787
+ border-radius: 8px;
788
+ padding: 16px;
789
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
790
+ }
791
+ .locator-header {
792
+ display: flex;
793
+ justify-content: space-between;
794
+ align-items: center;
795
+ margin-bottom: 12px;
796
+ }
797
+ .locator-header h3 {
798
+ font-size: 16px;
799
+ font-weight: 600;
800
+ }
801
+ .badges {
802
+ display: flex;
803
+ gap: 6px;
804
+ }
805
+ .badge {
806
+ padding: 2px 8px;
807
+ border-radius: 4px;
808
+ font-size: 11px;
809
+ font-weight: 500;
810
+ }
811
+ .badge-clickable {
812
+ background: #d4edda;
813
+ color: #155724;
814
+ }
815
+ .badge-enabled {
816
+ background: #d1ecf1;
817
+ color: #0c5460;
818
+ }
819
+ .badge-displayed {
820
+ background: #fff3cd;
821
+ color: #856404;
822
+ }
823
+ .element-text {
824
+ font-size: 13px;
825
+ color: #666;
826
+ margin-bottom: 8px;
827
+ }
828
+ .element-text code {
829
+ background: #f5f5f5;
830
+ padding: 2px 6px;
831
+ border-radius: 3px;
832
+ font-size: 12px;
833
+ }
834
+ .locators-list {
835
+ margin-top: 12px;
836
+ }
837
+ .locator-item {
838
+ display: flex;
839
+ align-items: center;
840
+ gap: 12px;
841
+ padding: 8px;
842
+ background: #f8f9fa;
843
+ border-radius: 4px;
844
+ margin-bottom: 6px;
845
+ }
846
+ .strategy {
847
+ font-size: 12px;
848
+ font-weight: 600;
849
+ color: #007AFF;
850
+ min-width: 120px;
851
+ }
852
+ .selector {
853
+ flex: 1;
854
+ font-size: 12px;
855
+ font-family: 'Monaco', 'Menlo', monospace;
856
+ background: white;
857
+ padding: 4px 8px;
858
+ border-radius: 3px;
859
+ overflow-x: auto;
860
+ }
861
+ .test-btn {
862
+ padding: 4px 12px;
863
+ background: #007AFF;
864
+ color: white;
865
+ border: none;
866
+ border-radius: 4px;
867
+ font-size: 12px;
868
+ cursor: pointer;
869
+ }
870
+ .test-btn:hover {
871
+ background: #0056b3;
872
+ }
873
+ </style>
874
+ </head>
875
+ <body>
876
+ <div class="container">
877
+ <div class="header">
878
+ <h1>🔍 Generated Locators</h1>
879
+ <p>Found ${locators.length} interactable element${locators.length !== 1 ? 's' : ''}</p>
880
+ </div>
881
+ <div class="locators-grid">
882
+ ${locators.length > 0 ? locatorCards : '<p>No locators found</p>'}
883
+ </div>
884
+ </div>
885
+ <script>
886
+ function testLocator(strategy, selector) {
887
+ window.parent.postMessage({
888
+ type: 'tool',
889
+ payload: {
890
+ toolName: 'appium_find_element',
891
+ params: {
892
+ strategy: strategy,
893
+ selector: selector
894
+ }
895
+ }
896
+ }, '*');
897
+ }
898
+ </script>
899
+ </body>
900
+ </html>
901
+ `;
902
+ }
903
+
904
+ /**
905
+ * Creates a page source inspector UI component
906
+ * @param pageSource - XML page source string
907
+ * @returns HTML string for page source inspector
908
+ */
909
+ export function createPageSourceInspectorUI(pageSource: string): string {
910
+ // Escape HTML for safe display
911
+ const escapedSource = pageSource
912
+ .replace(/&/g, '&amp;')
913
+ .replace(/</g, '&lt;')
914
+ .replace(/>/g, '&gt;')
915
+ .replace(/"/g, '&quot;')
916
+ .replace(/'/g, '&#039;');
917
+
918
+ return `
919
+ <!DOCTYPE html>
920
+ <html lang="en">
921
+ <head>
922
+ <meta charset="UTF-8">
923
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
924
+ <title>Page Source Inspector</title>
925
+ <style>
926
+ * {
927
+ margin: 0;
928
+ padding: 0;
929
+ box-sizing: border-box;
930
+ }
931
+ body {
932
+ font-family: 'Monaco', 'Menlo', 'Courier New', monospace;
933
+ background: #1e1e1e;
934
+ color: #d4d4d4;
935
+ padding: 0;
936
+ overflow: hidden;
937
+ }
938
+ .toolbar {
939
+ display: flex;
940
+ justify-content: space-between;
941
+ align-items: center;
942
+ padding: 12px 16px;
943
+ background: #2d2d2d;
944
+ border-bottom: 1px solid #3e3e3e;
945
+ }
946
+ .toolbar-left {
947
+ display: flex;
948
+ gap: 8px;
949
+ align-items: center;
950
+ }
951
+ .toolbar-right {
952
+ display: flex;
953
+ gap: 8px;
954
+ }
955
+ .btn {
956
+ padding: 6px 12px;
957
+ background: #007AFF;
958
+ color: white;
959
+ border: none;
960
+ border-radius: 4px;
961
+ font-size: 13px;
962
+ cursor: pointer;
963
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
964
+ }
965
+ .btn:hover {
966
+ background: #0056b3;
967
+ }
968
+ .btn-secondary {
969
+ background: #444;
970
+ }
971
+ .btn-secondary:hover {
972
+ background: #555;
973
+ }
974
+ .info {
975
+ font-size: 12px;
976
+ color: #999;
977
+ }
978
+ .viewer {
979
+ height: calc(100vh - 50px);
980
+ overflow: auto;
981
+ padding: 16px;
982
+ }
983
+ .xml-content {
984
+ background: #1e1e1e;
985
+ color: #d4d4d4;
986
+ white-space: pre;
987
+ font-size: 13px;
988
+ line-height: 1.6;
989
+ }
990
+ .xml-tag {
991
+ color: #569cd6;
992
+ }
993
+ .xml-attr {
994
+ color: #9cdcfe;
995
+ }
996
+ .xml-value {
997
+ color: #ce9178;
998
+ }
999
+ .search-box {
1000
+ padding: 6px 12px;
1001
+ background: #3e3e3e;
1002
+ border: 1px solid #555;
1003
+ border-radius: 4px;
1004
+ color: #d4d4d4;
1005
+ font-size: 13px;
1006
+ width: 200px;
1007
+ }
1008
+ .search-box:focus {
1009
+ outline: none;
1010
+ border-color: #007AFF;
1011
+ }
1012
+ </style>
1013
+ </head>
1014
+ <body>
1015
+ <div class="toolbar">
1016
+ <div class="toolbar-left">
1017
+ <span style="font-size: 14px; font-weight: 500;">📄 Page Source Inspector</span>
1018
+ <span class="info">${pageSource.length} characters</span>
1019
+ </div>
1020
+ <div class="toolbar-right">
1021
+ <input type="text" class="search-box" id="searchBox" placeholder="Search...">
1022
+ <button class="btn btn-secondary" onclick="copyToClipboard()">Copy</button>
1023
+ <button class="btn btn-secondary" onclick="formatXML()">Format</button>
1024
+ <button class="btn" onclick="generateLocators()">Generate Locators</button>
1025
+ </div>
1026
+ </div>
1027
+ <div class="viewer">
1028
+ <pre class="xml-content" id="xmlContent">${escapedSource}</pre>
1029
+ </div>
1030
+ <script>
1031
+ function copyToClipboard() {
1032
+ const text = document.getElementById('xmlContent').textContent;
1033
+ navigator.clipboard.writeText(text).then(() => {
1034
+ alert('Copied to clipboard!');
1035
+ });
1036
+ }
1037
+
1038
+ function formatXML() {
1039
+ const content = document.getElementById('xmlContent').textContent;
1040
+ try {
1041
+ const parser = new DOMParser();
1042
+ const xmlDoc = parser.parseFromString(content, 'text/xml');
1043
+ const serializer = new XMLSerializer();
1044
+ const formatted = serializer.serializeToString(xmlDoc);
1045
+ document.getElementById('xmlContent').textContent = formatted;
1046
+ } catch (e) {
1047
+ alert('Failed to format XML');
1048
+ }
1049
+ }
1050
+
1051
+ function generateLocators() {
1052
+ window.parent.postMessage({
1053
+ type: 'tool',
1054
+ payload: {
1055
+ toolName: 'generate_locators',
1056
+ params: {}
1057
+ }
1058
+ }, '*');
1059
+ }
1060
+
1061
+ // Search functionality
1062
+ document.getElementById('searchBox').addEventListener('input', (e) => {
1063
+ const searchTerm = e.target.value.toLowerCase();
1064
+ const content = document.getElementById('xmlContent');
1065
+ if (!searchTerm) {
1066
+ content.innerHTML = \`${escapedSource}\`;
1067
+ return;
1068
+ }
1069
+ const highlighted = content.textContent.replace(
1070
+ new RegExp(\`(\${searchTerm})\`, 'gi'),
1071
+ '<mark style="background: #ffd700; color: #000;">$1</mark>'
1072
+ );
1073
+ content.innerHTML = highlighted;
1074
+ });
1075
+ </script>
1076
+ </body>
1077
+ </html>
1078
+ `;
1079
+ }
1080
+
1081
+ /**
1082
+ * Creates a context switcher UI component
1083
+ * @param contexts - Array of context names
1084
+ * @param currentContext - Currently active context name
1085
+ * @returns HTML string for context switcher
1086
+ */
1087
+ export function createContextSwitcherUI(
1088
+ contexts: string[],
1089
+ currentContext: string | null
1090
+ ): string {
1091
+ const contextCards = contexts
1092
+ .map(
1093
+ (context) => `
1094
+ <div class="context-card ${context === currentContext ? 'active' : ''}"
1095
+ onclick="switchContext('${context}')">
1096
+ <div class="context-header">
1097
+ <h3>${context}</h3>
1098
+ ${context === currentContext ? '<span class="badge-active">Active</span>' : ''}
1099
+ </div>
1100
+ <div class="context-type">
1101
+ ${context === 'NATIVE_APP' ? '📱 Native App' : '🌐 WebView'}
1102
+ </div>
1103
+ <button class="switch-btn" onclick="event.stopPropagation(); switchContext('${context}')">
1104
+ ${context === currentContext ? 'Current' : 'Switch'}
1105
+ </button>
1106
+ </div>
1107
+ `
1108
+ )
1109
+ .join('');
1110
+
1111
+ return `
1112
+ <!DOCTYPE html>
1113
+ <html lang="en">
1114
+ <head>
1115
+ <meta charset="UTF-8">
1116
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
1117
+ <title>Context Switcher</title>
1118
+ <style>
1119
+ * {
1120
+ margin: 0;
1121
+ padding: 0;
1122
+ box-sizing: border-box;
1123
+ }
1124
+ body {
1125
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
1126
+ background: #f5f5f5;
1127
+ padding: 20px;
1128
+ }
1129
+ .container {
1130
+ max-width: 800px;
1131
+ margin: 0 auto;
1132
+ }
1133
+ .header {
1134
+ margin-bottom: 24px;
1135
+ }
1136
+ .header h1 {
1137
+ font-size: 24px;
1138
+ margin-bottom: 8px;
1139
+ }
1140
+ .header p {
1141
+ color: #666;
1142
+ font-size: 14px;
1143
+ }
1144
+ .contexts-grid {
1145
+ display: grid;
1146
+ grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
1147
+ gap: 16px;
1148
+ }
1149
+ .context-card {
1150
+ background: white;
1151
+ border: 2px solid #e0e0e0;
1152
+ border-radius: 8px;
1153
+ padding: 16px;
1154
+ cursor: pointer;
1155
+ transition: all 0.2s;
1156
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
1157
+ }
1158
+ .context-card:hover {
1159
+ border-color: #007AFF;
1160
+ box-shadow: 0 4px 12px rgba(0,122,255,0.15);
1161
+ transform: translateY(-2px);
1162
+ }
1163
+ .context-card.active {
1164
+ border-color: #007AFF;
1165
+ background: #f0f7ff;
1166
+ }
1167
+ .context-header {
1168
+ display: flex;
1169
+ justify-content: space-between;
1170
+ align-items: center;
1171
+ margin-bottom: 12px;
1172
+ }
1173
+ .context-header h3 {
1174
+ font-size: 16px;
1175
+ font-weight: 600;
1176
+ color: #1a1a1a;
1177
+ font-family: 'Monaco', 'Menlo', monospace;
1178
+ }
1179
+ .badge-active {
1180
+ padding: 4px 8px;
1181
+ background: #d4edda;
1182
+ color: #155724;
1183
+ border-radius: 4px;
1184
+ font-size: 11px;
1185
+ font-weight: 500;
1186
+ }
1187
+ .context-type {
1188
+ font-size: 13px;
1189
+ color: #666;
1190
+ margin-bottom: 12px;
1191
+ }
1192
+ .switch-btn {
1193
+ width: 100%;
1194
+ padding: 8px 16px;
1195
+ background: #007AFF;
1196
+ color: white;
1197
+ border: none;
1198
+ border-radius: 6px;
1199
+ font-size: 14px;
1200
+ font-weight: 500;
1201
+ cursor: pointer;
1202
+ transition: background 0.2s;
1203
+ }
1204
+ .switch-btn:hover {
1205
+ background: #0056b3;
1206
+ }
1207
+ .context-card.active .switch-btn {
1208
+ background: #6c757d;
1209
+ cursor: default;
1210
+ }
1211
+ </style>
1212
+ </head>
1213
+ <body>
1214
+ <div class="container">
1215
+ <div class="header">
1216
+ <h1>🌐 Context Switcher</h1>
1217
+ <p>Found ${contexts.length} context${contexts.length !== 1 ? 's' : ''}. Click to switch.</p>
1218
+ </div>
1219
+ <div class="contexts-grid">
1220
+ ${contexts.length > 0 ? contextCards : '<p>No contexts available</p>'}
1221
+ </div>
1222
+ </div>
1223
+ <script>
1224
+ function switchContext(contextName) {
1225
+ window.parent.postMessage({
1226
+ type: 'tool',
1227
+ payload: {
1228
+ toolName: 'appium_switch_context',
1229
+ params: {
1230
+ context: contextName
1231
+ }
1232
+ }
1233
+ }, '*');
1234
+ }
1235
+ </script>
1236
+ </body>
1237
+ </html>
1238
+ `;
1239
+ }
1240
+
1241
+ /**
1242
+ * Creates an app list UI component
1243
+ * @param apps - Array of app objects with packageName and appName
1244
+ * @returns HTML string for app list
1245
+ */
1246
+ export function createAppListUI(
1247
+ apps: Array<{ packageName: string; appName?: string }>
1248
+ ): string {
1249
+ const appCards = apps
1250
+ .map(
1251
+ (app) => `
1252
+ <div class="app-card" data-package="${app.packageName}">
1253
+ <div class="app-header">
1254
+ <h3>${app.appName || app.packageName}</h3>
1255
+ </div>
1256
+ <div class="app-details">
1257
+ <p><strong>Package:</strong> <code>${app.packageName}</code></p>
1258
+ </div>
1259
+ <div class="app-actions">
1260
+ <button class="btn btn-primary" onclick="activateApp('${app.packageName}')">Activate</button>
1261
+ <button class="btn btn-secondary" onclick="terminateApp('${app.packageName}')">Terminate</button>
1262
+ <button class="btn btn-danger" onclick="uninstallApp('${app.packageName}')">Uninstall</button>
1263
+ </div>
1264
+ </div>
1265
+ `
1266
+ )
1267
+ .join('');
1268
+
1269
+ return `
1270
+ <!DOCTYPE html>
1271
+ <html lang="en">
1272
+ <head>
1273
+ <meta charset="UTF-8">
1274
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
1275
+ <title>Installed Apps</title>
1276
+ <style>
1277
+ * {
1278
+ margin: 0;
1279
+ padding: 0;
1280
+ box-sizing: border-box;
1281
+ }
1282
+ body {
1283
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
1284
+ background: #f5f5f5;
1285
+ padding: 20px;
1286
+ }
1287
+ .container {
1288
+ max-width: 1200px;
1289
+ margin: 0 auto;
1290
+ }
1291
+ .header {
1292
+ margin-bottom: 24px;
1293
+ display: flex;
1294
+ justify-content: space-between;
1295
+ align-items: center;
1296
+ }
1297
+ .header h1 {
1298
+ font-size: 24px;
1299
+ }
1300
+ .header p {
1301
+ color: #666;
1302
+ font-size: 14px;
1303
+ }
1304
+ .search-box {
1305
+ padding: 8px 12px;
1306
+ border: 1px solid #ddd;
1307
+ border-radius: 6px;
1308
+ font-size: 14px;
1309
+ width: 300px;
1310
+ }
1311
+ .apps-grid {
1312
+ display: grid;
1313
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
1314
+ gap: 16px;
1315
+ }
1316
+ .app-card {
1317
+ background: white;
1318
+ border: 1px solid #e0e0e0;
1319
+ border-radius: 8px;
1320
+ padding: 16px;
1321
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
1322
+ transition: all 0.2s;
1323
+ }
1324
+ .app-card:hover {
1325
+ border-color: #007AFF;
1326
+ box-shadow: 0 4px 12px rgba(0,122,255,0.15);
1327
+ }
1328
+ .app-header h3 {
1329
+ font-size: 16px;
1330
+ font-weight: 600;
1331
+ margin-bottom: 12px;
1332
+ color: #1a1a1a;
1333
+ }
1334
+ .app-details {
1335
+ margin-bottom: 12px;
1336
+ font-size: 13px;
1337
+ }
1338
+ .app-details code {
1339
+ background: #f5f5f5;
1340
+ padding: 2px 6px;
1341
+ border-radius: 3px;
1342
+ font-size: 12px;
1343
+ font-family: 'Monaco', 'Menlo', monospace;
1344
+ }
1345
+ .app-actions {
1346
+ display: flex;
1347
+ gap: 8px;
1348
+ flex-wrap: wrap;
1349
+ }
1350
+ .btn {
1351
+ padding: 6px 12px;
1352
+ border: none;
1353
+ border-radius: 4px;
1354
+ font-size: 12px;
1355
+ font-weight: 500;
1356
+ cursor: pointer;
1357
+ transition: background 0.2s;
1358
+ }
1359
+ .btn-primary {
1360
+ background: #007AFF;
1361
+ color: white;
1362
+ }
1363
+ .btn-primary:hover {
1364
+ background: #0056b3;
1365
+ }
1366
+ .btn-secondary {
1367
+ background: #6c757d;
1368
+ color: white;
1369
+ }
1370
+ .btn-secondary:hover {
1371
+ background: #5a6268;
1372
+ }
1373
+ .btn-danger {
1374
+ background: #dc3545;
1375
+ color: white;
1376
+ }
1377
+ .btn-danger:hover {
1378
+ background: #c82333;
1379
+ }
1380
+ .hidden {
1381
+ display: none;
1382
+ }
1383
+ </style>
1384
+ </head>
1385
+ <body>
1386
+ <div class="container">
1387
+ <div class="header">
1388
+ <div>
1389
+ <h1>📱 Installed Apps</h1>
1390
+ <p>Found ${apps.length} app${apps.length !== 1 ? 's' : ''}</p>
1391
+ </div>
1392
+ <input type="text" class="search-box" id="searchBox" placeholder="Search apps...">
1393
+ </div>
1394
+ <div class="apps-grid" id="appsGrid">
1395
+ ${apps.length > 0 ? appCards : '<p>No apps found</p>'}
1396
+ </div>
1397
+ </div>
1398
+ <script>
1399
+ function activateApp(packageName) {
1400
+ window.parent.postMessage({
1401
+ type: 'tool',
1402
+ payload: {
1403
+ toolName: 'appium_activate_app',
1404
+ params: {
1405
+ id: packageName
1406
+ }
1407
+ }
1408
+ }, '*');
1409
+ }
1410
+
1411
+ function terminateApp(packageName) {
1412
+ if (confirm('Are you sure you want to terminate this app?')) {
1413
+ window.parent.postMessage({
1414
+ type: 'tool',
1415
+ payload: {
1416
+ toolName: 'appium_terminate_app',
1417
+ params: {
1418
+ id: packageName
1419
+ }
1420
+ }
1421
+ }, '*');
1422
+ }
1423
+ }
1424
+
1425
+ function uninstallApp(packageName) {
1426
+ if (confirm('Are you sure you want to uninstall this app? This action cannot be undone.')) {
1427
+ window.parent.postMessage({
1428
+ type: 'tool',
1429
+ payload: {
1430
+ toolName: 'appium_uninstall_app',
1431
+ params: {
1432
+ id: packageName
1433
+ }
1434
+ }
1435
+ }, '*');
1436
+ }
1437
+ }
1438
+
1439
+ // Search functionality
1440
+ document.getElementById('searchBox').addEventListener('input', (e) => {
1441
+ const searchTerm = e.target.value.toLowerCase();
1442
+ const cards = document.querySelectorAll('.app-card');
1443
+ cards.forEach(card => {
1444
+ const text = card.textContent.toLowerCase();
1445
+ if (text.includes(searchTerm)) {
1446
+ card.classList.remove('hidden');
1447
+ } else {
1448
+ card.classList.add('hidden');
1449
+ }
1450
+ });
1451
+ });
1452
+ </script>
1453
+ </body>
1454
+ </html>
1455
+ `;
1456
+ }
1457
+
1458
+ /**
1459
+ * Creates a test code viewer UI component
1460
+ * @param code - Generated test code string
1461
+ * @param language - Code language (java, javascript, etc.)
1462
+ * @returns HTML string for test code viewer
1463
+ */
1464
+ export function createTestCodeViewerUI(
1465
+ code: string,
1466
+ language: string = 'java'
1467
+ ): string {
1468
+ // Escape HTML for safe display
1469
+ const escapedCode = code
1470
+ .replace(/&/g, '&amp;')
1471
+ .replace(/</g, '&lt;')
1472
+ .replace(/>/g, '&gt;')
1473
+ .replace(/"/g, '&quot;')
1474
+ .replace(/'/g, '&#039;');
1475
+
1476
+ return `
1477
+ <!DOCTYPE html>
1478
+ <html lang="en">
1479
+ <head>
1480
+ <meta charset="UTF-8">
1481
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
1482
+ <title>Test Code Viewer</title>
1483
+ <style>
1484
+ * {
1485
+ margin: 0;
1486
+ padding: 0;
1487
+ box-sizing: border-box;
1488
+ }
1489
+ body {
1490
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
1491
+ background: #1e1e1e;
1492
+ color: #d4d4d4;
1493
+ overflow: hidden;
1494
+ }
1495
+ .toolbar {
1496
+ display: flex;
1497
+ justify-content: space-between;
1498
+ align-items: center;
1499
+ padding: 12px 16px;
1500
+ background: #2d2d2d;
1501
+ border-bottom: 1px solid #3e3e3e;
1502
+ }
1503
+ .toolbar-left {
1504
+ display: flex;
1505
+ gap: 12px;
1506
+ align-items: center;
1507
+ }
1508
+ .toolbar-right {
1509
+ display: flex;
1510
+ gap: 8px;
1511
+ }
1512
+ .btn {
1513
+ padding: 6px 12px;
1514
+ background: #007AFF;
1515
+ color: white;
1516
+ border: none;
1517
+ border-radius: 4px;
1518
+ font-size: 13px;
1519
+ cursor: pointer;
1520
+ transition: background 0.2s;
1521
+ }
1522
+ .btn:hover {
1523
+ background: #0056b3;
1524
+ }
1525
+ .btn-secondary {
1526
+ background: #444;
1527
+ }
1528
+ .btn-secondary:hover {
1529
+ background: #555;
1530
+ }
1531
+ .language-badge {
1532
+ padding: 4px 8px;
1533
+ background: #007AFF;
1534
+ color: white;
1535
+ border-radius: 4px;
1536
+ font-size: 11px;
1537
+ font-weight: 500;
1538
+ text-transform: uppercase;
1539
+ }
1540
+ .viewer {
1541
+ height: calc(100vh - 50px);
1542
+ overflow: auto;
1543
+ padding: 16px;
1544
+ }
1545
+ .code-content {
1546
+ background: #1e1e1e;
1547
+ color: #d4d4d4;
1548
+ white-space: pre;
1549
+ font-family: 'Monaco', 'Menlo', 'Courier New', monospace;
1550
+ font-size: 13px;
1551
+ line-height: 1.6;
1552
+ margin: 0;
1553
+ }
1554
+ .line-numbers {
1555
+ display: inline-block;
1556
+ padding-right: 16px;
1557
+ color: #858585;
1558
+ user-select: none;
1559
+ text-align: right;
1560
+ min-width: 50px;
1561
+ }
1562
+ </style>
1563
+ </head>
1564
+ <body>
1565
+ <div class="toolbar">
1566
+ <div class="toolbar-left">
1567
+ <span style="font-size: 14px; font-weight: 500;">💻 Test Code Viewer</span>
1568
+ <span class="language-badge">${language}</span>
1569
+ <span style="font-size: 12px; color: #999;">${code.length} characters, ${code.split('\\n').length} lines</span>
1570
+ </div>
1571
+ <div class="toolbar-right">
1572
+ <button class="btn btn-secondary" onclick="copyToClipboard()">Copy Code</button>
1573
+ <button class="btn btn-secondary" onclick="downloadCode()">Download</button>
1574
+ <button class="btn" onclick="formatCode()">Format</button>
1575
+ </div>
1576
+ </div>
1577
+ <div class="viewer">
1578
+ <pre class="code-content" id="codeContent">${escapedCode}</pre>
1579
+ </div>
1580
+ <script>
1581
+ function copyToClipboard() {
1582
+ const text = document.getElementById('codeContent').textContent;
1583
+ navigator.clipboard.writeText(text).then(() => {
1584
+ alert('Code copied to clipboard!');
1585
+ });
1586
+ }
1587
+
1588
+ function downloadCode() {
1589
+ const text = document.getElementById('codeContent').textContent;
1590
+ const blob = new Blob([text], { type: 'text/plain' });
1591
+ const url = URL.createObjectURL(blob);
1592
+ const a = document.createElement('a');
1593
+ a.href = url;
1594
+ a.download = 'TestCode.${language === 'java' ? 'java' : 'js'}';
1595
+ a.click();
1596
+ URL.revokeObjectURL(url);
1597
+ }
1598
+
1599
+ function formatCode() {
1600
+ // Basic formatting - could be enhanced with a proper formatter
1601
+ const content = document.getElementById('codeContent');
1602
+ const text = content.textContent;
1603
+ // Add line numbers
1604
+ const lines = text.split('\\n');
1605
+ const formatted = lines.map((line, i) =>
1606
+ \`<span class="line-numbers">\${i + 1}</span>\${line}\`
1607
+ ).join('\\n');
1608
+ content.innerHTML = formatted;
1609
+ }
1610
+
1611
+ // Initial format
1612
+ formatCode();
1613
+ </script>
1614
+ </body>
1615
+ </html>
1616
+ `;
1617
+ }
1618
+
1619
+ /**
1620
+ * Helper function to add UI resource to response content
1621
+ * Returns both text and UI resource for backward compatibility
1622
+ */
1623
+ export function addUIResourceToResponse(
1624
+ response: { content: Array<{ type: string; text?: string }> },
1625
+ uiResource: ReturnType<typeof createUIResource>
1626
+ ): { content: Array<any> } {
1627
+ return {
1628
+ content: [...response.content, uiResource],
1629
+ };
1630
+ }