@testdriverai/agent 7.11.229-canary → 7.11.231-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.
Files changed (100) hide show
  1. package/docs/_data/examples-manifest.json +16 -16
  2. package/docs/_scripts/generate-examples.js +38 -45
  3. package/docs/agent.mdx +174 -93
  4. package/docs/assert.mdx +73 -269
  5. package/docs/aws-setup.mdx +196 -314
  6. package/docs/bring-your-own-machine.mdx +139 -206
  7. package/docs/cache.mdx +144 -151
  8. package/docs/caching.mdx +99 -89
  9. package/docs/captcha.mdx +126 -111
  10. package/docs/ci-cd.mdx +154 -543
  11. package/docs/click.mdx +74 -229
  12. package/docs/client.mdx +177 -231
  13. package/docs/copilot/auto-healing.mdx +86 -370
  14. package/docs/copilot/running-tests.mdx +121 -930
  15. package/docs/customizing-devices.mdx +74 -251
  16. package/docs/dashcam.mdx +72 -405
  17. package/docs/debugging-with-screenshots.mdx +105 -371
  18. package/docs/docs.json +75 -18
  19. package/docs/double-click.mdx +48 -68
  20. package/docs/errors.mdx +102 -176
  21. package/docs/events.mdx +170 -327
  22. package/docs/examples/{hover-text-with-description.mdx → add-to-cart.mdx} +30 -35
  23. package/docs/examples/assert.mdx +28 -41
  24. package/docs/examples/click-button.mdx +71 -0
  25. package/docs/examples/{hover-image.mdx → click-icon.mdx} +32 -28
  26. package/docs/examples/element-not-found.mdx +27 -26
  27. package/docs/examples/findall-coffee-icons.mdx +28 -32
  28. package/docs/examples/installer.mdx +61 -25
  29. package/docs/examples/launch-vscode-linux.mdx +28 -51
  30. package/docs/examples/navigate-and-scroll.mdx +82 -0
  31. package/docs/examples/parse.mdx +24 -28
  32. package/docs/examples/press-keys.mdx +28 -25
  33. package/docs/examples/scroll.mdx +25 -27
  34. package/docs/examples/type.mdx +26 -21
  35. package/docs/exec.mdx +92 -256
  36. package/docs/extract.mdx +69 -170
  37. package/docs/find.mdx +140 -736
  38. package/docs/focus-application.mdx +69 -246
  39. package/docs/generating-tests.mdx +103 -137
  40. package/docs/guide/best-practices-polling.mdx +65 -141
  41. package/docs/hosted.mdx +80 -144
  42. package/docs/hover.mdx +62 -235
  43. package/docs/locating-elements.mdx +74 -369
  44. package/docs/making-assertions.mdx +116 -74
  45. package/docs/mcp-setup.mdx +80 -63
  46. package/docs/mouse-down.mdx +48 -125
  47. package/docs/mouse-up.mdx +47 -129
  48. package/docs/options.mdx +75 -48
  49. package/docs/parse.mdx +95 -184
  50. package/docs/performing-actions.mdx +104 -94
  51. package/docs/press-keys.mdx +59 -299
  52. package/docs/provision.mdx +137 -182
  53. package/docs/quickstart-claude.mdx +85 -0
  54. package/docs/quickstart-github.mdx +62 -32
  55. package/docs/quickstart-manual.mdx +60 -33
  56. package/docs/quickstart-vscode.mdx +97 -0
  57. package/docs/quickstart.mdx +25 -9
  58. package/docs/redraw.mdx +101 -165
  59. package/docs/reusable-code.mdx +97 -200
  60. package/docs/right-click.mdx +47 -89
  61. package/docs/screenshot.mdx +47 -201
  62. package/docs/screenshots.mdx +87 -137
  63. package/docs/scroll.mdx +71 -154
  64. package/docs/secrets.mdx +96 -91
  65. package/docs/self-hosted.mdx +83 -142
  66. package/docs/snippets/enterprise.mdx +15 -0
  67. package/docs/styles.css +68 -0
  68. package/docs/test-results-json.mdx +167 -204
  69. package/docs/type.mdx +56 -304
  70. package/docs/variables.mdx +121 -81
  71. package/docs/wait.mdx +33 -31
  72. package/docs/what-is-testdriver.mdx +80 -32
  73. package/examples/{hover-text-with-description.test.mjs → add-to-cart.test.mjs} +4 -5
  74. package/examples/assert.test.mjs +3 -20
  75. package/examples/{hover-text.test.mjs → click-button.test.mjs} +3 -4
  76. package/examples/{hover-image.test.mjs → click-icon.test.mjs} +5 -6
  77. package/examples/element-not-found.test.mjs +3 -5
  78. package/examples/findall-coffee-icons.test.mjs +3 -3
  79. package/examples/installer.test.mjs +1 -1
  80. package/examples/launch-vscode-linux.test.mjs +6 -33
  81. package/examples/{scroll-keyboard.test.mjs → navigate-and-scroll.test.mjs} +4 -5
  82. package/examples/parse.test.mjs +1 -2
  83. package/examples/press-keys.test.mjs +4 -4
  84. package/examples/scroll.test.mjs +3 -6
  85. package/examples/type.test.mjs +5 -2
  86. package/lib/provision.js +6 -2
  87. package/package.json +1 -1
  88. package/sdk.d.ts +4 -2
  89. package/sdk.js +1 -1
  90. package/docs/claude-mcp-plugin.mdx +0 -244
  91. package/docs/elements.mdx +0 -606
  92. package/docs/examples/ai.mdx +0 -78
  93. package/docs/examples/captcha-api.mdx +0 -92
  94. package/docs/examples/chrome-extension.mdx +0 -156
  95. package/docs/examples/drag-and-drop.mdx +0 -100
  96. package/docs/examples/formatted-logging.mdx +0 -74
  97. package/docs/examples/hover-text.mdx +0 -70
  98. package/docs/examples/match-image.mdx +0 -97
  99. package/docs/examples/scroll-keyboard.mdx +0 -80
  100. package/docs/examples/scroll-until-text.mdx +0 -109
