testdriverai 6.2.2 → 7.1.0
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/.github/workflows/acceptance-linux.yml +75 -0
- package/.github/workflows/acceptance-sdk-tests.yml +133 -0
- package/.vscode/settings.json +5 -1
- package/AGENTS.md +550 -0
- package/CODEOWNERS +0 -1
- package/README.md +126 -0
- package/{testdriver → _testdriver}/acceptance/drag-and-drop.yaml +2 -2
- package/{testdriver → _testdriver}/acceptance/snippets/login.yaml +1 -1
- package/_testdriver/examples/desktop/lifecycle/prerun.yaml +0 -0
- package/{testdriver → _testdriver}/examples/web/lifecycle/prerun.yaml +6 -1
- package/{testdriver → _testdriver}/lifecycle/postrun.yaml +3 -2
- package/_testdriver/lifecycle/prerun.yaml +15 -0
- package/{testdriver → _testdriver}/lifecycle/provision.yaml +7 -2
- package/agent/index.js +300 -85
- package/agent/interface.js +15 -0
- package/agent/lib/cache.js +142 -0
- package/agent/lib/commander.js +1 -39
- package/agent/lib/commands.js +910 -296
- package/agent/lib/redraw.js +129 -41
- package/agent/lib/sandbox.js +29 -6
- package/agent/lib/sdk.js +22 -0
- package/agent/lib/system.js +0 -3
- package/agent/lib/validation.js +1 -7
- package/debug-locate-response.js +82 -0
- package/debugger/index.html +15 -4
- package/docs/ARCHITECTURE.md +424 -0
- package/docs/AWESOME_LOGS_QUICK_REF.md +100 -0
- package/docs/MIGRATION.md +425 -0
- package/docs/PRESETS.md +210 -0
- package/docs/QUICK_START_TEST_RECORDING.md +215 -0
- package/docs/SDK_AWESOME_LOGS.md +468 -0
- package/docs/TEST_RECORDING.md +388 -0
- package/docs/docs.json +286 -152
- package/docs/guide/best-practices-polling.mdx +154 -0
- package/docs/sdk-browser-rendering.md +167 -0
- package/docs/v6/getting-started/self-hosting.mdx +407 -0
- package/docs/{guide → v6/guide}/dashcam.mdx +1 -1
- package/docs/{guide → v6/guide}/environment-variables.mdx +4 -5
- package/docs/{guide → v6/guide}/lifecycle.mdx +1 -1
- package/docs/v6/overview/comparison.mdx +101 -0
- package/docs/v7/README.md +135 -0
- package/docs/v7/api/ai.mdx +205 -0
- package/docs/v7/api/assert.mdx +285 -0
- package/docs/v7/api/assertions.mdx +403 -0
- package/docs/v7/api/click.mdx +287 -0
- package/docs/v7/api/client.mdx +322 -0
- package/docs/v7/api/dashcam.mdx +497 -0
- package/docs/v7/api/doubleClick.mdx +102 -0
- package/docs/v7/api/elements.mdx +479 -0
- package/docs/v7/api/exec.mdx +346 -0
- package/docs/v7/api/find.mdx +316 -0
- package/docs/v7/api/focusApplication.mdx +294 -0
- package/docs/v7/api/hover.mdx +279 -0
- package/docs/v7/api/mouseDown.mdx +161 -0
- package/docs/v7/api/mouseUp.mdx +164 -0
- package/docs/v7/api/pressKeys.mdx +349 -0
- package/docs/v7/api/rightClick.mdx +123 -0
- package/docs/v7/api/sandbox.mdx +404 -0
- package/docs/v7/api/scroll.mdx +300 -0
- package/docs/v7/api/type.mdx +314 -0
- package/docs/v7/commands/assert.mdx +45 -0
- package/docs/v7/commands/exec.mdx +282 -0
- package/docs/v7/commands/focus-application.mdx +44 -0
- package/docs/v7/commands/hover-image.mdx +69 -0
- package/docs/v7/commands/hover-text.mdx +47 -0
- package/docs/v7/commands/if.mdx +53 -0
- package/docs/v7/commands/match-image.mdx +67 -0
- package/docs/v7/commands/press-keys.mdx +87 -0
- package/docs/v7/commands/remember.mdx +49 -0
- package/docs/v7/commands/run.mdx +44 -0
- package/docs/v7/commands/scroll-until-image.mdx +66 -0
- package/docs/v7/commands/scroll-until-text.mdx +60 -0
- package/docs/v7/commands/scroll.mdx +69 -0
- package/docs/v7/commands/type.mdx +45 -0
- package/docs/v7/commands/wait-for-image.mdx +54 -0
- package/docs/v7/commands/wait-for-text.mdx +48 -0
- package/docs/v7/commands/wait.mdx +45 -0
- package/docs/v7/getting-started/configuration.mdx +380 -0
- package/docs/v7/getting-started/quickstart.mdx +332 -0
- package/docs/v7/guides/best-practices.mdx +486 -0
- package/docs/v7/guides/caching-ai.mdx +215 -0
- package/docs/v7/guides/caching-selectors.mdx +292 -0
- package/docs/v7/guides/caching.mdx +366 -0
- package/docs/v7/guides/ci-cd/azure.mdx +587 -0
- package/docs/v7/guides/ci-cd/circleci.mdx +523 -0
- package/docs/v7/guides/ci-cd/github-actions.mdx +457 -0
- package/docs/v7/guides/ci-cd/gitlab.mdx +498 -0
- package/docs/v7/guides/ci-cd/jenkins.mdx +664 -0
- package/docs/v7/guides/ci-cd/travis.mdx +438 -0
- package/docs/v7/guides/debugging.mdx +349 -0
- package/docs/v7/guides/faq.mdx +393 -0
- package/docs/v7/guides/migration.mdx +562 -0
- package/docs/v7/guides/performance.mdx +517 -0
- package/docs/{getting-started → v7/guides}/self-hosting.mdx +11 -12
- package/docs/v7/guides/troubleshooting.mdx +526 -0
- package/docs/v7/guides/vitest-plugin.mdx +477 -0
- package/docs/v7/guides/vitest.mdx +535 -0
- package/docs/v7/platforms/linux.mdx +308 -0
- package/docs/v7/platforms/macos.mdx +433 -0
- package/docs/v7/platforms/windows.mdx +430 -0
- package/docs/v7/playwright.mdx +342 -0
- package/docs/v7/presets/chrome-extension.mdx +223 -0
- package/docs/v7/presets/chrome.mdx +287 -0
- package/docs/v7/presets/electron.mdx +435 -0
- package/docs/v7/presets/vscode.mdx +398 -0
- package/docs/v7/presets/webapp.mdx +396 -0
- package/docs/v7/progressive-apis/CORE.md +459 -0
- package/docs/v7/progressive-apis/HOOKS.md +360 -0
- package/docs/v7/progressive-apis/PROGRESSIVE_DISCLOSURE.md +230 -0
- package/docs/v7/progressive-apis/PROVISION.md +266 -0
- package/eslint.config.js +19 -1
- package/interfaces/cli/lib/base.js +10 -4
- package/interfaces/logger.js +2 -1
- package/interfaces/shared-test-state.mjs +69 -0
- package/interfaces/vitest-plugin.mjs +830 -0
- package/package.json +29 -5
- package/schema.json +8 -29
- package/scripts/view-test-results.mjs +96 -0
- package/sdk-log-formatter.js +714 -0
- package/sdk.d.ts +1028 -0
- package/sdk.js +2567 -0
- package/{.github/workflows/self-hosted.yml → self-hosted.yml} +13 -4
- package/setup/aws/cloudformation.yaml +9 -2
- package/src/core/Dashcam.js +469 -0
- package/src/core/index.d.ts +150 -0
- package/src/core/index.js +12 -0
- package/src/presets/index.mjs +331 -0
- package/src/vitest/extended.mjs +108 -0
- package/src/vitest/hooks.d.ts +119 -0
- package/src/vitest/hooks.mjs +298 -0
- package/src/vitest/index.mjs +64 -0
- package/src/vitest/lifecycle.mjs +277 -0
- package/src/vitest/utils.mjs +150 -0
- package/test/dashcam.test.js +137 -0
- package/test/mcp-example-test.yaml +27 -0
- package/testdriver/acceptance-sdk/QUICK_REFERENCE.md +61 -0
- package/testdriver/acceptance-sdk/README.md +128 -0
- package/testdriver/acceptance-sdk/TEST_REPORTING.md +245 -0
- package/testdriver/acceptance-sdk/assert.test.mjs +26 -0
- package/testdriver/acceptance-sdk/auto-cache-key-demo.test.mjs +56 -0
- package/testdriver/acceptance-sdk/chrome-extension.test.mjs +89 -0
- package/testdriver/acceptance-sdk/drag-and-drop.test.mjs +58 -0
- package/testdriver/acceptance-sdk/element-not-found.test.mjs +25 -0
- package/testdriver/acceptance-sdk/exec-js.test.mjs +43 -0
- package/testdriver/acceptance-sdk/exec-output.test.mjs +59 -0
- package/testdriver/acceptance-sdk/exec-pwsh.test.mjs +57 -0
- package/testdriver/acceptance-sdk/focus-window.test.mjs +36 -0
- package/testdriver/acceptance-sdk/formatted-logging.test.mjs +26 -0
- package/testdriver/acceptance-sdk/hooks-example.test.mjs +38 -0
- package/testdriver/acceptance-sdk/hover-image.test.mjs +34 -0
- package/testdriver/acceptance-sdk/hover-text-with-description.test.mjs +38 -0
- package/testdriver/acceptance-sdk/hover-text.test.mjs +27 -0
- package/testdriver/acceptance-sdk/match-image.test.mjs +36 -0
- package/testdriver/acceptance-sdk/presets-example.test.mjs +87 -0
- package/testdriver/acceptance-sdk/press-keys.test.mjs +50 -0
- package/testdriver/acceptance-sdk/prompt.test.mjs +33 -0
- package/testdriver/acceptance-sdk/scroll-keyboard.test.mjs +38 -0
- package/testdriver/acceptance-sdk/scroll-until-image.test.mjs +39 -0
- package/testdriver/acceptance-sdk/scroll-until-text.test.mjs +28 -0
- package/testdriver/acceptance-sdk/scroll.test.mjs +41 -0
- package/testdriver/acceptance-sdk/setup/globalTeardown.mjs +11 -0
- package/testdriver/acceptance-sdk/setup/testHelpers.mjs +420 -0
- package/testdriver/acceptance-sdk/setup/vitestSetup.mjs +40 -0
- package/testdriver/acceptance-sdk/sully-ai.test.mjs +234 -0
- package/testdriver/acceptance-sdk/test-console-logs.test.mjs +42 -0
- package/testdriver/acceptance-sdk/type-checking-demo.js +49 -0
- package/testdriver/acceptance-sdk/type.test.mjs +45 -0
- package/verify-element-api.js +89 -0
- package/verify-types.js +0 -0
- package/vitest.config.example.js +19 -0
- package/vitest.config.mjs +66 -0
- package/vitest.config.mjs.bak +44 -0
- package/.github/workflows/acceptance-v6.yml +0 -169
- package/.vscode/mcp.json +0 -9
- package/docs/overview/comparison.mdx +0 -82
- package/testdriver/lifecycle/prerun.yaml +0 -17
- /package/{testdriver/examples/desktop/lifecycle/prerun.yaml → .env.example} +0 -0
- /package/{testdriver → _testdriver}/acceptance/assert.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/dashcam.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/embed.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/exec-js.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/exec-output.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/exec-shell.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/focus-window.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/hover-image.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/hover-text-with-description.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/hover-text.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/if-else.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/match-image.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/press-keys.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/prompt.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/remember.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/screenshots/cart.png +0 -0
- /package/{testdriver → _testdriver}/acceptance/scroll-keyboard.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/scroll-until-image.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/scroll-until-text.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/scroll.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/snippets/match-cart.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/type.yaml +0 -0
- /package/{testdriver → _testdriver}/behavior/failure.yaml +0 -0
- /package/{testdriver → _testdriver}/behavior/hover-text.yaml +0 -0
- /package/{testdriver → _testdriver}/behavior/lifecycle/postrun.yaml +0 -0
- /package/{testdriver → _testdriver}/behavior/lifecycle/prerun.yaml +0 -0
- /package/{testdriver → _testdriver}/behavior/lifecycle/provision.yaml +0 -0
- /package/{testdriver → _testdriver}/behavior/secrets.yaml +0 -0
- /package/{testdriver → _testdriver}/edge-cases/dashcam-chrome.yaml +0 -0
- /package/{testdriver → _testdriver}/edge-cases/exec-pwsh-multiline.yaml +0 -0
- /package/{testdriver → _testdriver}/edge-cases/js-exception.yaml +0 -0
- /package/{testdriver → _testdriver}/edge-cases/js-promise.yaml +0 -0
- /package/{testdriver → _testdriver}/edge-cases/lifecycle/postrun.yaml +0 -0
- /package/{testdriver → _testdriver}/edge-cases/prompt-in-middle.yaml +0 -0
- /package/{testdriver → _testdriver}/edge-cases/prompt-nested.yaml +0 -0
- /package/{testdriver → _testdriver}/edge-cases/success-test.yaml +0 -0
- /package/{testdriver → _testdriver}/examples/android/example.yaml +0 -0
- /package/{testdriver → _testdriver}/examples/android/lifecycle/postrun.yaml +0 -0
- /package/{testdriver → _testdriver}/examples/android/lifecycle/provision.yaml +0 -0
- /package/{testdriver → _testdriver}/examples/android/readme.md +0 -0
- /package/{testdriver → _testdriver}/examples/chrome-extension/lifecycle/provision.yaml +0 -0
- /package/{testdriver → _testdriver}/examples/desktop/lifecycle/provision.yaml +0 -0
- /package/{testdriver → _testdriver}/examples/vscode-extension/lifecycle/provision.yaml +0 -0
- /package/{testdriver → _testdriver}/examples/web/lifecycle/postrun.yaml +0 -0
- /package/docs/{account → v6/account}/dashboard.mdx +0 -0
- /package/docs/{account → v6/account}/enterprise.mdx +0 -0
- /package/docs/{account → v6/account}/pricing.mdx +0 -0
- /package/docs/{account → v6/account}/projects.mdx +0 -0
- /package/docs/{account → v6/account}/team.mdx +0 -0
- /package/docs/{action → v6/action}/ami.mdx +0 -0
- /package/docs/{action → v6/action}/performance.mdx +0 -0
- /package/docs/{action → v6/action}/secrets.mdx +0 -0
- /package/docs/{apps → v6/apps}/chrome-extensions.mdx +0 -0
- /package/docs/{apps → v6/apps}/desktop-apps.mdx +0 -0
- /package/docs/{apps → v6/apps}/mobile-apps.mdx +0 -0
- /package/docs/{apps → v6/apps}/static-websites.mdx +0 -0
- /package/docs/{apps → v6/apps}/tauri-apps.mdx +0 -0
- /package/docs/{bugs → v6/bugs}/jira.mdx +0 -0
- /package/docs/{cli → v6/cli}/overview.mdx +0 -0
- /package/docs/{commands → v6/commands}/assert.mdx +0 -0
- /package/docs/{commands → v6/commands}/exec.mdx +0 -0
- /package/docs/{commands → v6/commands}/focus-application.mdx +0 -0
- /package/docs/{commands → v6/commands}/hover-image.mdx +0 -0
- /package/docs/{commands → v6/commands}/hover-text.mdx +0 -0
- /package/docs/{commands → v6/commands}/if.mdx +0 -0
- /package/docs/{commands → v6/commands}/match-image.mdx +0 -0
- /package/docs/{commands → v6/commands}/press-keys.mdx +0 -0
- /package/docs/{commands → v6/commands}/remember.mdx +0 -0
- /package/docs/{commands → v6/commands}/run.mdx +0 -0
- /package/docs/{commands → v6/commands}/scroll-until-image.mdx +0 -0
- /package/docs/{commands → v6/commands}/scroll-until-text.mdx +0 -0
- /package/docs/{commands → v6/commands}/scroll.mdx +0 -0
- /package/docs/{commands → v6/commands}/type.mdx +0 -0
- /package/docs/{commands → v6/commands}/wait-for-image.mdx +0 -0
- /package/docs/{commands → v6/commands}/wait-for-text.mdx +0 -0
- /package/docs/{commands → v6/commands}/wait.mdx +0 -0
- /package/docs/{exporting → v6/exporting}/junit.mdx +0 -0
- /package/docs/{exporting → v6/exporting}/playwright.mdx +0 -0
- /package/docs/{features → v6/features}/auto-healing.mdx +0 -0
- /package/docs/{features → v6/features}/generation.mdx +0 -0
- /package/docs/{features → v6/features}/parallel-testing.mdx +0 -0
- /package/docs/{features → v6/features}/reusable-snippets.mdx +0 -0
- /package/docs/{features → v6/features}/selectorless.mdx +0 -0
- /package/docs/{features → v6/features}/visual-assertions.mdx +0 -0
- /package/docs/{getting-started → v6/getting-started}/ci.mdx +0 -0
- /package/docs/{getting-started → v6/getting-started}/cli.mdx +0 -0
- /package/docs/{getting-started → v6/getting-started}/editing.mdx +0 -0
- /package/docs/{getting-started → v6/getting-started}/playwright.mdx +0 -0
- /package/docs/{getting-started → v6/getting-started}/running.mdx +0 -0
- /package/docs/{getting-started → v6/getting-started}/vscode.mdx +0 -0
- /package/docs/{guide → v6/guide}/assertions.mdx +0 -0
- /package/docs/{guide → v6/guide}/authentication.mdx +0 -0
- /package/docs/{guide → v6/guide}/code.mdx +0 -0
- /package/docs/{guide → v6/guide}/locating.mdx +0 -0
- /package/docs/{guide → v6/guide}/protips.mdx +0 -0
- /package/docs/{guide → v6/guide}/variables.mdx +0 -0
- /package/docs/{guide → v6/guide}/waiting.mdx +0 -0
- /package/docs/{importing → v6/importing}/csv.mdx +0 -0
- /package/docs/{importing → v6/importing}/gherkin.mdx +0 -0
- /package/docs/{importing → v6/importing}/jira.mdx +0 -0
- /package/docs/{importing → v6/importing}/testrail.mdx +0 -0
- /package/docs/{integrations → v6/integrations}/electron.mdx +0 -0
- /package/docs/{integrations → v6/integrations}/netlify.mdx +0 -0
- /package/docs/{integrations → v6/integrations}/vercel.mdx +0 -0
- /package/docs/{interactive → v6/interactive}/explore.mdx +0 -0
- /package/docs/{interactive → v6/interactive}/run.mdx +0 -0
- /package/docs/{interactive → v6/interactive}/save.mdx +0 -0
- /package/docs/{overview → v6/overview}/faq.mdx +0 -0
- /package/docs/{overview → v6/overview}/performance.mdx +0 -0
- /package/docs/{overview → v6/overview}/quickstart.mdx +0 -0
- /package/docs/{overview → v6/overview}/what-is-testdriver.mdx +0 -0
- /package/docs/{scenarios → v6/scenarios}/ai-chatbot.mdx +0 -0
- /package/docs/{scenarios → v6/scenarios}/cookie-banner.mdx +0 -0
- /package/docs/{scenarios → v6/scenarios}/file-upload.mdx +0 -0
- /package/docs/{scenarios → v6/scenarios}/form-filling.mdx +0 -0
- /package/docs/{scenarios → v6/scenarios}/log-in.mdx +0 -0
- /package/docs/{scenarios → v6/scenarios}/pdf-generation.mdx +0 -0
- /package/docs/{scenarios → v6/scenarios}/spell-check.mdx +0 -0
- /package/docs/{security → v6/security}/action.mdx +0 -0
- /package/docs/{security → v6/security}/agent.mdx +0 -0
- /package/docs/{security → v6/security}/platform.mdx +0 -0
- /package/docs/{tutorials → v6/tutorials}/advanced-test.mdx +0 -0
- /package/docs/{tutorials → v6/tutorials}/basic-test.mdx +0 -0
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
# Core Classes
|
|
2
|
+
|
|
3
|
+
Direct access to TestDriver and Dashcam classes for full manual control.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The core module provides the fundamental building blocks without any automatic lifecycle management. Use this when you need complete control or when working outside of Vitest.
|
|
8
|
+
|
|
9
|
+
```javascript
|
|
10
|
+
import { TestDriver, Dashcam } from 'testdriverai/core';
|
|
11
|
+
|
|
12
|
+
const client = new TestDriver(apiKey, { os: 'linux' });
|
|
13
|
+
await client.auth();
|
|
14
|
+
await client.connect();
|
|
15
|
+
|
|
16
|
+
const dashcam = new Dashcam(client);
|
|
17
|
+
await dashcam.start();
|
|
18
|
+
|
|
19
|
+
// Your test code
|
|
20
|
+
|
|
21
|
+
await dashcam.stop();
|
|
22
|
+
await client.disconnect();
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## TestDriver Class
|
|
26
|
+
|
|
27
|
+
### Constructor
|
|
28
|
+
|
|
29
|
+
```javascript
|
|
30
|
+
import { TestDriver } from 'testdriverai/core';
|
|
31
|
+
|
|
32
|
+
const client = new TestDriver(apiKey, options);
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Parameters:**
|
|
36
|
+
- `apiKey` - Your TestDriver API key (string)
|
|
37
|
+
- `options` - Configuration object
|
|
38
|
+
|
|
39
|
+
**Options:**
|
|
40
|
+
```javascript
|
|
41
|
+
{
|
|
42
|
+
os: 'linux', // Target OS: 'linux', 'mac', 'windows'
|
|
43
|
+
apiRoot: 'https://...', // API endpoint
|
|
44
|
+
resolution: '1366x768', // Screen resolution
|
|
45
|
+
newSandbox: true, // Create new sandbox
|
|
46
|
+
analytics: true, // Enable analytics
|
|
47
|
+
cacheThresholds: {
|
|
48
|
+
find: 0.05,
|
|
49
|
+
findAll: 0.05
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Methods
|
|
55
|
+
|
|
56
|
+
#### auth()
|
|
57
|
+
Authenticate with TestDriver API.
|
|
58
|
+
|
|
59
|
+
```javascript
|
|
60
|
+
await client.auth();
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
#### connect(options)
|
|
64
|
+
Connect to a sandbox instance.
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
await client.connect({
|
|
68
|
+
new: true // Create new sandbox (default: true)
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
#### disconnect()
|
|
73
|
+
Disconnect from sandbox and clean up.
|
|
74
|
+
|
|
75
|
+
```javascript
|
|
76
|
+
await client.disconnect();
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### find(query)
|
|
80
|
+
Find an element on screen.
|
|
81
|
+
|
|
82
|
+
```javascript
|
|
83
|
+
const element = await client.find('Login button');
|
|
84
|
+
await element.click();
|
|
85
|
+
|
|
86
|
+
// Or chain:
|
|
87
|
+
await client.find('Login button').then(el => el.click());
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
#### findAll(query)
|
|
91
|
+
Find all matching elements.
|
|
92
|
+
|
|
93
|
+
```javascript
|
|
94
|
+
const buttons = await client.findAll('button');
|
|
95
|
+
console.log('Found', buttons.length, 'buttons');
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
#### click(target)
|
|
99
|
+
Click an element.
|
|
100
|
+
|
|
101
|
+
```javascript
|
|
102
|
+
await client.click('Submit button');
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
#### type(text)
|
|
106
|
+
Type text (at current cursor position).
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
await client.type('username@example.com');
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### pressKeys(keys)
|
|
113
|
+
Press keyboard keys or shortcuts.
|
|
114
|
+
|
|
115
|
+
```javascript
|
|
116
|
+
await client.pressKeys(['ctrl', 'a']);
|
|
117
|
+
await client.pressKeys(['enter']);
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
#### exec(shell, command, timeout, ignoreError)
|
|
121
|
+
Execute shell command.
|
|
122
|
+
|
|
123
|
+
```javascript
|
|
124
|
+
const output = await client.exec(
|
|
125
|
+
'sh', // Shell: 'sh' or 'pwsh'
|
|
126
|
+
'google-chrome "https://..." &', // Command
|
|
127
|
+
30000, // Timeout (ms)
|
|
128
|
+
false // Ignore errors
|
|
129
|
+
);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
#### focusApplication(appName)
|
|
133
|
+
Focus/activate an application window.
|
|
134
|
+
|
|
135
|
+
```javascript
|
|
136
|
+
await client.focusApplication('Google Chrome');
|
|
137
|
+
await client.focusApplication('Visual Studio Code');
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
#### scroll(direction, amount)
|
|
141
|
+
Scroll the page.
|
|
142
|
+
|
|
143
|
+
```javascript
|
|
144
|
+
await client.scroll('down', 500);
|
|
145
|
+
await client.scroll('up', 200);
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### assert(query)
|
|
149
|
+
Assert that something is true on screen.
|
|
150
|
+
|
|
151
|
+
```javascript
|
|
152
|
+
const result = await client.assert('Login successful message appears');
|
|
153
|
+
// Returns boolean
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Dashcam Class
|
|
157
|
+
|
|
158
|
+
### Constructor
|
|
159
|
+
|
|
160
|
+
```javascript
|
|
161
|
+
import { Dashcam } from 'testdriverai/core';
|
|
162
|
+
|
|
163
|
+
const dashcam = new Dashcam(client, options);
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Parameters:**
|
|
167
|
+
- `client` - TestDriver instance (required)
|
|
168
|
+
- `options` - Configuration object (optional)
|
|
169
|
+
|
|
170
|
+
**Options:**
|
|
171
|
+
```javascript
|
|
172
|
+
{
|
|
173
|
+
apiKey: process.env.TD_API_KEY // API key (same as TestDriver)
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Methods
|
|
178
|
+
|
|
179
|
+
#### auth(apiKey)
|
|
180
|
+
Authenticate with Dashcam CLI.
|
|
181
|
+
|
|
182
|
+
```javascript
|
|
183
|
+
await dashcam.auth(); // Uses TD_API_KEY env var (same as TestDriver)
|
|
184
|
+
// Or:
|
|
185
|
+
await dashcam.auth('your-api-key');
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
#### start()
|
|
189
|
+
Start recording.
|
|
190
|
+
|
|
191
|
+
```javascript
|
|
192
|
+
await dashcam.start();
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
#### stop()
|
|
196
|
+
Stop recording and get replay URL.
|
|
197
|
+
|
|
198
|
+
```javascript
|
|
199
|
+
const url = await dashcam.stop();
|
|
200
|
+
console.log('Replay:', url);
|
|
201
|
+
// Returns: https://app.dashcam.io/replay/...
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
#### isRecording()
|
|
205
|
+
Check if currently recording.
|
|
206
|
+
|
|
207
|
+
```javascript
|
|
208
|
+
if (dashcam.isRecording()) {
|
|
209
|
+
console.log('Recording in progress');
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
#### addFileLog(path, name)
|
|
214
|
+
Add a file to Dashcam logs.
|
|
215
|
+
|
|
216
|
+
```javascript
|
|
217
|
+
await dashcam.addFileLog('/var/log/app.log', 'Application Log');
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
#### addApplicationLog(application, name)
|
|
221
|
+
Track an application in Dashcam.
|
|
222
|
+
|
|
223
|
+
```javascript
|
|
224
|
+
await dashcam.addApplicationLog('Google Chrome', 'Browser');
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Complete Examples
|
|
228
|
+
|
|
229
|
+
### Basic Test
|
|
230
|
+
|
|
231
|
+
```javascript
|
|
232
|
+
import { TestDriver } from 'testdriverai/core';
|
|
233
|
+
|
|
234
|
+
async function runTest() {
|
|
235
|
+
const client = new TestDriver(process.env.TD_API_KEY, {
|
|
236
|
+
os: 'linux',
|
|
237
|
+
resolution: '1920x1080'
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
try {
|
|
241
|
+
// Connect
|
|
242
|
+
await client.auth();
|
|
243
|
+
await client.connect({ new: true });
|
|
244
|
+
|
|
245
|
+
// Focus browser
|
|
246
|
+
await client.focusApplication('Google Chrome');
|
|
247
|
+
|
|
248
|
+
// Navigate
|
|
249
|
+
const urlBar = await client.find('URL bar');
|
|
250
|
+
await urlBar.click();
|
|
251
|
+
await client.type('https://example.com');
|
|
252
|
+
await client.pressKeys(['enter']);
|
|
253
|
+
|
|
254
|
+
// Test
|
|
255
|
+
await client.find('heading').click();
|
|
256
|
+
const result = await client.assert('page loaded successfully');
|
|
257
|
+
|
|
258
|
+
console.log('Test passed:', result);
|
|
259
|
+
} finally {
|
|
260
|
+
// Always disconnect
|
|
261
|
+
await client.disconnect();
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
runTest();
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### With Dashcam
|
|
269
|
+
|
|
270
|
+
```javascript
|
|
271
|
+
import { TestDriver, Dashcam } from 'testdriverai/core';
|
|
272
|
+
|
|
273
|
+
async function runRecordedTest() {
|
|
274
|
+
const client = new TestDriver(process.env.TD_API_KEY, { os: 'linux' });
|
|
275
|
+
const dashcam = new Dashcam(client);
|
|
276
|
+
|
|
277
|
+
try {
|
|
278
|
+
// Setup
|
|
279
|
+
await client.auth();
|
|
280
|
+
await client.connect();
|
|
281
|
+
|
|
282
|
+
// Start recording
|
|
283
|
+
await dashcam.auth();
|
|
284
|
+
await dashcam.start();
|
|
285
|
+
|
|
286
|
+
// Run test
|
|
287
|
+
await client.focusApplication('Google Chrome');
|
|
288
|
+
await client.find('button').click();
|
|
289
|
+
|
|
290
|
+
// Stop recording
|
|
291
|
+
const url = await dashcam.stop();
|
|
292
|
+
console.log('Replay URL:', url);
|
|
293
|
+
|
|
294
|
+
} finally {
|
|
295
|
+
await client.disconnect();
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
runRecordedTest();
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Multiple Operations
|
|
303
|
+
|
|
304
|
+
```javascript
|
|
305
|
+
import { TestDriver } from 'testdriverai/core';
|
|
306
|
+
|
|
307
|
+
async function complexTest() {
|
|
308
|
+
const client = new TestDriver(process.env.TD_API_KEY, { os: 'linux' });
|
|
309
|
+
|
|
310
|
+
await client.auth();
|
|
311
|
+
await client.connect();
|
|
312
|
+
|
|
313
|
+
try {
|
|
314
|
+
// Launch application
|
|
315
|
+
await client.exec(
|
|
316
|
+
'sh',
|
|
317
|
+
'google-chrome --start-maximized "https://example.com" &',
|
|
318
|
+
30000
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
await client.focusApplication('Google Chrome');
|
|
322
|
+
|
|
323
|
+
// Fill form
|
|
324
|
+
await client.find('username field').type('user@example.com');
|
|
325
|
+
await client.find('password field').type('password123');
|
|
326
|
+
await client.find('submit button').click();
|
|
327
|
+
|
|
328
|
+
// Navigate
|
|
329
|
+
await client.find('dashboard link').click();
|
|
330
|
+
|
|
331
|
+
// Scroll and interact
|
|
332
|
+
await client.scroll('down', 500);
|
|
333
|
+
await client.find('settings button').click();
|
|
334
|
+
|
|
335
|
+
// Verify
|
|
336
|
+
const result = await client.assert('settings page is visible');
|
|
337
|
+
console.log('Test result:', result);
|
|
338
|
+
|
|
339
|
+
} finally {
|
|
340
|
+
await client.disconnect();
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
complexTest();
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Error Handling
|
|
348
|
+
|
|
349
|
+
```javascript
|
|
350
|
+
import { TestDriver } from 'testdriverai/core';
|
|
351
|
+
|
|
352
|
+
async function testWithErrorHandling() {
|
|
353
|
+
const client = new TestDriver(process.env.TD_API_KEY, { os: 'linux' });
|
|
354
|
+
|
|
355
|
+
try {
|
|
356
|
+
await client.auth();
|
|
357
|
+
await client.connect();
|
|
358
|
+
|
|
359
|
+
await client.focusApplication('Google Chrome');
|
|
360
|
+
|
|
361
|
+
// Try to find element
|
|
362
|
+
const element = await client.find('optional button');
|
|
363
|
+
|
|
364
|
+
if (element.found()) {
|
|
365
|
+
await element.click();
|
|
366
|
+
} else {
|
|
367
|
+
console.log('Button not found, continuing...');
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
} catch (error) {
|
|
371
|
+
console.error('Test failed:', error);
|
|
372
|
+
throw error;
|
|
373
|
+
} finally {
|
|
374
|
+
// Always cleanup
|
|
375
|
+
try {
|
|
376
|
+
await client.disconnect();
|
|
377
|
+
} catch (cleanupError) {
|
|
378
|
+
console.error('Cleanup error:', cleanupError);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
## TypeScript Support
|
|
385
|
+
|
|
386
|
+
```typescript
|
|
387
|
+
import { TestDriver, Dashcam, TestDriverOptions, DashcamOptions } from 'testdriverai/core';
|
|
388
|
+
|
|
389
|
+
const options: TestDriverOptions = {
|
|
390
|
+
os: 'linux',
|
|
391
|
+
resolution: '1366x768',
|
|
392
|
+
newSandbox: true,
|
|
393
|
+
analytics: true
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
const client = new TestDriver(process.env.TD_API_KEY!, options);
|
|
397
|
+
|
|
398
|
+
const dashcamOptions: DashcamOptions = {
|
|
399
|
+
apiKey: process.env.TD_API_KEY // Same as TestDriver
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
const dashcam = new Dashcam(client, dashcamOptions);
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
## When to Use Core Classes
|
|
406
|
+
|
|
407
|
+
**Use core classes when:**
|
|
408
|
+
- You need full manual control
|
|
409
|
+
- You're not using Vitest
|
|
410
|
+
- You're integrating with another test framework
|
|
411
|
+
- You're building custom abstractions
|
|
412
|
+
- You're debugging lifecycle issues
|
|
413
|
+
- You're writing scripts, not tests
|
|
414
|
+
|
|
415
|
+
**Use hooks or provision() instead when:**
|
|
416
|
+
- You're using Vitest
|
|
417
|
+
- You want automatic cleanup
|
|
418
|
+
- You prefer simpler APIs
|
|
419
|
+
- You're testing common applications
|
|
420
|
+
|
|
421
|
+
## Best Practices
|
|
422
|
+
|
|
423
|
+
1. **Always disconnect** - Use try/finally to ensure cleanup
|
|
424
|
+
2. **Check element.found()** - Before using optional elements
|
|
425
|
+
3. **Handle errors gracefully** - Log and re-throw when appropriate
|
|
426
|
+
4. **Use TypeScript** - Get type safety and autocomplete
|
|
427
|
+
5. **Set reasonable timeouts** - Default is 30 seconds for exec()
|
|
428
|
+
6. **Focus applications** - Before interacting with them
|
|
429
|
+
|
|
430
|
+
## Platform Differences
|
|
431
|
+
|
|
432
|
+
### Shell Commands
|
|
433
|
+
|
|
434
|
+
**Linux/Mac:**
|
|
435
|
+
```javascript
|
|
436
|
+
await client.exec('sh', 'google-chrome "https://example.com" &', 30000);
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
**Windows:**
|
|
440
|
+
```javascript
|
|
441
|
+
await client.exec(
|
|
442
|
+
'pwsh',
|
|
443
|
+
'Start-Process "C:/Program Files/Google/Chrome/Application/chrome.exe" -ArgumentList "https://example.com"',
|
|
444
|
+
30000
|
|
445
|
+
);
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### Application Names
|
|
449
|
+
|
|
450
|
+
- Linux: `'Google Chrome'`, `'Firefox'`, `'Visual Studio Code'`
|
|
451
|
+
- Mac: `'Google Chrome'`, `'Firefox'`, `'Visual Studio Code'`
|
|
452
|
+
- Windows: `'Google Chrome'`, `'Firefox'`, `'Visual Studio Code'`
|
|
453
|
+
|
|
454
|
+
## See Also
|
|
455
|
+
|
|
456
|
+
- [Provision API](./PROVISION.md) - Simplified API for common apps
|
|
457
|
+
- [Hooks API](./HOOKS.md) - Automatic lifecycle management
|
|
458
|
+
- [Migration Guide](../MIGRATION.md) - Upgrading from v6
|
|
459
|
+
- [API Reference](../../sdk.js) - Full source code
|