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.
Files changed (133) hide show
  1. package/.github/skills/testdriver:ai/SKILL.md +204 -0
  2. package/.github/skills/testdriver:assert/SKILL.md +284 -0
  3. package/.github/skills/testdriver:aws-setup/SKILL.md +515 -0
  4. package/.github/skills/testdriver:caching/SKILL.md +124 -0
  5. package/.github/skills/testdriver:captcha/SKILL.md +159 -0
  6. package/.github/skills/testdriver:ci-cd/SKILL.md +602 -0
  7. package/.github/skills/testdriver:click/SKILL.md +286 -0
  8. package/.github/skills/testdriver:client/SKILL.md +339 -0
  9. package/.github/skills/testdriver:cloud/SKILL.md +119 -0
  10. package/.github/skills/testdriver:customizing-devices/SKILL.md +153 -0
  11. package/.github/skills/testdriver:dashcam/SKILL.md +418 -0
  12. package/.github/skills/testdriver:debugging-with-screenshots/SKILL.md +271 -0
  13. package/.github/skills/testdriver:device-config/SKILL.md +317 -0
  14. package/.github/skills/testdriver:double-click/SKILL.md +102 -0
  15. package/.github/skills/testdriver:elements/SKILL.md +605 -0
  16. package/.github/skills/testdriver:enterprise/SKILL.md +114 -0
  17. package/.github/skills/testdriver:examples/SKILL.md +7 -0
  18. package/.github/skills/testdriver:exec/SKILL.md +345 -0
  19. package/.github/skills/testdriver:find/SKILL.md +721 -0
  20. package/.github/skills/testdriver:focus-application/SKILL.md +293 -0
  21. package/.github/skills/testdriver:generating-tests/SKILL.md +36 -0
  22. package/.github/skills/testdriver:hover/SKILL.md +278 -0
  23. package/.github/skills/testdriver:locating-elements/SKILL.md +71 -0
  24. package/.github/skills/testdriver:making-assertions/SKILL.md +32 -0
  25. package/.github/skills/testdriver:mcp-workflow/SKILL.md +410 -0
  26. package/.github/skills/testdriver:mouse-down/SKILL.md +161 -0
  27. package/.github/skills/testdriver:mouse-up/SKILL.md +164 -0
  28. package/.github/skills/testdriver:performing-actions/SKILL.md +51 -0
  29. package/.github/skills/testdriver:press-keys/SKILL.md +348 -0
  30. package/.github/skills/testdriver:quickstart/SKILL.md +161 -0
  31. package/.github/skills/testdriver:reusable-code/SKILL.md +240 -0
  32. package/.github/skills/testdriver:right-click/SKILL.md +123 -0
  33. package/.github/skills/testdriver:running-tests/SKILL.md +181 -0
  34. package/.github/skills/testdriver:screenshot/SKILL.md +167 -0
  35. package/.github/skills/testdriver:scroll/SKILL.md +299 -0
  36. package/.github/skills/testdriver:secrets/SKILL.md +115 -0
  37. package/.github/skills/testdriver:self-hosted/SKILL.md +65 -0
  38. package/.github/skills/testdriver:test-writer/SKILL.md +451 -0
  39. package/.github/skills/testdriver:testdriver/SKILL.md +523 -0
  40. package/.github/skills/testdriver:testdriver-mechanic/SKILL.md +165 -0
  41. package/.github/skills/testdriver:type/SKILL.md +357 -0
  42. package/.github/skills/testdriver:variables/SKILL.md +111 -0
  43. package/.github/skills/testdriver:waiting-for-elements/SKILL.md +66 -0
  44. package/.github/skills/testdriver:what-is-testdriver/SKILL.md +54 -0
  45. package/.github/workflows/acceptance-windows-scheduled.yaml +6 -1
  46. package/.github/workflows/acceptance.yaml +0 -36
  47. package/.github/workflows/update-examples.yaml +53 -0
  48. package/CHANGELOG.md +4 -0
  49. package/agent/events.js +1 -0
  50. package/agent/index.js +8 -0
  51. package/agent/lib/commands.js +48 -29
  52. package/agent/lib/redraw.js +3 -1
  53. package/agent/lib/sandbox.js +166 -14
  54. package/agent/lib/sdk.js +142 -3
  55. package/agent/lib/system.js +4 -6
  56. package/ai/skills/testdriver:ai/SKILL.md +204 -0
  57. package/ai/skills/testdriver:assert/SKILL.md +315 -0
  58. package/ai/skills/testdriver:aws-setup/SKILL.md +448 -0
  59. package/ai/skills/testdriver:caching/SKILL.md +124 -0
  60. package/ai/skills/testdriver:captcha/SKILL.md +159 -0
  61. package/ai/skills/testdriver:ci-cd/SKILL.md +602 -0
  62. package/ai/skills/testdriver:click/SKILL.md +286 -0
  63. package/ai/skills/testdriver:client/SKILL.md +372 -0
  64. package/ai/skills/testdriver:cloud/SKILL.md +119 -0
  65. package/ai/skills/testdriver:customizing-devices/SKILL.md +153 -0
  66. package/ai/skills/testdriver:dashcam/SKILL.md +418 -0
  67. package/ai/skills/testdriver:debugging-with-screenshots/SKILL.md +401 -0
  68. package/ai/skills/testdriver:device-config/SKILL.md +317 -0
  69. package/ai/skills/testdriver:double-click/SKILL.md +102 -0
  70. package/ai/skills/testdriver:elements/SKILL.md +605 -0
  71. package/ai/skills/testdriver:enterprise/SKILL.md +114 -0
  72. package/ai/skills/testdriver:examples/SKILL.md +7 -0
  73. package/ai/skills/testdriver:exec/SKILL.md +345 -0
  74. package/ai/skills/testdriver:find/SKILL.md +745 -0
  75. package/ai/skills/testdriver:focus-application/SKILL.md +293 -0
  76. package/ai/skills/testdriver:generating-tests/SKILL.md +36 -0
  77. package/ai/skills/testdriver:hover/SKILL.md +278 -0
  78. package/ai/skills/testdriver:locating-elements/SKILL.md +71 -0
  79. package/ai/skills/testdriver:making-assertions/SKILL.md +32 -0
  80. package/ai/skills/testdriver:mcp-workflow/SKILL.md +410 -0
  81. package/ai/skills/testdriver:mouse-down/SKILL.md +161 -0
  82. package/ai/skills/testdriver:mouse-up/SKILL.md +164 -0
  83. package/ai/skills/testdriver:ocr/SKILL.md +235 -0
  84. package/ai/skills/testdriver:performing-actions/SKILL.md +51 -0
  85. package/ai/skills/testdriver:press-keys/SKILL.md +348 -0
  86. package/ai/skills/testdriver:quickstart/SKILL.md +146 -0
  87. package/ai/skills/testdriver:reusable-code/SKILL.md +240 -0
  88. package/ai/skills/testdriver:right-click/SKILL.md +123 -0
  89. package/ai/skills/testdriver:running-tests/SKILL.md +185 -0
  90. package/ai/skills/testdriver:screenshot/SKILL.md +248 -0
  91. package/ai/skills/testdriver:scroll/SKILL.md +335 -0
  92. package/ai/skills/testdriver:secrets/SKILL.md +115 -0
  93. package/ai/skills/testdriver:self-hosted/SKILL.md +65 -0
  94. package/ai/skills/testdriver:test-writer/SKILL.md +451 -0
  95. package/ai/skills/testdriver:testdriver/SKILL.md +631 -0
  96. package/ai/skills/testdriver:testdriver-mechanic/SKILL.md +165 -0
  97. package/ai/skills/testdriver:type/SKILL.md +357 -0
  98. package/ai/skills/testdriver:variables/SKILL.md +111 -0
  99. package/ai/skills/testdriver:waiting-for-elements/SKILL.md +66 -0
  100. package/ai/skills/testdriver:what-is-testdriver/SKILL.md +54 -0
  101. package/debugger/index.html +12 -2
  102. package/docs/v7/examples/scroll-keyboard.mdx +1 -1
  103. package/docs/v7/find.mdx +1 -0
  104. package/examples/config.mjs +1 -1
  105. package/examples/findall-coffee-icons.test.mjs +42 -0
  106. package/examples/flake-diffthreshold-001.test.mjs +9 -0
  107. package/examples/flake-diffthreshold-01.test.mjs +9 -0
  108. package/examples/flake-diffthreshold-05.test.mjs +9 -0
  109. package/examples/{z_flake-noredraw-cache.test.mjs → flake-noredraw-cache.test.mjs} +2 -2
  110. package/examples/{z_flake-noredraw-nocache.test.mjs → flake-noredraw-nocache.test.mjs} +2 -2
  111. package/examples/{z_flake-redraw-cache.test.mjs → flake-redraw-cache.test.mjs} +2 -2
  112. package/examples/{z_flake-redraw-nocache.test.mjs → flake-redraw-nocache.test.mjs} +2 -2
  113. package/examples/flake-rocket-match.test.mjs +30 -0
  114. package/examples/{z_flake-shared.mjs → flake-shared.mjs} +2 -2
  115. package/examples/parse.test.mjs +19 -0
  116. package/examples/scroll-keyboard.test.mjs +1 -1
  117. package/interfaces/cli/lib/base.js +6 -0
  118. package/interfaces/logger.js +51 -13
  119. package/interfaces/vitest-plugin.mjs +137 -0
  120. package/lib/core/index.d.ts +22 -0
  121. package/lib/init-project.js +105 -6
  122. package/lib/vitest/hooks.mjs +2 -5
  123. package/lib/vitest/setup-disable-defender.mjs +52 -0
  124. package/package.json +2 -1
  125. package/sdk-log-formatter.js +90 -0
  126. package/sdk.d.ts +88 -51
  127. package/sdk.js +126 -18
  128. package/setup/aws/disable-defender.sh +42 -0
  129. package/vitest.config.mjs +1 -3
  130. package/examples/z_flake-diffthreshold-001.test.mjs +0 -9
  131. package/examples/z_flake-diffthreshold-01.test.mjs +0 -9
  132. package/examples/z_flake-diffthreshold-05.test.mjs +0 -9
  133. /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.