@testdriverai/agent 7.8.0-canary.10
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
package/lib/sentry.js
ADDED
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sentry initialization for TestDriver CLI
|
|
3
|
+
*
|
|
4
|
+
* This module initializes Sentry for error tracking and performance monitoring.
|
|
5
|
+
* It should be required at the very beginning of the CLI entry point.
|
|
6
|
+
*
|
|
7
|
+
* Distributed Tracing:
|
|
8
|
+
* The CLI uses session-based trace IDs (MD5 hash of session ID) to link
|
|
9
|
+
* CLI traces with API traces. Call setSessionTraceContext() after establishing
|
|
10
|
+
* a session to ensure all CLI errors/logs are linked to the same trace.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const Sentry = require("@sentry/node");
|
|
14
|
+
const crypto = require("crypto");
|
|
15
|
+
const os = require("os");
|
|
16
|
+
const { version } = require("../package.json");
|
|
17
|
+
const logger = require("../agent/lib/logger");
|
|
18
|
+
|
|
19
|
+
// Store trace contexts per session so concurrent tests don't overwrite each other.
|
|
20
|
+
// Keys are sessionIds, values are { traceId, sessionId }.
|
|
21
|
+
const _traceContexts = new Map();
|
|
22
|
+
|
|
23
|
+
// For backward compatibility, track the most recently set session
|
|
24
|
+
let currentTraceId = null;
|
|
25
|
+
let currentSessionId = null;
|
|
26
|
+
|
|
27
|
+
// Track if we've attached listeners to avoid duplicates
|
|
28
|
+
let emitterAttached = false;
|
|
29
|
+
|
|
30
|
+
const isEnabled = () => {
|
|
31
|
+
// Disable if explicitly disabled
|
|
32
|
+
if (process.env.TD_TELEMETRY === "false") {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
return true;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
if (isEnabled()) {
|
|
39
|
+
logger.log("Analytics enabled. Set TD_TELEMETRY=false to disable.");
|
|
40
|
+
Sentry.init({
|
|
41
|
+
dsn:
|
|
42
|
+
process.env.SENTRY_DSN ||
|
|
43
|
+
"https://452bd5a00dbd83a38ee8813e11c57694@o4510262629236736.ingest.us.sentry.io/4510480443637760",
|
|
44
|
+
environment: "sdk",
|
|
45
|
+
release: version,
|
|
46
|
+
sampleRate: 1.0,
|
|
47
|
+
tracesSampleRate: 1.0, // Sample 20% of transactions for performance
|
|
48
|
+
enableLogs: true,
|
|
49
|
+
integrations: [Sentry.httpIntegration(), Sentry.nodeContextIntegration()],
|
|
50
|
+
// Set initial context
|
|
51
|
+
initialScope: {
|
|
52
|
+
tags: {
|
|
53
|
+
platform: os.platform(),
|
|
54
|
+
arch: os.arch(),
|
|
55
|
+
nodeVersion: process.version,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
// Filter out common non-errors and expected test failures
|
|
59
|
+
// Only report actual exceptions and crashes, not failed tests or element lookups
|
|
60
|
+
beforeSend(event, hint) {
|
|
61
|
+
const error = hint.originalException;
|
|
62
|
+
|
|
63
|
+
if (error && error.message) {
|
|
64
|
+
const message = error.message;
|
|
65
|
+
|
|
66
|
+
// Don't send user-initiated exits
|
|
67
|
+
if (message.includes("User cancelled")) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Don't send expected test/element failures - these are normal test outcomes, not crashes
|
|
72
|
+
if (
|
|
73
|
+
message.includes("Element not found") ||
|
|
74
|
+
message.includes("No elements found") ||
|
|
75
|
+
message.includes("No element found") ||
|
|
76
|
+
message.includes("Assertion failed") ||
|
|
77
|
+
message.includes("assertion failed")
|
|
78
|
+
) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Filter out TestFailure errors (test failures, not crashes)
|
|
84
|
+
if (error && error.name === "TestFailure") {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Filter out ElementNotFoundError - expected test outcome, not a crash
|
|
89
|
+
if (error && error.name === "ElementNotFoundError") {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return event;
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Set user context for Sentry
|
|
100
|
+
* @param {Object} user - User object with id, email, etc.
|
|
101
|
+
*/
|
|
102
|
+
function setUser(user) {
|
|
103
|
+
if (!isEnabled()) return;
|
|
104
|
+
Sentry.setUser(user);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Set additional context
|
|
109
|
+
* @param {string} name - Context name
|
|
110
|
+
* @param {Object} context - Context data
|
|
111
|
+
*/
|
|
112
|
+
function setContext(name, context) {
|
|
113
|
+
if (!isEnabled()) return;
|
|
114
|
+
Sentry.setContext(name, context);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Set a tag
|
|
119
|
+
* @param {string} key - Tag key
|
|
120
|
+
* @param {string} value - Tag value
|
|
121
|
+
*/
|
|
122
|
+
function setTag(key, value) {
|
|
123
|
+
if (!isEnabled()) return;
|
|
124
|
+
Sentry.setTag(key, value);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Capture an exception
|
|
129
|
+
* @param {Error} error - The error to capture
|
|
130
|
+
* @param {Object} context - Additional context
|
|
131
|
+
*/
|
|
132
|
+
function captureException(error, context = {}) {
|
|
133
|
+
if (!isEnabled()) return;
|
|
134
|
+
|
|
135
|
+
Sentry.withScope((scope) => {
|
|
136
|
+
// Link to session trace if available
|
|
137
|
+
if (currentTraceId && currentSessionId) {
|
|
138
|
+
scope.setTag("session", currentSessionId);
|
|
139
|
+
scope.setContext("trace", {
|
|
140
|
+
trace_id: currentTraceId,
|
|
141
|
+
session_id: currentSessionId,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (context.tags) {
|
|
146
|
+
Object.entries(context.tags).forEach(([key, value]) => {
|
|
147
|
+
scope.setTag(key, value);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
if (context.extra) {
|
|
151
|
+
Object.entries(context.extra).forEach(([key, value]) => {
|
|
152
|
+
scope.setExtra(key, value);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
Sentry.captureException(error);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Capture a message
|
|
161
|
+
* @param {string} message - The message to capture
|
|
162
|
+
* @param {string} level - Severity level (info, warning, error)
|
|
163
|
+
*/
|
|
164
|
+
function captureMessage(message, level = "info") {
|
|
165
|
+
if (!isEnabled()) return;
|
|
166
|
+
|
|
167
|
+
Sentry.withScope((scope) => {
|
|
168
|
+
// Link to session trace if available
|
|
169
|
+
if (currentTraceId && currentSessionId) {
|
|
170
|
+
scope.setTag("session", currentSessionId);
|
|
171
|
+
scope.setContext("trace", {
|
|
172
|
+
trace_id: currentTraceId,
|
|
173
|
+
session_id: currentSessionId,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
Sentry.captureMessage(message, level);
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Set the session trace context for distributed tracing
|
|
182
|
+
* This links CLI errors/logs to the same trace as API calls
|
|
183
|
+
* @param {string} sessionId - The session ID
|
|
184
|
+
*/
|
|
185
|
+
function setSessionTraceContext(sessionId) {
|
|
186
|
+
if (!isEnabled() || !sessionId) return;
|
|
187
|
+
|
|
188
|
+
// Derive trace ID from session ID (same algorithm as API)
|
|
189
|
+
const traceId = crypto.createHash("md5").update(sessionId).digest("hex");
|
|
190
|
+
|
|
191
|
+
// Store per-session trace context for concurrent safety
|
|
192
|
+
_traceContexts.set(sessionId, { traceId, sessionId });
|
|
193
|
+
|
|
194
|
+
// Also update the module-level "latest" for backward compatibility
|
|
195
|
+
currentTraceId = traceId;
|
|
196
|
+
currentSessionId = sessionId;
|
|
197
|
+
|
|
198
|
+
// Set as global tag so all events include it
|
|
199
|
+
Sentry.setTag("session", sessionId);
|
|
200
|
+
Sentry.setTag("trace_id", currentTraceId);
|
|
201
|
+
|
|
202
|
+
// Try to set propagation context for trace linking (may not be available in all versions)
|
|
203
|
+
try {
|
|
204
|
+
const scope = Sentry.getCurrentScope();
|
|
205
|
+
if (scope && typeof scope.setPropagationContext === "function") {
|
|
206
|
+
scope.setPropagationContext({
|
|
207
|
+
traceId: currentTraceId,
|
|
208
|
+
spanId: currentTraceId.substring(0, 16),
|
|
209
|
+
sampled: true,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
} catch (e) {
|
|
213
|
+
// Ignore errors - propagation context may not be supported
|
|
214
|
+
logger.log("Could not set propagation context:", e.message);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Clear the session trace context
|
|
220
|
+
*/
|
|
221
|
+
function clearSessionTraceContext(sessionId) {
|
|
222
|
+
if (sessionId) {
|
|
223
|
+
_traceContexts.delete(sessionId);
|
|
224
|
+
// If the cleared session was the "latest", pick another or null
|
|
225
|
+
if (currentSessionId === sessionId) {
|
|
226
|
+
if (_traceContexts.size > 0) {
|
|
227
|
+
const last = Array.from(_traceContexts.values()).pop();
|
|
228
|
+
currentTraceId = last.traceId;
|
|
229
|
+
currentSessionId = last.sessionId;
|
|
230
|
+
} else {
|
|
231
|
+
currentTraceId = null;
|
|
232
|
+
currentSessionId = null;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
} else {
|
|
236
|
+
// Clear all (backward compatibility)
|
|
237
|
+
_traceContexts.clear();
|
|
238
|
+
currentTraceId = null;
|
|
239
|
+
currentSessionId = null;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Get the current trace ID (for debugging)
|
|
245
|
+
* @returns {string|null} Current trace ID or null
|
|
246
|
+
*/
|
|
247
|
+
function getTraceId() {
|
|
248
|
+
return currentTraceId;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Attach log listeners to an emitter to capture CLI logs as Sentry breadcrumbs
|
|
253
|
+
* @param {EventEmitter} emitter - The event emitter to listen to
|
|
254
|
+
*/
|
|
255
|
+
function attachLogListeners(emitter) {
|
|
256
|
+
if (!isEnabled() || !emitter || emitterAttached) return;
|
|
257
|
+
|
|
258
|
+
// Check if Sentry.logger is available
|
|
259
|
+
if (!Sentry.logger) {
|
|
260
|
+
logger.log("Sentry.logger not available, skipping log listeners");
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
emitterAttached = true;
|
|
265
|
+
|
|
266
|
+
// Helper to strip ANSI codes for cleaner logs
|
|
267
|
+
const stripAnsi = (str) => {
|
|
268
|
+
if (typeof str !== "string") return String(str);
|
|
269
|
+
return str.replace(/\x1B[[(?);]{0,2}(;?\d)*./g, "");
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
// Helper to get current log attributes with trace context
|
|
273
|
+
const getLogAttributes = (extra = {}) => {
|
|
274
|
+
const attrs = { ...extra };
|
|
275
|
+
if (currentSessionId) {
|
|
276
|
+
attrs["session.id"] = currentSessionId;
|
|
277
|
+
}
|
|
278
|
+
if (currentTraceId) {
|
|
279
|
+
attrs["sentry.trace.trace_id"] = currentTraceId;
|
|
280
|
+
}
|
|
281
|
+
// Get current user from Sentry scope
|
|
282
|
+
try {
|
|
283
|
+
const user = Sentry.getCurrentScope().getUser();
|
|
284
|
+
if (user) {
|
|
285
|
+
if (user.id) attrs["user.id"] = user.id;
|
|
286
|
+
if (user.email) attrs["user.email"] = user.email;
|
|
287
|
+
if (user.username) attrs["user.name"] = user.username;
|
|
288
|
+
}
|
|
289
|
+
} catch (e) {
|
|
290
|
+
// Ignore errors getting user
|
|
291
|
+
}
|
|
292
|
+
return attrs;
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
// Capture log:log as info logs
|
|
296
|
+
emitter.on("log:log", (message) => {
|
|
297
|
+
Sentry.logger.info(
|
|
298
|
+
stripAnsi(message),
|
|
299
|
+
getLogAttributes({ category: "cli.log" }),
|
|
300
|
+
);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
// Capture log:warn as warning logs
|
|
304
|
+
emitter.on("log:warn", (message) => {
|
|
305
|
+
Sentry.logger.warn(
|
|
306
|
+
stripAnsi(message),
|
|
307
|
+
getLogAttributes({ category: "cli.warn" }),
|
|
308
|
+
);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// Capture log:debug as debug logs (only in verbose mode)
|
|
312
|
+
if (process.env.VERBOSE || process.env.TD_DEBUG) {
|
|
313
|
+
emitter.on("log:debug", (message) => {
|
|
314
|
+
Sentry.logger.debug(
|
|
315
|
+
stripAnsi(message),
|
|
316
|
+
getLogAttributes({ category: "cli.debug" }),
|
|
317
|
+
);
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Capture command events
|
|
322
|
+
emitter.on("command:start", (data) => {
|
|
323
|
+
Sentry.logger.info(
|
|
324
|
+
`Command started: ${data?.command || data?.name || "unknown"}`,
|
|
325
|
+
getLogAttributes({
|
|
326
|
+
category: "cli.command",
|
|
327
|
+
...data,
|
|
328
|
+
}),
|
|
329
|
+
);
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
emitter.on("command:error", (data) => {
|
|
333
|
+
Sentry.logger.error(
|
|
334
|
+
`Command error: ${data?.message || data?.error || "unknown"}`,
|
|
335
|
+
getLogAttributes({
|
|
336
|
+
category: "cli.command",
|
|
337
|
+
...data,
|
|
338
|
+
}),
|
|
339
|
+
);
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
// Capture step events
|
|
343
|
+
emitter.on("step:start", (data) => {
|
|
344
|
+
Sentry.logger.info(
|
|
345
|
+
`Step started: ${data?.step || data?.name || "unknown"}`,
|
|
346
|
+
getLogAttributes({
|
|
347
|
+
category: "cli.step",
|
|
348
|
+
}),
|
|
349
|
+
);
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
emitter.on("step:error", (data) => {
|
|
353
|
+
Sentry.logger.error(
|
|
354
|
+
`Step error: ${data?.message || data?.error || "unknown"}`,
|
|
355
|
+
getLogAttributes({
|
|
356
|
+
category: "cli.step",
|
|
357
|
+
...data,
|
|
358
|
+
}),
|
|
359
|
+
);
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
// Capture test events
|
|
363
|
+
emitter.on("test:start", (data) => {
|
|
364
|
+
Sentry.logger.info(
|
|
365
|
+
`Test started: ${data?.name || "unknown"}`,
|
|
366
|
+
getLogAttributes({
|
|
367
|
+
category: "cli.test",
|
|
368
|
+
}),
|
|
369
|
+
);
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
emitter.on("test:error", (data) => {
|
|
373
|
+
Sentry.logger.error(
|
|
374
|
+
`Test error: ${data?.message || data?.error || "unknown"}`,
|
|
375
|
+
getLogAttributes({
|
|
376
|
+
category: "cli.test",
|
|
377
|
+
...data,
|
|
378
|
+
}),
|
|
379
|
+
);
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Start a new transaction for performance monitoring
|
|
385
|
+
* @param {string} name - Transaction name
|
|
386
|
+
* @param {string} op - Operation type
|
|
387
|
+
* @returns {Object} Transaction object
|
|
388
|
+
*/
|
|
389
|
+
function startTransaction(name, op = "cli") {
|
|
390
|
+
if (!isEnabled()) return null;
|
|
391
|
+
return Sentry.startSpan({ name, op });
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Flush pending events before process exit
|
|
396
|
+
* @param {number} timeout - Timeout in milliseconds
|
|
397
|
+
*/
|
|
398
|
+
async function flush(timeout = 2000) {
|
|
399
|
+
if (!isEnabled()) return;
|
|
400
|
+
await Sentry.flush(timeout);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
module.exports = {
|
|
404
|
+
Sentry,
|
|
405
|
+
isEnabled,
|
|
406
|
+
setUser,
|
|
407
|
+
setContext,
|
|
408
|
+
setTag,
|
|
409
|
+
captureException,
|
|
410
|
+
captureMessage,
|
|
411
|
+
setSessionTraceContext,
|
|
412
|
+
clearSessionTraceContext,
|
|
413
|
+
getTraceId,
|
|
414
|
+
attachLogListeners,
|
|
415
|
+
startTransaction,
|
|
416
|
+
flush,
|
|
417
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript definitions for TestDriver Vitest Hooks
|
|
3
|
+
* @module testdriverai/vitest/hooks
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type TestDriverSDK from '../../sdk';
|
|
7
|
+
import type { TestDriverOptions } from '../../sdk';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Vitest test context (from test function parameter)
|
|
11
|
+
*/
|
|
12
|
+
export interface VitestContext {
|
|
13
|
+
/**
|
|
14
|
+
* Current test task
|
|
15
|
+
*/
|
|
16
|
+
task: any;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Register cleanup handler
|
|
20
|
+
*/
|
|
21
|
+
onTestFinished?: (fn: () => void | Promise<void>) => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Options for TestDriver hook (includes all TestDriverOptions)
|
|
26
|
+
*/
|
|
27
|
+
export interface TestDriverHookOptions extends TestDriverOptions {
|
|
28
|
+
// All TestDriverOptions are already included via extends
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Create a TestDriver client for use in Vitest tests
|
|
33
|
+
* Manages lifecycle automatically (connects on first use, disconnects after test)
|
|
34
|
+
*
|
|
35
|
+
* @param context - Vitest test context (from async (context) => {})
|
|
36
|
+
* @param options - TestDriver options
|
|
37
|
+
* @returns TestDriver SDK instance
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* import { describe, expect, it } from "vitest";
|
|
41
|
+
* import { TestDriver } from "testdriverai/lib/vitest/hooks.mjs";
|
|
42
|
+
*
|
|
43
|
+
* describe("My Test Suite", () => {
|
|
44
|
+
* it("should do something", async (context) => {
|
|
45
|
+
* const testdriver = TestDriver(context, { newSandbox: true, headless: false });
|
|
46
|
+
*
|
|
47
|
+
* await testdriver.provision.chrome({ url: 'https://example.com' });
|
|
48
|
+
*
|
|
49
|
+
* const button = await testdriver.find("Sign In button");
|
|
50
|
+
* await button.click();
|
|
51
|
+
*
|
|
52
|
+
* const result = await testdriver.assert("the dashboard is visible");
|
|
53
|
+
* expect(result).toBeTruthy();
|
|
54
|
+
* });
|
|
55
|
+
* });
|
|
56
|
+
*/
|
|
57
|
+
export function TestDriver(context: VitestContext, options?: TestDriverHookOptions): TestDriverSDK;
|