appium-mcp 1.8.15 → 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.
- package/CHANGELOG.md +6 -0
- package/package.json +2 -1
- package/server.json +2 -2
- package/src/command.ts +249 -0
- package/src/devicemanager/adb-manager.ts +164 -0
- package/src/devicemanager/ios-manager.ts +145 -0
- package/src/index.ts +45 -0
- package/src/locators/element-filter.ts +136 -0
- package/src/locators/generate-all-locators.ts +150 -0
- package/src/locators/locator-generation.ts +657 -0
- package/src/locators/source-parsing.ts +149 -0
- package/src/logger.ts +11 -0
- package/src/resources/caps.json +697 -0
- package/src/resources/index.ts +8 -0
- package/src/resources/java/template.ts +83 -0
- package/src/resources/submodules/appium/.github/PULL_REQUEST_TEMPLATE.md +28 -0
- package/src/resources/submodules/appium/CHANGELOG.md +45 -0
- package/src/resources/submodules/appium/CONDUCT.md +48 -0
- package/src/resources/submodules/appium/GOVERNANCE.md +185 -0
- package/src/resources/submodules/appium/IDEAS.md +16 -0
- package/src/resources/submodules/appium/README.md +221 -0
- package/src/resources/submodules/appium/ROADMAP.md +30 -0
- package/src/resources/submodules/appium/SPONSORS.md +3 -0
- package/src/resources/submodules/appium/docs/README.md +6 -0
- package/src/resources/submodules/appium/docs/payout.md +35 -0
- package/src/resources/submodules/appium/packages/appium/CHANGELOG.md +1437 -0
- package/src/resources/submodules/appium/packages/appium/README.md +221 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/blog/index.md +2 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/announcing-appiumconf2024.md +45 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/announcing-browserstack-as-strategic-partner.md +46 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/announcing-headspin-as-development-partner.md +47 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/announcing-lambdatest-as-strategic-partner.md +42 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/announcing-sauce-labs-as-strategic-partner.md +36 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/announcing-sponsorship-program.md +48 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/appium3.md +40 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/blog/posts/hello-world.md +15 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/contributing/index.md +150 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/developing/build-docs.md +86 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/developing/build-doctor-checks.md +141 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/developing/build-drivers.md +860 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/developing/build-plugins.md +514 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/developing/config-system.md +451 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/developing/index.md +18 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/developing/sensitive.md +49 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/ecosystem/clients.md +132 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/ecosystem/drivers.md +207 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/ecosystem/index.md +45 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/ecosystem/plugins.md +138 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/ecosystem/tools.md +83 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/guides/branch-testing.md +57 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/guides/caching.md +76 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/guides/caps.md +275 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/guides/config.md +98 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/guides/context.md +44 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/guides/event-timing.md +73 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/guides/execute-methods.md +122 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/guides/grid.md +166 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/guides/headers.md +17 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/guides/log-filters.md +86 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/guides/managing-exts.md +87 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/guides/migrating-1-to-2.md +368 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/guides/migrating-2-to-3.md +464 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/guides/security.md +89 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/guides/settings.md +68 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/guides/tls.md +42 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/index.md +59 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/intro/appium.md +202 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/intro/clients.md +127 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/intro/drivers.md +188 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/intro/history.md +196 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/intro/index.md +39 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/index.md +29 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/install.md +50 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/next-steps.md +23 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/requirements.md +29 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/test-dotnet.md +105 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/test-java.md +23 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/test-js.md +75 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/test-py.md +60 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/test-rb.md +83 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/quickstart/uiauto2-driver.md +144 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/appium.md +394 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/bidi.md +70 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/index.md +30 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/jsonwp.md +214 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/mjsonwp.md +151 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/others.md +671 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/plugins.md +289 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/reference/api/webdriver.md +1114 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/reference/cli/env-vars.md +31 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/reference/cli/extensions.md +239 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/reference/cli/index.md +35 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/reference/cli/server.md +76 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/reference/cli/setup.md +76 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/reference/index.md +25 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/resources/index.md +28 -0
- package/src/resources/submodules/appium/packages/appium/docs/en/sponsors/index.md +64 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/blog/index.md +2 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/announcing-appiumconf2024.md +45 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/announcing-browserstack-as-strategic-partner.md +46 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/announcing-headspin-as-development-partner.md +47 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/announcing-lambdatest-as-strategic-partner.md +41 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/announcing-sauce-labs-as-strategic-partner.md +36 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/announcing-sponsorship-program.md +48 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/appium3.md +40 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/blog/posts/hello-world.md +15 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/contributing/index.md +158 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/developing/build-docs.md +86 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/developing/build-doctor-checks.md +141 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/developing/build-drivers.md +866 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/developing/build-plugins.md +520 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/developing/config-system.md +468 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/developing/index.md +18 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/developing/sensitive.md +49 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/ecosystem/clients.md +143 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/ecosystem/drivers.md +219 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/ecosystem/index.md +45 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/ecosystem/plugins.md +140 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/ecosystem/tools.md +87 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/guides/branch-testing.md +57 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/guides/caching.md +78 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/guides/caps.md +259 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/guides/config.md +102 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/guides/context.md +44 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/guides/event-timing.md +75 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/guides/execute-methods.md +142 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/guides/grid.md +166 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/guides/headers.md +17 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/guides/log-filters.md +86 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/guides/managing-exts.md +89 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/guides/migrating-1-to-2.md +402 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/guides/migrating-2-to-3.md +458 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/guides/security.md +89 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/guides/settings.md +70 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/guides/tls.md +43 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/index.md +55 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/intro/appium.md +191 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/intro/clients.md +139 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/intro/drivers.md +188 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/intro/history.md +196 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/intro/index.md +39 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/index.md +23 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/install.md +47 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/next-steps.md +19 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/requirements.md +29 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/test-dotnet.md +107 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/test-java.md +23 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/test-js.md +77 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/test-py.md +63 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/test-rb.md +85 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/quickstart/uiauto2-driver.md +148 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/appium.md +395 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/bidi.md +71 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/index.md +30 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/jsonwp.md +215 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/mjsonwp.md +152 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/others.md +672 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/plugins.md +291 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/reference/api/webdriver.md +1114 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/reference/cli/env-vars.md +31 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/reference/cli/extensions.md +240 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/reference/cli/index.md +35 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/reference/cli/server.md +76 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/reference/cli/setup.md +78 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/reference/index.md +25 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/resources/index.md +28 -0
- package/src/resources/submodules/appium/packages/appium/docs/ja/sponsors/index.md +61 -0
- package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/appium-logo-horiz-white.png +0 -0
- package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/appium-logo-horiz.png +0 -0
- package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/appium-logo-white.png +0 -0
- package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/appium-logo.png +0 -0
- package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/sponsor-logo-browserstack-dark.png +0 -0
- package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/sponsor-logo-browserstack-light.png +0 -0
- package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/sponsor-logo-lambdatest-dark.png +0 -0
- package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/sponsor-logo-lambdatest-light.png +0 -0
- package/src/resources/submodules/appium/packages/appium/docs/overrides/assets/images/sponsor-logo-sauce.png +0 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/blog/index.md +2 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/announcing-appiumconf2024.md +45 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/announcing-browserstack-as-strategic-partner.md +46 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/announcing-headspin-as-development-partner.md +47 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/announcing-lambdatest-as-strategic-partner.md +41 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/announcing-sauce-labs-as-strategic-partner.md +36 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/announcing-sponsorship-program.md +48 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/appium3.md +40 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/blog/posts/hello-world.md +15 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/contributing/index.md +132 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/developing/build-docs.md +86 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/developing/build-doctor-checks.md +141 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/developing/build-drivers.md +866 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/developing/build-plugins.md +520 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/developing/config-system.md +468 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/developing/index.md +18 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/developing/sensitive.md +49 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/ecosystem/clients.md +143 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/ecosystem/drivers.md +219 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/ecosystem/index.md +45 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/ecosystem/plugins.md +140 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/ecosystem/tools.md +87 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/guides/branch-testing.md +57 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/guides/caching.md +78 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/guides/caps.md +284 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/guides/config.md +102 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/guides/context.md +44 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/guides/event-timing.md +75 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/guides/execute-methods.md +142 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/guides/grid.md +166 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/guides/headers.md +17 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/guides/log-filters.md +86 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/guides/managing-exts.md +89 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/guides/migrating-1-to-2.md +410 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/guides/migrating-2-to-3.md +459 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/guides/security.md +89 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/guides/settings.md +70 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/guides/tls.md +43 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/index.md +54 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/intro/appium.md +200 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/intro/clients.md +139 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/intro/drivers.md +188 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/intro/history.md +196 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/intro/index.md +39 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/index.md +23 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/install.md +47 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/next-steps.md +19 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/requirements.md +21 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/test-dotnet.md +99 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/test-java.md +20 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/test-js.md +62 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/test-py.md +57 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/test-rb.md +80 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/quickstart/uiauto2-driver.md +148 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/appium.md +395 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/bidi.md +71 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/index.md +30 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/jsonwp.md +215 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/mjsonwp.md +152 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/others.md +672 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/plugins.md +291 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/reference/api/webdriver.md +1114 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/reference/cli/env-vars.md +31 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/reference/cli/extensions.md +240 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/reference/cli/index.md +35 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/reference/cli/server.md +76 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/reference/cli/setup.md +78 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/reference/index.md +25 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/resources/index.md +28 -0
- package/src/resources/submodules/appium/packages/appium/docs/zh/sponsors/index.md +61 -0
- package/src/resources/submodules/appium/packages/appium/types/manifest/README.md +30 -0
- package/src/resources/submodules/appium/packages/base-driver/CHANGELOG.md +1131 -0
- package/src/resources/submodules/appium/packages/base-driver/README.md +15 -0
- package/src/resources/submodules/appium/packages/base-driver/docs/mjsonwp/errors.md +82 -0
- package/src/resources/submodules/appium/packages/base-driver/docs/mjsonwp/protocol-methods.md +182 -0
- package/src/resources/submodules/appium/packages/base-driver/static/appium.png +0 -0
- package/src/resources/submodules/appium/packages/base-plugin/CHANGELOG.md +672 -0
- package/src/resources/submodules/appium/packages/base-plugin/README.md +15 -0
- package/src/resources/submodules/appium/packages/docutils/CHANGELOG.md +948 -0
- package/src/resources/submodules/appium/packages/docutils/README.md +27 -0
- package/src/resources/submodules/appium/packages/driver-test-support/CHANGELOG.md +717 -0
- package/src/resources/submodules/appium/packages/driver-test-support/README.md +112 -0
- package/src/resources/submodules/appium/packages/eslint-config-appium-ts/CHANGELOG.md +168 -0
- package/src/resources/submodules/appium/packages/eslint-config-appium-ts/README.md +33 -0
- package/src/resources/submodules/appium/packages/execute-driver-plugin/CHANGELOG.md +603 -0
- package/src/resources/submodules/appium/packages/execute-driver-plugin/README.md +42 -0
- package/src/resources/submodules/appium/packages/fake-driver/CHANGELOG.md +545 -0
- package/src/resources/submodules/appium/packages/fake-driver/README.md +7 -0
- package/src/resources/submodules/appium/packages/fake-driver/lib/screen.png +0 -0
- package/src/resources/submodules/appium/packages/fake-plugin/CHANGELOG.md +683 -0
- package/src/resources/submodules/appium/packages/fake-plugin/README.md +7 -0
- package/src/resources/submodules/appium/packages/images-plugin/CHANGELOG.md +602 -0
- package/src/resources/submodules/appium/packages/images-plugin/README.md +27 -0
- package/src/resources/submodules/appium/packages/images-plugin/docs/find-by-image.md +65 -0
- package/src/resources/submodules/appium/packages/images-plugin/docs/image-comparison.md +203 -0
- package/src/resources/submodules/appium/packages/images-plugin/test/fixtures/appstore.png +0 -0
- package/src/resources/submodules/appium/packages/images-plugin/test/fixtures/img1.png +0 -0
- package/src/resources/submodules/appium/packages/images-plugin/test/fixtures/img2.png +0 -0
- package/src/resources/submodules/appium/packages/images-plugin/test/fixtures/img2_part.png +0 -0
- package/src/resources/submodules/appium/packages/logger/CHANGELOG.md +162 -0
- package/src/resources/submodules/appium/packages/logger/README.md +31 -0
- package/src/resources/submodules/appium/packages/opencv/CHANGELOG.md +384 -0
- package/src/resources/submodules/appium/packages/opencv/README.md +68 -0
- package/src/resources/submodules/appium/packages/opencv/test/e2e/images/appium-diagram.jpg +0 -0
- package/src/resources/submodules/appium/packages/opencv/test/e2e/images/cc1.png +0 -0
- package/src/resources/submodules/appium/packages/opencv/test/e2e/images/cc2.png +0 -0
- package/src/resources/submodules/appium/packages/opencv/test/e2e/images/cc_rotated.png +0 -0
- package/src/resources/submodules/appium/packages/opencv/test/e2e/images/findwaldo.jpg +0 -0
- package/src/resources/submodules/appium/packages/opencv/test/e2e/images/number5.png +0 -0
- package/src/resources/submodules/appium/packages/opencv/test/e2e/images/waldo.jpg +0 -0
- package/src/resources/submodules/appium/packages/plugin-test-support/CHANGELOG.md +539 -0
- package/src/resources/submodules/appium/packages/plugin-test-support/README.md +49 -0
- package/src/resources/submodules/appium/packages/relaxed-caps-plugin/CHANGELOG.md +154 -0
- package/src/resources/submodules/appium/packages/relaxed-caps-plugin/README.md +35 -0
- package/src/resources/submodules/appium/packages/schema/CHANGELOG.md +271 -0
- package/src/resources/submodules/appium/packages/schema/README.md +50 -0
- package/src/resources/submodules/appium/packages/storage-plugin/CHANGELOG.md +73 -0
- package/src/resources/submodules/appium/packages/storage-plugin/README.md +83 -0
- package/src/resources/submodules/appium/packages/strongbox/CHANGELOG.md +94 -0
- package/src/resources/submodules/appium/packages/strongbox/README.md +96 -0
- package/src/resources/submodules/appium/packages/support/CHANGELOG.md +1054 -0
- package/src/resources/submodules/appium/packages/support/README.md +161 -0
- package/src/resources/submodules/appium/packages/test-support/CHANGELOG.md +712 -0
- package/src/resources/submodules/appium/packages/test-support/README.md +61 -0
- package/src/resources/submodules/appium/packages/tsconfig/CHANGELOG.md +131 -0
- package/src/resources/submodules/appium/packages/tsconfig/README.md +19 -0
- package/src/resources/submodules/appium/packages/types/CHANGELOG.md +793 -0
- package/src/resources/submodules/appium/packages/types/README.md +21 -0
- package/src/resources/submodules/appium/packages/universal-xml-plugin/CHANGELOG.md +435 -0
- package/src/resources/submodules/appium/packages/universal-xml-plugin/README.md +53 -0
- package/src/resources/submodules/appium/renovate/README.md +63 -0
- package/src/resources/submodules/appium-uiautomator2-driver/CHANGELOG.md +1204 -0
- package/src/resources/submodules/appium-uiautomator2-driver/README.md +2077 -0
- package/src/resources/submodules/appium-uiautomator2-driver/docs/actions.md +72 -0
- package/src/resources/submodules/appium-uiautomator2-driver/docs/activity-startup.md +47 -0
- package/src/resources/submodules/appium-uiautomator2-driver/docs/android-appbundle.md +69 -0
- package/src/resources/submodules/appium-uiautomator2-driver/docs/android-mobile-gestures.md +352 -0
- package/src/resources/submodules/appium-uiautomator2-driver/docs/bidi.md +50 -0
- package/src/resources/submodules/appium-uiautomator2-driver/docs/capability-sets.md +136 -0
- package/src/resources/submodules/appium-uiautomator2-driver/docs/scheduled-actions.md +155 -0
- package/src/resources/submodules/appium-uiautomator2-driver/docs/uiautomator-uiselector.md +51 -0
- package/src/resources/submodules/appium-uiautomator2-driver/docs/unlock/main.md +95 -0
- package/src/resources/submodules/appium-uiautomator2-driver/docs/unlock/screen1.png +0 -0
- package/src/resources/submodules/appium-uiautomator2-driver/docs/unlock/screen2.png +0 -0
- package/src/resources/submodules/appium-uiautomator2-driver/test/functional/assets/checkered-squares.png +0 -0
- package/src/resources/submodules/appium-uiautomator2-driver/test/functional/assets/start-button.png +0 -0
- package/src/resources/submodules/appium-uiautomator2-driver/test/functional/assets/stop-button.png +0 -0
- package/src/resources/submodules/appium-xcuitest-driver/.github/ISSUE_TEMPLATE.md +4 -0
- package/src/resources/submodules/appium-xcuitest-driver/CHANGELOG.md +2594 -0
- package/src/resources/submodules/appium-xcuitest-driver/README.md +55 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/assets/images/appium-logo-white.png +0 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/assets/images/appium-logo.png +0 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/assets/images/appium-plus-xctest.png +0 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/contributing.md +45 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/endpoints-wda.md +61 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/endpoints.md +98 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/assets/images/ios-xctest-file-movement/keynote.png +0 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/assets/images/ios-xctest-file-movement/on_my_iphone.png +0 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/assets/images/ios-xctest-file-movement/top_files.png +0 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/attach-to-running-wda.md +43 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/audio-capture.md +78 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/capability-sets.md +169 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/ci-setup.md +47 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/clipboard.md +47 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/elements-lookup-troubleshooting.md +158 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/file-transfer.md +147 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/gestures.md +52 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/hybrid.md +137 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/input-events.md +67 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/install-certificate.md +19 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/multiple-xcode-versions.md +37 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/parallel-tests.md +39 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/run-prebuilt-wda.md +135 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/run-preinstalled-wda.md +178 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/touch-id.md +33 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/troubleshooting.md +191 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/tvos.md +114 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/wda-custom-server.md +283 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/guides/wda-slowness.md +231 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/index.md +36 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/installation/index.md +137 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/overview.md +19 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/check-prov-prof.png +0 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/create-new-project.png +0 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/create-single-page.png +0 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/no-prov-prof.png +0 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/project-prov-prof.png +0 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/set-up-bundle.png +0 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/untrusted-dev.png +0 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/xcode-bundle-id.png +0 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/xcode-config.png +0 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/xcode-facebook-fail.png +0 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/assets/images/xcode-facebook-succeed.png +0 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/index.md +51 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/prov-profile-basic-auto.md +49 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/prov-profile-basic-manual.md +40 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/prov-profile-full-manual.md +50 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/prov-profile-generic-manual.md +49 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/preparation/real-device-config.md +100 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/reference/assets/images/useXctestrunFile.png +0 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/reference/bidi.md +75 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/reference/capabilities.md +165 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/reference/commands.md +490 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/reference/element-attributes.md +27 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/reference/execute-methods.md +2206 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/reference/ios-predicate.md +196 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/reference/locator-strategies.md +19 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/reference/scripts.md +29 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/reference/security-flags.md +22 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/reference/server-args.md +16 -0
- package/src/resources/submodules/appium-xcuitest-driver/docs/reference/settings.md +49 -0
- package/src/resources/submodules/appium-xcuitest-driver/test/assets/TestApp-iphonesimulator.app/Default-568h@2x.png +0 -0
- package/src/resources/submodules/appium-xcuitest-driver/test/assets/test.png +0 -0
- package/src/schema.ts +5 -0
- package/src/scripts/simple-index-documentation.ts +93 -0
- package/src/scripts/simple-query-documentation.ts +61 -0
- package/src/server.ts +40 -0
- package/src/session-store.ts +151 -0
- package/src/tests/README.md +83 -0
- package/src/tests/__mocks__/@appium/support.ts +30 -0
- package/src/tests/generate-all-locators.test.ts +178 -0
- package/src/tests/screenshot.test.ts +279 -0
- package/src/tests/test-setup-wda.ts +255 -0
- package/src/tools/README.md +179 -0
- package/src/tools/app-management/activate-app.ts +47 -0
- package/src/tools/app-management/install-app.ts +46 -0
- package/src/tools/app-management/list-apps.ts +87 -0
- package/src/tools/app-management/terminate-app.ts +48 -0
- package/src/tools/app-management/uninstall-app.ts +48 -0
- package/src/tools/context/get-contexts.ts +87 -0
- package/src/tools/context/switch-context.ts +101 -0
- package/src/tools/documentation/answer-appium.ts +73 -0
- package/src/tools/documentation/index.ts +98 -0
- package/src/tools/documentation/reasoning-rag.ts +435 -0
- package/src/tools/documentation/sentence-transformers-embeddings.ts +144 -0
- package/src/tools/documentation/simple-pdf-indexer.ts +508 -0
- package/src/tools/documentation/uploads/documents.json +1 -0
- package/src/tools/index.ts +159 -0
- package/src/tools/interactions/click.ts +48 -0
- package/src/tools/interactions/double-tap.ts +96 -0
- package/src/tools/interactions/drag-and-drop.ts +236 -0
- package/src/tools/interactions/find.ts +58 -0
- package/src/tools/interactions/get-page-source.ts +65 -0
- package/src/tools/interactions/get-text.ts +48 -0
- package/src/tools/interactions/long-press.ts +111 -0
- package/src/tools/interactions/screenshot.ts +116 -0
- package/src/tools/interactions/set-value.ts +49 -0
- package/src/tools/ios/boot-simulator.ts +88 -0
- package/src/tools/ios/install-wda.ts +277 -0
- package/src/tools/ios/setup-wda.ts +217 -0
- package/src/tools/navigations/scroll-to-element.ts +198 -0
- package/src/tools/navigations/scroll.ts +101 -0
- package/src/tools/navigations/swipe.ts +364 -0
- package/src/tools/session/create-session.ts +379 -0
- package/src/tools/session/delete-session.ts +56 -0
- package/src/tools/session/select-device.ts +326 -0
- package/src/tools/session/select-platform.ts +250 -0
- package/src/tools/test-generation/generate-tests.ts +48 -0
- package/src/tools/test-generation/locators.ts +103 -0
- package/src/ui/mcp-ui-utils.ts +1630 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import {
|
|
2
|
+
describe,
|
|
3
|
+
test,
|
|
4
|
+
expect,
|
|
5
|
+
beforeEach,
|
|
6
|
+
afterEach,
|
|
7
|
+
jest,
|
|
8
|
+
} from '@jest/globals';
|
|
9
|
+
import { join, isAbsolute } from 'path';
|
|
10
|
+
import * as os from 'node:os';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Local implementation of resolveScreenshotDir for testing.
|
|
14
|
+
* This mirrors the implementation in screenshot.ts to avoid importing
|
|
15
|
+
* the module which has heavy dependencies.
|
|
16
|
+
*/
|
|
17
|
+
function resolveScreenshotDir(): string {
|
|
18
|
+
const screenshotDir = process.env.SCREENSHOTS_DIR;
|
|
19
|
+
|
|
20
|
+
if (!screenshotDir) {
|
|
21
|
+
return os.tmpdir();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (isAbsolute(screenshotDir)) {
|
|
25
|
+
return screenshotDir;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return join(process.cwd(), screenshotDir);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Interface for screenshot dependencies (mirrors screenshot.ts).
|
|
33
|
+
*/
|
|
34
|
+
interface ScreenshotDeps {
|
|
35
|
+
getDriver: () => { getScreenshot: () => Promise<string> } | null;
|
|
36
|
+
writeFile: (path: string, data: Buffer) => Promise<void>;
|
|
37
|
+
mkdir: (path: string, options: { recursive: boolean }) => Promise<void>;
|
|
38
|
+
resolveScreenshotDir: () => string;
|
|
39
|
+
dateNow: () => number;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Local implementation of executeScreenshot for testing.
|
|
44
|
+
* This mirrors the implementation in screenshot.ts.
|
|
45
|
+
*/
|
|
46
|
+
async function executeScreenshot(deps: ScreenshotDeps): Promise<any> {
|
|
47
|
+
const driver = deps.getDriver();
|
|
48
|
+
if (!driver) {
|
|
49
|
+
throw new Error('No driver found');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
const screenshotBase64 = await driver.getScreenshot();
|
|
54
|
+
const screenshotBuffer = Buffer.from(screenshotBase64, 'base64');
|
|
55
|
+
const timestamp = deps.dateNow();
|
|
56
|
+
const filename = `screenshot_${timestamp}.png`;
|
|
57
|
+
const screenshotDir = deps.resolveScreenshotDir();
|
|
58
|
+
|
|
59
|
+
await deps.mkdir(screenshotDir, { recursive: true });
|
|
60
|
+
const filepath = join(screenshotDir, filename);
|
|
61
|
+
await deps.writeFile(filepath, screenshotBuffer);
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
content: [
|
|
65
|
+
{
|
|
66
|
+
type: 'text',
|
|
67
|
+
text: `Screenshot saved successfully to: ${filename}`,
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
};
|
|
71
|
+
} catch (err: any) {
|
|
72
|
+
return {
|
|
73
|
+
content: [
|
|
74
|
+
{
|
|
75
|
+
type: 'text',
|
|
76
|
+
text: `Failed to take screenshot. err: ${err.toString()}`,
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
describe('resolveScreenshotDir', () => {
|
|
84
|
+
const originalEnv = process.env.SCREENSHOTS_DIR;
|
|
85
|
+
const cwd = process.cwd();
|
|
86
|
+
|
|
87
|
+
beforeEach(() => {
|
|
88
|
+
delete process.env.SCREENSHOTS_DIR;
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
afterEach(() => {
|
|
92
|
+
if (originalEnv !== undefined) {
|
|
93
|
+
process.env.SCREENSHOTS_DIR = originalEnv;
|
|
94
|
+
} else {
|
|
95
|
+
delete process.env.SCREENSHOTS_DIR;
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test('should return os.tmpdir() when SCREENSHOTS_DIR is not set', () => {
|
|
100
|
+
const result = resolveScreenshotDir();
|
|
101
|
+
expect(result).toBe(os.tmpdir());
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('should return os.tmpdir() when SCREENSHOTS_DIR is empty string', () => {
|
|
105
|
+
process.env.SCREENSHOTS_DIR = '';
|
|
106
|
+
const result = resolveScreenshotDir();
|
|
107
|
+
expect(result).toBe(os.tmpdir());
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test('should return absolute path as-is when SCREENSHOTS_DIR is absolute', () => {
|
|
111
|
+
const absolutePath = '/tmp/screenshots';
|
|
112
|
+
process.env.SCREENSHOTS_DIR = absolutePath;
|
|
113
|
+
const result = resolveScreenshotDir();
|
|
114
|
+
expect(result).toBe(absolutePath);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test('should join relative path with process.cwd()', () => {
|
|
118
|
+
const relativePath = 'screenshots';
|
|
119
|
+
process.env.SCREENSHOTS_DIR = relativePath;
|
|
120
|
+
const result = resolveScreenshotDir();
|
|
121
|
+
expect(result).toBe(join(cwd, relativePath));
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test('should handle nested relative paths', () => {
|
|
125
|
+
const relativePath = 'output/screenshots/test';
|
|
126
|
+
process.env.SCREENSHOTS_DIR = relativePath;
|
|
127
|
+
const result = resolveScreenshotDir();
|
|
128
|
+
expect(result).toBe(join(cwd, relativePath));
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test('should handle relative path starting with ./', () => {
|
|
132
|
+
const relativePath = './screenshots';
|
|
133
|
+
process.env.SCREENSHOTS_DIR = relativePath;
|
|
134
|
+
const result = resolveScreenshotDir();
|
|
135
|
+
expect(result).toBe(join(cwd, relativePath));
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test('should handle relative path with parent directory reference', () => {
|
|
139
|
+
const relativePath = '../screenshots';
|
|
140
|
+
process.env.SCREENSHOTS_DIR = relativePath;
|
|
141
|
+
const result = resolveScreenshotDir();
|
|
142
|
+
expect(result).toBe(join(cwd, relativePath));
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
describe('executeScreenshot', () => {
|
|
147
|
+
const mockBase64 = 'dGVzdA=='; // 'test' in base64
|
|
148
|
+
const mockTimestamp = 1234567890;
|
|
149
|
+
|
|
150
|
+
function createMockDeps(
|
|
151
|
+
overrides: Partial<ScreenshotDeps> = {}
|
|
152
|
+
): ScreenshotDeps {
|
|
153
|
+
return {
|
|
154
|
+
getDriver: jest.fn(() => ({
|
|
155
|
+
getScreenshot: jest.fn(() => Promise.resolve(mockBase64)),
|
|
156
|
+
})) as any,
|
|
157
|
+
writeFile: jest.fn(() => Promise.resolve()) as any,
|
|
158
|
+
mkdir: jest.fn(() => Promise.resolve()) as any,
|
|
159
|
+
resolveScreenshotDir: jest.fn(() => '/mock/screenshots') as any,
|
|
160
|
+
dateNow: jest.fn(() => mockTimestamp) as any,
|
|
161
|
+
...overrides,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
test('should throw error when no driver found', async () => {
|
|
166
|
+
const deps = createMockDeps({
|
|
167
|
+
getDriver: jest.fn(() => null) as any,
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
await expect(executeScreenshot(deps)).rejects.toThrow('No driver found');
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
test('should return success content with filename', async () => {
|
|
174
|
+
const deps = createMockDeps();
|
|
175
|
+
|
|
176
|
+
const result = await executeScreenshot(deps);
|
|
177
|
+
|
|
178
|
+
expect(result).toEqual({
|
|
179
|
+
content: [
|
|
180
|
+
{
|
|
181
|
+
type: 'text',
|
|
182
|
+
text: `Screenshot saved successfully to: screenshot_${mockTimestamp}.png`,
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
test('should use resolved screenshot directory from SCREENSHOTS_DIR', async () => {
|
|
189
|
+
const customDir = '/custom/path/screenshots';
|
|
190
|
+
const deps = createMockDeps({
|
|
191
|
+
resolveScreenshotDir: jest.fn(() => customDir) as any,
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
await executeScreenshot(deps);
|
|
195
|
+
|
|
196
|
+
expect(deps.mkdir).toHaveBeenCalledWith(customDir, { recursive: true });
|
|
197
|
+
expect(deps.writeFile).toHaveBeenCalledWith(
|
|
198
|
+
join(customDir, `screenshot_${mockTimestamp}.png`),
|
|
199
|
+
expect.any(Buffer)
|
|
200
|
+
);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
test('should create directory with recursive option', async () => {
|
|
204
|
+
const deps = createMockDeps();
|
|
205
|
+
|
|
206
|
+
await executeScreenshot(deps);
|
|
207
|
+
|
|
208
|
+
expect(deps.mkdir).toHaveBeenCalledWith('/mock/screenshots', {
|
|
209
|
+
recursive: true,
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
test('should write screenshot buffer to correct filepath', async () => {
|
|
214
|
+
const deps = createMockDeps();
|
|
215
|
+
|
|
216
|
+
await executeScreenshot(deps);
|
|
217
|
+
|
|
218
|
+
expect(deps.writeFile).toHaveBeenCalledWith(
|
|
219
|
+
`/mock/screenshots/screenshot_${mockTimestamp}.png`,
|
|
220
|
+
Buffer.from(mockBase64, 'base64')
|
|
221
|
+
);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
test('should return error content when screenshot fails', async () => {
|
|
225
|
+
const errorMessage = 'Screenshot capture failed';
|
|
226
|
+
const deps = createMockDeps({
|
|
227
|
+
getDriver: jest.fn(() => ({
|
|
228
|
+
getScreenshot: jest.fn(() => Promise.reject(new Error(errorMessage))),
|
|
229
|
+
})) as any,
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
const result = await executeScreenshot(deps);
|
|
233
|
+
|
|
234
|
+
expect(result).toEqual({
|
|
235
|
+
content: [
|
|
236
|
+
{
|
|
237
|
+
type: 'text',
|
|
238
|
+
text: `Failed to take screenshot. err: Error: ${errorMessage}`,
|
|
239
|
+
},
|
|
240
|
+
],
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
test('should return error content when mkdir fails', async () => {
|
|
245
|
+
const errorMessage = 'Permission denied';
|
|
246
|
+
const deps = createMockDeps({
|
|
247
|
+
mkdir: jest.fn(() => Promise.reject(new Error(errorMessage))) as any,
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
const result = await executeScreenshot(deps);
|
|
251
|
+
|
|
252
|
+
expect(result).toEqual({
|
|
253
|
+
content: [
|
|
254
|
+
{
|
|
255
|
+
type: 'text',
|
|
256
|
+
text: `Failed to take screenshot. err: Error: ${errorMessage}`,
|
|
257
|
+
},
|
|
258
|
+
],
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
test('should return error content when writeFile fails', async () => {
|
|
263
|
+
const errorMessage = 'Disk full';
|
|
264
|
+
const deps = createMockDeps({
|
|
265
|
+
writeFile: jest.fn(() => Promise.reject(new Error(errorMessage))) as any,
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
const result = await executeScreenshot(deps);
|
|
269
|
+
|
|
270
|
+
expect(result).toEqual({
|
|
271
|
+
content: [
|
|
272
|
+
{
|
|
273
|
+
type: 'text',
|
|
274
|
+
text: `Failed to take screenshot. err: Error: ${errorMessage}`,
|
|
275
|
+
},
|
|
276
|
+
],
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
});
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test file for setup-wda tool
|
|
3
|
+
* Run with: npx tsx src/tests/test-setup-wda.ts
|
|
4
|
+
*/
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import fs from 'fs';
|
|
7
|
+
import os from 'os';
|
|
8
|
+
import { createRequire } from 'module';
|
|
9
|
+
import https from 'https';
|
|
10
|
+
import { exec } from 'child_process';
|
|
11
|
+
import { promisify } from 'util';
|
|
12
|
+
|
|
13
|
+
const execAsync = promisify(exec);
|
|
14
|
+
|
|
15
|
+
// Mock server object to test the tool
|
|
16
|
+
class MockServer {
|
|
17
|
+
private tools: Map<string, any> = new Map();
|
|
18
|
+
|
|
19
|
+
addTool(tool: any) {
|
|
20
|
+
this.tools.set(tool.name, tool);
|
|
21
|
+
console.log(`✅ Tool registered: ${tool.name}`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getTool(name: string) {
|
|
25
|
+
return this.tools.get(name);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function downloadFile(url: string, destPath: string): Promise<void> {
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
const file = fs.createWriteStream(destPath);
|
|
32
|
+
|
|
33
|
+
https
|
|
34
|
+
.get(url, async (response) => {
|
|
35
|
+
// Handle redirects
|
|
36
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
37
|
+
file.close();
|
|
38
|
+
fs.unlinkSync(destPath);
|
|
39
|
+
try {
|
|
40
|
+
await downloadFile(response.headers.location!, destPath);
|
|
41
|
+
resolve();
|
|
42
|
+
} catch (err) {
|
|
43
|
+
reject(err);
|
|
44
|
+
}
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (response.statusCode !== 200) {
|
|
49
|
+
file.close();
|
|
50
|
+
fs.unlinkSync(destPath);
|
|
51
|
+
return reject(
|
|
52
|
+
new Error(`Failed to download: ${response.statusCode}`)
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const totalSize = parseInt(
|
|
57
|
+
response.headers['content-length'] || '0',
|
|
58
|
+
10
|
|
59
|
+
);
|
|
60
|
+
let downloadedSize = 0;
|
|
61
|
+
|
|
62
|
+
response.on('data', (chunk) => {
|
|
63
|
+
downloadedSize += chunk.length;
|
|
64
|
+
const percent = ((downloadedSize / totalSize) * 100).toFixed(1);
|
|
65
|
+
process.stdout.write(
|
|
66
|
+
`\r Downloading... ${percent}% (${Math.round(downloadedSize / 1024 / 1024)}MB / ${Math.round(totalSize / 1024 / 1024)}MB)`
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
response.pipe(file);
|
|
71
|
+
|
|
72
|
+
file.on('finish', () => {
|
|
73
|
+
file.close();
|
|
74
|
+
process.stdout.write('\n');
|
|
75
|
+
resolve();
|
|
76
|
+
});
|
|
77
|
+
})
|
|
78
|
+
.on('error', (err) => {
|
|
79
|
+
file.close();
|
|
80
|
+
fs.unlinkSync(destPath);
|
|
81
|
+
reject(err);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function unzipFile(zipPath: string, destDir: string): Promise<void> {
|
|
87
|
+
console.log(` Extracting to: ${destDir}`);
|
|
88
|
+
await execAsync(`unzip -q "${zipPath}" -d "${destDir}"`);
|
|
89
|
+
console.log(' ✅ Extraction complete');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function cachePath(folder: string): string {
|
|
93
|
+
return path.join(os.homedir(), '.cache', 'appium-mcp', folder);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function getLatestWDAVersion(): Promise<string> {
|
|
97
|
+
return new Promise((resolve, reject) => {
|
|
98
|
+
const options = {
|
|
99
|
+
hostname: 'api.github.com',
|
|
100
|
+
path: '/repos/appium/WebDriverAgent/releases/latest',
|
|
101
|
+
method: 'GET',
|
|
102
|
+
headers: {
|
|
103
|
+
'User-Agent': 'mcp-appium-test',
|
|
104
|
+
Accept: 'application/vnd.github.v3+json',
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
https
|
|
109
|
+
.get(options, (response) => {
|
|
110
|
+
let data = '';
|
|
111
|
+
|
|
112
|
+
response.on('data', (chunk) => {
|
|
113
|
+
data += chunk;
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
response.on('end', () => {
|
|
117
|
+
try {
|
|
118
|
+
const release = JSON.parse(data);
|
|
119
|
+
if (release.tag_name) {
|
|
120
|
+
// Remove 'v' prefix if present
|
|
121
|
+
const version = release.tag_name.replace(/^v/, '');
|
|
122
|
+
resolve(version);
|
|
123
|
+
} else {
|
|
124
|
+
reject(new Error('No tag_name found in release data'));
|
|
125
|
+
}
|
|
126
|
+
} catch (error) {
|
|
127
|
+
reject(error);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
})
|
|
131
|
+
.on('error', (err) => {
|
|
132
|
+
reject(err);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async function main() {
|
|
138
|
+
console.log('🧪 Testing WDA Download and Setup\n');
|
|
139
|
+
console.log('='.repeat(60));
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
// Fetch latest WDA version from GitHub releases API
|
|
143
|
+
console.log('\n🔍 Fetching latest WDA version from GitHub...');
|
|
144
|
+
const wdaVersion = await getLatestWDAVersion();
|
|
145
|
+
console.log(`✅ Latest WDA Version: v${wdaVersion}`);
|
|
146
|
+
console.log(
|
|
147
|
+
' Source: https://github.com/appium/WebDriverAgent/releases/latest'
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
// Create cache directory structure using home directory
|
|
151
|
+
const versionCacheDir = cachePath(`wda/${wdaVersion}`);
|
|
152
|
+
const extractDir = path.join(versionCacheDir, 'extracted');
|
|
153
|
+
const zipPath = path.join(
|
|
154
|
+
versionCacheDir,
|
|
155
|
+
'WebDriverAgentRunner-Runner.zip'
|
|
156
|
+
);
|
|
157
|
+
const appPath = path.join(extractDir, 'WebDriverAgentRunner-Runner.app');
|
|
158
|
+
|
|
159
|
+
console.log('\n📁 Cache Directory:', versionCacheDir);
|
|
160
|
+
console.log(` (~/.cache/appium-device-farm/wda/${wdaVersion})`);
|
|
161
|
+
|
|
162
|
+
// Check if this version is already cached
|
|
163
|
+
if (fs.existsSync(appPath)) {
|
|
164
|
+
console.log('\n✅ WDA version already cached! Skipping download.');
|
|
165
|
+
console.log(` Location: ${appPath}`);
|
|
166
|
+
|
|
167
|
+
// Show app contents
|
|
168
|
+
const appContents = fs.readdirSync(appPath);
|
|
169
|
+
console.log('\n📋 Cached App bundle contents:');
|
|
170
|
+
appContents.forEach((item) => {
|
|
171
|
+
console.log(` - ${item}`);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
console.log('\n' + '='.repeat(60));
|
|
175
|
+
console.log('🎉 Using cached WDA!');
|
|
176
|
+
console.log(`💡 Cache location: ${versionCacheDir}`);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Version not cached, proceed with download
|
|
181
|
+
console.log('\n⚠️ Version not found in cache. Downloading...');
|
|
182
|
+
|
|
183
|
+
// Create cache directories
|
|
184
|
+
fs.mkdirSync(versionCacheDir, { recursive: true });
|
|
185
|
+
fs.mkdirSync(extractDir, { recursive: true });
|
|
186
|
+
|
|
187
|
+
// Download URL
|
|
188
|
+
const downloadUrl = `https://github.com/appium/WebDriverAgent/releases/download/v${wdaVersion}/WebDriverAgentRunner-Runner.zip`;
|
|
189
|
+
|
|
190
|
+
console.log('\n⬇️ Downloading WDA from GitHub releases...');
|
|
191
|
+
console.log(` URL: ${downloadUrl}`);
|
|
192
|
+
|
|
193
|
+
const startTime = Date.now();
|
|
194
|
+
await downloadFile(downloadUrl, zipPath);
|
|
195
|
+
const downloadTime = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
196
|
+
|
|
197
|
+
console.log(` ✅ Download complete (${downloadTime}s)`);
|
|
198
|
+
|
|
199
|
+
// Check file size
|
|
200
|
+
const stats = fs.statSync(zipPath);
|
|
201
|
+
const fileSizeMB = (stats.size / 1024 / 1024).toFixed(2);
|
|
202
|
+
console.log(` 📦 File size: ${fileSizeMB} MB`);
|
|
203
|
+
|
|
204
|
+
// Unzip the file
|
|
205
|
+
console.log('\n📂 Extracting WDA bundle...');
|
|
206
|
+
await unzipFile(zipPath, extractDir);
|
|
207
|
+
|
|
208
|
+
// List contents
|
|
209
|
+
console.log('\n📋 Extracted contents:');
|
|
210
|
+
const contents = fs.readdirSync(extractDir);
|
|
211
|
+
contents.forEach((item) => {
|
|
212
|
+
const itemPath = path.join(extractDir, item);
|
|
213
|
+
const isDir = fs.statSync(itemPath).isDirectory();
|
|
214
|
+
console.log(` ${isDir ? '📁' : '📄'} ${item}`);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// Check if WebDriverAgentRunner-Runner.app exists
|
|
218
|
+
if (fs.existsSync(appPath)) {
|
|
219
|
+
console.log('\n✅ WebDriverAgentRunner-Runner.app found!');
|
|
220
|
+
console.log(` Location: ${appPath}`);
|
|
221
|
+
|
|
222
|
+
// Show app contents
|
|
223
|
+
const appContents = fs.readdirSync(appPath);
|
|
224
|
+
console.log('\n App bundle contents:');
|
|
225
|
+
appContents.forEach((item) => {
|
|
226
|
+
console.log(` - ${item}`);
|
|
227
|
+
});
|
|
228
|
+
} else {
|
|
229
|
+
console.log('\n⚠️ WebDriverAgentRunner-Runner.app not found');
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
console.log('\n' + '='.repeat(60));
|
|
233
|
+
console.log('🎉 Download and setup completed successfully!');
|
|
234
|
+
console.log(`\n💡 Cached location: ${versionCacheDir}`);
|
|
235
|
+
console.log(
|
|
236
|
+
' This version will be reused on subsequent runs (no re-download needed)'
|
|
237
|
+
);
|
|
238
|
+
} catch (error: any) {
|
|
239
|
+
console.error('\n❌ Test failed:', error.message);
|
|
240
|
+
if (error.stack) {
|
|
241
|
+
console.error('\nStack trace:', error.stack);
|
|
242
|
+
}
|
|
243
|
+
process.exit(1);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Run main function
|
|
248
|
+
(async () => {
|
|
249
|
+
try {
|
|
250
|
+
await main();
|
|
251
|
+
} catch (error: any) {
|
|
252
|
+
console.error('\n💥 Unexpected error:', error);
|
|
253
|
+
process.exit(1);
|
|
254
|
+
}
|
|
255
|
+
})();
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# Tools Directory
|
|
2
|
+
|
|
3
|
+
This directory contains all MCP tools available in MCP Appium.
|
|
4
|
+
|
|
5
|
+
## Tool Categories
|
|
6
|
+
|
|
7
|
+
### Session Management (`session/`)
|
|
8
|
+
|
|
9
|
+
- `create-session.ts` - Create mobile automation sessions
|
|
10
|
+
- `delete-session.ts` - Clean up sessions
|
|
11
|
+
- `select-platform.ts` - Choose Android or iOS
|
|
12
|
+
- `select-device.ts` - Choose specific device
|
|
13
|
+
|
|
14
|
+
### iOS Setup (`ios/`)
|
|
15
|
+
|
|
16
|
+
- `boot-simulator.ts` - Boot iOS simulators
|
|
17
|
+
- `setup-wda.ts` - Setup WebDriverAgent
|
|
18
|
+
- `install-wda.ts` - Install WebDriverAgent
|
|
19
|
+
|
|
20
|
+
### Navigation (`navigations/`)
|
|
21
|
+
|
|
22
|
+
- `scroll.ts` - Scroll screens
|
|
23
|
+
- `scroll-to-element.ts` - Scroll until element found
|
|
24
|
+
- `swipe.ts` - Swipe screens in any direction or between custom coordinates
|
|
25
|
+
|
|
26
|
+
### Element Interactions (`interactions/`)
|
|
27
|
+
|
|
28
|
+
- `find.ts` - Find elements
|
|
29
|
+
- `click.ts` - Click elements
|
|
30
|
+
- `double-tap.ts` - Double tap elements
|
|
31
|
+
- `long-press.ts` - Long press (press and hold) elements
|
|
32
|
+
- `drag-and-drop.ts` - Drag and drop elements or coordinates
|
|
33
|
+
- `set-value.ts` - Enter text
|
|
34
|
+
- `get-text.ts` - Get element text
|
|
35
|
+
- `get-page-source.ts` - Get page source (XML) from current screen
|
|
36
|
+
- `screenshot.ts` - Capture screenshots
|
|
37
|
+
|
|
38
|
+
### App Management (`app-management/`)
|
|
39
|
+
|
|
40
|
+
- `activate-app.ts` - Activate apps
|
|
41
|
+
- `terminate-app.ts` - Terminate apps
|
|
42
|
+
- `install-app.ts` - Install apps
|
|
43
|
+
- `uninstall-app.ts` - Uninstall apps
|
|
44
|
+
- `list-apps.ts` - List installed apps
|
|
45
|
+
|
|
46
|
+
### Test Generation (`test-generation/`)
|
|
47
|
+
|
|
48
|
+
- `locators.ts` - Generate page locators
|
|
49
|
+
- `generate-tests.ts` - Generate test code from scenarios
|
|
50
|
+
|
|
51
|
+
### Documentation (`documentation/`)
|
|
52
|
+
|
|
53
|
+
- `answer-appium.ts` - Answer Appium questions using RAG
|
|
54
|
+
|
|
55
|
+
## Adding a New Tool
|
|
56
|
+
|
|
57
|
+
See [docs/CONTRIBUTING.md](../../docs/CONTRIBUTING.md) for detailed instructions.
|
|
58
|
+
|
|
59
|
+
Quick steps:
|
|
60
|
+
|
|
61
|
+
1. Create a new file in the appropriate subdirectory (e.g., `interactions/my-tool.ts`)
|
|
62
|
+
2. Define the tool following the template
|
|
63
|
+
3. Import and register it in `index.ts`
|
|
64
|
+
4. Test with `npm run build && npm start`
|
|
65
|
+
|
|
66
|
+
### Tool Template
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import { FastMCP } from 'fastmcp/dist/FastMCP.js';
|
|
70
|
+
import { z } from 'zod';
|
|
71
|
+
import { getDriver } from '../../session-store.js';
|
|
72
|
+
|
|
73
|
+
export default function myTool(server: FastMCP): void {
|
|
74
|
+
server.addTool({
|
|
75
|
+
name: 'appium_my_tool',
|
|
76
|
+
description: 'What this tool does',
|
|
77
|
+
parameters: z.object({
|
|
78
|
+
param: z.string().describe('Parameter description'),
|
|
79
|
+
}),
|
|
80
|
+
annotations: {
|
|
81
|
+
readOnlyHint: false,
|
|
82
|
+
openWorldHint: false,
|
|
83
|
+
},
|
|
84
|
+
execute: async (args: any, context: any): Promise<any> => {
|
|
85
|
+
const driver = getDriver();
|
|
86
|
+
if (!driver) {
|
|
87
|
+
throw new Error('No active session');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Implementation
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
content: [
|
|
94
|
+
{
|
|
95
|
+
type: 'text',
|
|
96
|
+
text: 'Success',
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
};
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Registering a Tool
|
|
106
|
+
|
|
107
|
+
Add to `src/tools/index.ts`:
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
import myTool from './interactions/my-tool.js';
|
|
111
|
+
|
|
112
|
+
export default function registerTools(server: FastMCP): void {
|
|
113
|
+
// ... existing tools ...
|
|
114
|
+
myTool(server);
|
|
115
|
+
// ...
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Best Practices
|
|
120
|
+
|
|
121
|
+
1. **Always check for active session**: Use `getDriver()` and check for null
|
|
122
|
+
2. **Provide helpful errors**: Give clear error messages
|
|
123
|
+
3. **Use proper types**: Leverage TypeScript and Zod for type safety
|
|
124
|
+
4. **Add logging**: Use the logger from `logger.js` for debugging. Import with: `import log from 'logger.js'`. Use `log.info()`, `log.error()`, `log.warn()` instead of `console.log/error/warn` to maintain JSON-RPC compatibility
|
|
125
|
+
5. **Handle errors**: Always wrap risky operations in try-catch
|
|
126
|
+
6. **Return proper format**: Always return content in expected MCP format
|
|
127
|
+
|
|
128
|
+
## Session Store
|
|
129
|
+
|
|
130
|
+
Tools interact with the session through `session-store.ts`:
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
import {
|
|
134
|
+
getDriver,
|
|
135
|
+
hasActiveSession,
|
|
136
|
+
safeDeleteSession,
|
|
137
|
+
} from '../../session-store.js';
|
|
138
|
+
|
|
139
|
+
// Check if session exists
|
|
140
|
+
if (!hasActiveSession()) {
|
|
141
|
+
throw new Error('No active session');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Get the driver
|
|
145
|
+
const driver = getDriver();
|
|
146
|
+
|
|
147
|
+
// Use the driver
|
|
148
|
+
await driver.someMethod();
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Common Patterns
|
|
152
|
+
|
|
153
|
+
### Platform-Specific Logic
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
import { getPlatformName } from '../../session-store.js';
|
|
157
|
+
|
|
158
|
+
if (getPlatformName(driver) === 'Android') {
|
|
159
|
+
// Android implementation
|
|
160
|
+
} else if (getPlatformName(driver) === 'iOS') {
|
|
161
|
+
// iOS implementation
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Testing
|
|
166
|
+
|
|
167
|
+
After adding a new tool:
|
|
168
|
+
|
|
169
|
+
1. Build: `npm run build`
|
|
170
|
+
2. Run linter: `npm run lint`
|
|
171
|
+
3. Test with an MCP client
|
|
172
|
+
4. Verify tool appears in tools list
|
|
173
|
+
|
|
174
|
+
## Need Help?
|
|
175
|
+
|
|
176
|
+
- Check existing tools for examples
|
|
177
|
+
- Read [docs/CONTRIBUTING.md](../../docs/CONTRIBUTING.md)
|
|
178
|
+
- Look at examples in `examples/` directory
|
|
179
|
+
- Open an issue for questions
|