package/docs/assert.mdx CHANGED
@@ -1,315 +1,119 @@
1
1
  ---
2
2
  title: "assert()"
3
3
  sidebarTitle: "assert"
4
- description: "Make AI-powered assertions about screen state"
4
+ description: "Check a plain-language statement about the screen, and fail the test if it's false."
5
5
  icon: "check-circle"
6
6
  ---
7
7
 
8
- ## Overview
8
+ Check that something is true on screen. The AI looks at the current screen and decides whether your statement holds.
9
9
 
10
- Make assertions about the screen state with natural language and AI. The AI examines the screen. It makes sure that your assertion is true.
10
+ ```javascript
11
+ await testdriver.assert('the dashboard shows a welcome message');
12
+ ```
11
13
 
12
- ## Syntax
14
+ For writing good assertions, see [Make assertions](/making-assertions).
13
15
 
14
- ```javascript
15
- await testdriver.assert(assertion)
16
- await testdriver.assert(assertion, options)
16
+ ## Signature
17
+
18
+ ```typescript
19
+ testdriver.assert(assertion: string, options?: AssertOptions): Promise<boolean>
17
20
  ```
18
21
 
19
22
  ## Parameters
20
23
 
21
24
  <ParamField path="assertion" type="string" required>
22
- Natural language description of what should be true
25
+ A statement about the screen that should be true, such as `'the cart shows 1 item'`.
23
26
  </ParamField>
24
27
 
25
- <ParamField path="options" type="object">
26
- Optional configuration
27
-
28
+ <ParamField path="options" type="AssertOptions">
28
29
  <Expandable title="properties">
29
- <ParamField path="ai" type="object">
30
- AI sampling configuration for this assert call (overrides global `ai` config from constructor).
31
-
32
- <Expandable title="properties">
33
- <ParamField path="temperature" type="number">
34
- Controls randomness. `0` = deterministic, higher = more creative. Default: model default.
35
- </ParamField>
36
-
37
- <ParamField path="top" type="object">
38
- Sampling parameters
39
-
40
- <Expandable title="properties">
41
- <ParamField path="p" type="number">
42
- Top-P (nucleus sampling). Range: 0-1.
43
- </ParamField>
44
-
45
- <ParamField path="k" type="number">
46
- Top-K sampling. `1` = most deterministic.
47
- </ParamField>
48
- </Expandable>
49
- </ParamField>
50
- </Expandable>
30
+ <ParamField path="threshold" type="number" default="0.05">
31
+ How much the screen may differ from a cached passing run (0 to 1) and still reuse its result. Defaults to the client's `cache.thresholds.assert`, which is `0.05`. `-1` turns caching off for this call. See [Caching](/caching).
32
+ </ParamField>
33
+ <ParamField path="cacheKey" type="string">
34
+ Store and look up the cached result under this key instead of the client's.
35
+ </ParamField>
36
+ <ParamField path="ai" type="AIConfig">
37
+ Sampling settings for this call, such as `{ temperature: 0 }`. Overrides the client's [`ai` option](/options#param-ai).
38
+ </ParamField>
39
+ <ParamField path="os" type="string">
40
+ The OS to store the cached result under. Set automatically from the client.
41
+ </ParamField>
42
+ <ParamField path="resolution" type="string">
43
+ The resolution to store the cached result under. Set automatically from the client.
51
44
  </ParamField>
52
45
  </Expandable>
53
46
  </ParamField>
54
47
 
55
48
  ## Returns
56
49
 
57
- `Promise<boolean>` - `true` if the assertion passes. It throws an error if the assertion fails.
50
+ `Promise<boolean>`. Resolves to `true` when the statement is true.
51
+
52
+ ## Errors
53
+
54
+ When the statement is false, `assert()` throws, so the test fails at that line. The error message starts with `AI Assertion failed:`, followed by your statement and the AI's explanation.
55
+
56
+ Inside `ai()`, assertions don't throw. They resolve to `false` so the AI can keep working.
58
57
 
59
58
  ## Examples
60
59
 
61
- ### Basic Assertions
60
+ ### Check the result of an action
62
61
 
63
62
  ```javascript
