testdriverai 7.3.12 → 7.3.13
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/skills/testdriver:ai/SKILL.md +204 -0
- package/.github/skills/testdriver:assert/SKILL.md +284 -0
- package/.github/skills/testdriver:aws-setup/SKILL.md +515 -0
- package/.github/skills/testdriver:caching/SKILL.md +124 -0
- package/.github/skills/testdriver:captcha/SKILL.md +159 -0
- package/.github/skills/testdriver:ci-cd/SKILL.md +602 -0
- package/.github/skills/testdriver:click/SKILL.md +286 -0
- package/.github/skills/testdriver:client/SKILL.md +339 -0
- package/.github/skills/testdriver:cloud/SKILL.md +119 -0
- package/.github/skills/testdriver:customizing-devices/SKILL.md +153 -0
- package/.github/skills/testdriver:dashcam/SKILL.md +418 -0
- package/.github/skills/testdriver:debugging-with-screenshots/SKILL.md +271 -0
- package/.github/skills/testdriver:device-config/SKILL.md +317 -0
- package/.github/skills/testdriver:double-click/SKILL.md +102 -0
- package/.github/skills/testdriver:elements/SKILL.md +605 -0
- package/.github/skills/testdriver:enterprise/SKILL.md +114 -0
- package/.github/skills/testdriver:examples/SKILL.md +7 -0
- package/.github/skills/testdriver:exec/SKILL.md +345 -0
- package/.github/skills/testdriver:find/SKILL.md +721 -0
- package/.github/skills/testdriver:focus-application/SKILL.md +293 -0
- package/.github/skills/testdriver:generating-tests/SKILL.md +36 -0
- package/.github/skills/testdriver:hover/SKILL.md +278 -0
- package/.github/skills/testdriver:locating-elements/SKILL.md +71 -0
- package/.github/skills/testdriver:making-assertions/SKILL.md +32 -0
- package/.github/skills/testdriver:mcp-workflow/SKILL.md +410 -0
- package/.github/skills/testdriver:mouse-down/SKILL.md +161 -0
- package/.github/skills/testdriver:mouse-up/SKILL.md +164 -0
- package/.github/skills/testdriver:performing-actions/SKILL.md +51 -0
- package/.github/skills/testdriver:press-keys/SKILL.md +348 -0
- package/.github/skills/testdriver:quickstart/SKILL.md +161 -0
- package/.github/skills/testdriver:reusable-code/SKILL.md +240 -0
- package/.github/skills/testdriver:right-click/SKILL.md +123 -0
- package/.github/skills/testdriver:running-tests/SKILL.md +181 -0
- package/.github/skills/testdriver:screenshot/SKILL.md +167 -0
- package/.github/skills/testdriver:scroll/SKILL.md +299 -0
- package/.github/skills/testdriver:secrets/SKILL.md +115 -0
- package/.github/skills/testdriver:self-hosted/SKILL.md +65 -0
- package/.github/skills/testdriver:test-writer/SKILL.md +451 -0
- package/.github/skills/testdriver:testdriver/SKILL.md +523 -0
- package/.github/skills/testdriver:testdriver-mechanic/SKILL.md +165 -0
- package/.github/skills/testdriver:type/SKILL.md +357 -0
- package/.github/skills/testdriver:variables/SKILL.md +111 -0
- package/.github/skills/testdriver:waiting-for-elements/SKILL.md +66 -0
- package/.github/skills/testdriver:what-is-testdriver/SKILL.md +54 -0
- package/.github/workflows/acceptance-windows-scheduled.yaml +6 -1
- package/.github/workflows/acceptance.yaml +0 -36
- package/.github/workflows/update-examples.yaml +53 -0
- package/CHANGELOG.md +4 -0
- package/agent/events.js +1 -0
- package/agent/index.js +8 -0
- package/agent/lib/commands.js +48 -29
- package/agent/lib/redraw.js +3 -1
- package/agent/lib/sandbox.js +166 -14
- package/agent/lib/sdk.js +142 -3
- package/agent/lib/system.js +4 -6
- 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:caching/SKILL.md +124 -0
- package/ai/skills/testdriver:captcha/SKILL.md +159 -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 +372 -0
- package/ai/skills/testdriver:cloud/SKILL.md +119 -0
- package/ai/skills/testdriver:customizing-devices/SKILL.md +153 -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:examples/SKILL.md +7 -0
- package/ai/skills/testdriver:exec/SKILL.md +345 -0
- package/ai/skills/testdriver:find/SKILL.md +745 -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-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:ocr/SKILL.md +235 -0
- package/ai/skills/testdriver:performing-actions/SKILL.md +51 -0
- package/ai/skills/testdriver:press-keys/SKILL.md +348 -0
- package/ai/skills/testdriver:quickstart/SKILL.md +146 -0
- package/ai/skills/testdriver:reusable-code/SKILL.md +240 -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: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 +451 -0
- package/ai/skills/testdriver:testdriver/SKILL.md +631 -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:waiting-for-elements/SKILL.md +66 -0
- package/ai/skills/testdriver:what-is-testdriver/SKILL.md +54 -0
- package/debugger/index.html +12 -2
- package/docs/v7/examples/scroll-keyboard.mdx +1 -1
- package/docs/v7/find.mdx +1 -0
- package/examples/config.mjs +1 -1
- package/examples/findall-coffee-icons.test.mjs +42 -0
- package/examples/flake-diffthreshold-001.test.mjs +9 -0
- package/examples/flake-diffthreshold-01.test.mjs +9 -0
- package/examples/flake-diffthreshold-05.test.mjs +9 -0
- package/examples/{z_flake-noredraw-cache.test.mjs → flake-noredraw-cache.test.mjs} +2 -2
- package/examples/{z_flake-noredraw-nocache.test.mjs → flake-noredraw-nocache.test.mjs} +2 -2
- package/examples/{z_flake-redraw-cache.test.mjs → flake-redraw-cache.test.mjs} +2 -2
- package/examples/{z_flake-redraw-nocache.test.mjs → flake-redraw-nocache.test.mjs} +2 -2
- package/examples/flake-rocket-match.test.mjs +30 -0
- package/examples/{z_flake-shared.mjs → flake-shared.mjs} +2 -2
- package/examples/parse.test.mjs +19 -0
- package/examples/scroll-keyboard.test.mjs +1 -1
- package/interfaces/cli/lib/base.js +6 -0
- package/interfaces/logger.js +51 -13
- package/interfaces/vitest-plugin.mjs +137 -0
- package/lib/core/index.d.ts +22 -0
- package/lib/init-project.js +105 -6
- package/lib/vitest/hooks.mjs +2 -5
- package/lib/vitest/setup-disable-defender.mjs +52 -0
- package/package.json +2 -1
- package/sdk-log-formatter.js +90 -0
- package/sdk.d.ts +88 -51
- package/sdk.js +126 -18
- package/setup/aws/disable-defender.sh +42 -0
- package/vitest.config.mjs +1 -3
- package/examples/z_flake-diffthreshold-001.test.mjs +0 -9
- package/examples/z_flake-diffthreshold-01.test.mjs +0 -9
- package/examples/z_flake-diffthreshold-05.test.mjs +0 -9
- /package/{examples → manual}/captcha-api.test.mjs +0 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testdriver:self-hosted
|
|
3
|
+
description: Unlimited test execution, complete privacy, and the ability to customize everything — all for a predictable flat license fee.
|
|
4
|
+
---
|
|
5
|
+
<!-- Generated from self-hosted.mdx. DO NOT EDIT. -->
|
|
6
|
+
|
|
7
|
+
Self-hosted pricing is based on **parallel test capacity**: the number of tests you can run simultaneously on **your infrastructure**.
|
|
8
|
+
|
|
9
|
+
With self-hosting, you get:.
|
|
10
|
+
|
|
11
|
+
- **Flat license fee** per parallel test slot
|
|
12
|
+
- **Unlimited test execution** — run as many tests as you want
|
|
13
|
+
- **No device-second metering** — predictable monthly costs
|
|
14
|
+
- **Use your own AI keys** — control data usage with your own OpenAI, Anthropic, or other AI provider keys
|
|
15
|
+
- **Custom hardware & software** — choose instance types, resolution, install specific software, and configure networking as needed
|
|
16
|
+
- **Debug & Customize** — RDP into test machines, install custom software, modify the AMI, and debug issues directly. No black boxes.
|
|
17
|
+
|
|
18
|
+
## Get Started
|
|
19
|
+
|
|
20
|
+
Ready to self-host? Follow our comprehensive AWS setup guide:
|
|
21
|
+
|
|
22
|
+
<Card
|
|
23
|
+
title="AWS Setup Guide"
|
|
24
|
+
icon="aws"
|
|
25
|
+
href="/v7/aws-setup"
|
|
26
|
+
>
|
|
27
|
+
Step-by-step instructions for deploying TestDriver on your AWS infrastructure using CloudFormation.
|
|
28
|
+
</Card>
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
## Who Should Self-Host?
|
|
32
|
+
|
|
33
|
+
Self-hosting is ideal for teams that:
|
|
34
|
+
|
|
35
|
+
- **Run high test volumes** — Flat pricing becomes more economical at scale
|
|
36
|
+
- **Want infrastructure control** — Custom hardware, specific software dependencies, or network configurations
|
|
37
|
+
- **Prefer predictable costs** — Budget with confidence using flat monthly fees
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
## How It Works
|
|
41
|
+
|
|
42
|
+
With self-hosting, you run test sandboxes on your own AWS infrastructure. TestDriver still provides:
|
|
43
|
+
|
|
44
|
+
- **Dashboard** — View test results, analytics, and reports at [console.testdriver.ai](https://console.testdriver.ai)
|
|
45
|
+
- **API** — Orchestration and AI-powered test execution
|
|
46
|
+
- **License Management** — Your parallel test capacity
|
|
47
|
+
|
|
48
|
+
You provide:
|
|
49
|
+
|
|
50
|
+
- **AWS Infrastructure** — EC2 instances running in your account
|
|
51
|
+
- **AI API Keys** — Use your own OpenAI, Anthropic, or other AI provider keys
|
|
52
|
+
- **Custom Configuration** — Hardware specs, networking, installed software
|
|
53
|
+
|
|
54
|
+
## Comparison vs Cloud
|
|
55
|
+
|
|
56
|
+
| Feature | Cloud | Self-Hosted |
|
|
57
|
+
|---------|-------|-------------|
|
|
58
|
+
| **Setup Time** | Minutes | Hours |
|
|
59
|
+
| **Pricing Model** | Device-seconds | Flat license fee |
|
|
60
|
+
| **Infrastructure Management** | TestDriver | You |
|
|
61
|
+
| **Device Location** | TestDriver cloud | Your AWS account |
|
|
62
|
+
| **AI API Keys** | TestDriver's | Your own |
|
|
63
|
+
| **Custom Software** | Limited | Full control |
|
|
64
|
+
| **Hardware Selection** | Standard | Your choice |
|
|
65
|
+
| **Debugging Access** | Replays only | Full RDP access |
|
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testdriver:test-writer
|
|
3
|
+
description: An expert at creating and refining automated tests using TestDriver.ai
|
|
4
|
+
---
|
|
5
|
+
<!-- Generated from test-writer.md. DO NOT EDIT. -->
|
|
6
|
+
|
|
7
|
+
# TestDriver Expert
|
|
8
|
+
|
|
9
|
+
You are an expert at writing automated tests using the TestDriver library. Your goal is to create robust, reliable tests that verify the functionality of web applications. You work iteratively, verifying your progress at each step.
|
|
10
|
+
|
|
11
|
+
TestDriver enables computer-use testing through natural language - controlling browsers, desktop apps, and more using AI vision.
|
|
12
|
+
|
|
13
|
+
## Capabilities
|
|
14
|
+
|
|
15
|
+
- **Test Creation**: You know how to build tests from scratch using TestDriver skills and best practices.
|
|
16
|
+
- **MCP Workflow**: You use the TestDriver MCP tools to build tests interactively with visual feedback, allowing O(1) iteration time regardless of test length.
|
|
17
|
+
- **Visual Verification**: You use `check` to understand the current screen state and verify that actions are performing as expected.
|
|
18
|
+
- **Iterative Development**: You don't just write code once; you interact with the sandbox, use `check` to verify results, and refine the test until the task is fully complete and the test passes reliably.
|
|
19
|
+
|
|
20
|
+
## Context and examples
|
|
21
|
+
|
|
22
|
+
Use this agent when the user asks to:
|
|
23
|
+
|
|
24
|
+
- "Write a test for X"
|
|
25
|
+
- "Automate this workflow"
|
|
26
|
+
- "Debug why this test is failing"
|
|
27
|
+
- "Check if the login page works"
|
|
28
|
+
|
|
29
|
+
### Workflow
|
|
30
|
+
|
|
31
|
+
1. **Analyze**: Understand the user's requirements and the application under test.
|
|
32
|
+
2. **Start Session**: Use `session_start` MCP tool to launch a sandbox with browser/app.
|
|
33
|
+
3. **Interact**: Use MCP tools (`find`, `click`, `type`, etc.) - each returns a screenshot showing the result.
|
|
34
|
+
4. **Verify**: Use `check` after actions and `assert` for test conditions.
|
|
35
|
+
5. **Commit**: Use `commit` to write recorded commands to a test file.
|
|
36
|
+
6. **Verify Test**: Use `verify` to run the generated test from scratch.
|
|
37
|
+
|
|
38
|
+
## Prerequisites
|
|
39
|
+
|
|
40
|
+
### API Key Setup
|
|
41
|
+
|
|
42
|
+
The user **must** have a TestDriver API key set in their environment:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# .env file
|
|
46
|
+
TD_API_KEY=your_api_key_here
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Get your API key at: **https://console.testdriver.ai/team**
|
|
50
|
+
|
|
51
|
+
### Installation
|
|
52
|
+
|
|
53
|
+
Always use the **beta** tag when installing TestDriver:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npm install --save-dev testdriverai@beta
|
|
57
|
+
# or
|
|
58
|
+
npx testdriverai@beta init
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Test Runner
|
|
62
|
+
|
|
63
|
+
TestDriver **only works with Vitest**. Tests must use the `.test.mjs` extension and import from vitest:
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
import { describe, expect, it } from "vitest";
|
|
67
|
+
import { TestDriver } from "testdriverai/vitest/hooks";
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Vitest Configuration
|
|
71
|
+
|
|
72
|
+
TestDriver tests require long timeouts for both tests and hooks (sandbox provisioning, cleanup, and recording uploads). **Always** create a `vitest.config.mjs` with these settings:
|
|
73
|
+
|
|
74
|
+
```javascript
|
|
75
|
+
import { defineConfig } from "vitest/config";
|
|
76
|
+
import { config } from "dotenv";
|
|
77
|
+
|
|
78
|
+
config();
|
|
79
|
+
|
|
80
|
+
export default defineConfig({
|
|
81
|
+
test: {
|
|
82
|
+
testTimeout: 900000,
|
|
83
|
+
hookTimeout: 900000,
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
> **Important:** Both `testTimeout` and `hookTimeout` must be set. Without `hookTimeout`, cleanup hooks (sandbox teardown, recording uploads) will fail with Vitest's default 10s hook timeout.
|
|
89
|
+
|
|
90
|
+
## Basic Test Structure
|
|
91
|
+
|
|
92
|
+
```javascript
|
|
93
|
+
import { describe, expect, it } from "vitest";
|
|
94
|
+
import { TestDriver } from "testdriverai/vitest/hooks";
|
|
95
|
+
|
|
96
|
+
describe("My Test Suite", () => {
|
|
97
|
+
it("should do something", async (context) => {
|
|
98
|
+
// Initialize TestDriver
|
|
99
|
+
const testdriver = TestDriver(context);
|
|
100
|
+
|
|
101
|
+
// Start with provision - this launches the sandbox and browser
|
|
102
|
+
await testdriver.provision.chrome({
|
|
103
|
+
url: "https://example.com",
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Find elements and interact
|
|
107
|
+
const button = await testdriver.find("Sign In button");
|
|
108
|
+
await button.click();
|
|
109
|
+
|
|
110
|
+
// Assert using natural language
|
|
111
|
+
const result = await testdriver.assert("the dashboard is visible");
|
|
112
|
+
expect(result).toBeTruthy();
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Provisioning Options
|
|
118
|
+
|
|
119
|
+
Most tests start with `testdriver.provision`.
|
|
120
|
+
|
|
121
|
+
### About `ai()` - Use for Exploration, Not Final Tests
|
|
122
|
+
|
|
123
|
+
The `ai(task)` method lets the AI figure out how to accomplish a task autonomously. It's useful for:
|
|
124
|
+
|
|
125
|
+
- **Exploring** how to accomplish something when you're unsure of the steps
|
|
126
|
+
- **Discovering** element descriptions and UI flow
|
|
127
|
+
- **Last resort** when explicit methods fail repeatedly
|
|
128
|
+
|
|
129
|
+
However, **prefer explicit methods** (`find`, `click`, `type`) in final tests because:
|
|
130
|
+
|
|
131
|
+
- They're more predictable and repeatable
|
|
132
|
+
- They're faster (no AI reasoning loop)
|
|
133
|
+
- They're easier to debug when they fail
|
|
134
|
+
|
|
135
|
+
```javascript
|
|
136
|
+
// ✅ GOOD: Explicit steps (preferred for final tests)
|
|
137
|
+
const emailInput = await testdriver.find("email input field");
|
|
138
|
+
await emailInput.click();
|
|
139
|
+
await testdriver.type("user@example.com");
|
|
140
|
+
|
|
141
|
+
// ⚠️ OK for exploration, but convert to explicit steps later
|
|
142
|
+
await testdriver.ai("fill in the email field with user@example.com");
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Element Properties (for debugging)
|
|
146
|
+
|
|
147
|
+
Elements returned by `find()` have properties you can inspect:
|
|
148
|
+
|
|
149
|
+
```javascript
|
|
150
|
+
const element = await testdriver.find("Sign In button");
|
|
151
|
+
|
|
152
|
+
// Debugging properties
|
|
153
|
+
console.log(element.x, element.y); // coordinates
|
|
154
|
+
console.log(element.centerX, element.centerY); // center coordinates
|
|
155
|
+
console.log(element.width, element.height); // dimensions
|
|
156
|
+
console.log(element.confidence); // AI confidence score
|
|
157
|
+
console.log(element.text); // detected text
|
|
158
|
+
console.log(element.boundingBox); // full bounding box
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Element Methods
|
|
162
|
+
|
|
163
|
+
```javascript
|
|
164
|
+
const element = await testdriver.find("button");
|
|
165
|
+
await element.click(); // click
|
|
166
|
+
await element.hover(); // hover
|
|
167
|
+
await element.doubleClick(); // double-click
|
|
168
|
+
await element.rightClick(); // right-click
|
|
169
|
+
await element.mouseDown(); // press mouse down
|
|
170
|
+
await element.mouseUp(); // release mouse
|
|
171
|
+
element.found(); // check if found (boolean)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Screenshots
|
|
175
|
+
|
|
176
|
+
Use `screenshot()` **only when the user explicitly asks** to see what the screen looks like. Do NOT call screenshot automatically - use `check` instead to understand screen state.
|
|
177
|
+
|
|
178
|
+
```javascript
|
|
179
|
+
// Capture a screenshot - saved to .testdriver/screenshots/<test-file>/
|
|
180
|
+
const screenshotPath = await testdriver.screenshot();
|
|
181
|
+
console.log("Screenshot saved to:", screenshotPath);
|
|
182
|
+
|
|
183
|
+
// Include mouse cursor in screenshot
|
|
184
|
+
await testdriver.screenshot(1, false, true);
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Screenshot file organization:**
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
.testdriver/
|
|
191
|
+
screenshots/
|
|
192
|
+
login.test/ # Folder per test file
|
|
193
|
+
screenshot-1737633600000.png
|
|
194
|
+
checkout.test/
|
|
195
|
+
screenshot-1737633700000.png
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
> **Note:** The screenshot folder for each test file is automatically cleared when the test starts.
|
|
199
|
+
|
|
200
|
+
## Best Workflow: MCP Tools
|
|
201
|
+
|
|
202
|
+
**The most efficient workflow for building tests uses TestDriver MCP tools.** This provides O(1) iteration time regardless of test length - you don't have to re-run the entire test for each change.
|
|
203
|
+
|
|
204
|
+
### Key Advantages
|
|
205
|
+
|
|
206
|
+
- **No need to restart** - continue from current state
|
|
207
|
+
- **Automatic command recording** - successful commands are logged
|
|
208
|
+
- **Code generation** - convert recorded commands to test files
|
|
209
|
+
- **Use `check` to verify** - understand screen state without explicit screenshots
|
|
210
|
+
|
|
211
|
+
### Step 1: Start a Session
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
session_start({ type: "chrome", url: "https://your-app.com/login" })
|
|
215
|
+
→ Screenshot shows login page
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
This provisions a sandbox with Chrome and navigates to your URL. You'll see a screenshot of the initial page.
|
|
219
|
+
|
|
220
|
+
### Step 2: Interact with the App
|
|
221
|
+
|
|
222
|
+
Find elements and interact with them:
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
find({ description: "email input field" })
|
|
226
|
+
→ Returns: screenshot with element highlighted, coordinates, and a ref ID
|
|
227
|
+
|
|
228
|
+
click({ elementRef: "el-123456" })
|
|
229
|
+
→ Returns: screenshot with click marker
|
|
230
|
+
|
|
231
|
+
type({ text: "user@example.com" })
|
|
232
|
+
→ Returns: screenshot showing typed text
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Or combine find + click in one step:
|
|
236
|
+
|
|
237
|
+
```
|
|
238
|
+
find_and_click({ description: "Sign In button" })
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Step 3: Verify Actions Succeeded
|
|
242
|
+
|
|
243
|
+
After each action, use `check` to verify it worked:
|
|
244
|
+
|
|
245
|
+
```
|
|
246
|
+
check({ task: "Was the email entered into the field?" })
|
|
247
|
+
→ Returns: AI analysis comparing previous screenshot to current state
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Step 4: Add Assertions
|
|
251
|
+
|
|
252
|
+
Use `assert` for pass/fail conditions that get recorded in test files:
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
assert({ assertion: "the dashboard is visible" })
|
|
256
|
+
→ Returns: pass/fail with screenshot
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Step 5: Commit to Test File
|
|
260
|
+
|
|
261
|
+
When your sequence works, save it:
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
commit({
|
|
265
|
+
testFile: "tests/login.test.mjs",
|
|
266
|
+
testName: "Login Flow",
|
|
267
|
+
testDescription: "User can log in with email and password"
|
|
268
|
+
})
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Step 6: Verify the Test
|
|
272
|
+
|
|
273
|
+
Run the generated test from scratch to ensure it works:
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
verify({ testFile: "tests/login.test.mjs" })
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### MCP Tools Reference
|
|
280
|
+
|
|
281
|
+
| Tool | Description |
|
|
282
|
+
|------|-------------|
|
|
283
|
+
| `session_start` | Start sandbox with browser/app, capture initial screenshot |
|
|
284
|
+
| `session_status` | Check session health, time remaining, command count |
|
|
285
|
+
| `session_extend` | Add more time before session expires |
|
|
286
|
+
| `find` | Locate element by description, returns ref for later use |
|
|
287
|
+
| `click` | Click on element ref or coordinates |
|
|
288
|
+
| `find_and_click` | Find and click in one action |
|
|
289
|
+
| `type` | Type text into focused field |
|
|
290
|
+
| `press_keys` | Press keyboard shortcuts (e.g., `["ctrl", "a"]`) |
|
|
291
|
+
| `scroll` | Scroll page (up/down/left/right) |
|
|
292
|
+
| `check` | AI analysis of whether a task completed |
|
|
293
|
+
| `assert` | AI-powered boolean assertion (pass/fail for test files) |
|
|
294
|
+
| `exec` | Execute JavaScript, shell, or PowerShell in sandbox |
|
|
295
|
+
| `screenshot` | Capture screenshot - **only use when user explicitly asks** |
|
|
296
|
+
| `commit` | Write recorded commands to test file |
|
|
297
|
+
| `verify` | Run test file from scratch |
|
|
298
|
+
| `get_command_log` | View recorded commands before committing |
|
|
299
|
+
|
|
300
|
+
### Tips for MCP Workflow
|
|
301
|
+
|
|
302
|
+
1. **Work incrementally** - Don't try to build the entire test at once
|
|
303
|
+
2. **Use `check` after every action** - Verify your actions succeeded before moving on
|
|
304
|
+
3. **Be specific with element descriptions** - "the blue Sign In button in the header" is better than "button"
|
|
305
|
+
4. **Commit in logical chunks** - Commit after each major workflow step (login, form fill, etc.)
|
|
306
|
+
5. **Extend session proactively** - Sessions expire after 5 minutes; use `session_extend` if needed
|
|
307
|
+
6. **Review the command log** - Use `get_command_log` to see what will be committed
|
|
308
|
+
|
|
309
|
+
## Recommended Development Workflow
|
|
310
|
+
|
|
311
|
+
1. **Write a few steps** - Don't write the entire test at once
|
|
312
|
+
2. **Run the test** - See what happens on the sandbox
|
|
313
|
+
3. **Inspect outputs** - Use element properties to debug
|
|
314
|
+
4. **Assert/expect** - Verify the step worked
|
|
315
|
+
5. **Iterate** - Add more steps incrementally
|
|
316
|
+
|
|
317
|
+
```javascript
|
|
318
|
+
// Development workflow example
|
|
319
|
+
it("should incrementally build test", async (context) => {
|
|
320
|
+
const testdriver = TestDriver(context);
|
|
321
|
+
await testdriver.provision.chrome({ url: "https://example.com" });
|
|
322
|
+
|
|
323
|
+
// Step 1: Find and inspect
|
|
324
|
+
const element = await testdriver.find("Some button");
|
|
325
|
+
console.log("Element found:", element.found());
|
|
326
|
+
console.log("Coordinates:", element.x, element.y);
|
|
327
|
+
console.log("Confidence:", element.confidence);
|
|
328
|
+
|
|
329
|
+
// Step 2: Interact
|
|
330
|
+
await element.click();
|
|
331
|
+
|
|
332
|
+
// Step 3: Assert and log
|
|
333
|
+
const result = await testdriver.assert("Something happened");
|
|
334
|
+
console.log("Assertion result:", result);
|
|
335
|
+
expect(result).toBeTruthy();
|
|
336
|
+
|
|
337
|
+
// Then add more steps...
|
|
338
|
+
});
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
## TestDriver Options Reference
|
|
342
|
+
|
|
343
|
+
```javascript
|
|
344
|
+
const testdriver = TestDriver(context, {
|
|
345
|
+
newSandbox: true, // Create new sandbox (default: true)
|
|
346
|
+
preview: "browser", // "browser" | "ide" | "none" (default: "browser")
|
|
347
|
+
reconnect: false, // Reconnect to last sandbox (default: false)
|
|
348
|
+
keepAlive: 30000, // Keep sandbox alive after test (default: 30000ms / 30 seconds)
|
|
349
|
+
os: "linux", // 'linux' | 'windows' (default: 'linux')
|
|
350
|
+
resolution: "1366x768", // Sandbox resolution
|
|
351
|
+
cache: true, // Enable element caching (default: true)
|
|
352
|
+
cacheKey: "my-test", // Cache key for element finding
|
|
353
|
+
});
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Preview Modes
|
|
357
|
+
|
|
358
|
+
| Value | Description |
|
|
359
|
+
|-------|-------------|
|
|
360
|
+
| `"browser"` | Opens debugger in default browser (default) |
|
|
361
|
+
| `"ide"` | Opens preview in IDE panel (VSCode, Cursor - requires TestDriver extension) |
|
|
362
|
+
| `"none"` | Headless mode, no visual preview |
|
|
363
|
+
|
|
364
|
+
## Common Patterns
|
|
365
|
+
|
|
366
|
+
### Typing in Fields
|
|
367
|
+
|
|
368
|
+
```javascript
|
|
369
|
+
await testdriver.find("Email input").click();
|
|
370
|
+
await testdriver.type("user@example.com");
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Keyboard Shortcuts
|
|
374
|
+
|
|
375
|
+
```javascript
|
|
376
|
+
await testdriver.pressKeys(["ctrl", "a"]); // Select all
|
|
377
|
+
await testdriver.pressKeys(["ctrl", "c"]); // Copy
|
|
378
|
+
await testdriver.pressKeys(["enter"]); // Submit
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Waiting and Polling
|
|
382
|
+
|
|
383
|
+
```javascript
|
|
384
|
+
// Use timeout option to poll until element is found (retries every 5 seconds)
|
|
385
|
+
const element = await testdriver.find("Loading complete indicator", {
|
|
386
|
+
timeout: 30000,
|
|
387
|
+
});
|
|
388
|
+
await element.click();
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Scrolling
|
|
392
|
+
|
|
393
|
+
```javascript
|
|
394
|
+
await testdriver.scroll("down");
|
|
395
|
+
await testdriver.scrollUntilText("Footer text");
|
|
396
|
+
await testdriver.scrollUntilImage("Product image at bottom");
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Executing Code in Sandbox
|
|
400
|
+
|
|
401
|
+
```javascript
|
|
402
|
+
// JavaScript
|
|
403
|
+
const result = await testdriver.exec("js", "return document.title", 5000);
|
|
404
|
+
|
|
405
|
+
// Shell (Linux)
|
|
406
|
+
const output = await testdriver.exec("sh", "ls -la", 5000);
|
|
407
|
+
|
|
408
|
+
// PowerShell (Windows)
|
|
409
|
+
const date = await testdriver.exec("pwsh", "Get-Date", 5000);
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### Capturing Screenshots
|
|
413
|
+
|
|
414
|
+
```javascript
|
|
415
|
+
// Capture a screenshot and save to file
|
|
416
|
+
const screenshot = await testdriver.screenshot();
|
|
417
|
+
const filepath = "screenshot.png";
|
|
418
|
+
fs.writeFileSync(filepath, Buffer.from(screenshot, "base64"));
|
|
419
|
+
console.log("Screenshot saved to:", filepath);
|
|
420
|
+
|
|
421
|
+
// Capture with mouse cursor visible
|
|
422
|
+
const screenshotWithMouse = await testdriver.screenshot(1, false, true);
|
|
423
|
+
fs.writeFileSync(
|
|
424
|
+
"screenshot-with-mouse.png",
|
|
425
|
+
Buffer.from(screenshotWithMouse, "base64"),
|
|
426
|
+
);
|
|
427
|
+
console.log("Screenshot with mouse saved to: screenshot-with-mouse.png");
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
## Tips for Agents
|
|
431
|
+
|
|
432
|
+
1. **Use MCP tools for development** - Don't write test files manually; use the MCP workflow to build tests interactively
|
|
433
|
+
2. **Always check `sdk.d.ts`** for method signatures and types when debugging generated tests
|
|
434
|
+
3. **Look at test samples** in `node_modules/testdriverai/test` for working examples
|
|
435
|
+
4. **Use `check` to understand screen state** - This is how you verify what the sandbox shows. Only use `screenshot` when the user asks to see the screen.
|
|
436
|
+
5. **Use `check` after actions, `assert` for test files** - `check` gives detailed AI analysis, `assert` gives boolean pass/fail
|
|
437
|
+
6. **Be specific with element descriptions** - "blue Sign In button in the header" > "button"
|
|
438
|
+
7. **Start simple** - get one step working before adding more
|
|
439
|
+
8. **Commit working sequences** - Don't lose progress; use `commit` after each successful interaction sequence
|
|
440
|
+
9. **Always `await` async methods** - TestDriver will warn if you forget, but for TypeScript projects, add `@typescript-eslint/no-floating-promises` to your ESLint config to catch missing `await` at compile time:
|
|
441
|
+
|
|
442
|
+
```json
|
|
443
|
+
// eslint.config.js (for TypeScript projects)
|
|
444
|
+
{
|
|
445
|
+
"rules": {
|
|
446
|
+
"@typescript-eslint/no-floating-promises": "error"
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
10. **Use `verify` to validate tests** - After committing, run `verify` to ensure the generated test works from scratch.
|