@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
package/eslint.config.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const globals = require("globals");
|
|
2
|
+
const pluginJs = require("@eslint/js");
|
|
3
|
+
|
|
4
|
+
module.exports = [
|
|
5
|
+
pluginJs.configs.recommended,
|
|
6
|
+
{
|
|
7
|
+
// Base config for all JavaScript files - provides Node.js globals
|
|
8
|
+
languageOptions: {
|
|
9
|
+
sourceType: "commonjs",
|
|
10
|
+
globals: {
|
|
11
|
+
...globals.node,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
// Specific config for interface and agent files - adds browser globals
|
|
17
|
+
files: ["./interfaces/**/*.js", "./agent/**/*.js"],
|
|
18
|
+
languageOptions: {
|
|
19
|
+
sourceType: "commonjs",
|
|
20
|
+
globals: {
|
|
21
|
+
...globals.browser,
|
|
22
|
+
...globals.node,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
// Specific config for test files - adds Jest and Mocha globals
|
|
28
|
+
files: ["test/**/*.js"],
|
|
29
|
+
languageOptions: {
|
|
30
|
+
sourceType: "commonjs",
|
|
31
|
+
globals: {
|
|
32
|
+
...globals.node,
|
|
33
|
+
...globals.jest,
|
|
34
|
+
...globals.mocha,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
// Config for ES Module files (.mjs) - used in SDK tests
|
|
40
|
+
files: ["**/*.mjs"],
|
|
41
|
+
languageOptions: {
|
|
42
|
+
sourceType: "module",
|
|
43
|
+
ecmaVersion: 2022,
|
|
44
|
+
globals: {
|
|
45
|
+
...globals.node,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
rules: {
|
|
49
|
+
// Warn about floating promises (unawaited async calls)
|
|
50
|
+
// This catches missing `await` on async methods like click(), assert(), etc.
|
|
51
|
+
// Note: For TypeScript projects, use @typescript-eslint/no-floating-promises instead
|
|
52
|
+
"require-await": "warn",
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
// this needs to be it's own object for some reason
|
|
57
|
+
// https://github.com/eslint/eslint/issues/17400
|
|
58
|
+
ignores: [
|
|
59
|
+
"agent/lib/subimage/**",
|
|
60
|
+
"node_modules/**",
|
|
61
|
+
".git",
|
|
62
|
+
"test-results/**",
|
|
63
|
+
"examples/test-recording-example.test.js",
|
|
64
|
+
"vitest.config.example.js",
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
];
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - AI Test (Vitest)
|
|
3
|
+
* Tests the AI exploratory loop (ai) functionality
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
8
|
+
import { getDefaults } from "./config.mjs";
|
|
9
|
+
|
|
10
|
+
describe("AI Test", () => {
|
|
11
|
+
it("should use ai to search for testdriver on Google", async (context) => {
|
|
12
|
+
const testdriver = TestDriver(context, { ...getDefaults(context) });
|
|
13
|
+
|
|
14
|
+
// provision.chrome() automatically calls ready() and starts dashcam
|
|
15
|
+
await testdriver.provision.chrome({
|
|
16
|
+
url: 'https://duckduckgo.com',
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// Use ai to search for testdriver
|
|
20
|
+
let aiRes = await testdriver.ai("click on the empty search box, type 'testdriver', and hit enter.");
|
|
21
|
+
|
|
22
|
+
console.log("AI response:", aiRes);
|
|
23
|
+
|
|
24
|
+
// Assert the search results are displayed
|
|
25
|
+
const result = await testdriver.assert(
|
|
26
|
+
"search results for testdriver are visible",
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
expect(result).toBeTruthy();
|
|
30
|
+
});
|
|
31
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Assert Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/assert.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
8
|
+
import { getDefaults } from "./config.mjs";
|
|
9
|
+
|
|
10
|
+
describe("Assert Test", () => {
|
|
11
|
+
it("should assert the testdriver login page shows", async (context) => {
|
|
12
|
+
const testdriver = TestDriver(context, {
|
|
13
|
+
...getDefaults(context),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
// provision.chrome() automatically calls ready() and starts dashcam
|
|
17
|
+
await testdriver.provision.chrome({
|
|
18
|
+
url: 'http://testdriver-sandbox.vercel.app/login',
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Take a screenshot
|
|
22
|
+
await testdriver.screenshot();
|
|
23
|
+
|
|
24
|
+
// Assert the TestDriver.ai Sandbox login page is displayed
|
|
25
|
+
const result = await testdriver.assert(
|
|
26
|
+
"the TestDriver.ai Sandbox login page is displayed",
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
expect(result).toBeTruthy();
|
|
30
|
+
});
|
|
31
|
+
// it("should assert the testdriver login page shows 2", async (context) => {
|
|
32
|
+
// const testdriver = TestDriver(context);
|
|
33
|
+
|
|
34
|
+
// // provision.chrome() automatically calls ready() and starts dashcam
|
|
35
|
+
// await testdriver.provision.chrome({
|
|
36
|
+
// url: 'http://testdriver-sandbox.vercel.app/login',
|
|
37
|
+
// });
|
|
38
|
+
|
|
39
|
+
// // Assert the TestDriver.ai Sandbox login page is displayed
|
|
40
|
+
// const result = await testdriver.assert(
|
|
41
|
+
// "the TestDriver.ai Sandbox login page is displayed",
|
|
42
|
+
// );
|
|
43
|
+
|
|
44
|
+
// expect(result).toBeTruthy();
|
|
45
|
+
// });
|
|
46
|
+
});
|
|
47
|
+
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Chrome Extension Test (Vitest)
|
|
3
|
+
* Tests loading a Chrome extension using provision.chromeExtension()
|
|
4
|
+
*
|
|
5
|
+
* This test suite covers:
|
|
6
|
+
* 1. Loading extension from local path (extensionPath)
|
|
7
|
+
* 2. Loading extension from Chrome Web Store (extensionId)
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { describe, expect, it } from "vitest";
|
|
11
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
12
|
+
import { getDefaults } from "./config.mjs";
|
|
13
|
+
|
|
14
|
+
describe("Chrome Extension Test", () => {
|
|
15
|
+
it("should load hello-world Chrome extension from local path", async (context) => {
|
|
16
|
+
|
|
17
|
+
console.log('connecting to', process.env.TD_IP)
|
|
18
|
+
|
|
19
|
+
const testdriver = TestDriver(context, { ...getDefaults(context), cacheKey: new Date().getTime().toString() });
|
|
20
|
+
|
|
21
|
+
// Determine OS-specific paths and commands
|
|
22
|
+
const shell = testdriver.os === 'windows' ? 'pwsh' : 'sh';
|
|
23
|
+
const extensionsDir = testdriver.os === 'windows'
|
|
24
|
+
? 'C:\\Users\\testdriver\\Downloads\\chrome-extensions-samples'
|
|
25
|
+
: '/tmp/chrome-extensions-samples';
|
|
26
|
+
const extensionPath = testdriver.os === 'windows'
|
|
27
|
+
? `${extensionsDir}\\functional-samples\\tutorial.hello-world`
|
|
28
|
+
: `${extensionsDir}/functional-samples/tutorial.hello-world`;
|
|
29
|
+
|
|
30
|
+
// Clone the Chrome extensions samples repo
|
|
31
|
+
const cloneCmd = testdriver.os === 'windows'
|
|
32
|
+
? `git clone --depth 1 https://github.com/GoogleChrome/chrome-extensions-samples.git "${extensionsDir}"`
|
|
33
|
+
: `git clone --depth 1 https://github.com/GoogleChrome/chrome-extensions-samples.git ${extensionsDir}`;
|
|
34
|
+
|
|
35
|
+
await testdriver.exec(shell, cloneCmd, 60000, true);
|
|
36
|
+
|
|
37
|
+
// Launch Chrome with the hello-world extension loaded
|
|
38
|
+
await testdriver.provision.chromeExtension({
|
|
39
|
+
extensionPath: extensionPath
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Navigate to testdriver.ai (extensions don't load on New Tab)
|
|
43
|
+
const addressBar = await testdriver.find("Chrome address bar");
|
|
44
|
+
await addressBar.click();
|
|
45
|
+
await testdriver.type("testdriver.ai");
|
|
46
|
+
await testdriver.pressKeys(["enter"]);
|
|
47
|
+
|
|
48
|
+
// Wait for page to load
|
|
49
|
+
const pageResult = await testdriver.assert("I can see testdriver.ai");
|
|
50
|
+
expect(pageResult).toBeTruthy();
|
|
51
|
+
|
|
52
|
+
// The hello-world extension adds a puzzle piece icon to the toolbar
|
|
53
|
+
// When clicked, it shows a popup with "Hello Extensions"
|
|
54
|
+
|
|
55
|
+
// Click on the extensions button (puzzle piece icon) in Chrome toolbar
|
|
56
|
+
const extensionsButton = await testdriver.find("The extensions button in the Chrome toolbar", {zoom: true});
|
|
57
|
+
await extensionsButton.click();
|
|
58
|
+
|
|
59
|
+
// Look for the hello world extension in the extensions menu
|
|
60
|
+
const helloExtension = await testdriver.find("Hello Extensions extension in the extensions dropdown");
|
|
61
|
+
await helloExtension.click();
|
|
62
|
+
|
|
63
|
+
await testdriver.wait(2000); // wait for the popup to open
|
|
64
|
+
|
|
65
|
+
// Verify the extension popup shows "Hello Extensions" text
|
|
66
|
+
const popupResult = await testdriver.assert("a popup shows with the text 'Hello Extensions'");
|
|
67
|
+
expect(popupResult).toBeTruthy();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// it("should load Loom from Chrome Web Store by extensionId", async (context) => {
|
|
71
|
+
// const testdriver = TestDriver(context, { ...getDefaults(context) });
|
|
72
|
+
|
|
73
|
+
// // Launch Chrome with Loom loaded by its Chrome Web Store ID
|
|
74
|
+
// // Loom ID: liecbddmkiiihnedobmlmillhodjkdmb
|
|
75
|
+
// await testdriver.provision.chromeExtension({
|
|
76
|
+
// extensionId: 'liecbddmkiiihnedobmlmillhodjkdmb'
|
|
77
|
+
// });
|
|
78
|
+
|
|
79
|
+
// // Navigate to testdriver.ai (extensions don't load on New Tab)
|
|
80
|
+
// const addressBar = await testdriver.find("Chrome address bar");
|
|
81
|
+
// await addressBar.click();
|
|
82
|
+
// await testdriver.type("testdriver.ai");
|
|
83
|
+
// await testdriver.pressKeys(["enter"]);
|
|
84
|
+
|
|
85
|
+
// // Wait for page to load
|
|
86
|
+
// const pageResult = await testdriver.assert("I can see testdriver.ai");
|
|
87
|
+
// expect(pageResult).toBeTruthy();
|
|
88
|
+
|
|
89
|
+
// // Click on the extensions button (puzzle piece icon) in Chrome toolbar
|
|
90
|
+
// const extensionsButton = await testdriver.find("The puzzle-shaped icon in the Chrome toolbar.", {zoom: true});
|
|
91
|
+
// await extensionsButton.click();
|
|
92
|
+
|
|
93
|
+
// // Look for Loom in the extensions menu
|
|
94
|
+
// const loomExtension = await testdriver.find("Loom extension in the extensions dropdown");
|
|
95
|
+
// expect(loomExtension.found()).toBeTruthy();
|
|
96
|
+
// });
|
|
97
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Element Not Found Test
|
|
3
|
+
* Tests that finding a non-existent element returns properly without timing out
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
8
|
+
import { getDefaults } from "./config.mjs";
|
|
9
|
+
|
|
10
|
+
describe("Element Not Found Test", () => {
|
|
11
|
+
it("should handle non-existent element gracefully without timing out", async (context) => {
|
|
12
|
+
const testdriver = TestDriver(context, { ...getDefaults(context), headless: true });
|
|
13
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
14
|
+
|
|
15
|
+
//
|
|
16
|
+
|
|
17
|
+
// Try to find an element that definitely doesn't exist
|
|
18
|
+
const element = await testdriver.find(
|
|
19
|
+
"a purple unicorn dancing on the moon",
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
// Should return an element that is not found
|
|
23
|
+
expect(element.found()).toBe(false);
|
|
24
|
+
expect(element.coordinates).toBeNull();
|
|
25
|
+
}); // 90 second timeout for the test (should complete much faster)
|
|
26
|
+
});
|
|
27
|
+
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Exec Output Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/exec-output.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
8
|
+
import { getDefaults } from "./config.mjs";
|
|
9
|
+
|
|
10
|
+
describe.skip("Exec Output Test", () => {
|
|
11
|
+
it(
|
|
12
|
+
"should set date using PowerShell and navigate to calendar",
|
|
13
|
+
async (context) => {
|
|
14
|
+
const testdriver = TestDriver(context, { ...getDefaults(context), headless: true });
|
|
15
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
16
|
+
|
|
17
|
+
//
|
|
18
|
+
// Generate date in query string format
|
|
19
|
+
const queryString = await testdriver.exec(
|
|
20
|
+
"pwsh",
|
|
21
|
+
`
|
|
22
|
+
$date = (Get-Date).AddMonths(1)
|
|
23
|
+
Write-Output $date.ToString("yyyy-MM-dd")
|
|
24
|
+
`,
|
|
25
|
+
10000,
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
// Assert that the date is valid
|
|
29
|
+
const dateValidResult = await testdriver.assert(
|
|
30
|
+
`${queryString} is a valid date`,
|
|
31
|
+
);
|
|
32
|
+
expect(dateValidResult).toBeTruthy();
|
|
33
|
+
|
|
34
|
+
// Generate date in display format
|
|
35
|
+
const expectedDate = await testdriver.exec(
|
|
36
|
+
"pwsh",
|
|
37
|
+
`
|
|
38
|
+
$date = (Get-Date).AddMonths(1)
|
|
39
|
+
Write-Output $date.ToString("ddd MMM d yyyy")
|
|
40
|
+
`,
|
|
41
|
+
10000,
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
// Navigate to calendar with date parameter
|
|
45
|
+
await testdriver.focusApplication("Google Chrome");
|
|
46
|
+
await testdriver.pressKeys(["ctrl", "l"]);
|
|
47
|
+
await testdriver.type(
|
|
48
|
+
`https://teamup.com/ks48cf2135e7e080bc?view=d&date=${queryString}`,
|
|
49
|
+
);
|
|
50
|
+
await testdriver.pressKeys(["enter"]);
|
|
51
|
+
|
|
52
|
+
// Assert that the expected date shows
|
|
53
|
+
await testdriver.focusApplication("Google Chrome");
|
|
54
|
+
const result = await testdriver.assert(
|
|
55
|
+
`the text ${expectedDate} is visible on screen`,
|
|
56
|
+
);
|
|
57
|
+
expect(result).toBeTruthy();
|
|
58
|
+
},
|
|
59
|
+
);
|
|
60
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Exec Shell Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/exec-shell.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
8
|
+
import { getDefaults } from "./config.mjs";
|
|
9
|
+
|
|
10
|
+
describe.skip("Exec PowerShell Test", () => {
|
|
11
|
+
it(
|
|
12
|
+
"should generate random email using PowerShell and enter it",
|
|
13
|
+
async (context) => {
|
|
14
|
+
const testdriver = TestDriver(context, { ...getDefaults(context), headless: true });
|
|
15
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
16
|
+
|
|
17
|
+
//
|
|
18
|
+
// Generate random email using PowerShell
|
|
19
|
+
const randomEmail = await testdriver.exec({
|
|
20
|
+
language: "pwsh",
|
|
21
|
+
code: `
|
|
22
|
+
# Random email generator in PowerShell
|
|
23
|
+
|
|
24
|
+
# Arrays of possible names and domains
|
|
25
|
+
$firstNames = @("john", "jane", "alex", "chris", "sara", "mike", "lisa", "david", "emma", "ryan")
|
|
26
|
+
$lastNames = @("smith", "johnson", "williams", "brown", "jones", "garcia", "miller", "davis", "martin", "lee")
|
|
27
|
+
$domains = @("example.com", "testmail.com", "mailinator.com", "demo.org", "company.net")
|
|
28
|
+
|
|
29
|
+
# Random selection
|
|
30
|
+
$first = Get-Random -InputObject $firstNames
|
|
31
|
+
$last = Get-Random -InputObject $lastNames
|
|
32
|
+
$domain = Get-Random -InputObject $domains
|
|
33
|
+
$number = Get-Random -Minimum 1 -Maximum 1000
|
|
34
|
+
|
|
35
|
+
# Generate the email
|
|
36
|
+
$email = "$first.$last$number@$domain".ToLower()
|
|
37
|
+
|
|
38
|
+
# Output
|
|
39
|
+
Write-Output "$email"
|
|
40
|
+
`,
|
|
41
|
+
timeout: 10000,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Enter the email in username field
|
|
45
|
+
const usernameField = await testdriver.find(
|
|
46
|
+
"Username, input field for username",
|
|
47
|
+
);
|
|
48
|
+
await usernameField.click();
|
|
49
|
+
await testdriver.type(randomEmail);
|
|
50
|
+
|
|
51
|
+
// Assert that the username field shows a valid email address
|
|
52
|
+
const result = await testdriver.assert(
|
|
53
|
+
`the username field contains ${randomEmail} which is a valid email address`,
|
|
54
|
+
);
|
|
55
|
+
expect(result).toBeTruthy();
|
|
56
|
+
},
|
|
57
|
+
);
|
|
58
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - FindAll Coffee Icons Test
|
|
3
|
+
* Loads a random icon grid and uses findAll() to locate and click all 4 coffee cup icons
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
8
|
+
import { getDefaults } from "./config.mjs";
|
|
9
|
+
|
|
10
|
+
describe("FindAll Coffee Icons", () => {
|
|
11
|
+
it("should find and click all 4 coffee cup icons", async (context) => {
|
|
12
|
+
const testdriver = TestDriver(context, {
|
|
13
|
+
...getDefaults(context),
|
|
14
|
+
headless: true,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
await testdriver.provision.chrome({
|
|
18
|
+
url: "https://v0-random-icon-grid.vercel.app/",
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Use findAll to locate all coffee cup icons on the page
|
|
22
|
+
const coffeeIcons = await testdriver.findAll("coffee cup icon, there are exactly 4 on the page");
|
|
23
|
+
|
|
24
|
+
// Log each icon's coordinates
|
|
25
|
+
console.log(`Found ${coffeeIcons.length} coffee icons:`);
|
|
26
|
+
coffeeIcons.forEach((icon, i) => {
|
|
27
|
+
console.log(` Icon ${i + 1}: (${icon.x}, ${icon.y}) center=(${icon.centerX}, ${icon.centerY})`);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Verify we found 3 or 4 coffee icons
|
|
31
|
+
expect(coffeeIcons.length).toBeGreaterThanOrEqual(3);
|
|
32
|
+
expect(coffeeIcons.length).toBeLessThanOrEqual(4);
|
|
33
|
+
|
|
34
|
+
// Click each coffee cup icon
|
|
35
|
+
for (const icon of coffeeIcons) {
|
|
36
|
+
await icon.click();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Verify the selection count is displayed
|
|
40
|
+
await testdriver.assert("the page says 'Selected: 3 / 4' or 'Matched 4 of a kind!'");
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Focus Window Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/focus-window.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
8
|
+
import { getDefaults } from "./config.mjs";
|
|
9
|
+
|
|
10
|
+
describe("Focus Window Test", () => {
|
|
11
|
+
it.skip(
|
|
12
|
+
"should click Microsoft Edge icon and focus Google Chrome",
|
|
13
|
+
async (context) => {
|
|
14
|
+
const testdriver = TestDriver(context, { ...getDefaults(context), headless: true });
|
|
15
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
16
|
+
|
|
17
|
+
//
|
|
18
|
+
// Show desktop
|
|
19
|
+
await testdriver.pressKeys(["winleft", "d"]);
|
|
20
|
+
|
|
21
|
+
// Click on the Microsoft Edge icon
|
|
22
|
+
const edgeIcon = await testdriver.find(
|
|
23
|
+
"a blue and green swirl icon on the taskbar representing Microsoft Edge",
|
|
24
|
+
);
|
|
25
|
+
await edgeIcon.click();
|
|
26
|
+
|
|
27
|
+
// Focus Google Chrome
|
|
28
|
+
await testdriver.focusApplication("Google Chrome");
|
|
29
|
+
|
|
30
|
+
// Assert Chrome is focused (implicit through successful focus)
|
|
31
|
+
const result = await testdriver.assert(
|
|
32
|
+
"Google Chrome is the focused application",
|
|
33
|
+
);
|
|
34
|
+
expect(result).toBeTruthy();
|
|
35
|
+
},
|
|
36
|
+
);
|
|
37
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Formatted Logging Demo
|
|
3
|
+
* Demonstrates nice Vitest-style formatted logs for Dashcam replay
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
8
|
+
import { getDefaults } from "./config.mjs";
|
|
9
|
+
|
|
10
|
+
describe("Formatted Logging Test", () => {
|
|
11
|
+
it("should demonstrate formatted logs in dashcam replay", async (context) => {
|
|
12
|
+
const testdriver = TestDriver(context, { ...getDefaults(context), headless: true });
|
|
13
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
14
|
+
|
|
15
|
+
// Find and click - logs will be nicely formatted
|
|
16
|
+
const signInButton = await testdriver.find(
|
|
17
|
+
"Sign In, black button below the password field",
|
|
18
|
+
);
|
|
19
|
+
await signInButton.click();
|
|
20
|
+
|
|
21
|
+
// Assert - logs will show pass/fail with nice formatting
|
|
22
|
+
const result = await testdriver.assert(
|
|
23
|
+
"an error shows that fields are required",
|
|
24
|
+
);
|
|
25
|
+
expect(result).toBeTruthy();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Hover Image Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/hover-image.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
8
|
+
import { getDefaults } from "./config.mjs";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Perform login flow for SauceLabs demo app
|
|
12
|
+
* @param {import('../../sdk.js').default} client - TestDriver client instance
|
|
13
|
+
* @param {string} username - Username (default: 'standard_user')
|
|
14
|
+
*/
|
|
15
|
+
async function performLogin(client, username = "standard_user") {
|
|
16
|
+
await client.focusApplication("Google Chrome");
|
|
17
|
+
const password = await client.extract("the password");
|
|
18
|
+
const usernameField = await client.find(
|
|
19
|
+
"username input",
|
|
20
|
+
);
|
|
21
|
+
await usernameField.click();
|
|
22
|
+
await client.type(username);
|
|
23
|
+
await client.pressKeys(["tab"]);
|
|
24
|
+
await client.type(password, { secret: true });
|
|
25
|
+
await client.pressKeys(["tab"]);
|
|
26
|
+
await client.pressKeys(["enter"]);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
describe("Hover Image Test", () => {
|
|
30
|
+
it("should click on shopping cart icon and verify empty cart", async (context) => {
|
|
31
|
+
const testdriver = TestDriver(context, { ...getDefaults(context) });
|
|
32
|
+
|
|
33
|
+
// provision.chrome() automatically calls ready() and starts dashcam
|
|
34
|
+
await testdriver.provision.chrome({
|
|
35
|
+
url: 'http://testdriver-sandbox.vercel.app/login'
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Perform login first
|
|
39
|
+
await performLogin(testdriver);
|
|
40
|
+
|
|
41
|
+
// Click on the shopping cart icon
|
|
42
|
+
await testdriver.focusApplication("Google Chrome");
|
|
43
|
+
const cartIcon = await testdriver.find(
|
|
44
|
+
"shopping cart icon next to the Cart text in the top right corner",
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
await cartIcon.click();
|
|
48
|
+
|
|
49
|
+
// Assert that you see an empty shopping cart
|
|
50
|
+
const result = await testdriver.assert("Your cart is empty");
|
|
51
|
+
expect(result).toBeTruthy();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Hover Text With Description Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/hover-text-with-description.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
8
|
+
import { getDefaults } from "./config.mjs";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Perform login flow for SauceLabs demo app
|
|
12
|
+
* @param {TestDriver} client - TestDriver client
|
|
13
|
+
* @param {string} username - Username (default: 'standard_user')
|
|
14
|
+
*/
|
|
15
|
+
async function performLogin(client, username = "standard_user") {
|
|
16
|
+
await client.focusApplication("Google Chrome");
|
|
17
|
+
const password = await client.extract("the password");
|
|
18
|
+
const usernameField = await client.find("username input");
|
|
19
|
+
await usernameField.click();
|
|
20
|
+
await client.type(username);
|
|
21
|
+
await client.pressKeys(["tab"]);
|
|
22
|
+
await client.type(password, { secret: true });
|
|
23
|
+
await client.pressKeys(["tab"]);
|
|
24
|
+
await client.pressKeys(["enter"]);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
describe("Hover Text With Description Test", () => {
|
|
28
|
+
it("should add TestDriver Hat to cart and verify", async (context) => {
|
|
29
|
+
const testdriver = TestDriver(context, {
|
|
30
|
+
...getDefaults(context),
|
|
31
|
+
headless: true,
|
|
32
|
+
});
|
|
33
|
+
await testdriver.provision.chrome({
|
|
34
|
+
url: "http://testdriver-sandbox.vercel.app/login",
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
//
|
|
38
|
+
// Perform login first
|
|
39
|
+
await performLogin(testdriver);
|
|
40
|
+
|
|
41
|
+
// Click on "Add to Cart" under TestDriver Hat
|
|
42
|
+
const addToCartButton = await testdriver.find(
|
|
43
|
+
"Add to Cart, add to cart button under TestDriver Hat",
|
|
44
|
+
);
|
|
45
|
+
await addToCartButton.click();
|
|
46
|
+
|
|
47
|
+
// Click on the cart
|
|
48
|
+
const cartButton = await testdriver.find(
|
|
49
|
+
"Cart, cart button in the top right corner",
|
|
50
|
+
);
|
|
51
|
+
await cartButton.click();
|
|
52
|
+
|
|
53
|
+
// Assert the TestDriver Hat is in the cart
|
|
54
|
+
const result = await testdriver.assert("There is an item in the cart");
|
|
55
|
+
expect(result).toBeTruthy();
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Hover Text Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/hover-text.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
8
|
+
import { getDefaults } from "./config.mjs";
|
|
9
|
+
|
|
10
|
+
describe("Hover Text Test", () => {
|
|
11
|
+
it("should click Sign In and verify error message", async (context) => {
|
|
12
|
+
const testdriver = TestDriver(context, { ...getDefaults(context) });
|
|
13
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
14
|
+
|
|
15
|
+
// Click on Sign In button using new find() API
|
|
16
|
+
|
|
17
|
+
const signInButton = await testdriver.find(
|
|
18
|
+
"Sign In, black button below the password field",
|
|
19
|
+
);
|
|
20
|
+
await signInButton.click();
|
|
21
|
+
|
|
22
|
+
// Assert that an error shows that fields are required
|
|
23
|
+
const result = await testdriver.assert(
|
|
24
|
+
"an error shows that fields are required",
|
|
25
|
+
);
|
|
26
|
+
expect(result).toBeTruthy();
|
|
27
|
+
});
|
|
28
|
+
});
|