64
- // Verify page elements
65
- await testdriver.assert('the login page is displayed');
66
- await testdriver.assert('submit button is visible');
67
- await testdriver.assert('error message is shown');
68
-
69
- // Verify text content
70
- await testdriver.assert('the page title is "Welcome"');
71
- await testdriver.assert('username field contains "john.doe"');
72
- await testdriver.assert('success message says "Account created"');
73
-
74
- // Verify states
75
- await testdriver.assert('the form is empty');
76
- await testdriver.assert('the checkbox is checked');
77
- await testdriver.assert('the dropdown shows "United States"');
78
-
79
- // Verify visual appearance
80
- await testdriver.assert('the button is blue');
81
- await testdriver.assert('the loading spinner is displayed');
82
- await testdriver.assert('the modal dialog is open');
63
+ await testdriver.find('Add to cart button').click();
64
+ await testdriver.assert('the cart icon shows 1 item');
83
65
  ```
84
66
 
85
- ## Best Practices
86
-
87
- <Check>
88
- **Be specific in assertions**
89
-
90
- More specific assertions are more reliable:
91
-
92
- ```javascript
93
- // ❌ Too vague
94
- await testdriver.assert('button is visible');
95
-
96
- // ✅ Specific
97
- await testdriver.assert('blue submit button is visible below the form');
98
- ```
99
- </Check>
100
-
101
- <Check>
102
- **Assert state changes**
103
-
104
- Make sure of the state before and after actions:
105
-
106
- ```javascript
107
- // Before
108
- await testdriver.assert('cart is empty');
109
-
110
- // Action
111
- const addBtn = await testdriver.find('add to cart');
112
- await addBtn.click();
113
-
114
- // After
115
- await testdriver.assert('cart contains 1 item');
116
- ```
117
- </Check>
118
-
119
- <Check>
120
- **Use with test framework assertions**
121
-
122
- Combine AI assertions with traditional test assertions:
123
-
124
- ```javascript
125
- // AI assertion
126
- const result = await testdriver.assert('success message is displayed');
127
-
128
- // Framework assertion
129
- expect(result).toBeTruthy();
130
-
131
- // Extract for detailed comparison
132
- const message = await testdriver.extract('the success message text');
133
- expect(message).toContain('successfully');
134
- ```
135
- </Check>
136
-
137
- ## Polling Assertions
138
-
139
- For conditions that may take time to become true:
67
+ ### Check text in a field
140
68
 
141
69
  ```javascript
