@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,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Reconnect Test Part 1: Provision
|
|
3
|
+
*
|
|
4
|
+
* This test provisions a new sandbox and navigates to the login page.
|
|
5
|
+
* The sandbox ID is saved to .testdriver/last-sandbox for the next test.
|
|
6
|
+
*
|
|
7
|
+
* The sandbox has keepAlive: 120000 (2 minutes) after disconnect.
|
|
8
|
+
* Run reconnect-signin.test.mjs within 2 minutes of this test completing.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* 1. npm test -- examples/reconnect-provision.test.mjs
|
|
12
|
+
* 2. (within 2 minutes) examples/reconnect-signin.test.mjs
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { afterAll, describe, expect, it } from "vitest";
|
|
16
|
+
import { TestDriver } from "../../lib/vitest/hooks.mjs";
|
|
17
|
+
|
|
18
|
+
describe("Reconnect Test - Part 1: Provision", () => {
|
|
19
|
+
|
|
20
|
+
afterAll(async () => {
|
|
21
|
+
// Explicitly DO NOT disconnect - we want the sandbox to stay alive
|
|
22
|
+
// for the reconnect test. The sandbox will auto-terminate after keepAlive TTL.
|
|
23
|
+
console.log("\n⚠️ NOT disconnecting - sandbox will stay alive for ~2 minutes (keepAlive: 120000)");
|
|
24
|
+
console.log(" Run reconnect-signin.test.mjs within 2 minutes to test reconnect\n");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("should provision sandbox and navigate to login page", async (context) => {
|
|
28
|
+
|
|
29
|
+
const testdriver = TestDriver(context, { newSandbox: true, headless: false });
|
|
30
|
+
|
|
31
|
+
// Provision Chrome and navigate to login page
|
|
32
|
+
await testdriver.provision.chrome({
|
|
33
|
+
url: 'http://testdriver-sandbox.vercel.app/login',
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
// Verify we're on the login page
|
|
38
|
+
const result = await testdriver.assert("I can see a Sign In button");
|
|
39
|
+
expect(result).toBeTruthy();
|
|
40
|
+
|
|
41
|
+
// Get the sandbox ID that was saved
|
|
42
|
+
const lastSandbox = testdriver.getLastSandboxId();
|
|
43
|
+
console.log("\n✅ Sandbox provisioned:", lastSandbox?.sandboxId);
|
|
44
|
+
console.log(" Sandbox info saved to .testdriver/last-sandbox");
|
|
45
|
+
|
|
46
|
+
expect(lastSandbox).toBeTruthy();
|
|
47
|
+
expect(lastSandbox.sandboxId).toBeTruthy();
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Console Log Test
|
|
3
|
+
* Tests that console.log statements are captured and sent to dashcam
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../../lib/vitest/hooks.mjs";
|
|
8
|
+
|
|
9
|
+
describe("Console Log Test", () => {
|
|
10
|
+
it("should capture console logs and send them to dashcam", async (context) => {
|
|
11
|
+
console.log("🎬 Test starting - this should appear in dashcam");
|
|
12
|
+
|
|
13
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
14
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
15
|
+
|
|
16
|
+
console.log("✅ Chrome launched successfully");
|
|
17
|
+
|
|
18
|
+
// Give Chrome a moment to fully render the UI
|
|
19
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
20
|
+
|
|
21
|
+
console.log("🔍 Looking for Sign In button");
|
|
22
|
+
|
|
23
|
+
// Find and click the sign in button
|
|
24
|
+
const signInButton = await testdriver.find(
|
|
25
|
+
"Sign In, black button below the password field",
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
console.log("👆 Clicking Sign In button");
|
|
29
|
+
await signInButton.click();
|
|
30
|
+
|
|
31
|
+
console.log("🧪 Asserting error message appears");
|
|
32
|
+
|
|
33
|
+
// Assert error shows
|
|
34
|
+
const result = await testdriver.assert(
|
|
35
|
+
"an error shows that fields are required",
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
console.log("✅ Test completed successfully - all logs should be in dashcam");
|
|
39
|
+
|
|
40
|
+
expect(result).toBeTruthy();
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Quick test of the new find() API
|
|
5
|
+
* This is a simple smoke test to verify the Element class works
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const TestDriver = require("../sdk");
|
|
9
|
+
|
|
10
|
+
async function testFindAPI() {
|
|
11
|
+
console.log("Testing new find() API...\n");
|
|
12
|
+
|
|
13
|
+
const client = new TestDriver("test-key", {
|
|
14
|
+
logging: false,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
// Test 1: Create element without connecting
|
|
18
|
+
console.log("✓ Test 1: Creating Element instance");
|
|
19
|
+
const element = client.find("test element");
|
|
20
|
+
console.log(" Element description:", element.description);
|
|
21
|
+
console.log(" Element found():", element.found());
|
|
22
|
+
console.log(" Element coordinates:", element.getCoordinates());
|
|
23
|
+
|
|
24
|
+
// Test 2: Verify element methods exist
|
|
25
|
+
console.log("\n✓ Test 2: Verifying Element methods");
|
|
26
|
+
console.log(" Has find():", typeof element.find === "function");
|
|
27
|
+
console.log(" Has click():", typeof element.click === "function");
|
|
28
|
+
console.log(" Has hover():", typeof element.hover === "function");
|
|
29
|
+
console.log(
|
|
30
|
+
" Has doubleClick():",
|
|
31
|
+
typeof element.doubleClick === "function",
|
|
32
|
+
);
|
|
33
|
+
console.log(" Has rightClick():", typeof element.rightClick === "function");
|
|
34
|
+
console.log(" Has mouseDown():", typeof element.mouseDown === "function");
|
|
35
|
+
console.log(" Has mouseUp():", typeof element.mouseUp === "function");
|
|
36
|
+
console.log(" Has found():", typeof element.found === "function");
|
|
37
|
+
console.log(
|
|
38
|
+
" Has getCoordinates():",
|
|
39
|
+
typeof element.getCoordinates === "function",
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
// Test 3: Verify error handling for clicking unfound element
|
|
43
|
+
console.log("\n✓ Test 3: Error handling for unfound element");
|
|
44
|
+
try {
|
|
45
|
+
await element.click();
|
|
46
|
+
console.log(" ❌ Should have thrown error");
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.log(" ✓ Correctly throws error:", error.message);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Test 4: Verify TypeScript types exist (if running from TypeScript)
|
|
52
|
+
console.log("\n✓ Test 4: SDK methods");
|
|
53
|
+
console.log(" Has find():", typeof client.find === "function");
|
|
54
|
+
console.log(
|
|
55
|
+
" Has deprecated hoverText():",
|
|
56
|
+
typeof client.hoverText === "undefined" ? "not yet connected" : "exists",
|
|
57
|
+
);
|
|
58
|
+
console.log(
|
|
59
|
+
" Has deprecated waitForText():",
|
|
60
|
+
typeof client.waitForText === "undefined" ? "not yet connected" : "exists",
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
console.log("\n✅ All basic tests passed!");
|
|
64
|
+
console.log(
|
|
65
|
+
"\nNote: Full integration tests require connection to TestDriver sandbox.",
|
|
66
|
+
);
|
|
67
|
+
console.log("See examples/sdk-find-example.js for complete usage examples.");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
testFindAPI().catch((error) => {
|
|
71
|
+
console.error("Test failed:", error);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Test script for the init command
|
|
4
|
+
# Usage: ./test-init.sh
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
echo "🧪 Testing testdriverai init command..."
|
|
9
|
+
echo ""
|
|
10
|
+
|
|
11
|
+
# Cleanup function
|
|
12
|
+
cleanup() {
|
|
13
|
+
echo "🧹 Cleaning up test directories..."
|
|
14
|
+
rm -rf /tmp/testdriver-test-*
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
trap cleanup EXIT
|
|
18
|
+
|
|
19
|
+
# Test 1: Full init with all features
|
|
20
|
+
echo "1️⃣ Testing full initialization (package.json, tests, workflow, npm install)..."
|
|
21
|
+
cd /tmp
|
|
22
|
+
mkdir -p testdriver-test-init
|
|
23
|
+
cd testdriver-test-init
|
|
24
|
+
node /Users/ianjennings/Development/cli/bin/testdriverai.js init
|
|
25
|
+
echo ""
|
|
26
|
+
echo "✅ Files created:"
|
|
27
|
+
find . -type f -not -path "./node_modules/*" | sort
|
|
28
|
+
echo ""
|
|
29
|
+
echo "📄 package.json:"
|
|
30
|
+
cat package.json
|
|
31
|
+
echo ""
|
|
32
|
+
echo "📄 vitest.config.js:"
|
|
33
|
+
cat vitest.config.js
|
|
34
|
+
echo ""
|
|
35
|
+
echo "📄 GitHub workflow:"
|
|
36
|
+
cat .github/workflows/testdriver.yml
|
|
37
|
+
echo ""
|
|
38
|
+
echo "📄 First 15 lines of tests/example.test.js:"
|
|
39
|
+
head -15 tests/example.test.js
|
|
40
|
+
echo ""
|
|
41
|
+
echo "📦 Installed dependencies:"
|
|
42
|
+
npm list --depth=0
|
|
43
|
+
echo ""
|
|
44
|
+
echo "---"
|
|
45
|
+
echo ""
|
|
46
|
+
|
|
47
|
+
# Test 2: Help command
|
|
48
|
+
echo "2️⃣ Testing help command..."
|
|
49
|
+
node /Users/ianjennings/Development/cli/bin/testdriverai.js init --help
|
|
50
|
+
echo ""
|
|
51
|
+
echo "---"
|
|
52
|
+
echo ""
|
|
53
|
+
|
|
54
|
+
echo "✅ All tests passed!"
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Simple test to verify prompt caching functionality
|
|
5
|
+
*
|
|
6
|
+
* This test demonstrates that:
|
|
7
|
+
* 1. First .prompt() call makes an API request and caches the YAML response
|
|
8
|
+
* 2. Second .prompt() call with the same prompt uses the cached YAML
|
|
9
|
+
* 3. Cache can be disabled with TD_NO_PROMPT_CACHE=true
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const TestDriver = require("./sdk.js");
|
|
13
|
+
const promptCache = require("./agent/lib/cache.js");
|
|
14
|
+
|
|
15
|
+
async function testPromptCache() {
|
|
16
|
+
console.log("Testing prompt caching functionality...\n");
|
|
17
|
+
|
|
18
|
+
// API key loaded automatically from .env
|
|
19
|
+
const client = new TestDriver({
|
|
20
|
+
os: "linux",
|
|
21
|
+
logging: true,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
// Connect to sandbox
|
|
26
|
+
console.log("Connecting to sandbox...");
|
|
27
|
+
await client.connect();
|
|
28
|
+
console.log("Connected!\n");
|
|
29
|
+
|
|
30
|
+
const testPrompt = "click the search button";
|
|
31
|
+
|
|
32
|
+
// Clear cache for this prompt to start fresh
|
|
33
|
+
const cachePath = promptCache.getCachePath(testPrompt);
|
|
34
|
+
console.log(`Cache path for "${testPrompt}": ${cachePath}\n`);
|
|
35
|
+
|
|
36
|
+
// Test 1: First call (should make API request and cache)
|
|
37
|
+
console.log("Test 1: First .ai() call (should cache the response)");
|
|
38
|
+
const stats1 = promptCache.getCacheStats();
|
|
39
|
+
console.log(`Cache before: ${stats1.count} files`);
|
|
40
|
+
|
|
41
|
+
await client.ai(testPrompt);
|
|
42
|
+
|
|
43
|
+
const stats2 = promptCache.getCacheStats();
|
|
44
|
+
console.log(`Cache after: ${stats2.count} files`);
|
|
45
|
+
console.log(
|
|
46
|
+
`Cache hit: ${promptCache.hasCache(testPrompt) ? "YES" : "NO"}\n`,
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
// Test 2: Second call (should use cache)
|
|
50
|
+
console.log(
|
|
51
|
+
"Test 2: Second .ai() call with same prompt (should use cache)",
|
|
52
|
+
);
|
|
53
|
+
console.log('Look for "(using cached response)" message above...\n');
|
|
54
|
+
await client.ai(testPrompt);
|
|
55
|
+
|
|
56
|
+
// Test 3: Third call with cache disabled (should make API call)
|
|
57
|
+
console.log(
|
|
58
|
+
"\nTest 3: Third .ai() call with cache=false (should bypass cache)",
|
|
59
|
+
);
|
|
60
|
+
await client.ai(testPrompt, false);
|
|
61
|
+
|
|
62
|
+
// Test 4: Show cache contents
|
|
63
|
+
console.log("\nTest 4: Cache contents");
|
|
64
|
+
const cachedYaml = promptCache.readCache(testPrompt);
|
|
65
|
+
if (cachedYaml) {
|
|
66
|
+
console.log("Cached YAML preview (first 500 chars):");
|
|
67
|
+
console.log(cachedYaml.substring(0, 500));
|
|
68
|
+
console.log("...\n");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Test 5: Cache statistics
|
|
72
|
+
console.log("Test 5: Cache statistics");
|
|
73
|
+
const finalStats = promptCache.getCacheStats();
|
|
74
|
+
console.log(`Total cached prompts: ${finalStats.count}`);
|
|
75
|
+
console.log(`Cache files:`, finalStats.files.slice(0, 5));
|
|
76
|
+
|
|
77
|
+
console.log("\n✅ Prompt caching test completed!");
|
|
78
|
+
console.log("\nTo disable caching, pass false: client.ai(prompt, false)");
|
|
79
|
+
console.log("To clear cache, delete .testdriver/.cache/*.yaml files");
|
|
80
|
+
} catch (error) {
|
|
81
|
+
console.error("❌ Test failed:", error.message);
|
|
82
|
+
throw error;
|
|
83
|
+
} finally {
|
|
84
|
+
// Disconnect
|
|
85
|
+
await client.disconnect();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Run the test
|
|
90
|
+
if (require.main === module) {
|
|
91
|
+
testPromptCache().catch((error) => {
|
|
92
|
+
console.error("Test error:", error);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
module.exports = testPromptCache;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quick test to verify provision() authentication works
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { test } from 'vitest';
|
|
6
|
+
import { provision } from '../../lib/presets/index.mjs';
|
|
7
|
+
|
|
8
|
+
test('provision auth test', async (context) => {
|
|
9
|
+
console.log('Starting provision...');
|
|
10
|
+
|
|
11
|
+
const { testdriver, dashcam } = await provision('chrome', {
|
|
12
|
+
url: 'http://testdriver-sandbox.vercel.app/',
|
|
13
|
+
}, context);
|
|
14
|
+
|
|
15
|
+
console.log('✅ Provision complete!');
|
|
16
|
+
console.log('TestDriver:', testdriver);
|
|
17
|
+
console.log('Dashcam:', dashcam);
|
|
18
|
+
|
|
19
|
+
// Try a simple find
|
|
20
|
+
const result = await testdriver.find('any element');
|
|
21
|
+
console.log('Find result:', result);
|
|
22
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const TestDriver = require("./sdk.js");
|
|
2
|
+
|
|
3
|
+
async function test() {
|
|
4
|
+
console.log("Testing sandbox rendering...");
|
|
5
|
+
|
|
6
|
+
// API key loaded automatically from .env
|
|
7
|
+
const client = new TestDriver({
|
|
8
|
+
os: process.env.TEST_PLATFORM || "linux",
|
|
9
|
+
headless: false, // Should open browser
|
|
10
|
+
logging: true,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
console.log("Connecting to sandbox...");
|
|
15
|
+
const instance = await client.connect();
|
|
16
|
+
console.log("Connected to instance:", instance);
|
|
17
|
+
|
|
18
|
+
// Wait a bit to see if browser opens
|
|
19
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
20
|
+
|
|
21
|
+
await client.disconnect();
|
|
22
|
+
console.log("Test completed successfully");
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error("Test failed:", error);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
test();
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const SDK = require("./sdk.js");
|
|
2
|
+
|
|
3
|
+
const client = new SDK("test-key");
|
|
4
|
+
|
|
5
|
+
// Get all public methods (non-private, non-constructor)
|
|
6
|
+
const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(client))
|
|
7
|
+
.filter((m) => !m.startsWith("_") && m !== "constructor")
|
|
8
|
+
.sort();
|
|
9
|
+
|
|
10
|
+
console.log("Public SDK Methods:");
|
|
11
|
+
console.log(methods.join(", "));
|
|
12
|
+
console.log("\nTotal:", methods.length, "methods");
|
|
13
|
+
|
|
14
|
+
// Check if commands will be set up after connect
|
|
15
|
+
console.log("\nCommands before connect:", client.commands);
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Quick test to verify SDK refactoring works correctly
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const TestDriver = require("./sdk.js");
|
|
8
|
+
|
|
9
|
+
async function test() {
|
|
10
|
+
console.log("Testing SDK refactor...\n");
|
|
11
|
+
|
|
12
|
+
// Test 1: SDK construction (API key loaded automatically from .env)
|
|
13
|
+
console.log("✓ Test 1: Creating SDK instance");
|
|
14
|
+
const client = new TestDriver({
|
|
15
|
+
logging: false,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
console.log(" - agent exists:", !!client.agent);
|
|
19
|
+
console.log(" - emitter exists:", !!client.emitter);
|
|
20
|
+
console.log(" - config exists:", !!client.config);
|
|
21
|
+
console.log(" - session exists:", !!client.session);
|
|
22
|
+
console.log(" - apiClient exists:", !!client.apiClient);
|
|
23
|
+
console.log(" - analytics exists:", !!client.analytics);
|
|
24
|
+
console.log(" - sandbox exists:", !!client.sandbox);
|
|
25
|
+
console.log(" - system exists:", !!client.system);
|
|
26
|
+
|
|
27
|
+
// Test 2: Check agent methods are accessible
|
|
28
|
+
console.log("\n✓ Test 2: Checking agent methods");
|
|
29
|
+
console.log(
|
|
30
|
+
" - agent.exploratoryLoop exists:",
|
|
31
|
+
typeof client.agent.exploratoryLoop,
|
|
32
|
+
);
|
|
33
|
+
console.log(" - agent.buildEnv exists:", typeof client.agent.buildEnv);
|
|
34
|
+
console.log(
|
|
35
|
+
" - agent.getRecentSandboxId exists:",
|
|
36
|
+
typeof client.agent.getRecentSandboxId,
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
// Test 3: Check SDK methods
|
|
40
|
+
console.log("\n✓ Test 3: Checking SDK methods");
|
|
41
|
+
console.log(" - ai() exists:", typeof client.ai);
|
|
42
|
+
console.log(" - auth() exists:", typeof client.auth);
|
|
43
|
+
console.log(" - connect() exists:", typeof client.connect);
|
|
44
|
+
console.log(" - disconnect() exists:", typeof client.disconnect);
|
|
45
|
+
|
|
46
|
+
console.log("\n✅ All basic tests passed!");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
test().catch((error) => {
|
|
50
|
+
console.error("\n❌ Test failed:", error.message);
|
|
51
|
+
console.error(error.stack);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quick test to verify stack trace filtering works
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Mock the MatchError similar to commands.js
|
|
6
|
+
class MatchError extends Error {
|
|
7
|
+
constructor(message, fatal = false) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.fatal = fatal;
|
|
10
|
+
this.attachScreenshot = true;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Simulate SDK wrapper with stack filtering (improved version)
|
|
15
|
+
class TestSDK {
|
|
16
|
+
constructor() {
|
|
17
|
+
const command = async (message) => {
|
|
18
|
+
// Simulate the command throwing an error
|
|
19
|
+
throw new MatchError(`AI Assertion failed: ${message}`, true);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// Wrap the method with proper stack trace handling
|
|
23
|
+
this.assert = async function (...args) {
|
|
24
|
+
// Capture the call site for better error reporting
|
|
25
|
+
const callSite = {};
|
|
26
|
+
Error.captureStackTrace(callSite, this.assert);
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
return await command(...args);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
// Replace the stack trace to point to the actual caller
|
|
32
|
+
if (Error.captureStackTrace && callSite.stack) {
|
|
33
|
+
const errorMessage = error.stack?.split("\n")[0];
|
|
34
|
+
const callerStack = callSite.stack?.split("\n").slice(1);
|
|
35
|
+
error.stack = errorMessage + "\n" + callerStack.join("\n");
|
|
36
|
+
}
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
}.bind(this);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Test it
|
|
44
|
+
async function runTest() {
|
|
45
|
+
const client = new TestSDK();
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
console.log("Testing stack trace...\n");
|
|
49
|
+
await client.assert("home page appears"); // Line 42 - this should show in stack
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.log("Error caught!");
|
|
52
|
+
console.log("Stack trace:");
|
|
53
|
+
console.log(error.stack);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
runTest();
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Verify Element class API
|
|
5
|
+
* Tests that all expected methods and properties are available
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
async function verify() {
|
|
9
|
+
// Create a test element instance - need to access Element class directly
|
|
10
|
+
const { Element } = require("./sdk.js");
|
|
11
|
+
const elem = new Element("test", null, null, null);
|
|
12
|
+
|
|
13
|
+
console.log("Verifying Element class API...\n");
|
|
14
|
+
|
|
15
|
+
// Check methods exist
|
|
16
|
+
const methods = [
|
|
17
|
+
"find",
|
|
18
|
+
"found",
|
|
19
|
+
"click",
|
|
20
|
+
"hover",
|
|
21
|
+
"doubleClick",
|
|
22
|
+
"rightClick",
|
|
23
|
+
"mouseDown",
|
|
24
|
+
"mouseUp",
|
|
25
|
+
"getCoordinates",
|
|
26
|
+
"getResponse",
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
let passed = 0;
|
|
30
|
+
let failed = 0;
|
|
31
|
+
|
|
32
|
+
console.log("Testing methods:");
|
|
33
|
+
methods.forEach((method) => {
|
|
34
|
+
if (typeof elem[method] === "function") {
|
|
35
|
+
console.log(` ✓ ${method}()`);
|
|
36
|
+
passed++;
|
|
37
|
+
} else {
|
|
38
|
+
console.log(` ✗ ${method}() - MISSING`);
|
|
39
|
+
failed++;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Test property getters (should return null when element not found)
|
|
44
|
+
const props = [
|
|
45
|
+
"x",
|
|
46
|
+
"y",
|
|
47
|
+
"centerX",
|
|
48
|
+
"centerY",
|
|
49
|
+
"width",
|
|
50
|
+
"height",
|
|
51
|
+
"confidence",
|
|
52
|
+
"screenshot",
|
|
53
|
+
"boundingBox",
|
|
54
|
+
"text",
|
|
55
|
+
"label",
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
console.log("\nTesting properties (should be null when not found):");
|
|
59
|
+
props.forEach((prop) => {
|
|
60
|
+
if (prop in elem) {
|
|
61
|
+
const value = elem[prop];
|
|
62
|
+
if (value === null) {
|
|
63
|
+
console.log(` ✓ ${prop} = null`);
|
|
64
|
+
passed++;
|
|
65
|
+
} else {
|
|
66
|
+
console.log(` ✗ ${prop} = ${value} (expected null)`);
|
|
67
|
+
failed++;
|
|
68
|
+
}
|
|
69
|
+
} else {
|
|
70
|
+
console.log(` ✗ ${prop} - MISSING`);
|
|
71
|
+
failed++;
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
console.log("\n" + "=".repeat(50));
|
|
76
|
+
console.log(`Results: ${passed} passed, ${failed} failed`);
|
|
77
|
+
console.log("=".repeat(50));
|
|
78
|
+
|
|
79
|
+
if (failed > 0) {
|
|
80
|
+
process.exit(1);
|
|
81
|
+
} else {
|
|
82
|
+
console.log("\n✅ All Element API verification tests passed!");
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
verify().catch((err) => {
|
|
87
|
+
console.error("Error:", err);
|
|
88
|
+
process.exit(1);
|
|
89
|
+
});
|
|
File without changes
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manual test to verify unawaited promise detection
|
|
3
|
+
*
|
|
4
|
+
* Run with: vitest run test/manual-unawaited-promise.test.mjs
|
|
5
|
+
*
|
|
6
|
+
* Expected: You should see a warning like:
|
|
7
|
+
* ⚠️ Warning: Previous find() may not have been awaited.
|
|
8
|
+
*/
|
|
9
|
+
import { describe, expect, it } from "vitest";
|
|
10
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
11
|
+
|
|
12
|
+
describe("Unawaited Promise Detection", () => {
|
|
13
|
+
it("should warn when a promise is not awaited", async (context) => {
|
|
14
|
+
const testdriver = TestDriver(context);
|
|
15
|
+
|
|
16
|
+
await testdriver.provision.chrome({
|
|
17
|
+
url: 'https://example.com',
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// INTENTIONALLY missing await - should trigger warning on next call
|
|
21
|
+
testdriver.find("some button");
|
|
22
|
+
|
|
23
|
+
// This second call should print a warning about the previous unawaited find()
|
|
24
|
+
const element = await testdriver.find("Example Domain heading");
|
|
25
|
+
|
|
26
|
+
console.log("Element found:", element.found());
|
|
27
|
+
|
|
28
|
+
// If we got here without error and saw the warning, the feature works!
|
|
29
|
+
expect(true).toBeTruthy();
|
|
30
|
+
});
|
|
31
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import TestDriver from "testdriverai/vitest";
|
|
2
|
+
import { defineConfig } from "vitest/config";
|
|
3
|
+
import { createRequire } from "module";
|
|
4
|
+
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
const { resolveEnv, getEnvironmentNames } = require("../shared/resolve-env");
|
|
7
|
+
|
|
8
|
+
// Always include AWS setup - it will be a no-op unless TD_OS=windows
|
|
9
|
+
// Note: dotenv is loaded automatically by the TestDriver SDK
|
|
10
|
+
const setupFiles = [
|
|
11
|
+
"testdriverai/vitest/setup",
|
|
12
|
+
"testdriverai/vitest/setup-aws"
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const sharedTestConfig = {
|
|
16
|
+
retry: 0,
|
|
17
|
+
testTimeout: 900000,
|
|
18
|
+
hookTimeout: 900000,
|
|
19
|
+
maxConcurrency: 100,
|
|
20
|
+
disableConsoleIntercept: false,
|
|
21
|
+
silent: false,
|
|
22
|
+
reporters: [
|
|
23
|
+
"verbose",
|
|
24
|
+
TestDriver()
|
|
25
|
+
],
|
|
26
|
+
setupFiles,
|
|
27
|
+
include: ["examples/**/*.test.mjs"],
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// ── Resolve env vars via shared/resolve-env.js ──────────────────────
|
|
31
|
+
// Uses: environments.json (URLs) + envs/{env}.env (overlay) + fixtures (API keys)
|
|
32
|
+
// TD_PLAN selects which plan's API key to use (default: enterprise)
|
|
33
|
+
const plan = process.env.TD_PLAN || "enterprise";
|
|
34
|
+
const defaultEnv = process.env.TD_ENV || "dev";
|
|
35
|
+
const environments = getEnvironmentNames();
|
|
36
|
+
|
|
37
|
+
// Apply default env to the main process so the reporter/plugin picks it up
|
|
38
|
+
// (vitest's test.env only propagates to worker processes, not the main process)
|
|
39
|
+
const defaultResolved = resolveEnv(defaultEnv, plan);
|
|
40
|
+
Object.assign(process.env, defaultResolved);
|
|
41
|
+
|
|
42
|
+
// ── Usage ───────────────────────────────────────────────────────────
|
|
43
|
+
// TD_PLAN=enterprise vitest run --project dev
|
|
44
|
+
// TD_PLAN=free vitest run --project test examples/assert.test.mjs
|
|
45
|
+
// vitest run --project canary --project stable
|
|
46
|
+
export default defineConfig({
|
|
47
|
+
test: {
|
|
48
|
+
...sharedTestConfig,
|
|
49
|
+
env: defaultResolved,
|
|
50
|
+
projects: environments.map((envName) => ({
|
|
51
|
+
extends: true,
|
|
52
|
+
test: {
|
|
53
|
+
name: envName,
|
|
54
|
+
env: resolveEnv(envName, plan),
|
|
55
|
+
},
|
|
56
|
+
})),
|
|
57
|
+
},
|
|
58
|
+
});
|