@testdriverai/agent 7.8.0-test.38
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/.prettierignore +4 -0
- package/.prettierrc +1 -0
- package/CHANGELOG.md +953 -0
- package/README.md +81 -0
- package/agent/events.js +135 -0
- package/agent/index.js +2450 -0
- package/agent/interface.js +35 -0
- package/agent/lib/analytics.js +22 -0
- package/agent/lib/censorship.js +75 -0
- package/agent/lib/commander.js +246 -0
- package/agent/lib/commands.js +1684 -0
- package/agent/lib/config.js +60 -0
- package/agent/lib/generator.js +91 -0
- package/agent/lib/http.js +144 -0
- package/agent/lib/logger.js +56 -0
- package/agent/lib/outputs.js +29 -0
- package/agent/lib/parser.js +209 -0
- package/agent/lib/redraw.js +386 -0
- package/agent/lib/resources/cursor-2.png +0 -0
- package/agent/lib/sandbox.js +1104 -0
- package/agent/lib/sdk.js +633 -0
- package/agent/lib/session.js +25 -0
- package/agent/lib/source-mapper.js +342 -0
- package/agent/lib/subimage/index.js +77 -0
- package/agent/lib/subimage/opencv.js +69 -0
- package/agent/lib/system.js +204 -0
- package/agent/lib/theme.js +14 -0
- package/agent/lib/valid-version.js +21 -0
- package/agent/lib/validation.js +169 -0
- package/ai/.claude-plugin/plugin.json +9 -0
- package/ai/agents/testdriver.md +638 -0
- package/ai/skills/testdriver-ai/SKILL.md +204 -0
- package/ai/skills/testdriver-assert/SKILL.md +315 -0
- package/ai/skills/testdriver-aws-setup/SKILL.md +448 -0
- package/ai/skills/testdriver-cache/SKILL.md +221 -0
- package/ai/skills/testdriver-caching/SKILL.md +124 -0
- package/ai/skills/testdriver-captcha/SKILL.md +158 -0
- package/ai/skills/testdriver-ci-cd/SKILL.md +602 -0
- package/ai/skills/testdriver-click/SKILL.md +286 -0
- package/ai/skills/testdriver-client/SKILL.md +477 -0
- package/ai/skills/testdriver-cloud/SKILL.md +119 -0
- package/ai/skills/testdriver-customizing-devices/SKILL.md +319 -0
- package/ai/skills/testdriver-dashcam/SKILL.md +418 -0
- package/ai/skills/testdriver-debugging-with-screenshots/SKILL.md +401 -0
- package/ai/skills/testdriver-device-config/SKILL.md +317 -0
- package/ai/skills/testdriver-double-click/SKILL.md +102 -0
- package/ai/skills/testdriver-elements/SKILL.md +605 -0
- package/ai/skills/testdriver-enterprise/SKILL.md +114 -0
- package/ai/skills/testdriver-errors/SKILL.md +246 -0
- package/ai/skills/testdriver-events/SKILL.md +356 -0
- package/ai/skills/testdriver-examples/SKILL.md +7 -0
- package/ai/skills/testdriver-exec/SKILL.md +317 -0
- package/ai/skills/testdriver-find/SKILL.md +829 -0
- package/ai/skills/testdriver-focus-application/SKILL.md +293 -0
- package/ai/skills/testdriver-generating-tests/SKILL.md +36 -0
- package/ai/skills/testdriver-hover/SKILL.md +278 -0
- package/ai/skills/testdriver-locating-elements/SKILL.md +71 -0
- package/ai/skills/testdriver-making-assertions/SKILL.md +32 -0
- package/ai/skills/testdriver-mcp/SKILL.md +7 -0
- package/ai/skills/testdriver-mcp-workflow/SKILL.md +410 -0
- package/ai/skills/testdriver-mouse-down/SKILL.md +161 -0
- package/ai/skills/testdriver-mouse-up/SKILL.md +164 -0
- package/ai/skills/testdriver-parse/SKILL.md +236 -0
- package/ai/skills/testdriver-performing-actions/SKILL.md +54 -0
- package/ai/skills/testdriver-press-keys/SKILL.md +348 -0
- package/ai/skills/testdriver-provision/SKILL.md +331 -0
- package/ai/skills/testdriver-quickstart/SKILL.md +144 -0
- package/ai/skills/testdriver-redraw/SKILL.md +214 -0
- package/ai/skills/testdriver-reusable-code/SKILL.md +249 -0
- package/ai/skills/testdriver-right-click/SKILL.md +123 -0
- package/ai/skills/testdriver-running-tests/SKILL.md +185 -0
- package/ai/skills/testdriver-screenshot/SKILL.md +248 -0
- package/ai/skills/testdriver-screenshots/SKILL.md +184 -0
- package/ai/skills/testdriver-scroll/SKILL.md +335 -0
- package/ai/skills/testdriver-secrets/SKILL.md +115 -0
- package/ai/skills/testdriver-self-hosted/SKILL.md +65 -0
- package/ai/skills/testdriver-test-writer/SKILL.md +448 -0
- package/ai/skills/testdriver-testdriver/SKILL.md +628 -0
- package/ai/skills/testdriver-testdriver-mechanic/SKILL.md +165 -0
- package/ai/skills/testdriver-type/SKILL.md +357 -0
- package/ai/skills/testdriver-variables/SKILL.md +111 -0
- package/ai/skills/testdriver-wait/SKILL.md +50 -0
- package/ai/skills/testdriver-waiting-for-elements/SKILL.md +90 -0
- package/ai/skills/testdriver-what-is-testdriver/SKILL.md +54 -0
- package/bin/testdriverai.js +22 -0
- package/debugger/bg.png +0 -0
- package/debugger/icon.png +0 -0
- package/debugger/index.html +469 -0
- package/debugger/td.png +0 -0
- package/debugger/tray-buffered.png +0 -0
- package/debugger/tray.png +0 -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/_data/examples-manifest.json +177 -0
- package/docs/_data/examples-manifest.schema.json +41 -0
- package/docs/_scripts/extract-example-urls.js +165 -0
- package/docs/_scripts/generate-examples.js +560 -0
- package/docs/_scripts/generate-skills.js +154 -0
- package/docs/_scripts/link-replacer.js +164 -0
- package/docs/_scripts/upload-docs-to-openai.js +284 -0
- package/docs/changelog.mdx +161 -0
- package/docs/claude-mcp-plugin.mdx +160 -0
- package/docs/docs.json +442 -0
- package/docs/github-integration-setup.md +266 -0
- package/docs/guide/best-practices-polling.mdx +174 -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/parse/output.png +0 -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/v7-chat.png +0 -0
- package/docs/images/content/vscode/v7-choose-agent.png +0 -0
- package/docs/images/content/vscode/v7-full.png +0 -0
- package/docs/images/content/vscode/v7-onboarding.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 +276 -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 +843 -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 +276 -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 +763 -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/docs/v7/ai.mdx +205 -0
- package/docs/v7/assert.mdx +316 -0
- package/docs/v7/aws-setup.mdx +449 -0
- package/docs/v7/cache.mdx +223 -0
- package/docs/v7/caching.mdx +128 -0
- package/docs/v7/captcha.mdx +159 -0
- package/docs/v7/ci-cd.mdx +603 -0
- package/docs/v7/click.mdx +287 -0
- package/docs/v7/client.mdx +478 -0
- package/docs/v7/copilot/auto-healing.mdx +265 -0
- package/docs/v7/copilot/creating-tests.mdx +156 -0
- package/docs/v7/copilot/github.mdx +143 -0
- package/docs/v7/copilot/running-tests.mdx +149 -0
- package/docs/v7/copilot/setup.mdx +143 -0
- package/docs/v7/customizing-devices.mdx +319 -0
- package/docs/v7/dashcam.mdx +419 -0
- package/docs/v7/debugging-with-screenshots.mdx +402 -0
- package/docs/v7/device-config.mdx +317 -0
- package/docs/v7/double-click.mdx +102 -0
- package/docs/v7/elements.mdx +606 -0
- package/docs/v7/enterprise.mdx +9 -0
- package/docs/v7/errors.mdx +248 -0
- package/docs/v7/events.mdx +358 -0
- package/docs/v7/examples/ai.mdx +72 -0
- package/docs/v7/examples/assert.mdx +72 -0
- package/docs/v7/examples/captcha-api.mdx +92 -0
- package/docs/v7/examples/chrome-extension.mdx +132 -0
- package/docs/v7/examples/drag-and-drop.mdx +100 -0
- package/docs/v7/examples/element-not-found.mdx +67 -0
- package/docs/v7/examples/exec-output.mdx +85 -0
- package/docs/v7/examples/exec-pwsh.mdx +83 -0
- package/docs/v7/examples/focus-window.mdx +62 -0
- package/docs/v7/examples/hover-image.mdx +94 -0
- package/docs/v7/examples/hover-text.mdx +69 -0
- package/docs/v7/examples/installer.mdx +91 -0
- package/docs/v7/examples/launch-vscode-linux.mdx +101 -0
- package/docs/v7/examples/match-image.mdx +96 -0
- package/docs/v7/examples/press-keys.mdx +92 -0
- package/docs/v7/examples/scroll-keyboard.mdx +79 -0
- package/docs/v7/examples/scroll-until-image.mdx +81 -0
- package/docs/v7/examples/scroll-until-text.mdx +109 -0
- package/docs/v7/examples/scroll.mdx +81 -0
- package/docs/v7/examples/type.mdx +92 -0
- package/docs/v7/examples/windows-installer.mdx +89 -0
- package/docs/v7/exec.mdx +318 -0
- package/docs/v7/find.mdx +830 -0
- package/docs/v7/focus-application.mdx +294 -0
- package/docs/v7/generating-tests.mdx +36 -0
- package/docs/v7/hosted.mdx +158 -0
- package/docs/v7/hover.mdx +279 -0
- package/docs/v7/locating-elements.mdx +71 -0
- package/docs/v7/making-assertions.mdx +32 -0
- package/docs/v7/mcp.mdx +9 -0
- package/docs/v7/mouse-down.mdx +161 -0
- package/docs/v7/mouse-up.mdx +164 -0
- package/docs/v7/parse.mdx +237 -0
- package/docs/v7/performing-actions.mdx +54 -0
- package/docs/v7/press-keys.mdx +349 -0
- package/docs/v7/provision.mdx +333 -0
- package/docs/v7/quickstart.mdx +173 -0
- package/docs/v7/redraw.mdx +216 -0
- package/docs/v7/reusable-code.mdx +249 -0
- package/docs/v7/right-click.mdx +123 -0
- package/docs/v7/running-tests.mdx +185 -0
- package/docs/v7/screenshot.mdx +249 -0
- package/docs/v7/screenshots.mdx +186 -0
- package/docs/v7/scroll.mdx +336 -0
- package/docs/v7/secrets.mdx +115 -0
- package/docs/v7/self-hosted.mdx +149 -0
- package/docs/v7/type.mdx +358 -0
- package/docs/v7/variables.mdx +111 -0
- package/docs/v7/wait.mdx +52 -0
- package/docs/v7/waiting-for-elements.mdx +90 -0
- package/docs/v7/what-is-testdriver.mdx +54 -0
- package/eslint.config.js +67 -0
- package/examples/ai.test.mjs +31 -0
- package/examples/assert.test.mjs +47 -0
- package/examples/chrome-extension.test.mjs +97 -0
- package/examples/config.mjs +5 -0
- package/examples/element-not-found.test.mjs +27 -0
- package/examples/exec-output.test.mjs +60 -0
- package/examples/exec-pwsh.test.mjs +58 -0
- package/examples/findall-coffee-icons.test.mjs +42 -0
- package/examples/focus-window.test.mjs +37 -0
- package/examples/formatted-logging.test.mjs +27 -0
- package/examples/hover-image.test.mjs +53 -0
- package/examples/hover-text-with-description.test.mjs +57 -0
- package/examples/hover-text.test.mjs +28 -0
- package/examples/installer.test.mjs +50 -0
- package/examples/launch-vscode-linux.test.mjs +55 -0
- package/examples/match-image.test.mjs +55 -0
- package/examples/parse.test.mjs +19 -0
- package/examples/press-keys.test.mjs +44 -0
- package/examples/prompt.test.mjs +34 -0
- package/examples/scroll-keyboard.test.mjs +38 -0
- package/examples/scroll-until-image.test.mjs +40 -0
- package/examples/scroll.test.mjs +42 -0
- package/examples/type.test.mjs +46 -0
- package/examples/windows-installer.test.mjs +54 -0
- package/index.js +2 -0
- package/interfaces/cli/commands/init.js +438 -0
- package/interfaces/cli/commands/setup.js +382 -0
- package/interfaces/cli/lib/base.js +285 -0
- package/interfaces/cli.js +20 -0
- package/interfaces/junit-reporter.js +290 -0
- package/interfaces/logger.js +388 -0
- package/interfaces/readline.js +234 -0
- package/interfaces/shared-test-state.mjs +64 -0
- package/interfaces/vitest-plugin.d.ts +115 -0
- package/interfaces/vitest-plugin.mjs +1698 -0
- package/lib/captcha/solver.js +358 -0
- package/lib/core/Dashcam.js +533 -0
- package/lib/core/index.d.ts +172 -0
- package/lib/core/index.js +12 -0
- package/lib/environments.json +18 -0
- package/lib/github-comment-formatter.js +263 -0
- package/lib/github-comment.mjs +452 -0
- package/lib/init-project.js +575 -0
- package/lib/presets/index.mjs +331 -0
- package/lib/resolve-channel.js +46 -0
- package/lib/sentry.js +417 -0
- package/lib/vitest/hooks.d.ts +57 -0
- package/lib/vitest/hooks.mjs +674 -0
- package/lib/vitest/setup-aws.mjs +247 -0
- package/lib/vitest/setup-self-hosted.mjs +151 -0
- package/lib/vitest/setup.mjs +46 -0
- package/manual/captcha-api.test.mjs +51 -0
- package/manual/drag-and-drop.test.mjs +59 -0
- package/manual/flake-diffthreshold-001.test.mjs +9 -0
- package/manual/flake-diffthreshold-01.test.mjs +9 -0
- package/manual/flake-diffthreshold-05.test.mjs +9 -0
- package/manual/flake-noredraw-cache.test.mjs +9 -0
- package/manual/flake-noredraw-nocache.test.mjs +9 -0
- package/manual/flake-redraw-cache.test.mjs +9 -0
- package/manual/flake-redraw-nocache.test.mjs +9 -0
- package/manual/flake-rocket-match.test.mjs +30 -0
- package/manual/flake-shared.mjs +51 -0
- package/manual/no-provision.test.mjs +31 -0
- package/manual/packer-hover-image.test.mjs +176 -0
- package/manual/scroll-until-text.test.mjs +68 -0
- package/manual/test-init-command.js +223 -0
- package/mcp-server/README.md +322 -0
- package/mcp-server/dist/codegen.d.ts +9 -0
- package/mcp-server/dist/codegen.js +165 -0
- package/mcp-server/dist/mcp-app.html +114 -0
- package/mcp-server/dist/package.json +1 -0
- package/mcp-server/dist/provision-types.d.ts +290 -0
- package/mcp-server/dist/provision-types.js +174 -0
- package/mcp-server/dist/server.d.ts +6 -0
- package/mcp-server/dist/server.mjs +1925 -0
- package/mcp-server/dist/session.d.ts +85 -0
- package/mcp-server/dist/session.js +152 -0
- package/mcp-server/mcp-app.html +28 -0
- package/mcp-server/mcp-config.example.json +19 -0
- package/mcp-server/package-lock.json +4027 -0
- package/mcp-server/package.json +31 -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 +2391 -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 +158 -0
- package/schema.json +1046 -0
- package/scripts/generate-skills.js +94 -0
- package/sdk-log-formatter.js +1157 -0
- package/sdk.d.ts +1486 -0
- package/sdk.js +4336 -0
- package/setup/aws/cloudformation.yaml +463 -0
- package/setup/aws/disable-defender.sh +42 -0
- package/setup/aws/install-dev-runner.sh +79 -0
- package/setup/aws/spawn-runner.sh +289 -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/vitest.config.mjs +58 -0
- package/vitest.runner.config.mjs +33 -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
|
@@ -0,0 +1,322 @@
|
|
|
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
|
+
### Quick Install (Recommended)
|
|
15
|
+
|
|
16
|
+
Use `add-mcp` to automatically configure TestDriver for your MCP client:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx add-mcp testdriver
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
This will prompt you to select your MCP client (VS Code, Cursor, Claude Desktop, etc.) and configure it automatically.
|
|
23
|
+
|
|
24
|
+
### Manual Configuration
|
|
25
|
+
|
|
26
|
+
If you prefer to configure manually, add the following to your MCP config file:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"inputs": [
|
|
31
|
+
{
|
|
32
|
+
"type": "promptString",
|
|
33
|
+
"id": "testdriver-api-key",
|
|
34
|
+
"description": "TestDriver API Key From https://console.testdriver.ai/team",
|
|
35
|
+
"password": true
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"servers": {
|
|
39
|
+
"testdriver": {
|
|
40
|
+
"command": "npx",
|
|
41
|
+
"args": ["-p", "testdriverai", "testdriverai-mcp"],
|
|
42
|
+
"env": {
|
|
43
|
+
"TD_API_KEY": "${input:testdriver-api-key}"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### From Source
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
cd mcp-server
|
|
54
|
+
npm install
|
|
55
|
+
npm run build
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Usage
|
|
59
|
+
|
|
60
|
+
### With GitHub Copilot Coding Agent
|
|
61
|
+
|
|
62
|
+
To use the TestDriver MCP server with GitHub Copilot coding agent:
|
|
63
|
+
|
|
64
|
+
1. **Create a Copilot environment secret:**
|
|
65
|
+
- Go to your repository **Settings** → **Environments**
|
|
66
|
+
- Create or select the `copilot` environment
|
|
67
|
+
- Add an environment secret named `COPILOT_MCP_TD_API_KEY`
|
|
68
|
+
- Set the value to your TestDriver API key from https://console.testdriver.ai/team
|
|
69
|
+
|
|
70
|
+
2. **Add the MCP configuration** to your repository's **Settings** → **Copilot** → **Coding agent** → **MCP configuration**:
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"mcpServers": {
|
|
75
|
+
"testdriver": {
|
|
76
|
+
"type": "local",
|
|
77
|
+
"command": "npx",
|
|
78
|
+
"args": ["-p", "testdriverai", "testdriverai-mcp"],
|
|
79
|
+
"tools": ["*"],
|
|
80
|
+
"env": {
|
|
81
|
+
"TD_API_KEY": "COPILOT_MCP_TD_API_KEY"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**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.
|
|
89
|
+
|
|
90
|
+
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).
|
|
91
|
+
|
|
92
|
+
### With Claude Desktop / Cursor
|
|
93
|
+
|
|
94
|
+
Add to your MCP config (`~/.cursor/mcp.json` or `~/Library/Application Support/Claude/claude_desktop_config.json`):
|
|
95
|
+
|
|
96
|
+
**Using npx (recommended):**
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"inputs": [
|
|
101
|
+
{
|
|
102
|
+
"type": "promptString",
|
|
103
|
+
"id": "testdriver-api-key",
|
|
104
|
+
"description": "TestDriver API Key From https://console.testdriver.ai/team",
|
|
105
|
+
"password": true
|
|
106
|
+
}
|
|
107
|
+
],
|
|
108
|
+
"servers": {
|
|
109
|
+
"testdriver": {
|
|
110
|
+
"command": "npx",
|
|
111
|
+
"args": ["-p", "testdriverai", "testdriverai-mcp"],
|
|
112
|
+
"env": {
|
|
113
|
+
"TD_API_KEY": "${input:testdriver-api-key}"
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Using local build:**
|
|
121
|
+
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
"inputs": [
|
|
125
|
+
{
|
|
126
|
+
"type": "promptString",
|
|
127
|
+
"id": "testdriver-api-key",
|
|
128
|
+
"description": "TestDriver API Key From https://console.testdriver.ai/team",
|
|
129
|
+
"password": true
|
|
130
|
+
}
|
|
131
|
+
],
|
|
132
|
+
"servers": {
|
|
133
|
+
"testdriver": {
|
|
134
|
+
"command": "node",
|
|
135
|
+
"args": ["/path/to/testdriverai/mcp-server/dist/server.js"],
|
|
136
|
+
"env": {
|
|
137
|
+
"TD_API_KEY": "${input:testdriver-api-key}"
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### API Endpoint Configuration
|
|
145
|
+
|
|
146
|
+
The API endpoint can be configured in three ways (in order of precedence):
|
|
147
|
+
|
|
148
|
+
1. **Per-session**: Pass `apiRoot` to `session_start` tool
|
|
149
|
+
2. **Environment variable**: Set `TD_API_ROOT` in your MCP config
|
|
150
|
+
3. **Default**: `https://api.testdriver.ai`
|
|
151
|
+
|
|
152
|
+
Common values:
|
|
153
|
+
- **Production**: `https://api.testdriver.ai`
|
|
154
|
+
- **Local dev**: Your ngrok URL (e.g., `https://abc123.ngrok.io`)
|
|
155
|
+
|
|
156
|
+
### Self-Hosted AWS Instances
|
|
157
|
+
|
|
158
|
+
Connect to your own AWS-hosted Windows instances instead of using TestDriver cloud:
|
|
159
|
+
|
|
160
|
+
1. **Deploy AWS Infrastructure**: Use the [CloudFormation template](https://docs.testdriver.ai/v7/aws-setup) to set up VPC, security groups, and launch templates
|
|
161
|
+
|
|
162
|
+
2. **Spawn an instance**: Use `spawn-runner.sh` to launch an EC2 instance:
|
|
163
|
+
```bash
|
|
164
|
+
AWS_REGION=us-east-2 \
|
|
165
|
+
AMI_ID=ami-0504bf50fad62f312 \
|
|
166
|
+
AWS_LAUNCH_TEMPLATE_ID=lt-xxx \
|
|
167
|
+
bash setup/aws/spawn-runner.sh
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
3. **Connect via MCP**: Pass the IP to `session_start`:
|
|
171
|
+
```json
|
|
172
|
+
{
|
|
173
|
+
"type": "chrome",
|
|
174
|
+
"url": "https://example.com",
|
|
175
|
+
"os": "windows",
|
|
176
|
+
"ip": "1.2.3.4"
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Or set `TD_IP` environment variable:
|
|
181
|
+
```json
|
|
182
|
+
{
|
|
183
|
+
"inputs": [
|
|
184
|
+
{
|
|
185
|
+
"type": "promptString",
|
|
186
|
+
"id": "testdriver-api-key",
|
|
187
|
+
"description": "TestDriver API Key From https://console.testdriver.ai/team",
|
|
188
|
+
"password": true
|
|
189
|
+
}
|
|
190
|
+
],
|
|
191
|
+
"servers": {
|
|
192
|
+
"testdriver": {
|
|
193
|
+
"command": "node",
|
|
194
|
+
"args": ["/path/to/mcp-server/dist/server.js"],
|
|
195
|
+
"env": {
|
|
196
|
+
"TD_API_KEY": "${input:testdriver-api-key}",
|
|
197
|
+
"TD_IP": "1.2.3.4"
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**Benefits of self-hosted:**
|
|
205
|
+
- Flat license fee (no device-second metering)
|
|
206
|
+
- Use your own AI API keys
|
|
207
|
+
- Custom hardware and software configurations
|
|
208
|
+
- Full RDP access for debugging
|
|
209
|
+
|
|
210
|
+
### Development
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
# Run in development mode with auto-reload
|
|
214
|
+
npm run dev
|
|
215
|
+
|
|
216
|
+
# Build for production
|
|
217
|
+
npm run build
|
|
218
|
+
|
|
219
|
+
# Start production server
|
|
220
|
+
npm start
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Tools
|
|
224
|
+
|
|
225
|
+
### Session Management
|
|
226
|
+
|
|
227
|
+
| Tool | Description |
|
|
228
|
+
|------|-------------|
|
|
229
|
+
| `session_start` | Start a new session and provision sandbox |
|
|
230
|
+
| `session_status` | Check session health and time remaining |
|
|
231
|
+
| `session_extend` | Extend session keepAlive time |
|
|
232
|
+
|
|
233
|
+
### Element Interaction
|
|
234
|
+
|
|
235
|
+
| Tool | Description |
|
|
236
|
+
|------|-------------|
|
|
237
|
+
| `find` | Find element by natural language description |
|
|
238
|
+
| `click` | Click on element or coordinates |
|
|
239
|
+
| `find_and_click` | Find and click in one action |
|
|
240
|
+
| `type` | Type text into focused field |
|
|
241
|
+
| `press_keys` | Press keyboard shortcuts |
|
|
242
|
+
| `scroll` | Scroll the page |
|
|
243
|
+
|
|
244
|
+
### Verification
|
|
245
|
+
|
|
246
|
+
| Tool | Description |
|
|
247
|
+
|------|-------------|
|
|
248
|
+
| `assert` | AI-powered assertion about screen state |
|
|
249
|
+
| `check` | AI analyzes screen state (for agent understanding, no code generated) |
|
|
250
|
+
| `exec` | Execute code in sandbox |
|
|
251
|
+
| `screenshot` | Capture screenshot (displays to user only) |
|
|
252
|
+
|
|
253
|
+
### Local Screenshots
|
|
254
|
+
|
|
255
|
+
| Tool | Description |
|
|
256
|
+
|------|-------------|
|
|
257
|
+
| `list_local_screenshots` | List screenshots saved in `.testdriver` directory |
|
|
258
|
+
| `view_local_screenshot` | View a local screenshot (returns image to AI + displays to user) |
|
|
259
|
+
|
|
260
|
+
The local screenshot tools allow AI agents to review screenshots from previous test runs:
|
|
261
|
+
|
|
262
|
+
```
|
|
263
|
+
1. Call list_local_screenshots to see available screenshots
|
|
264
|
+
2. Call view_local_screenshot with a path to view and analyze it
|
|
265
|
+
3. The image is returned to the AI (if the client supports images) AND displayed to the user
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
This is useful for:
|
|
269
|
+
- Debugging test failures by examining saved screenshots
|
|
270
|
+
- Reviewing test execution history
|
|
271
|
+
- Comparing current screen state to previous runs
|
|
272
|
+
|
|
273
|
+
## Workflow
|
|
274
|
+
|
|
275
|
+
1. **Start Session**: `session_start` provisions a sandbox with browser/app
|
|
276
|
+
2. **Interact**: Use `find`, `click`, `type` etc. - each action returns generated code
|
|
277
|
+
3. **Build Test**: Append the generated code from each action to your test file
|
|
278
|
+
4. **Assert**: Use `assert` to verify expected state
|
|
279
|
+
5. **Run Test**: Use the CLI (`vitest run <testFile>`) to run the test from scratch
|
|
280
|
+
|
|
281
|
+
Each tool returns a screenshot showing the result AND the code to add to your test file.
|
|
282
|
+
|
|
283
|
+
## Architecture
|
|
284
|
+
|
|
285
|
+
```
|
|
286
|
+
┌─────────────────────────────────────────────────────┐
|
|
287
|
+
│ MCP Server │
|
|
288
|
+
├─────────────────────────────────────────────────────┤
|
|
289
|
+
│ │
|
|
290
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌────────────┐ │
|
|
291
|
+
│ │ Tools │ │ Session │ │ CodeGen │ │
|
|
292
|
+
│ │ (find, │ │ Manager │ │ (inline │ │
|
|
293
|
+
│ │ click, │ │ (state, │ │ code │ │
|
|
294
|
+
│ │ type...) │ │ expiry) │ │ output) │ │
|
|
295
|
+
│ └──────┬──────┘ └──────┬──────┘ └─────┬──────┘ │
|
|
296
|
+
│ │ │ │ │
|
|
297
|
+
│ └────────────────┼───────────────┘ │
|
|
298
|
+
│ │ │
|
|
299
|
+
│ ┌───────────────────────┴───────────────────────┐ │
|
|
300
|
+
│ │ TestDriver SDK │ │
|
|
301
|
+
│ │ (sandbox control, AI vision) │ │
|
|
302
|
+
│ └───────────────────────────────────────────────┘ │
|
|
303
|
+
│ │ │
|
|
304
|
+
└──────────────────────────┼─────────────────────────┘
|
|
305
|
+
│
|
|
306
|
+
▼
|
|
307
|
+
┌──────────────┐
|
|
308
|
+
│ Sandbox │
|
|
309
|
+
│ (VM + app) │
|
|
310
|
+
└──────────────┘
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
## MCP Apps Integration
|
|
314
|
+
|
|
315
|
+
Every action tool returns a rich UI via MCP Apps showing:
|
|
316
|
+
|
|
317
|
+
- Screenshot of current screen
|
|
318
|
+
- Element highlights (for `find`)
|
|
319
|
+
- Click markers (for `click`)
|
|
320
|
+
- Scroll indicators (for `scroll`)
|
|
321
|
+
- Action status and duration
|
|
322
|
+
- Session info and time remaining
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code generation for TestDriver test files
|
|
3
|
+
* Generates code snippets for inline responses
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Generate code for a single action (for inline responses)
|
|
7
|
+
* Returns the code snippet that the agent should append to their test file
|
|
8
|
+
*/
|
|
9
|
+
export declare function generateActionCode(action: string, args: Record<string, unknown>, result?: Record<string, unknown>): string;
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code generation for TestDriver test files
|
|
3
|
+
* Generates code snippets for inline responses
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Escape string for JavaScript
|
|
7
|
+
*/
|
|
8
|
+
function escapeString(str) {
|
|
9
|
+
return str
|
|
10
|
+
.replace(/\\/g, "\\\\")
|
|
11
|
+
.replace(/"/g, '\\"')
|
|
12
|
+
.replace(/\n/g, "\\n")
|
|
13
|
+
.replace(/\r/g, "\\r")
|
|
14
|
+
.replace(/\t/g, "\\t");
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Generate code for a single action (for inline responses)
|
|
18
|
+
* Returns the code snippet that the agent should append to their test file
|
|
19
|
+
*/
|
|
20
|
+
export function generateActionCode(action, args, result) {
|
|
21
|
+
switch (action) {
|
|
22
|
+
case "provision.chrome": {
|
|
23
|
+
const url = args.url || "https://example.com";
|
|
24
|
+
const maximized = args.maximized;
|
|
25
|
+
const guest = args.guest;
|
|
26
|
+
const opts = [`url: "${escapeString(url)}"`];
|
|
27
|
+
if (maximized !== undefined)
|
|
28
|
+
opts.push(`maximized: ${maximized}`);
|
|
29
|
+
if (guest !== undefined)
|
|
30
|
+
opts.push(`guest: ${guest}`);
|
|
31
|
+
return `await testdriver.provision.chrome({ ${opts.join(", ")} });`;
|
|
32
|
+
}
|
|
33
|
+
case "provision.chromeExtension": {
|
|
34
|
+
const extensionPath = args.extensionPath;
|
|
35
|
+
const extensionId = args.extensionId;
|
|
36
|
+
const maximized = args.maximized;
|
|
37
|
+
const opts = [];
|
|
38
|
+
if (extensionPath)
|
|
39
|
+
opts.push(`extensionPath: "${escapeString(extensionPath)}"`);
|
|
40
|
+
if (extensionId)
|
|
41
|
+
opts.push(`extensionId: "${escapeString(extensionId)}"`);
|
|
42
|
+
if (maximized !== undefined)
|
|
43
|
+
opts.push(`maximized: ${maximized}`);
|
|
44
|
+
return `await testdriver.provision.chromeExtension({ ${opts.join(", ")} });`;
|
|
45
|
+
}
|
|
46
|
+
case "provision.vscode": {
|
|
47
|
+
const workspace = args.workspace;
|
|
48
|
+
const extensions = args.extensions;
|
|
49
|
+
const opts = [];
|
|
50
|
+
if (workspace)
|
|
51
|
+
opts.push(`workspace: "${escapeString(workspace)}"`);
|
|
52
|
+
if (extensions && extensions.length > 0) {
|
|
53
|
+
opts.push(`extensions: [${extensions.map(e => `"${escapeString(e)}"`).join(", ")}]`);
|
|
54
|
+
}
|
|
55
|
+
return `await testdriver.provision.vscode({ ${opts.join(", ")} });`;
|
|
56
|
+
}
|
|
57
|
+
case "provision.installer": {
|
|
58
|
+
const url = args.url;
|
|
59
|
+
const filename = args.filename;
|
|
60
|
+
const appName = args.appName;
|
|
61
|
+
const launch = args.launch;
|
|
62
|
+
const opts = [`url: "${escapeString(url)}"`];
|
|
63
|
+
if (filename)
|
|
64
|
+
opts.push(`filename: "${escapeString(filename)}"`);
|
|
65
|
+
if (appName)
|
|
66
|
+
opts.push(`appName: "${escapeString(appName)}"`);
|
|
67
|
+
if (launch !== undefined)
|
|
68
|
+
opts.push(`launch: ${launch}`);
|
|
69
|
+
return `await testdriver.provision.installer({ ${opts.join(", ")} });`;
|
|
70
|
+
}
|
|
71
|
+
case "provision.electron": {
|
|
72
|
+
const appPath = args.appPath;
|
|
73
|
+
const electronArgs = args.args;
|
|
74
|
+
const opts = [`appPath: "${escapeString(appPath)}"`];
|
|
75
|
+
if (electronArgs && electronArgs.length > 0) {
|
|
76
|
+
opts.push(`args: [${electronArgs.map(a => `"${escapeString(a)}"`).join(", ")}]`);
|
|
77
|
+
}
|
|
78
|
+
return `await testdriver.provision.electron({ ${opts.join(", ")} });`;
|
|
79
|
+
}
|
|
80
|
+
case "find": {
|
|
81
|
+
const description = args.description;
|
|
82
|
+
return `const element = await testdriver.find("${escapeString(description)}");`;
|
|
83
|
+
}
|
|
84
|
+
case "findall": {
|
|
85
|
+
const description = args.description;
|
|
86
|
+
return `const elements = await testdriver.findAll("${escapeString(description)}");`;
|
|
87
|
+
}
|
|
88
|
+
case "click": {
|
|
89
|
+
// When used after find, reference the element
|
|
90
|
+
const clickAction = args.action || "click";
|
|
91
|
+
if (clickAction === "click") {
|
|
92
|
+
return `await element.click();`;
|
|
93
|
+
}
|
|
94
|
+
else if (clickAction === "double-click") {
|
|
95
|
+
return `await element.doubleClick();`;
|
|
96
|
+
}
|
|
97
|
+
else if (clickAction === "right-click") {
|
|
98
|
+
return `await element.rightClick();`;
|
|
99
|
+
}
|
|
100
|
+
return `await element.click();`;
|
|
101
|
+
}
|
|
102
|
+
case "hover": {
|
|
103
|
+
return `await element.hover();`;
|
|
104
|
+
}
|
|
105
|
+
case "find_and_click": {
|
|
106
|
+
const description = args.description;
|
|
107
|
+
const clickAction = args.action || "click";
|
|
108
|
+
if (clickAction === "click") {
|
|
109
|
+
return `await testdriver.find("${escapeString(description)}").click();`;
|
|
110
|
+
}
|
|
111
|
+
else if (clickAction === "double-click") {
|
|
112
|
+
return `await testdriver.find("${escapeString(description)}").doubleClick();`;
|
|
113
|
+
}
|
|
114
|
+
else if (clickAction === "right-click") {
|
|
115
|
+
return `await testdriver.find("${escapeString(description)}").rightClick();`;
|
|
116
|
+
}
|
|
117
|
+
return `await testdriver.find("${escapeString(description)}").click();`;
|
|
118
|
+
}
|
|
119
|
+
case "type": {
|
|
120
|
+
const text = String(args.text);
|
|
121
|
+
const secret = args.secret;
|
|
122
|
+
if (secret) {
|
|
123
|
+
return `await testdriver.type(process.env.TD_SECRET || "", { secret: true });`;
|
|
124
|
+
}
|
|
125
|
+
return `await testdriver.type("${escapeString(text)}");`;
|
|
126
|
+
}
|
|
127
|
+
case "press_keys": {
|
|
128
|
+
const keys = args.keys;
|
|
129
|
+
return `await testdriver.pressKeys([${keys.map(k => `"${k}"`).join(", ")}]);`;
|
|
130
|
+
}
|
|
131
|
+
case "scroll": {
|
|
132
|
+
const direction = args.direction || "down";
|
|
133
|
+
const amount = args.amount;
|
|
134
|
+
if (amount) {
|
|
135
|
+
return `await testdriver.scroll("${direction}", { amount: ${amount} });`;
|
|
136
|
+
}
|
|
137
|
+
return `await testdriver.scroll("${direction}");`;
|
|
138
|
+
}
|
|
139
|
+
case "assert": {
|
|
140
|
+
const assertion = args.assertion;
|
|
141
|
+
return `const assertResult = await testdriver.assert("${escapeString(assertion)}");\nexpect(assertResult).toBeTruthy();`;
|
|
142
|
+
}
|
|
143
|
+
case "exec": {
|
|
144
|
+
const language = args.language || "sh";
|
|
145
|
+
const code = args.code;
|
|
146
|
+
const timeout = args.timeout;
|
|
147
|
+
if (code.includes("\n")) {
|
|
148
|
+
// Escape backticks and template literal interpolation syntax
|
|
149
|
+
const escapedCode = code.replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
150
|
+
return `await testdriver.exec("${language}", \`${escapedCode}\`${timeout ? `, ${timeout}` : ""});`;
|
|
151
|
+
}
|
|
152
|
+
return `await testdriver.exec("${language}", "${escapeString(code)}"${timeout ? `, ${timeout}` : ""});`;
|
|
153
|
+
}
|
|
154
|
+
case "wait": {
|
|
155
|
+
const timeout = args.timeout;
|
|
156
|
+
return `await testdriver.wait(${timeout});`;
|
|
157
|
+
}
|
|
158
|
+
case "focus_application": {
|
|
159
|
+
const name = args.name;
|
|
160
|
+
return `await testdriver.focusApplication("${escapeString(name)}");`;
|
|
161
|
+
}
|
|
162
|
+
default:
|
|
163
|
+
return `// Unknown action: ${action}`;
|
|
164
|
+
}
|
|
165
|
+
}
|