142
- async function waitForAssertion(testdriver, assertion, timeout = 30000) {
143
- const startTime = Date.now();
144
-
145
- while (Date.now() - startTime < timeout) {
146
- try {
147
- await testdriver.assert(assertion);
148
- return true; // Assertion passed
149
- } catch (error) {
150
- // Assertion failed, wait and retry
151
- await new Promise(r => setTimeout(r, 1000));
152
- }
153
- }
154
-
155
- throw new Error(`Assertion timeout: "${assertion}"`);
156
- }
157
-
158
- // Usage
159
- await waitForAssertion(testdriver, 'page has finished loading', 30000);
160
- await waitForAssertion(testdriver, 'results are displayed', 10000);
70
+ await testdriver.find('Username input field').click();
71
+ await testdriver.type('standard_user');
72
+ await testdriver.assert('the username field contains "standard_user"');
161
73
  ```
162
74
 
163
- ## Use Cases
164
-
165
- <AccordionGroup>
166
- <Accordion title="Form Validation">
167
- ```javascript
168
- // Try to submit empty form
169
- const submitBtn = await testdriver.find('submit button');
170
- await submitBtn.click();
171
-
172
- // Verify validation errors
173
- await testdriver.assert('email field shows "required" error');
174
- await testdriver.assert('password field shows "required" error');
175
-
176
- // Verify form not submitted
177
- await testdriver.assert('still on the form page');
178
- ```
179
- </Accordion>
180
-
181
- <Accordion title="Page Navigation">
182
- ```javascript
183
- const loginBtn = await testdriver.find('login button');
184
- await loginBtn.click();
185
-
186
- // Verify navigation
187
- await testdriver.assert('user dashboard is displayed');
188
- await testdriver.assert('welcome message shows user name');
189
- await testdriver.assert('logout button is visible');
190
- ```
191
- </Accordion>
192
-
193
- <Accordion title="Dynamic Content">
194
- ```javascript
195
- const loadBtn = await testdriver.find('load more button');
196
- await loadBtn.click();
197
-
198
- // Poll for content using helper
199
- await waitForAssertion(testdriver, 'more than 10 items are shown', 10000);
200
- await testdriver.assert('load more button is still visible');
201
- ```
202
- </Accordion>
203
-
204
- <Accordion title="Visual States">
205
- ```javascript
206
- // Verify hover effect
207
- const button = await testdriver.find('primary button');
208
- await button.hover();
209
-
210
- await testdriver.assert('button background is darker');
211
-
212
- // Verify button is enabled
213
- await testdriver.assert('submit button is enabled');
214
- ```
215
- </Accordion>
216
-
217
- <Accordion title="Multi-Step Workflows">
218
- ```javascript
219
- // Step 1
220
- await testdriver.assert('step 1 is active');
221
- const nextBtn = await testdriver.find('next button');
222
- await nextBtn.click();
223
-
224
- // Step 2
225
- await testdriver.assert('step 2 is active');
226
- await testdriver.assert('step 1 is completed');
227
- await nextBtn.click();
228
-
229
- // Step 3
230
- await testdriver.assert('step 3 is active');
231
- await testdriver.assert('step 2 is completed');
232
- ```
233
- </Accordion>
234
- </AccordionGroup>
235
-
236
- ## Complete Example
75
+ ### Use it with expect()
76
+
77
+ `assert()` already fails the test when the statement is false. An `expect()` makes the check visible to anyone reading the test:
237
78
 
238
79
  ```javascript
