testdriverai 7.3.2 → 7.3.3
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/.claude/settings.local.json +7 -0
- package/.env.example +4 -0
- package/.github/workflows/acceptance-linux-scheduled.yaml +45 -0
- package/.github/workflows/acceptance-windows-scheduled.yaml +54 -0
- package/.github/workflows/acceptance.yaml +106 -0
- package/.github/workflows/publish.yaml +75 -0
- package/.github/workflows/test-init.yml +157 -0
- package/.github/workflows/testdriver.yml +170 -0
- package/.github/workflows/windows-self-hosted.yaml +82 -0
- package/.prettierignore +4 -0
- package/.prettierrc +1 -0
- package/CHANGELOG.md +158 -0
- package/SKILLs.md +17 -0
- package/ai/.claude-plugin/plugin.json +9 -0
- package/docs/GITHUB_COMMENTS.md +330 -0
- package/docs/GITHUB_COMMENTS_ANNOUNCEMENT.md +167 -0
- package/docs/QUICK-START-GITHUB-COMMENTS.md +84 -0
- package/docs/TEST-GITHUB-COMMENTS.md +129 -0
- package/docs/_scripts/generate-skills.js +149 -0
- package/docs/_scripts/link-replacer.js +164 -0
- package/docs/_scripts/upload-docs-to-openai.js +284 -0
- package/docs/claude-mcp-plugin.mdx +160 -0
- package/docs/docs.json +394 -0
- package/docs/github-integration-setup.md +266 -0
- package/docs/guide/best-practices-polling.mdx +154 -0
- package/docs/images/content/account/newprojectsettings.png +0 -0
- package/docs/images/content/account/projectpage.png +0 -0
- package/docs/images/content/account/projectreplays.png +0 -0
- package/docs/images/content/account/team-manage.png +0 -0
- package/docs/images/content/account/teampage.png +0 -0
- package/docs/images/content/extension/cursor.svg +1 -0
- package/docs/images/content/extension/vscode.svg +57 -0
- package/docs/images/content/extension/windsurf.svg +3 -0
- package/docs/images/content/self-hosted/launchtemplateid.png +0 -0
- package/docs/images/content/side-by-side.png +0 -0
- package/docs/images/content/vscode/ide-full.png +0 -0
- package/docs/images/content/vscode/running.png +0 -0
- package/docs/images/content/vscode/vscode-2-assert.png +0 -0
- package/docs/images/content/vscode/vscode-agent-preview.png +0 -0
- package/docs/images/content/vscode/vscode-copilot-ask.png +0 -0
- package/docs/images/content/vscode/vscode-file-creation.png +0 -0
- package/docs/images/content/vscode/vscode-install.png +0 -0
- package/docs/images/content/vscode/vscode-overview.png +0 -0
- package/docs/images/content/vscode/vscode-setup-walkthrough.png +0 -0
- package/docs/images/content/vscode/vscode-stopchat.png +0 -0
- package/docs/images/content/vscode/vscode-stoptest.png +0 -0
- package/docs/images/content/vscode/vscode-tdservice.png +0 -0
- package/docs/images/content/vscode/vscode-test-output.png +0 -0
- package/docs/images/content/vscode/vscode-testhistory.png +0 -0
- package/docs/images/content/vscode/vscode-testpane-runtests.png +0 -0
- package/docs/images/content/vscode/vscode-testpane.png +0 -0
- package/docs/images/template/dark.png +0 -0
- package/docs/images/template/icon.png +0 -0
- package/docs/images/template/light.png +0 -0
- package/docs/snippets/calendar-link.mdx +4 -0
- package/docs/snippets/gitignore-warning.mdx +7 -0
- package/docs/snippets/lifecycle-warning.mdx +6 -0
- package/docs/snippets/test-prereqs.mdx +12 -0
- package/docs/snippets/tests/assert-replay.mdx +7 -0
- package/docs/snippets/tests/assert-yaml.mdx +8 -0
- package/docs/snippets/tests/exec-js-replay.mdx +7 -0
- package/docs/snippets/tests/exec-js-yaml.mdx +32 -0
- package/docs/snippets/tests/exec-shell-replay.mdx +7 -0
- package/docs/snippets/tests/exec-shell-yaml.mdx +15 -0
- package/docs/snippets/tests/hover-image-replay.mdx +7 -0
- package/docs/snippets/tests/hover-image-yaml.mdx +17 -0
- package/docs/snippets/tests/hover-text-replay.mdx +7 -0
- package/docs/snippets/tests/hover-text-with-description-replay.mdx +7 -0
- package/docs/snippets/tests/hover-text-with-description-yaml.mdx +24 -0
- package/docs/snippets/tests/hover-text-yaml.mdx +14 -0
- package/docs/snippets/tests/match-image-replay.mdx +7 -0
- package/docs/snippets/tests/match-image-yaml.mdx +17 -0
- package/docs/snippets/tests/press-keys-replay.mdx +7 -0
- package/docs/snippets/tests/press-keys-yaml.mdx +36 -0
- package/docs/snippets/tests/remember-replay.mdx +7 -0
- package/docs/snippets/tests/remember-yaml.mdx +28 -0
- package/docs/snippets/tests/scroll-replay.mdx +7 -0
- package/docs/snippets/tests/scroll-until-image-replay.mdx +7 -0
- package/docs/snippets/tests/scroll-until-image-yaml.mdx +14 -0
- package/docs/snippets/tests/scroll-until-text-replay.mdx +7 -0
- package/docs/snippets/tests/scroll-until-text-yaml.mdx +17 -0
- package/docs/snippets/tests/scroll-yaml.mdx +30 -0
- package/docs/snippets/tests/type-repeated-replay.mdx +7 -0
- package/docs/snippets/tests/type-repeated-yaml.mdx +22 -0
- package/docs/snippets/tests/type-replay.mdx +7 -0
- package/docs/snippets/tests/type-yaml.mdx +28 -0
- package/docs/snippets/tests/wait-for-image-replay.mdx +7 -0
- package/docs/snippets/tests/wait-for-image-yaml.mdx +18 -0
- package/docs/snippets/tests/wait-for-text-replay.mdx +7 -0
- package/docs/snippets/tests/wait-for-text-yaml.mdx +18 -0
- package/docs/snippets/tests/wait-replay.mdx +7 -0
- package/docs/snippets/tests/wait-yaml.mdx +13 -0
- package/docs/styles.css +65 -0
- package/docs/v6/account/dashboard.mdx +16 -0
- package/docs/v6/account/enterprise.mdx +110 -0
- package/docs/v6/account/pricing.mdx +33 -0
- package/docs/v6/account/projects.mdx +33 -0
- package/docs/v6/account/team.mdx +35 -0
- package/docs/v6/action/ami.mdx +109 -0
- package/docs/v6/action/performance.mdx +105 -0
- package/docs/v6/action/secrets.mdx +93 -0
- package/docs/v6/apps/chrome-extensions.mdx +48 -0
- package/docs/v6/apps/desktop-apps.mdx +93 -0
- package/docs/v6/apps/mobile-apps.mdx +26 -0
- package/docs/v6/apps/static-websites.mdx +54 -0
- package/docs/v6/apps/tauri-apps.mdx +361 -0
- package/docs/v6/bugs/jira.mdx +232 -0
- package/docs/v6/cli/overview.mdx +66 -0
- package/docs/v6/commands/assert.mdx +45 -0
- package/docs/v6/commands/exec.mdx +282 -0
- package/docs/v6/commands/focus-application.mdx +44 -0
- package/docs/v6/commands/hover-image.mdx +69 -0
- package/docs/v6/commands/hover-text.mdx +47 -0
- package/docs/v6/commands/if.mdx +53 -0
- package/docs/v6/commands/match-image.mdx +67 -0
- package/docs/v6/commands/press-keys.mdx +87 -0
- package/docs/v6/commands/remember.mdx +49 -0
- package/docs/v6/commands/run.mdx +44 -0
- package/docs/v6/commands/scroll-until-image.mdx +66 -0
- package/docs/v6/commands/scroll-until-text.mdx +60 -0
- package/docs/v6/commands/scroll.mdx +69 -0
- package/docs/v6/commands/type.mdx +45 -0
- package/docs/v6/commands/wait-for-image.mdx +54 -0
- package/docs/v6/commands/wait-for-text.mdx +48 -0
- package/docs/v6/commands/wait.mdx +45 -0
- package/docs/v6/exporting/junit.mdx +218 -0
- package/docs/v6/exporting/playwright.mdx +197 -0
- package/docs/v6/features/auto-healing.mdx +144 -0
- package/docs/v6/features/generation.mdx +116 -0
- package/docs/v6/features/parallel-testing.mdx +151 -0
- package/docs/v6/features/reusable-snippets.mdx +131 -0
- package/docs/v6/features/selectorless.mdx +80 -0
- package/docs/v6/features/visual-assertions.mdx +139 -0
- package/docs/v6/getting-started/ci.mdx +146 -0
- package/docs/v6/getting-started/cli.mdx +91 -0
- package/docs/v6/getting-started/editing.mdx +100 -0
- package/docs/v6/getting-started/playwright.mdx +342 -0
- package/docs/v6/getting-started/running.mdx +48 -0
- package/docs/v6/getting-started/self-hosting.mdx +408 -0
- package/docs/v6/getting-started/vscode.mdx +88 -0
- package/docs/v6/guide/assertions.mdx +189 -0
- package/docs/v6/guide/authentication.mdx +136 -0
- package/docs/v6/guide/code.mdx +65 -0
- package/docs/v6/guide/dashcam.mdx +118 -0
- package/docs/v6/guide/environment-variables.mdx +26 -0
- package/docs/v6/guide/lifecycle.mdx +242 -0
- package/docs/v6/guide/locating.mdx +141 -0
- package/docs/v6/guide/protips.mdx +43 -0
- package/docs/v6/guide/variables.mdx +143 -0
- package/docs/v6/guide/waiting.mdx +130 -0
- package/docs/v6/importing/csv.mdx +196 -0
- package/docs/v6/importing/gherkin.mdx +143 -0
- package/docs/v6/importing/jira.mdx +164 -0
- package/docs/v6/importing/testrail.mdx +162 -0
- package/docs/v6/integrations/electron.mdx +146 -0
- package/docs/v6/integrations/netlify.mdx +100 -0
- package/docs/v6/integrations/vercel.mdx +125 -0
- package/docs/v6/interactive/explore.mdx +99 -0
- package/docs/v6/interactive/run.mdx +52 -0
- package/docs/v6/interactive/save.mdx +63 -0
- package/docs/v6/overview/comparison.mdx +101 -0
- package/docs/v6/overview/faq.mdx +162 -0
- package/docs/v6/overview/performance.mdx +52 -0
- package/docs/v6/overview/quickstart.mdx +137 -0
- package/docs/v6/overview/what-is-testdriver.mdx +85 -0
- package/docs/v6/scenarios/ai-chatbot.mdx +28 -0
- package/docs/v6/scenarios/cookie-banner.mdx +32 -0
- package/docs/v6/scenarios/file-upload.mdx +33 -0
- package/docs/v6/scenarios/form-filling.mdx +32 -0
- package/docs/v6/scenarios/log-in.mdx +75 -0
- package/docs/v6/scenarios/pdf-generation.mdx +25 -0
- package/docs/v6/scenarios/spell-check.mdx +22 -0
- package/docs/v6/security/action.mdx +84 -0
- package/docs/v6/security/agent.mdx +73 -0
- package/docs/v6/security/platform.mdx +77 -0
- package/docs/v6/tutorials/advanced-test.mdx +81 -0
- package/docs/v6/tutorials/basic-test.mdx +45 -0
- package/docs/v7/_drafts/agents.mdx +852 -0
- package/docs/v7/_drafts/architecture.mdx +399 -0
- package/docs/v7/_drafts/auto-cache-key.mdx +167 -0
- package/docs/v7/_drafts/awesome-logs-quick-ref.mdx +100 -0
- package/docs/v7/_drafts/best-practices.mdx +486 -0
- package/docs/v7/_drafts/caching-ai.mdx +215 -0
- package/docs/v7/_drafts/caching-selectors.mdx +424 -0
- package/docs/v7/_drafts/caching.mdx +366 -0
- package/docs/v7/_drafts/cli-to-sdk-migration.mdx +425 -0
- package/docs/v7/_drafts/commands/assert.mdx +45 -0
- package/docs/v7/_drafts/commands/exec.mdx +282 -0
- package/docs/v7/_drafts/commands/focus-application.mdx +44 -0
- package/docs/v7/_drafts/commands/hover-image.mdx +69 -0
- package/docs/v7/_drafts/commands/hover-text.mdx +47 -0
- package/docs/v7/_drafts/commands/if.mdx +53 -0
- package/docs/v7/_drafts/commands/match-image.mdx +67 -0
- package/docs/v7/_drafts/commands/press-keys.mdx +87 -0
- package/docs/v7/_drafts/commands/remember.mdx +49 -0
- package/docs/v7/_drafts/commands/run.mdx +44 -0
- package/docs/v7/_drafts/commands/scroll-until-image.mdx +66 -0
- package/docs/v7/_drafts/commands/scroll-until-text.mdx +60 -0
- package/docs/v7/_drafts/commands/scroll.mdx +69 -0
- package/docs/v7/_drafts/commands/type.mdx +45 -0
- package/docs/v7/_drafts/commands/wait-for-image.mdx +54 -0
- package/docs/v7/_drafts/commands/wait-for-text.mdx +48 -0
- package/docs/v7/_drafts/commands/wait.mdx +45 -0
- package/docs/v7/_drafts/configuration.mdx +378 -0
- package/docs/v7/_drafts/contributing.mdx +174 -0
- package/docs/v7/_drafts/core.mdx +458 -0
- package/docs/v7/_drafts/dashcam-title-feature.mdx +89 -0
- package/docs/v7/_drafts/debugging.mdx +349 -0
- package/docs/v7/_drafts/error-handling.mdx +501 -0
- package/docs/v7/_drafts/faq.mdx +393 -0
- package/docs/v7/_drafts/hooks.mdx +360 -0
- package/docs/v7/_drafts/init-command.mdx +95 -0
- package/docs/v7/_drafts/installation.mdx +420 -0
- package/docs/v7/_drafts/migration.mdx +562 -0
- package/docs/v7/_drafts/observable.mdx +604 -0
- package/docs/v7/_drafts/playwright.mdx +342 -0
- package/docs/v7/_drafts/plugin-migration.mdx +220 -0
- package/docs/v7/_drafts/powerful.mdx +419 -0
- package/docs/v7/_drafts/presets.mdx +210 -0
- package/docs/v7/_drafts/progressive-disclosure.mdx +230 -0
- package/docs/v7/_drafts/prompt-cache.mdx +200 -0
- package/docs/v7/_drafts/provision.mdx +390 -0
- package/docs/v7/_drafts/quick-start-test-recording.mdx +214 -0
- package/docs/v7/_drafts/readme.mdx +135 -0
- package/docs/v7/_drafts/reports.mdx +414 -0
- package/docs/v7/_drafts/scalable.mdx +754 -0
- package/docs/v7/_drafts/screenshot.mdx +155 -0
- package/docs/v7/_drafts/sdk-awesome-logs.mdx +468 -0
- package/docs/v7/_drafts/sdk-browser-rendering.mdx +167 -0
- package/docs/v7/_drafts/sdk-migration.mdx +474 -0
- package/docs/v7/_drafts/sdk-v7-complete.mdx +345 -0
- package/docs/v7/_drafts/self-hosting.mdx +369 -0
- package/docs/v7/_drafts/test-recording.mdx +382 -0
- package/docs/v7/_drafts/troubleshooting.mdx +526 -0
- package/docs/v7/_drafts/vitest-plugin.mdx +477 -0
- package/docs/v7/_drafts/vitest.mdx +535 -0
- package/docs/v7/_drafts/writing-tests.mdx +25 -0
- package/{ai/skills/testdriver:ai/SKILL.md → docs/v7/ai.mdx} +4 -3
- package/{ai/skills/testdriver:assert/SKILL.md → docs/v7/assert.mdx} +4 -3
- package/{ai/skills/testdriver:aws-setup/SKILL.md → docs/v7/aws-setup.mdx} +4 -3
- package/{ai/skills/testdriver:caching/SKILL.md → docs/v7/caching.mdx} +7 -3
- package/{ai/skills/testdriver:captcha/SKILL.md → docs/v7/captcha.mdx} +4 -3
- package/{ai/skills/testdriver:ci-cd/SKILL.md → docs/v7/ci-cd.mdx} +4 -3
- package/{ai/skills/testdriver:click/SKILL.md → docs/v7/click.mdx} +4 -3
- package/{ai/skills/testdriver:client/SKILL.md → docs/v7/client.mdx} +8 -3
- package/{ai/skills/testdriver:cloud/SKILL.md → docs/v7/cloud.mdx} +4 -3
- package/{ai/skills/testdriver:customizing-devices/SKILL.md → docs/v7/customizing-devices.mdx} +3 -3
- package/{ai/skills/testdriver:dashcam/SKILL.md → docs/v7/dashcam.mdx} +4 -3
- package/docs/v7/debugging-with-screenshots.mdx +402 -0
- package/{ai/skills/testdriver:device-config/SKILL.md → docs/v7/device-config.mdx} +3 -3
- package/{ai/skills/testdriver:double-click/SKILL.md → docs/v7/double-click.mdx} +3 -3
- package/{ai/skills/testdriver:elements/SKILL.md → docs/v7/elements.mdx} +4 -3
- package/{ai/skills/testdriver:enterprise/SKILL.md → docs/v7/enterprise.mdx} +5 -3
- package/docs/v7/examples.mdx +5 -0
- package/{ai/skills/testdriver:exec/SKILL.md → docs/v7/exec.mdx} +4 -3
- package/{ai/skills/testdriver:find/SKILL.md → docs/v7/find.mdx} +4 -3
- package/{ai/skills/testdriver:focus-application/SKILL.md → docs/v7/focus-application.mdx} +4 -3
- package/{ai/skills/testdriver:generating-tests/SKILL.md → docs/v7/generating-tests.mdx} +3 -3
- package/{ai/skills/testdriver:hover/SKILL.md → docs/v7/hover.mdx} +4 -3
- package/{ai/skills/testdriver:locating-elements/SKILL.md → docs/v7/locating-elements.mdx} +3 -3
- package/{ai/skills/testdriver:making-assertions/SKILL.md → docs/v7/making-assertions.mdx} +3 -3
- package/{ai/skills/testdriver:mouse-down/SKILL.md → docs/v7/mouse-down.mdx} +3 -3
- package/{ai/skills/testdriver:mouse-up/SKILL.md → docs/v7/mouse-up.mdx} +3 -3
- package/docs/v7/ocr.mdx +236 -0
- package/{ai/skills/testdriver:performing-actions/SKILL.md → docs/v7/performing-actions.mdx} +3 -3
- package/{ai/skills/testdriver:press-keys/SKILL.md → docs/v7/press-keys.mdx} +4 -3
- package/{ai/skills/testdriver:quickstart/SKILL.md → docs/v7/quickstart.mdx} +6 -20
- package/{ai/skills/testdriver:reusable-code/SKILL.md → docs/v7/reusable-code.mdx} +3 -3
- package/{ai/skills/testdriver:right-click/SKILL.md → docs/v7/right-click.mdx} +3 -3
- package/{ai/skills/testdriver:running-tests/SKILL.md → docs/v7/running-tests.mdx} +7 -3
- package/{ai/skills/testdriver:screenshot/SKILL.md → docs/v7/screenshot.mdx} +88 -6
- package/{ai/skills/testdriver:scroll/SKILL.md → docs/v7/scroll.mdx} +40 -3
- package/{ai/skills/testdriver:secrets/SKILL.md → docs/v7/secrets.mdx} +3 -3
- package/{ai/skills/testdriver:self-hosted/SKILL.md → docs/v7/self-hosted.mdx} +4 -3
- package/{ai/skills/testdriver:type/SKILL.md → docs/v7/type.mdx} +4 -3
- package/{ai/skills/testdriver:variables/SKILL.md → docs/v7/variables.mdx} +3 -3
- package/{ai/skills/testdriver:waiting-for-elements/SKILL.md → docs/v7/waiting-for-elements.mdx} +3 -3
- package/{ai/skills/testdriver:what-is-testdriver/SKILL.md → docs/v7/what-is-testdriver.mdx} +3 -3
- package/eslint.config.js +67 -0
- package/examples/ai.test.mjs +30 -0
- package/examples/assert.test.mjs +47 -0
- package/examples/captcha-api.test.mjs +50 -0
- package/examples/chrome-extension.test.mjs +94 -0
- package/examples/drag-and-drop.test.mjs +58 -0
- package/examples/element-not-found.test.mjs +26 -0
- package/examples/exec-output.test.mjs +59 -0
- package/examples/exec-pwsh.test.mjs +57 -0
- package/examples/focus-window.test.mjs +36 -0
- package/examples/formatted-logging.test.mjs +26 -0
- package/examples/hover-image.test.mjs +52 -0
- package/examples/hover-text-with-description.test.mjs +56 -0
- package/examples/hover-text.test.mjs +27 -0
- package/examples/installer.test.mjs +49 -0
- package/examples/launch-vscode-linux.test.mjs +54 -0
- package/examples/match-image.test.mjs +54 -0
- package/examples/no-provision.test.mjs +23 -0
- package/examples/press-keys.test.mjs +50 -0
- package/examples/prompt.test.mjs +33 -0
- package/examples/scroll-keyboard.test.mjs +37 -0
- package/examples/scroll-until-image.test.mjs +39 -0
- package/examples/scroll-until-text.test.mjs +67 -0
- package/examples/scroll.test.mjs +41 -0
- package/examples/type.test.mjs +45 -0
- package/examples/windows-installer.test.mjs +53 -0
- package/jsconfig.json +26 -0
- package/manual/test-init-command.js +223 -0
- package/mcp-server/README.md +312 -0
- package/mcp-server/mcp-app.html +28 -0
- package/mcp-server/mcp-config.example.json +19 -0
- package/mcp-server/package-lock.json +4018 -0
- package/mcp-server/package.json +29 -0
- package/mcp-server/src/codegen.ts +189 -0
- package/mcp-server/src/mcp-app.css +360 -0
- package/mcp-server/src/mcp-app.ts +547 -0
- package/mcp-server/src/provision-types.ts +209 -0
- package/mcp-server/src/server.ts +2313 -0
- package/mcp-server/src/session.ts +194 -0
- package/mcp-server/tsconfig.json +16 -0
- package/mcp-server/vite.config.ts +23 -0
- package/package.json +2 -17
- package/scripts/generate-skills.js +94 -0
- package/setup/aws/cloudformation.yaml +470 -0
- package/setup/aws/spawn-runner.sh +190 -0
- package/test/api-resilience.test.mjs +0 -0
- package/test/captcha-solver.test.mjs +152 -0
- package/test/chrome-remote-debugging.test.mjs +66 -0
- package/test/duckduckgo/experiment.test.mjs +28 -0
- package/test/duckduckgo/setup.test.mjs +29 -0
- package/test/manual/debug-locate-response.js +82 -0
- package/test/manual/reconnect-provision.test.mjs +49 -0
- package/test/manual/test-console-logs.test.mjs +42 -0
- package/test/manual/test-find-api.js +73 -0
- package/test/manual/test-init.sh +54 -0
- package/test/manual/test-prompt-cache.js +97 -0
- package/test/manual/test-provision-auth.mjs +22 -0
- package/test/manual/test-sandbox-render.js +29 -0
- package/test/manual/test-sdk-methods.js +15 -0
- package/test/manual/test-sdk-refactor.js +53 -0
- package/test/manual/test-stack-trace.mjs +57 -0
- package/test/manual/verify-element-api.js +89 -0
- package/test/manual/verify-types.js +0 -0
- package/test/manual-unawaited-promise.test.mjs +31 -0
- package/test-ide-preview.mjs +17 -0
- package/tests/airbnb-booking.test.mjs +39 -0
- package/tests/airbnb-search.test.mjs +43 -0
- package/tests/example.test.js +33 -0
- package/tests/login.js +28 -0
- package/vitest.config.mjs +24 -0
- package/vscode-extension/.vscodeignore +12 -0
- package/vscode-extension/README.md +94 -0
- package/vscode-extension/media/icon.png +0 -0
- package/vscode-extension/package-lock.json +4126 -0
- package/vscode-extension/package.json +86 -0
- package/vscode-extension/src/extension.ts +829 -0
- package/vscode-extension/testdriverai-0.1.0.vsix +0 -0
- package/vscode-extension/tsconfig.json +16 -0
- package/ai/skills/testdriver:examples/SKILL.md +0 -7
- package/ai/skills/testdriver:mcp-workflow/SKILL.md +0 -410
- package/ai/skills/testdriver:testdriver/SKILL.md +0 -523
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test Init Command
|
|
5
|
+
*
|
|
6
|
+
* This script tests the `testdriverai init` command by:
|
|
7
|
+
* 1. Creating a temporary test project
|
|
8
|
+
* 2. Running the init command
|
|
9
|
+
* 3. Verifying all files were created correctly
|
|
10
|
+
* 4. Running the generated test
|
|
11
|
+
* 5. Cleaning up
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* node manual/test-init-command.js
|
|
15
|
+
*
|
|
16
|
+
* Requirements:
|
|
17
|
+
* - TD_API_KEY environment variable must be set
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
const fs = require('fs');
|
|
21
|
+
const path = require('path');
|
|
22
|
+
const { execSync } = require('child_process');
|
|
23
|
+
const os = require('os');
|
|
24
|
+
|
|
25
|
+
// Colors for terminal output
|
|
26
|
+
const colors = {
|
|
27
|
+
reset: '\x1b[0m',
|
|
28
|
+
green: '\x1b[32m',
|
|
29
|
+
red: '\x1b[31m',
|
|
30
|
+
cyan: '\x1b[36m',
|
|
31
|
+
yellow: '\x1b[33m',
|
|
32
|
+
gray: '\x1b[90m',
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
function log(message, color = 'reset') {
|
|
36
|
+
console.log(`${colors[color]}${message}${colors.reset}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function success(message) {
|
|
40
|
+
log(`✓ ${message}`, 'green');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function error(message) {
|
|
44
|
+
log(`✗ ${message}`, 'red');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function info(message) {
|
|
48
|
+
log(message, 'cyan');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function step(message) {
|
|
52
|
+
log(`\n${message}`, 'cyan');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Main test function
|
|
56
|
+
async function testInitCommand() {
|
|
57
|
+
// Check for API key
|
|
58
|
+
if (!process.env.TD_API_KEY) {
|
|
59
|
+
error('TD_API_KEY environment variable is required');
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const testDir = path.join(os.tmpdir(), `test-init-${Date.now()}`);
|
|
64
|
+
const cliPath = path.join(__dirname, '..');
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
step('📦 Creating test directory...');
|
|
68
|
+
fs.mkdirSync(testDir, { recursive: true });
|
|
69
|
+
success(`Created: ${testDir}`);
|
|
70
|
+
|
|
71
|
+
step('🔧 Setting up .env file...');
|
|
72
|
+
const envContent = `TD_API_KEY=${process.env.TD_API_KEY}\n`;
|
|
73
|
+
fs.writeFileSync(path.join(testDir, '.env'), envContent);
|
|
74
|
+
success('Created .env with API key');
|
|
75
|
+
|
|
76
|
+
step('🚀 Running init command...');
|
|
77
|
+
try {
|
|
78
|
+
execSync(`node ${path.join(cliPath, 'bin/testdriverai.js')} init`, {
|
|
79
|
+
cwd: testDir,
|
|
80
|
+
stdio: 'inherit',
|
|
81
|
+
env: { ...process.env, TD_API_KEY: process.env.TD_API_KEY }
|
|
82
|
+
});
|
|
83
|
+
success('Init command completed');
|
|
84
|
+
} catch (err) {
|
|
85
|
+
error('Init command failed');
|
|
86
|
+
throw err;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
step('🔍 Verifying project structure...');
|
|
90
|
+
|
|
91
|
+
const expectedFiles = [
|
|
92
|
+
'package.json',
|
|
93
|
+
'vitest.config.js',
|
|
94
|
+
'tests/example.test.js',
|
|
95
|
+
'tests/login.js',
|
|
96
|
+
'.env',
|
|
97
|
+
'.gitignore',
|
|
98
|
+
'.github/workflows/testdriver.yml'
|
|
99
|
+
];
|
|
100
|
+
|
|
101
|
+
for (const file of expectedFiles) {
|
|
102
|
+
const filePath = path.join(testDir, file);
|
|
103
|
+
if (!fs.existsSync(filePath)) {
|
|
104
|
+
error(`Missing file: ${file}`);
|
|
105
|
+
throw new Error(`Expected file not found: ${file}`);
|
|
106
|
+
}
|
|
107
|
+
success(`Found: ${file}`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
step('📝 Verifying vitest.config.js contents...');
|
|
111
|
+
const vitestConfig = fs.readFileSync(path.join(testDir, 'vitest.config.js'), 'utf8');
|
|
112
|
+
|
|
113
|
+
if (!vitestConfig.includes('TestDriver()')) {
|
|
114
|
+
error('TestDriver reporter not found in vitest.config.js');
|
|
115
|
+
console.log(vitestConfig);
|
|
116
|
+
throw new Error('TestDriver reporter not configured');
|
|
117
|
+
}
|
|
118
|
+
success('TestDriver reporter is configured');
|
|
119
|
+
|
|
120
|
+
if (!vitestConfig.includes('setupFiles') || !vitestConfig.includes('testdriverai/vitest/setup')) {
|
|
121
|
+
error('setupFiles not configured correctly');
|
|
122
|
+
console.log(vitestConfig);
|
|
123
|
+
throw new Error('setupFiles not configured');
|
|
124
|
+
}
|
|
125
|
+
success('setupFiles is configured correctly');
|
|
126
|
+
|
|
127
|
+
if (!vitestConfig.includes('reporters')) {
|
|
128
|
+
error('reporters array not found');
|
|
129
|
+
console.log(vitestConfig);
|
|
130
|
+
throw new Error('reporters not configured');
|
|
131
|
+
}
|
|
132
|
+
success('reporters array includes TestDriver');
|
|
133
|
+
|
|
134
|
+
step('📝 Verifying example test contents...');
|
|
135
|
+
const testFile = fs.readFileSync(path.join(testDir, 'tests/example.test.js'), 'utf8');
|
|
136
|
+
|
|
137
|
+
if (!testFile.includes('.provision.chrome')) {
|
|
138
|
+
error('Test does not use .provision.chrome');
|
|
139
|
+
console.log(testFile);
|
|
140
|
+
throw new Error('Test does not use .provision pattern');
|
|
141
|
+
}
|
|
142
|
+
success('Test uses .provision.chrome');
|
|
143
|
+
|
|
144
|
+
if (!testFile.includes("from 'testdriverai/vitest/hooks'")) {
|
|
145
|
+
error('Test does not import from testdriverai/vitest/hooks');
|
|
146
|
+
console.log(testFile);
|
|
147
|
+
throw new Error('Test does not import TestDriver from vitest/hooks');
|
|
148
|
+
}
|
|
149
|
+
success('Test imports TestDriver from vitest/hooks');
|
|
150
|
+
|
|
151
|
+
if (!testFile.includes("from './login.js'")) {
|
|
152
|
+
error('Test does not import login from ./login.js');
|
|
153
|
+
console.log(testFile);
|
|
154
|
+
throw new Error('Test does not import login snippet');
|
|
155
|
+
}
|
|
156
|
+
success('Test imports login snippet');
|
|
157
|
+
|
|
158
|
+
step('📝 Verifying login snippet contents...');
|
|
159
|
+
const loginFile = fs.readFileSync(path.join(testDir, 'tests/login.js'), 'utf8');
|
|
160
|
+
|
|
161
|
+
if (!loginFile.includes('.extract(')) {
|
|
162
|
+
error('Login snippet does not use .extract()');
|
|
163
|
+
console.log(loginFile);
|
|
164
|
+
throw new Error('Login snippet does not demonstrate .extract()');
|
|
165
|
+
}
|
|
166
|
+
success('Login snippet demonstrates .extract()');
|
|
167
|
+
|
|
168
|
+
if (!loginFile.includes('secret: true')) {
|
|
169
|
+
error('Login snippet does not use secret option');
|
|
170
|
+
console.log(loginFile);
|
|
171
|
+
throw new Error('Login snippet does not demonstrate secret typing');
|
|
172
|
+
}
|
|
173
|
+
success('Login snippet demonstrates secret typing');
|
|
174
|
+
|
|
175
|
+
step('🧪 Running generated test...');
|
|
176
|
+
try {
|
|
177
|
+
execSync('npm test', {
|
|
178
|
+
cwd: testDir,
|
|
179
|
+
stdio: 'inherit',
|
|
180
|
+
env: { ...process.env, TD_API_KEY: process.env.TD_API_KEY }
|
|
181
|
+
});
|
|
182
|
+
success('Test execution completed successfully');
|
|
183
|
+
} catch (err) {
|
|
184
|
+
error('Test execution failed');
|
|
185
|
+
throw err;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
step('✅ All checks passed!');
|
|
189
|
+
log('\nTest summary:', 'green');
|
|
190
|
+
log(' • Init command executed successfully', 'green');
|
|
191
|
+
log(' • All expected files created', 'green');
|
|
192
|
+
log(' • Configuration files are correct', 'green');
|
|
193
|
+
log(' • Example test has proper patterns', 'green');
|
|
194
|
+
log(' • Generated test runs successfully', 'green');
|
|
195
|
+
|
|
196
|
+
} catch (err) {
|
|
197
|
+
step('❌ Test failed!');
|
|
198
|
+
error(err.message);
|
|
199
|
+
if (err.stack) {
|
|
200
|
+
log(err.stack, 'gray');
|
|
201
|
+
}
|
|
202
|
+
process.exit(1);
|
|
203
|
+
} finally {
|
|
204
|
+
// Optional: Clean up test directory
|
|
205
|
+
// Commented out so you can inspect the generated files
|
|
206
|
+
// step('🧹 Cleaning up...');
|
|
207
|
+
// if (fs.existsSync(testDir)) {
|
|
208
|
+
// fs.rmSync(testDir, { recursive: true, force: true });
|
|
209
|
+
// success('Cleaned up test directory');
|
|
210
|
+
// }
|
|
211
|
+
|
|
212
|
+
info(`\nTest project preserved at: ${testDir}`);
|
|
213
|
+
info('To clean up manually, run:');
|
|
214
|
+
log(` rm -rf ${testDir}`, 'gray');
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Run the test
|
|
219
|
+
testInitCommand().catch(err => {
|
|
220
|
+
error('Unexpected error:');
|
|
221
|
+
console.error(err);
|
|
222
|
+
process.exit(1);
|
|
223
|
+
});
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
# TestDriver MCP Server
|
|
2
|
+
|
|
3
|
+
MCP server that enables AI agents to iteratively build TestDriver tests with visual feedback.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Live Session Control**: Direct sandbox control via MCP tools
|
|
8
|
+
- **Visual Feedback**: Every action returns a screenshot with overlays (MCP Apps)
|
|
9
|
+
- **Inline Code Generation**: Each action returns the code to append to your test file
|
|
10
|
+
- **Assertions**: AI-powered assertions about screen state
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
### Via npx (Recommended)
|
|
15
|
+
|
|
16
|
+
No installation needed! Just configure your MCP client to use npx:
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"inputs": [
|
|
21
|
+
{
|
|
22
|
+
"type": "promptString",
|
|
23
|
+
"id": "testdriver-api-key",
|
|
24
|
+
"description": "TestDriver API Key From https://console.testdriver.ai/team",
|
|
25
|
+
"password": true
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"servers": {
|
|
29
|
+
"testdriver": {
|
|
30
|
+
"command": "npx",
|
|
31
|
+
"args": ["-p", "testdriverai", "testdriverai-mcp"],
|
|
32
|
+
"env": {
|
|
33
|
+
"TD_API_KEY": "${input:testdriver-api-key}"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### From Source
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
cd mcp-server
|
|
44
|
+
npm install
|
|
45
|
+
npm run build
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Usage
|
|
49
|
+
|
|
50
|
+
### With GitHub Copilot Coding Agent
|
|
51
|
+
|
|
52
|
+
To use the TestDriver MCP server with GitHub Copilot coding agent:
|
|
53
|
+
|
|
54
|
+
1. **Create a Copilot environment secret:**
|
|
55
|
+
- Go to your repository **Settings** → **Environments**
|
|
56
|
+
- Create or select the `copilot` environment
|
|
57
|
+
- Add an environment secret named `COPILOT_MCP_TD_API_KEY`
|
|
58
|
+
- Set the value to your TestDriver API key from https://console.testdriver.ai/team
|
|
59
|
+
|
|
60
|
+
2. **Add the MCP configuration** to your repository's **Settings** → **Copilot** → **Coding agent** → **MCP configuration**:
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"mcpServers": {
|
|
65
|
+
"testdriver": {
|
|
66
|
+
"type": "local",
|
|
67
|
+
"command": "npx",
|
|
68
|
+
"args": ["-p", "testdriverai", "testdriverai-mcp"],
|
|
69
|
+
"tools": ["*"],
|
|
70
|
+
"env": {
|
|
71
|
+
"TD_API_KEY": "COPILOT_MCP_TD_API_KEY"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Note:** The MCP server supports both `TD_API_KEY` and `COPILOT_MCP_TD_API_KEY` environment variables for maximum compatibility with GitHub Copilot coding agent.
|
|
79
|
+
|
|
80
|
+
For more information, see [Extending GitHub Copilot coding agent with Model Context Protocol](https://docs.github.com/en/copilot/customizing-copilot/extending-copilot-coding-agent-with-mcp).
|
|
81
|
+
|
|
82
|
+
### With Claude Desktop / Cursor
|
|
83
|
+
|
|
84
|
+
Add to your MCP config (`~/.cursor/mcp.json` or `~/Library/Application Support/Claude/claude_desktop_config.json`):
|
|
85
|
+
|
|
86
|
+
**Using npx (recommended):**
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"inputs": [
|
|
91
|
+
{
|
|
92
|
+
"type": "promptString",
|
|
93
|
+
"id": "testdriver-api-key",
|
|
94
|
+
"description": "TestDriver API Key From https://console.testdriver.ai/team",
|
|
95
|
+
"password": true
|
|
96
|
+
}
|
|
97
|
+
],
|
|
98
|
+
"servers": {
|
|
99
|
+
"testdriver": {
|
|
100
|
+
"command": "npx",
|
|
101
|
+
"args": ["-p", "testdriverai", "testdriverai-mcp"],
|
|
102
|
+
"env": {
|
|
103
|
+
"TD_API_KEY": "${input:testdriver-api-key}"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Using local build:**
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"inputs": [
|
|
115
|
+
{
|
|
116
|
+
"type": "promptString",
|
|
117
|
+
"id": "testdriver-api-key",
|
|
118
|
+
"description": "TestDriver API Key From https://console.testdriver.ai/team",
|
|
119
|
+
"password": true
|
|
120
|
+
}
|
|
121
|
+
],
|
|
122
|
+
"servers": {
|
|
123
|
+
"testdriver": {
|
|
124
|
+
"command": "node",
|
|
125
|
+
"args": ["/path/to/testdriverai/mcp-server/dist/server.js"],
|
|
126
|
+
"env": {
|
|
127
|
+
"TD_API_KEY": "${input:testdriver-api-key}"
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### API Endpoint Configuration
|
|
135
|
+
|
|
136
|
+
The API endpoint can be configured in three ways (in order of precedence):
|
|
137
|
+
|
|
138
|
+
1. **Per-session**: Pass `apiRoot` to `session_start` tool
|
|
139
|
+
2. **Environment variable**: Set `TD_API_ROOT` in your MCP config
|
|
140
|
+
3. **Default**: `https://testdriver-api.onrender.com`
|
|
141
|
+
|
|
142
|
+
Common values:
|
|
143
|
+
- **Production**: `https://testdriver-api.onrender.com`
|
|
144
|
+
- **Local dev**: Your ngrok URL (e.g., `https://abc123.ngrok.io`)
|
|
145
|
+
|
|
146
|
+
### Self-Hosted AWS Instances
|
|
147
|
+
|
|
148
|
+
Connect to your own AWS-hosted Windows instances instead of using TestDriver cloud:
|
|
149
|
+
|
|
150
|
+
1. **Deploy AWS Infrastructure**: Use the [CloudFormation template](https://docs.testdriver.ai/v7/aws-setup) to set up VPC, security groups, and launch templates
|
|
151
|
+
|
|
152
|
+
2. **Spawn an instance**: Use `spawn-runner.sh` to launch an EC2 instance:
|
|
153
|
+
```bash
|
|
154
|
+
AWS_REGION=us-east-2 \
|
|
155
|
+
AMI_ID=ami-0504bf50fad62f312 \
|
|
156
|
+
AWS_LAUNCH_TEMPLATE_ID=lt-xxx \
|
|
157
|
+
bash setup/aws/spawn-runner.sh
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
3. **Connect via MCP**: Pass the IP to `session_start`:
|
|
161
|
+
```json
|
|
162
|
+
{
|
|
163
|
+
"type": "chrome",
|
|
164
|
+
"url": "https://example.com",
|
|
165
|
+
"os": "windows",
|
|
166
|
+
"ip": "1.2.3.4"
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Or set `TD_IP` environment variable:
|
|
171
|
+
```json
|
|
172
|
+
{
|
|
173
|
+
"inputs": [
|
|
174
|
+
{
|
|
175
|
+
"type": "promptString",
|
|
176
|
+
"id": "testdriver-api-key",
|
|
177
|
+
"description": "TestDriver API Key From https://console.testdriver.ai/team",
|
|
178
|
+
"password": true
|
|
179
|
+
}
|
|
180
|
+
],
|
|
181
|
+
"servers": {
|
|
182
|
+
"testdriver": {
|
|
183
|
+
"command": "node",
|
|
184
|
+
"args": ["/path/to/mcp-server/dist/server.js"],
|
|
185
|
+
"env": {
|
|
186
|
+
"TD_API_KEY": "${input:testdriver-api-key}",
|
|
187
|
+
"TD_IP": "1.2.3.4"
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Benefits of self-hosted:**
|
|
195
|
+
- Flat license fee (no device-second metering)
|
|
196
|
+
- Use your own AI API keys
|
|
197
|
+
- Custom hardware and software configurations
|
|
198
|
+
- Full RDP access for debugging
|
|
199
|
+
|
|
200
|
+
### Development
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
# Run in development mode with auto-reload
|
|
204
|
+
npm run dev
|
|
205
|
+
|
|
206
|
+
# Build for production
|
|
207
|
+
npm run build
|
|
208
|
+
|
|
209
|
+
# Start production server
|
|
210
|
+
npm start
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Tools
|
|
214
|
+
|
|
215
|
+
### Session Management
|
|
216
|
+
|
|
217
|
+
| Tool | Description |
|
|
218
|
+
|------|-------------|
|
|
219
|
+
| `session_start` | Start a new session and provision sandbox |
|
|
220
|
+
| `session_status` | Check session health and time remaining |
|
|
221
|
+
| `session_extend` | Extend session keepAlive time |
|
|
222
|
+
|
|
223
|
+
### Element Interaction
|
|
224
|
+
|
|
225
|
+
| Tool | Description |
|
|
226
|
+
|------|-------------|
|
|
227
|
+
| `find` | Find element by natural language description |
|
|
228
|
+
| `click` | Click on element or coordinates |
|
|
229
|
+
| `find_and_click` | Find and click in one action |
|
|
230
|
+
| `type` | Type text into focused field |
|
|
231
|
+
| `press_keys` | Press keyboard shortcuts |
|
|
232
|
+
| `scroll` | Scroll the page |
|
|
233
|
+
|
|
234
|
+
### Verification
|
|
235
|
+
|
|
236
|
+
| Tool | Description |
|
|
237
|
+
|------|-------------|
|
|
238
|
+
| `assert` | AI-powered assertion about screen state |
|
|
239
|
+
| `check` | AI analyzes screen state (for agent understanding, no code generated) |
|
|
240
|
+
| `exec` | Execute code in sandbox |
|
|
241
|
+
| `screenshot` | Capture screenshot (displays to user only) |
|
|
242
|
+
|
|
243
|
+
### Local Screenshots
|
|
244
|
+
|
|
245
|
+
| Tool | Description |
|
|
246
|
+
|------|-------------|
|
|
247
|
+
| `list_local_screenshots` | List screenshots saved in `.testdriver` directory |
|
|
248
|
+
| `view_local_screenshot` | View a local screenshot (returns image to AI + displays to user) |
|
|
249
|
+
|
|
250
|
+
The local screenshot tools allow AI agents to review screenshots from previous test runs:
|
|
251
|
+
|
|
252
|
+
```
|
|
253
|
+
1. Call list_local_screenshots to see available screenshots
|
|
254
|
+
2. Call view_local_screenshot with a path to view and analyze it
|
|
255
|
+
3. The image is returned to the AI (if the client supports images) AND displayed to the user
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
This is useful for:
|
|
259
|
+
- Debugging test failures by examining saved screenshots
|
|
260
|
+
- Reviewing test execution history
|
|
261
|
+
- Comparing current screen state to previous runs
|
|
262
|
+
|
|
263
|
+
## Workflow
|
|
264
|
+
|
|
265
|
+
1. **Start Session**: `session_start` provisions a sandbox with browser/app
|
|
266
|
+
2. **Interact**: Use `find`, `click`, `type` etc. - each action returns generated code
|
|
267
|
+
3. **Build Test**: Append the generated code from each action to your test file
|
|
268
|
+
4. **Assert**: Use `assert` to verify expected state
|
|
269
|
+
5. **Run Test**: Use the CLI (`vitest run <testFile>`) to run the test from scratch
|
|
270
|
+
|
|
271
|
+
Each tool returns a screenshot showing the result AND the code to add to your test file.
|
|
272
|
+
|
|
273
|
+
## Architecture
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
┌─────────────────────────────────────────────────────┐
|
|
277
|
+
│ MCP Server │
|
|
278
|
+
├─────────────────────────────────────────────────────┤
|
|
279
|
+
│ │
|
|
280
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌────────────┐ │
|
|
281
|
+
│ │ Tools │ │ Session │ │ CodeGen │ │
|
|
282
|
+
│ │ (find, │ │ Manager │ │ (inline │ │
|
|
283
|
+
│ │ click, │ │ (state, │ │ code │ │
|
|
284
|
+
│ │ type...) │ │ expiry) │ │ output) │ │
|
|
285
|
+
│ └──────┬──────┘ └──────┬──────┘ └─────┬──────┘ │
|
|
286
|
+
│ │ │ │ │
|
|
287
|
+
│ └────────────────┼───────────────┘ │
|
|
288
|
+
│ │ │
|
|
289
|
+
│ ┌───────────────────────┴───────────────────────┐ │
|
|
290
|
+
│ │ TestDriver SDK │ │
|
|
291
|
+
│ │ (sandbox control, AI vision) │ │
|
|
292
|
+
│ └───────────────────────────────────────────────┘ │
|
|
293
|
+
│ │ │
|
|
294
|
+
└──────────────────────────┼─────────────────────────┘
|
|
295
|
+
│
|
|
296
|
+
▼
|
|
297
|
+
┌──────────────┐
|
|
298
|
+
│ Sandbox │
|
|
299
|
+
│ (VM + app) │
|
|
300
|
+
└──────────────┘
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
## MCP Apps Integration
|
|
304
|
+
|
|
305
|
+
Every action tool returns a rich UI via MCP Apps showing:
|
|
306
|
+
|
|
307
|
+
- Screenshot of current screen
|
|
308
|
+
- Element highlights (for `find`)
|
|
309
|
+
- Click markers (for `click`)
|
|
310
|
+
- Scroll indicators (for `scroll`)
|
|
311
|
+
- Action status and duration
|
|
312
|
+
- Session info and time remaining
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<meta name="color-scheme" content="light dark">
|
|
7
|
+
<title>TestDriver Screenshot</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<main class="main">
|
|
11
|
+
<div class="screenshot-wrapper">
|
|
12
|
+
<div class="loading-overlay" id="loading-overlay">
|
|
13
|
+
<div class="loading-spinner"></div>
|
|
14
|
+
<span class="loading-text">Waiting for screenshot...</span>
|
|
15
|
+
</div>
|
|
16
|
+
<div class="screenshot-container" id="screenshot-container" style="display: none;">
|
|
17
|
+
<img id="screenshot" alt="Screenshot" />
|
|
18
|
+
<div id="overlays"></div>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
<div class="status-bar">
|
|
22
|
+
<span id="action-status"></span>
|
|
23
|
+
<span id="session-info"></span>
|
|
24
|
+
</div>
|
|
25
|
+
</main>
|
|
26
|
+
<script type="module" src="/src/mcp-app.ts"></script>
|
|
27
|
+
</body>
|
|
28
|
+
</html>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"inputs": [
|
|
3
|
+
{
|
|
4
|
+
"type": "promptString",
|
|
5
|
+
"id": "testdriver-api-key",
|
|
6
|
+
"description": "TestDriver API Key From https://console.testdriver.ai/team",
|
|
7
|
+
"password": true
|
|
8
|
+
}
|
|
9
|
+
],
|
|
10
|
+
"servers": {
|
|
11
|
+
"testdriver": {
|
|
12
|
+
"command": "npx",
|
|
13
|
+
"args": ["-p", "testdriverai", "testdriverai-mcp"],
|
|
14
|
+
"env": {
|
|
15
|
+
"TD_API_KEY": "${input:testdriver-api-key}"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|