@testdriverai/mcp 7.11.136-test → 7.11.138-test
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/ai/skills/testdriver-assert/SKILL.md +5 -5
- package/ai/skills/testdriver-caching/SKILL.md +2 -2
- package/ai/skills/testdriver-changelog/SKILL.md +186 -0
- package/ai/skills/testdriver-claude-mcp-plugin/SKILL.md +208 -0
- package/ai/skills/testdriver-click/SKILL.md +13 -13
- package/ai/skills/testdriver-client/SKILL.md +1 -1
- package/ai/skills/testdriver-debugging-with-screenshots/SKILL.md +5 -5
- package/ai/skills/testdriver-double-click/SKILL.md +7 -7
- package/ai/skills/testdriver-enterprise/SKILL.md +1 -1
- package/ai/skills/testdriver-events/SKILL.md +1 -1
- package/ai/skills/testdriver-exec/SKILL.md +10 -10
- package/ai/skills/testdriver-extract/SKILL.md +6 -6
- package/ai/skills/testdriver-find/SKILL.md +61 -61
- package/ai/skills/testdriver-focus-application/SKILL.md +6 -6
- package/ai/skills/testdriver-generating-tests/SKILL.md +3 -3
- package/ai/skills/testdriver-hosted/SKILL.md +3 -3
- package/ai/skills/testdriver-hover/SKILL.md +6 -6
- package/ai/skills/testdriver-making-assertions/SKILL.md +2 -2
- package/ai/skills/testdriver-mouse-down/SKILL.md +9 -9
- package/ai/skills/testdriver-mouse-up/SKILL.md +9 -9
- package/ai/skills/testdriver-parse/SKILL.md +4 -4
- package/ai/skills/testdriver-performing-actions/SKILL.md +4 -4
- package/ai/skills/testdriver-press-keys/SKILL.md +5 -5
- package/ai/skills/testdriver-quickstart/SKILL.md +51 -54
- package/ai/skills/testdriver-redraw/SKILL.md +1 -1
- package/ai/skills/testdriver-right-click/SKILL.md +7 -7
- package/ai/skills/testdriver-screenshot/SKILL.md +9 -9
- package/ai/skills/testdriver-scroll/SKILL.md +13 -13
- package/ai/skills/testdriver-self-hosted/SKILL.md +1 -1
- package/ai/skills/testdriver-type/SKILL.md +7 -7
- package/ai/skills/testdriver-wait/SKILL.md +5 -5
- package/ai/skills/testdriver-what-is-testdriver/SKILL.md +11 -11
- package/docs/{v7/_drafts → _drafts}/agents.mdx +1 -1
- package/docs/{v7/_drafts → _drafts}/best-practices.mdx +4 -4
- package/docs/{v7/_drafts → _drafts}/caching-selectors.mdx +3 -3
- package/docs/{v7/_drafts → _drafts}/configuration.mdx +4 -4
- package/docs/{v7/_drafts → _drafts}/debugging.mdx +4 -4
- package/docs/{v7/_drafts → _drafts}/error-handling.mdx +4 -4
- package/docs/{v7/_drafts → _drafts}/faq.mdx +7 -7
- package/docs/{v7/_drafts → _drafts}/installation.mdx +2 -2
- package/docs/{v7/_drafts → _drafts}/migration.mdx +4 -4
- package/docs/{v7/_drafts → _drafts}/observable.mdx +3 -3
- package/docs/{v7/_drafts → _drafts}/powerful.mdx +4 -4
- package/docs/{v7/_drafts → _drafts}/readme.mdx +11 -11
- package/docs/{v7/_drafts → _drafts}/reports.mdx +4 -4
- package/docs/{v7/_drafts → _drafts}/scalable.mdx +10 -10
- package/docs/{v7/_drafts → _drafts}/troubleshooting.mdx +4 -4
- package/docs/{v7/_drafts → _drafts}/vitest-plugin.mdx +2 -2
- package/docs/{v7/_drafts → _drafts}/vitest.mdx +9 -9
- package/docs/_scripts/generate-examples.js +9 -10
- package/docs/_scripts/generate-skills.js +4 -4
- package/docs/{v7/agent.mdx → agent.mdx} +17 -17
- package/docs/{v7/assert.mdx → assert.mdx} +5 -5
- package/docs/{v7/aws-setup.mdx → aws-setup.mdx} +6 -6
- package/docs/{v7/cache.mdx → cache.mdx} +9 -9
- package/docs/{v7/caching.mdx → caching.mdx} +13 -12
- package/docs/{v7/captcha.mdx → captcha.mdx} +7 -7
- package/docs/changelog.mdx +13 -13
- package/docs/{v7/ci-cd.mdx → ci-cd.mdx} +10 -10
- package/docs/{v7/click.mdx → click.mdx} +13 -13
- package/docs/client.mdx +323 -0
- package/docs/{v7/copilot → copilot}/auto-healing.mdx +2 -2
- package/docs/{v7/copilot → copilot}/running-tests.mdx +8 -8
- package/docs/{v7/customizing-devices.mdx → customizing-devices.mdx} +1 -1
- package/docs/{v7/dashcam.mdx → dashcam.mdx} +3 -3
- package/docs/{v7/debugging-with-screenshots.mdx → debugging-with-screenshots.mdx} +12 -12
- package/docs/docs.json +429 -288
- package/docs/{v7/double-click.mdx → double-click.mdx} +7 -7
- package/docs/{v7/elements.mdx → elements.mdx} +7 -7
- package/docs/{v7/enterprise.mdx → enterprise.mdx} +2 -2
- package/docs/{v7/errors.mdx → errors.mdx} +3 -3
- package/docs/{v7/events.mdx → events.mdx} +4 -4
- package/docs/{v7/exec.mdx → exec.mdx} +10 -10
- package/docs/{v7/extract.mdx → extract.mdx} +10 -10
- package/docs/{v7/find.mdx → find.mdx} +61 -61
- package/docs/{v7/focus-application.mdx → focus-application.mdx} +6 -6
- package/docs/{v7/generating-tests.mdx → generating-tests.mdx} +10 -10
- package/docs/guide/best-practices-polling.mdx +6 -1
- package/docs/{v7/hosted.mdx → hosted.mdx} +7 -7
- package/docs/{v7/hover.mdx → hover.mdx} +6 -6
- package/docs/interacting-with-your-app.mdx +198 -0
- package/docs/locating-elements.mdx +423 -0
- package/docs/{v7/making-assertions.mdx → making-assertions.mdx} +7 -7
- package/docs/{v7/mouse-down.mdx → mouse-down.mdx} +9 -9
- package/docs/{v7/mouse-up.mdx → mouse-up.mdx} +9 -9
- package/docs/options.mdx +320 -0
- package/docs/{v7/parse.mdx → parse.mdx} +12 -12
- package/docs/{v7/performing-actions.mdx → performing-actions.mdx} +11 -11
- package/docs/{v7/press-keys.mdx → press-keys.mdx} +5 -5
- package/docs/{v7/provision.mdx → provision.mdx} +9 -9
- package/docs/quickstart-cli.mdx +437 -0
- package/docs/quickstart-github.mdx +54 -0
- package/docs/quickstart-manual.mdx +135 -0
- package/docs/quickstart.mdx +22 -0
- package/docs/{v7/redraw.mdx → redraw.mdx} +7 -7
- package/docs/{v7/reusable-code.mdx → reusable-code.mdx} +3 -3
- package/docs/{v7/right-click.mdx → right-click.mdx} +7 -7
- package/docs/{v7/screenshot.mdx → screenshot.mdx} +9 -9
- package/docs/{v7/screenshots.mdx → screenshots.mdx} +3 -3
- package/docs/{v7/scroll.mdx → scroll.mdx} +13 -13
- package/docs/{v7/secrets.mdx → secrets.mdx} +4 -4
- package/docs/{v7/self-hosted.mdx → self-hosted.mdx} +7 -7
- package/docs/{v7/test-results-json.mdx → test-results-json.mdx} +4 -4
- package/docs/{v7/type.mdx → type.mdx} +7 -7
- package/docs/{v7/variables.mdx → variables.mdx} +2 -2
- package/docs/{v7/wait.mdx → wait.mdx} +5 -5
- package/docs/what-is-testdriver.mdx +54 -0
- package/lib/environments.json +1 -1
- package/lib/github-comment.mjs +2 -3
- package/package.json +1 -1
- package/scripts/generate-skills.js +1 -1
- package/docs/v7/client.mdx +0 -486
- package/docs/v7/quickstart.mdx +0 -451
- package/docs/v7/what-is-testdriver.mdx +0 -54
- /package/docs/{v7/_drafts → _drafts}/architecture.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/auto-cache-key.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/awesome-logs-quick-ref.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/cli-to-sdk-migration.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/commands/assert.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/commands/exec.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/commands/focus-application.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/commands/hover-image.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/commands/hover-text.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/commands/if.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/commands/match-image.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/commands/press-keys.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/commands/remember.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/commands/run.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/commands/scroll-until-image.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/commands/scroll-until-text.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/commands/scroll.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/commands/type.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/commands/wait-for-image.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/commands/wait-for-text.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/commands/wait.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/contributing.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/dashcam-title-feature.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/hooks.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/init-command.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/playwright.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/plugin-migration.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/presets.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/progressive-disclosure.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/provision.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/quick-start-test-recording.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/screenshot.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/sdk-awesome-logs.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/sdk-browser-rendering.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/sdk-migration.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/sdk-v7-complete.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/self-hosting.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/test-recording.mdx +0 -0
- /package/docs/{v7/_drafts → _drafts}/writing-tests.mdx +0 -0
- /package/docs/{v7/examples → examples}/ai.mdx +0 -0
- /package/docs/{v7/examples → examples}/assert.mdx +0 -0
- /package/docs/{v7/examples → examples}/captcha-api.mdx +0 -0
- /package/docs/{v7/examples → examples}/chrome-extension.mdx +0 -0
- /package/docs/{v7/examples → examples}/drag-and-drop.mdx +0 -0
- /package/docs/{v7/examples → examples}/element-not-found.mdx +0 -0
- /package/docs/{v7/examples → examples}/findall-coffee-icons.mdx +0 -0
- /package/docs/{v7/examples → examples}/formatted-logging.mdx +0 -0
- /package/docs/{v7/examples → examples}/hover-image.mdx +0 -0
- /package/docs/{v7/examples → examples}/hover-text-with-description.mdx +0 -0
- /package/docs/{v7/examples → examples}/hover-text.mdx +0 -0
- /package/docs/{v7/examples → examples}/installer.mdx +0 -0
- /package/docs/{v7/examples → examples}/launch-vscode-linux.mdx +0 -0
- /package/docs/{v7/examples → examples}/match-image.mdx +0 -0
- /package/docs/{v7/examples → examples}/parse.mdx +0 -0
- /package/docs/{v7/examples → examples}/press-keys.mdx +0 -0
- /package/docs/{v7/examples → examples}/scroll-keyboard.mdx +0 -0
- /package/docs/{v7/examples → examples}/scroll-until-text.mdx +0 -0
- /package/docs/{v7/examples → examples}/scroll.mdx +0 -0
- /package/docs/{v7/examples → examples}/type.mdx +0 -0
- /package/docs/{v7/mcp.mdx → mcp.mdx} +0 -0
|
@@ -4,11 +4,11 @@ description: "Build maintainable test suites with reusable code patterns"
|
|
|
4
4
|
icon: "recycle"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
When your test suite becomes larger, put the common patterns into reusable code. This keeps the tests short, easy to read, and easy to keep.
|
|
8
8
|
|
|
9
9
|
## Helper Functions
|
|
10
10
|
|
|
11
|
-
The
|
|
11
|
+
The most simple method is to put the common actions into helper functions. Make a `helpers/` directory for the shared utilities:
|
|
12
12
|
|
|
13
13
|
```javascript test/helpers/auth.js
|
|
14
14
|
export async function login(testdriver, { email, password }) {
|
|
@@ -37,7 +37,7 @@ export async function logout(testdriver) {
|
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
<Warning>
|
|
40
|
-
**
|
|
40
|
+
**Do not put dynamic values in element descriptions.** An element selector must describe the *type* of the element. It must not describe specific content that can change.
|
|
41
41
|
|
|
42
42
|
**❌ Bad:** `await testdriver.find('profile name TestDriver in the top right')`
|
|
43
43
|
**✅ Good:** `await testdriver.find('user profile name in the top right')`
|
|
@@ -6,7 +6,7 @@ icon: "bars"
|
|
|
6
6
|
|
|
7
7
|
## Overview
|
|
8
8
|
|
|
9
|
-
The `rightClick()` method
|
|
9
|
+
The `rightClick()` method does a right-click action on an element. It usually opens context menus. You can call it on an [`Element`](/core-concepts/elements) instance. Or you can use it with a selector.
|
|
10
10
|
|
|
11
11
|
## Syntax
|
|
12
12
|
|
|
@@ -30,7 +30,7 @@ When called directly on the AI client:
|
|
|
30
30
|
|
|
31
31
|
## Returns
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
It returns a `Promise<void>`. The promise resolves when the right-click action completes.
|
|
34
34
|
|
|
35
35
|
## Examples
|
|
36
36
|
|
|
@@ -116,8 +116,8 @@ test('uses custom context menu', async () => {
|
|
|
116
116
|
|
|
117
117
|
## Related Methods
|
|
118
118
|
|
|
119
|
-
- [`click()`](/
|
|
120
|
-
- [`doubleClick()`](/
|
|
121
|
-
- [`mouseDown()`](/
|
|
122
|
-
- [`mouseUp()`](/
|
|
123
|
-
- [`hover()`](/
|
|
119
|
+
- [`click()`](/click) - Single click on an element
|
|
120
|
+
- [`doubleClick()`](/double-click) - Double-click on an element
|
|
121
|
+
- [`mouseDown()`](/mouse-down) - Press mouse button without releasing
|
|
122
|
+
- [`mouseUp()`](/mouse-up) - Release mouse button
|
|
123
|
+
- [`hover()`](/hover) - Move mouse over element without clicking
|
|
@@ -7,10 +7,10 @@ icon: "camera"
|
|
|
7
7
|
|
|
8
8
|
## Overview
|
|
9
9
|
|
|
10
|
-
Capture a screenshot of the
|
|
10
|
+
Capture a screenshot of the screen. TestDriver saves it to a local file automatically. TestDriver groups the screenshots by test file. This makes debug and review easy.
|
|
11
11
|
|
|
12
12
|
<Note>
|
|
13
|
-
**Automatic Screenshots**: TestDriver can
|
|
13
|
+
**Automatic Screenshots**: TestDriver can capture screenshots automatically before and after each command (click, type, find, and more). It saves them with clear filenames such as `001-click-before-L42-submit-button.png`. The filename includes the line number from your test file. Enable this with `autoScreenshots: true` in your TestDriver options.
|
|
14
14
|
</Note>
|
|
15
15
|
|
|
16
16
|
## Syntax
|
|
@@ -22,16 +22,16 @@ const filePath = await testdriver.screenshot(filename)
|
|
|
22
22
|
## Parameters
|
|
23
23
|
|
|
24
24
|
<ParamField path="filename" type="string" optional>
|
|
25
|
-
|
|
25
|
+
A custom filename for the screenshot (without the .png extension). If you do not give one, TestDriver makes a filename from the timestamp automatically.
|
|
26
26
|
</ParamField>
|
|
27
27
|
|
|
28
28
|
## Returns
|
|
29
29
|
|
|
30
|
-
`Promise<string>` - The absolute file path where the screenshot
|
|
30
|
+
`Promise<string>` - The absolute file path where TestDriver saved the screenshot
|
|
31
31
|
|
|
32
32
|
## File Organization
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
TestDriver saves screenshots automatically to `.testdriver/screenshots/<test-file-name>/` in your project root:
|
|
35
35
|
|
|
36
36
|
```
|
|
37
37
|
.testdriver/
|
|
@@ -239,11 +239,11 @@ These commands allow you to:
|
|
|
239
239
|
- Compare screenshots across test runs to identify flaky behavior
|
|
240
240
|
|
|
241
241
|
<Note>
|
|
242
|
-
For detailed workflows and examples of using these MCP commands for debugging, see the [Debugging with Screenshots](/
|
|
242
|
+
For detailed workflows and examples of using these MCP commands for debugging, see the [Debugging with Screenshots](/debugging-with-screenshots) guide.
|
|
243
243
|
</Note>
|
|
244
244
|
|
|
245
245
|
## Related
|
|
246
246
|
|
|
247
|
-
- [Debugging with Screenshots](/
|
|
248
|
-
- [assert()](/
|
|
249
|
-
- [find()](/
|
|
247
|
+
- [Debugging with Screenshots](/debugging-with-screenshots) - View and analyze saved screenshots using MCP
|
|
248
|
+
- [assert()](/assert) - Make AI-powered assertions
|
|
249
|
+
- [find()](/find) - Locate elements on screen
|
|
@@ -8,11 +8,11 @@ mode: "wide"
|
|
|
8
8
|
|
|
9
9
|
## Overview
|
|
10
10
|
|
|
11
|
-
TestDriver can capture screenshots
|
|
11
|
+
TestDriver can capture screenshots by hand at any point during a test. It can also capture them automatically before and after each command. TestDriver saves the screenshots to a structured directory. This makes debug easy.
|
|
12
12
|
|
|
13
13
|
## Manual Screenshots
|
|
14
14
|
|
|
15
|
-
Use `testdriver.screenshot()` to capture the
|
|
15
|
+
Use `testdriver.screenshot()` to capture the present screen:
|
|
16
16
|
|
|
17
17
|
```javascript
|
|
18
18
|
const path = await testdriver.screenshot();
|
|
@@ -27,7 +27,7 @@ await testdriver.screenshot(filename?)
|
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
<ParamField path="filename" type="string">
|
|
30
|
-
|
|
30
|
+
A custom filename for the screenshot. TestDriver adds `.png` automatically if it is not there. If you do not give this, the default is `screenshot-<timestamp>.png`.
|
|
31
31
|
</ParamField>
|
|
32
32
|
|
|
33
33
|
**Returns:** `Promise<string>` — the absolute file path of the saved screenshot.
|
|
@@ -7,17 +7,17 @@ icon: "arrows-up-down"
|
|
|
7
7
|
|
|
8
8
|
## Overview
|
|
9
9
|
|
|
10
|
-
Scroll the page or active element in any direction
|
|
10
|
+
Scroll the page or the active element in any direction with the mouse wheel or the keyboard.
|
|
11
11
|
|
|
12
12
|
<Warning>
|
|
13
13
|
**Focus Requirements**
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
15
|
+
A scroll needs focus on the page or on a frame. If an input field or another interactive element has focus, scroll commands can fail. Before you scroll, put the focus on the page:
|
|
16
|
+
- Click a non-interactive area (for example, the page background)
|
|
17
|
+
- Push the Escape key to remove the focus from interactive elements
|
|
18
|
+
- Click outside of input fields or text areas
|
|
19
19
|
|
|
20
|
-
**If scroll
|
|
20
|
+
**If the scroll still does not work**, use the Page Down or Page Up keys directly:
|
|
21
21
|
```javascript
|
|
22
22
|
await testdriver.pressKeys(['pagedown']); // Scroll down
|
|
23
23
|
await testdriver.pressKeys(['pageup']); // Scroll up
|
|
@@ -89,7 +89,7 @@ await testdriver.pressKeys(['pagedown']);
|
|
|
89
89
|
## Best Practices
|
|
90
90
|
|
|
91
91
|
<Check>
|
|
92
|
-
**
|
|
92
|
+
**Make sure that the page has focus before you scroll**
|
|
93
93
|
|
|
94
94
|
```javascript
|
|
95
95
|
// After typing in an input, unfocus it first
|
|
@@ -110,7 +110,7 @@ await testdriver.pressKeys(['pagedown']);
|
|
|
110
110
|
</Check>
|
|
111
111
|
|
|
112
112
|
<Check>
|
|
113
|
-
**Control scroll distance with the options object**
|
|
113
|
+
**Control the scroll distance with the options object**
|
|
114
114
|
|
|
115
115
|
```javascript
|
|
116
116
|
// For web pages, mouse scroll works well
|
|
@@ -122,9 +122,9 @@ await testdriver.pressKeys(['pagedown']);
|
|
|
122
122
|
</Check>
|
|
123
123
|
|
|
124
124
|
<Warning>
|
|
125
|
-
**
|
|
125
|
+
**The keyboard scroll uses Page Down and Page Up**
|
|
126
126
|
|
|
127
|
-
|
|
127
|
+
A keyboard scroll usually moves one "page" each time. This can be more than the click amount that you set. It is more compatible than a mouse scroll, but it is less precise.
|
|
128
128
|
</Warning>
|
|
129
129
|
|
|
130
130
|
## Use Cases
|
|
@@ -201,6 +201,6 @@ describe('Scrolling', () => {
|
|
|
201
201
|
|
|
202
202
|
## Related Methods
|
|
203
203
|
|
|
204
|
-
- [`find()`](/
|
|
205
|
-
- [`pressKeys()`](/
|
|
206
|
-
- [`wait()`](/
|
|
204
|
+
- [`find()`](/find) - Find elements after a scroll
|
|
205
|
+
- [`pressKeys()`](/press-keys) - Use the Page Down and Page Up keys
|
|
206
|
+
- [`wait()`](/wait) - Wait after a scroll
|
|
@@ -4,11 +4,11 @@ description: "Securely manage passwords and sensitive data in your tests"
|
|
|
4
4
|
icon: "key"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
Protect sensitive information
|
|
7
|
+
Protect sensitive information such as passwords, API keys, and tokens in your TestDriver tests.
|
|
8
8
|
|
|
9
9
|
## Typing Secrets Securely
|
|
10
10
|
|
|
11
|
-
When
|
|
11
|
+
When you type sensitive information such as passwords, use the `secret: true` option. This stops TestDriver from a log or a store of the value:
|
|
12
12
|
|
|
13
13
|
```javascript
|
|
14
14
|
import { test } from 'vitest';
|
|
@@ -32,12 +32,12 @@ test('login with secure password', async (context) => {
|
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
<Note>
|
|
35
|
-
When `secret: true
|
|
35
|
+
When you set `secret: true`, the typed text shows as `****` in all logs, recordings, and dashcam output.
|
|
36
36
|
</Note>
|
|
37
37
|
|
|
38
38
|
## Storing Secrets in GitHub
|
|
39
39
|
|
|
40
|
-
Store sensitive credentials as GitHub repository secrets
|
|
40
|
+
Store sensitive credentials as GitHub repository secrets. Then they are never in your code:
|
|
41
41
|
|
|
42
42
|
<Steps>
|
|
43
43
|
<Step title="Navigate to Repository Settings">
|
|
@@ -6,26 +6,26 @@ icon: "server"
|
|
|
6
6
|
mode: "wide"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
Self-hosted is our enterprise solution for teams that need unlimited test
|
|
9
|
+
Self-hosted is our enterprise solution. Use it for teams that need unlimited test runs, infrastructure control, and dedicated support. The price uses **parallel test capacity** with a flat license fee. There is no per-second bill.
|
|
10
10
|
|
|
11
11
|
<CardGroup cols={2}>
|
|
12
12
|
<Card title="Unlimited Execution" icon="infinity">
|
|
13
|
-
Run as many tests as you want
|
|
13
|
+
Run as many tests as you want. There is no device-second count. The monthly costs are known.
|
|
14
14
|
</Card>
|
|
15
15
|
<Card title="Assisted Setup & Support" icon="headset">
|
|
16
|
-
Our team helps you deploy, configure, and optimize your infrastructure. Dedicated engineering support included.
|
|
16
|
+
Our team helps you to deploy, configure, and optimize your infrastructure. Dedicated engineering support is included.
|
|
17
17
|
</Card>
|
|
18
18
|
<Card title="Full Control" icon="gear">
|
|
19
|
-
Use your own AI keys, custom hardware, specific software, and network configurations. RDP into test machines for
|
|
19
|
+
Use your own AI keys, custom hardware, specific software, and network configurations. Use RDP into the test machines for debug.
|
|
20
20
|
</Card>
|
|
21
21
|
<Card title="Security & Compliance" icon="shield-check">
|
|
22
|
-
Keep data in your environment. Air-gapped deployment available for regulated industries.
|
|
22
|
+
Keep the data in your environment. Air-gapped deployment is available for regulated industries.
|
|
23
23
|
</Card>
|
|
24
24
|
</CardGroup>
|
|
25
25
|
|
|
26
26
|
## Deployment Options
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Select the level of control that you need:
|
|
29
29
|
|
|
30
30
|
| Component | Standard | Air-Gapped |
|
|
31
31
|
|-----------|----------|------------|
|
|
@@ -49,7 +49,7 @@ Run test sandboxes on your AWS infrastructure while using TestDriver's hosted da
|
|
|
49
49
|
<Card
|
|
50
50
|
title="AWS Setup Guide"
|
|
51
51
|
icon="aws"
|
|
52
|
-
href="/
|
|
52
|
+
href="/aws-setup"
|
|
53
53
|
>
|
|
54
54
|
Step-by-step instructions for deploying TestDriver on your AWS infrastructure using CloudFormation.
|
|
55
55
|
</Card>
|
|
@@ -7,9 +7,9 @@ icon: "file-code"
|
|
|
7
7
|
|
|
8
8
|
## Overview
|
|
9
9
|
|
|
10
|
-
TestDriver
|
|
10
|
+
TestDriver writes a JSON result file for each test case after it finishes. These files have full metadata about the test run. This includes the SDK version, the runner version, infrastructure details, interaction statistics, and links to recordings.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
TestDriver writes the result files to:
|
|
13
13
|
|
|
14
14
|
```
|
|
15
15
|
.testdriver/results/<testFile>/<testName>.json
|
|
@@ -22,12 +22,12 @@ For example, a test file `tests/login.test.mjs` with a test named `"should log i
|
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
<Note>
|
|
25
|
-
|
|
25
|
+
TestDriver makes the test names safe for the file system. It changes special characters to underscores. It cuts the names to 200 characters.
|
|
26
26
|
</Note>
|
|
27
27
|
|
|
28
28
|
## Enabling
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
You do not need configuration. The TestDriver Vitest reporter plugin writes the JSON files automatically each time the tests run.
|
|
31
31
|
|
|
32
32
|
## JSON Schema
|
|
33
33
|
|
|
@@ -7,7 +7,7 @@ icon: "keyboard"
|
|
|
7
7
|
|
|
8
8
|
## Overview
|
|
9
9
|
|
|
10
|
-
Type text or numbers into the
|
|
10
|
+
Type text or numbers into the input field that has focus. You can set an optional delay between the keystrokes.
|
|
11
11
|
|
|
12
12
|
## Syntax
|
|
13
13
|
|
|
@@ -30,7 +30,7 @@ await testdriver.type(text, options)
|
|
|
30
30
|
</ParamField>
|
|
31
31
|
|
|
32
32
|
<ParamField path="secret" type="boolean" default={false}>
|
|
33
|
-
If `true`,
|
|
33
|
+
If `true`, TestDriver makes the text sensitive data. It does not log or store it in the debug info or in dashcam.
|
|
34
34
|
</ParamField>
|
|
35
35
|
</Expandable>
|
|
36
36
|
</ParamField>
|
|
@@ -79,9 +79,9 @@ await testdriver.type('4111111111111111', { secret: true });
|
|
|
79
79
|
```
|
|
80
80
|
|
|
81
81
|
<Warning>
|
|
82
|
-
**Always use `secret: true` for passwords and sensitive data
|
|
82
|
+
**Always use `secret: true` for passwords and sensitive data.**
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
If you do not use this option, the typed text shows in these:
|
|
85
85
|
- Dashcam video replays
|
|
86
86
|
- TestDriver logs
|
|
87
87
|
- Debug screenshots
|
|
@@ -353,6 +353,6 @@ describe('Form Filling with Type', () => {
|
|
|
353
353
|
|
|
354
354
|
## Related Methods
|
|
355
355
|
|
|
356
|
-
- [`pressKeys()`](/
|
|
357
|
-
- [`find()`](/
|
|
358
|
-
- [`click()`](/
|
|
356
|
+
- [`pressKeys()`](/press-keys) - Press keyboard keys and shortcuts
|
|
357
|
+
- [`find()`](/find) - Locate input fields
|
|
358
|
+
- [`click()`](/click) - Focus input fields
|
|
@@ -4,11 +4,11 @@ description: "Use dynamic data and secure secrets in your tests"
|
|
|
4
4
|
icon: "square-root-variable"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Make your tests larger with dynamic data and secure secrets. Select the correct method for your test needs.
|
|
8
8
|
|
|
9
9
|
## Environment Variables
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Use environment variables for **configuration that changes between environments** (dev, staging, production). Also use them for **secrets that you must not commit to the code**. Use this method when you must run the same tests against different servers or with different credentials.
|
|
12
12
|
|
|
13
13
|
```javascript
|
|
14
14
|
import { test } from 'vitest';
|
|
@@ -8,7 +8,7 @@ icon: "clock"
|
|
|
8
8
|
|
|
9
9
|
## Description
|
|
10
10
|
|
|
11
|
-
The `wait` method
|
|
11
|
+
The `wait` method stops the test for a number of milliseconds. Then it continues. Use this to add delays between actions, to wait for animations to complete, or to let state changes become stable.
|
|
12
12
|
|
|
13
13
|
## Syntax
|
|
14
14
|
|
|
@@ -38,8 +38,8 @@ await testdriver.wait();
|
|
|
38
38
|
|
|
39
39
|
## Best Practices
|
|
40
40
|
|
|
41
|
-
- **Use for simple delays
|
|
42
|
-
- **
|
|
41
|
+
- **Use it for simple delays**. Wait for animations, transitions, or state changes after an action.
|
|
42
|
+
- **Do not use it to wait for an element**. If you wait for a specific element to show, use `find()` with a `timeout` option:
|
|
43
43
|
```javascript
|
|
44
44
|
// ✅ Better for waiting for elements
|
|
45
45
|
const element = await testdriver.find('success message', { timeout: 30000 });
|
|
@@ -48,5 +48,5 @@ await testdriver.wait();
|
|
|
48
48
|
await testdriver.wait(5000);
|
|
49
49
|
const element = await testdriver.find('success message');
|
|
50
50
|
```
|
|
51
|
-
-
|
|
52
|
-
- Use
|
|
51
|
+
- Do not use very long timeouts. This keeps the tests efficient.
|
|
52
|
+
- Use it only when necessary. The TestDriver [redraw detection](/performing-actions#waiting-for-dynamic-content) waits automatically for the screen and the network to become stable after each action.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "What is TestDriver?"
|
|
3
|
+
description: "Reliably test your most difficult user flows"
|
|
4
|
+
icon: "circle-info"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## The problem with usual test tools
|
|
8
|
+
|
|
9
|
+
Usual test tools such as Playwright test one web application. They use one browser tab and they use selectors.
|
|
10
|
+
|
|
11
|
+
But selectors are frequently not reliable, or they are not available. This makes tests weak and not stable:
|
|
12
|
+
|
|
13
|
+
| Challenge | Problem | Examples |
|
|
14
|
+
|-----------|---------|----------|
|
|
15
|
+
| **Teams that move quickly** | They change the UI structure frequently. This breaks the CSS and XPath selectors. | Agile teams, startups, vibe-coders |
|
|
16
|
+
| **Dynamic content** | You cannot select it with selectors. | AI chatbots, PDFs, images, videos |
|
|
17
|
+
| **Software that you do not own** | It can have no correct accessibility attributes. | Other websites, extensions, third-party applications |
|
|
18
|
+
| **Workflows with more than one application** | You cannot test them with web-only tools. | Desktop apps, browser extensions, IDEs |
|
|
19
|
+
| **Visual states** | You cannot make a check of them with code selectors. | Charts, graphs, videos, images, spelling errors, UI layout |
|
|
20
|
+
|
|
21
|
+
## The TestDriver solution
|
|
22
|
+
|
|
23
|
+
TestDriver is a complete test platform. It handles these conditions. It has a Javascript SDK, hosted infrastructure, and debug tools. These tools make it easy to write, run, and keep tests for your most difficult user flows.
|
|
24
|
+
|
|
25
|
+
### Javascript SDK
|
|
26
|
+
|
|
27
|
+
This is an example of a TestDriver test. The test installs a production Chrome extension from the Chrome Web Store. Then it makes sure that the extension is in the extensions menu:
|
|
28
|
+
|
|
29
|
+
```javascript Installing Loom from the Chrome Web Store
|
|
30
|
+
import { describe, expect, it } from "vitest";
|
|
31
|
+
import { TestDriver } from "testdriverai/vitest/hooks";
|
|
32
|
+
|
|
33
|
+
describe("Chrome Extension Test", () => {
|
|
34
|
+
const testdriver = TestDriver(context);
|
|
35
|
+
|
|
36
|
+
// Launch Chrome with Loom loaded by its Chrome Web Store ID
|
|
37
|
+
await testdriver.provision.chromeExtension({
|
|
38
|
+
extensionId: 'liecbddmkiiihnedobmlmillhodjkdmb'
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Click on the extensions button (puzzle piece icon) in Chrome toolbar
|
|
42
|
+
const extensionsButton = await testdriver.find("The puzzle-shaped icon in the Chrome toolbar.");
|
|
43
|
+
await extensionsButton.click();
|
|
44
|
+
|
|
45
|
+
// Look for Loom in the extensions menu
|
|
46
|
+
const loomExtension = await testdriver.find("Loom extension in the extensions dropdown");
|
|
47
|
+
expect(loomExtension.found()).toBeTruthy();
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
<Tip>[vitest](https://vitest.dev/) is the preferred test runner for TestDriver.</Tip>
|
|
53
|
+
|
|
54
|
+
,
|
package/lib/environments.json
CHANGED
package/lib/github-comment.mjs
CHANGED
|
@@ -222,9 +222,8 @@ function getReplayGifUrl(replayUrl, replayId) {
|
|
|
222
222
|
} else {
|
|
223
223
|
// Map console URLs → API URLs for all environments
|
|
224
224
|
// console-test.testdriver.ai → api-test.testdriver.ai
|
|
225
|
-
// console
|
|
226
|
-
|
|
227
|
-
const consoleEnvMatch = replayUrl.match(/https:\/\/console-(test|canary)\.testdriver\.ai/);
|
|
225
|
+
// console.testdriver.ai → api.testdriver.ai (stable and canary share this console)
|
|
226
|
+
const consoleEnvMatch = replayUrl.match(/https:\/\/console-(test)\.testdriver\.ai/);
|
|
228
227
|
if (consoleEnvMatch) {
|
|
229
228
|
apiBaseUrl = `https://api-${consoleEnvMatch[1]}.testdriver.ai`;
|
|
230
229
|
} else if (replayUrl.includes('console.testdriver.ai')) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
2
|
const path = require("path");
|
|
3
3
|
|
|
4
|
-
const docsDir = path.resolve(__dirname, "../docs
|
|
4
|
+
const docsDir = path.resolve(__dirname, "../docs");
|
|
5
5
|
const skillsDir = path.resolve(__dirname, "../ai/skills");
|
|
6
6
|
|
|
7
7
|
console.log(`Generating skills from ${docsDir} to ${skillsDir}`);
|