239
- import { beforeAll, afterAll, describe, it, expect } from 'vitest';
240
- import TestDriver from 'testdriverai';
80
+ const loggedIn = await testdriver.assert('the dashboard is visible');
81
+ expect(loggedIn).toBe(true);
82
+ ```
241
83
 
242
- describe('Assertions', () => {
243
- let testdriver;
84
+ ### Wait for something before asserting
244
85
 
245
- beforeAll(async () => {
246
- client = new TestDriver(process.env.TD_API_KEY);
247
- await testdriver.auth();
248
- await testdriver.connect();
249
- });
86
+ `assert()` checks the screen once. For something that takes time to appear, wait for it with [`find()`](/find) first:
250
87
 
251
- afterAll(async () => {
252
- await testdriver.disconnect();
253
- });
88
+ ```javascript
89
+ await testdriver.find('Order confirmation heading', { timeout: 30000 });
90
+ await testdriver.assert('the confirmation shows an order number');
91
+ ```
254
92
 
255
- it('should validate login flow', async () => {
256
- await testdriver.focusApplication('Google Chrome');
257
-
258
- // Verify initial state
259
- await testdriver.assert('the login page is displayed');
260
- await testdriver.assert('username field is empty');
261
- await testdriver.assert('password field is empty');
262
-
263
- // Fill form
264
- const usernameField = await testdriver.find('username input');
265
- await usernameField.click();
266
- await testdriver.type('testuser');
267
-
268
- await testdriver.pressKeys(['tab']);
269
- await testdriver.type('password123');
270
-
271
- // Verify fields filled
272
- await testdriver.assert('username field contains "testuser"');
273
- await testdriver.assert('password field is not empty');
274
-
275
- // Submit
276
- await testdriver.pressKeys(['enter']);
277
-
278
- // Poll for success
279
- await waitForAssertion(testdriver, 'user dashboard is displayed', 10000);
280
-
281
- // Verify logged in state
282
- await testdriver.assert('welcome message is shown');
283
- await testdriver.assert('logout button is visible');
284
-
285
- // Verify login page is gone
286
- await testdriver.assert('login form is displayed', false, true);
287
- });
93
+ ## Complete example
94
+
95
+ ```javascript tests/login.test.mjs
96
+ import { describe, expect, it } from 'vitest';
97
+ import { TestDriver } from 'testdriverai/vitest/hooks';
98
+
99
+ describe('Login', () => {
100
+ it('shows an error when the form is empty', async (context) => {
101
+ const testdriver = TestDriver(context);
102
+ await testdriver.provision.chrome({ url: 'https://testdriver-sandbox.vercel.app/login' });
103
+
104
+ await testdriver.assert('the login form is empty');
105
+
106
+ await testdriver.find('Sign in button below the password field').click();
288
107
 
289
- it('should show validation errors', async () => {
290
- // Try empty submission
291
- const submitBtn = await testdriver.find('submit button');
292
- await submitBtn.click();
293
-
294
- // Verify multiple errors
295
- const errors = [
296
- 'email field shows error',
297
- 'name field shows error',
298
- 'password field shows error'
299
- ];
300
-
301
- for (const error of errors) {
302
- const result = await testdriver.assert(error);
303
- expect(result).toBeTruthy();
304
- }
305
-
306
- // Verify not submitted
307
- await testdriver.assert('confirmation page is shown', false, true);
108
+ const result = await testdriver.assert('an error says the fields are required');
109
+ expect(result).toBe(true);
308
110
  });
309
111
  });
310
112
  ```
311
113
 
312
- ## Related Methods
114
+ ## Related
313
115
 
314
- - [`extract()`](/extract) - Extract information for detailed assertions
315
- - [`find()`](/find) - Locate elements to verify
116
+ - [Make assertions](/making-assertions): write assertions that catch real regressions
117
+ - [extract()](/extract): read a value off the screen to compare yourself
118
+ - [find()](/find): wait for an element before asserting
119
+ - [Caching](/caching): how assertion results are reused