testdriverai 7.0.0 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/AGENTS.md +550 -0
  2. package/CODEOWNERS +0 -1
  3. package/README.md +126 -0
  4. package/agent/index.js +43 -18
  5. package/agent/lib/commands.js +794 -135
  6. package/agent/lib/redraw.js +124 -39
  7. package/agent/lib/sandbox.js +10 -1
  8. package/agent/lib/sdk.js +21 -0
  9. package/docs/MIGRATION.md +425 -0
  10. package/docs/PRESETS.md +210 -0
  11. package/docs/docs.json +91 -37
  12. package/docs/guide/best-practices-polling.mdx +154 -0
  13. package/docs/v7/api/dashcam.mdx +497 -0
  14. package/docs/v7/api/doubleClick.mdx +102 -0
  15. package/docs/v7/api/mouseDown.mdx +161 -0
  16. package/docs/v7/api/mouseUp.mdx +164 -0
  17. package/docs/v7/api/rightClick.mdx +123 -0
  18. package/docs/v7/getting-started/configuration.mdx +380 -0
  19. package/docs/v7/getting-started/quickstart.mdx +273 -140
  20. package/docs/v7/guides/best-practices.mdx +486 -0
  21. package/docs/v7/guides/caching-ai.mdx +215 -0
  22. package/docs/v7/guides/caching-selectors.mdx +292 -0
  23. package/docs/v7/guides/caching.mdx +366 -0
  24. package/docs/v7/guides/ci-cd/azure.mdx +587 -0
  25. package/docs/v7/guides/ci-cd/circleci.mdx +523 -0
  26. package/docs/v7/guides/ci-cd/github-actions.mdx +457 -0
  27. package/docs/v7/guides/ci-cd/gitlab.mdx +498 -0
  28. package/docs/v7/guides/ci-cd/jenkins.mdx +664 -0
  29. package/docs/v7/guides/ci-cd/travis.mdx +438 -0
  30. package/docs/v7/guides/debugging.mdx +349 -0
  31. package/docs/v7/guides/faq.mdx +393 -0
  32. package/docs/v7/guides/performance.mdx +517 -0
  33. package/docs/v7/guides/troubleshooting.mdx +526 -0
  34. package/docs/v7/guides/vitest-plugin.mdx +477 -0
  35. package/docs/v7/guides/vitest.mdx +535 -0
  36. package/docs/v7/platforms/linux.mdx +308 -0
  37. package/docs/v7/platforms/macos.mdx +433 -0
  38. package/docs/v7/platforms/windows.mdx +430 -0
  39. package/docs/v7/presets/chrome-extension.mdx +223 -0
  40. package/docs/v7/presets/chrome.mdx +287 -0
  41. package/docs/v7/presets/electron.mdx +435 -0
  42. package/docs/v7/presets/vscode.mdx +398 -0
  43. package/docs/v7/presets/webapp.mdx +396 -0
  44. package/docs/v7/progressive-apis/CORE.md +459 -0
  45. package/docs/v7/progressive-apis/HOOKS.md +360 -0
  46. package/docs/v7/progressive-apis/PROGRESSIVE_DISCLOSURE.md +230 -0
  47. package/docs/v7/progressive-apis/PROVISION.md +266 -0
  48. package/interfaces/vitest-plugin.mjs +186 -100
  49. package/package.json +12 -1
  50. package/sdk.d.ts +335 -42
  51. package/sdk.js +756 -95
  52. package/src/core/Dashcam.js +469 -0
  53. package/src/core/index.d.ts +150 -0
  54. package/src/core/index.js +12 -0
  55. package/src/presets/index.mjs +331 -0
  56. package/src/vitest/extended.mjs +108 -0
  57. package/src/vitest/hooks.d.ts +119 -0
  58. package/src/vitest/hooks.mjs +298 -0
  59. package/src/vitest/index.mjs +64 -0
  60. package/src/vitest/lifecycle.mjs +277 -0
  61. package/src/vitest/utils.mjs +150 -0
  62. package/test/dashcam.test.js +137 -0
  63. package/testdriver/acceptance-sdk/assert.test.mjs +13 -31
  64. package/testdriver/acceptance-sdk/auto-cache-key-demo.test.mjs +56 -0
  65. package/testdriver/acceptance-sdk/chrome-extension.test.mjs +89 -0
  66. package/testdriver/acceptance-sdk/drag-and-drop.test.mjs +7 -19
  67. package/testdriver/acceptance-sdk/element-not-found.test.mjs +6 -19
  68. package/testdriver/acceptance-sdk/exec-js.test.mjs +6 -18
  69. package/testdriver/acceptance-sdk/exec-output.test.mjs +8 -20
  70. package/testdriver/acceptance-sdk/exec-pwsh.test.mjs +13 -25
  71. package/testdriver/acceptance-sdk/focus-window.test.mjs +8 -20
  72. package/testdriver/acceptance-sdk/formatted-logging.test.mjs +5 -20
  73. package/testdriver/acceptance-sdk/hooks-example.test.mjs +38 -0
  74. package/testdriver/acceptance-sdk/hover-image.test.mjs +10 -19
  75. package/testdriver/acceptance-sdk/hover-text-with-description.test.mjs +7 -19
  76. package/testdriver/acceptance-sdk/hover-text.test.mjs +5 -19
  77. package/testdriver/acceptance-sdk/match-image.test.mjs +7 -19
  78. package/testdriver/acceptance-sdk/presets-example.test.mjs +87 -0
  79. package/testdriver/acceptance-sdk/press-keys.test.mjs +5 -19
  80. package/testdriver/acceptance-sdk/prompt.test.mjs +6 -18
  81. package/testdriver/acceptance-sdk/scroll-keyboard.test.mjs +6 -20
  82. package/testdriver/acceptance-sdk/scroll-until-image.test.mjs +6 -18
  83. package/testdriver/acceptance-sdk/scroll-until-text.test.mjs +9 -23
  84. package/testdriver/acceptance-sdk/scroll.test.mjs +12 -21
  85. package/testdriver/acceptance-sdk/setup/testHelpers.mjs +124 -352
  86. package/testdriver/acceptance-sdk/sully-ai.test.mjs +234 -0
  87. package/testdriver/acceptance-sdk/test-console-logs.test.mjs +42 -0
  88. package/testdriver/acceptance-sdk/type.test.mjs +19 -58
  89. package/vitest.config.mjs +1 -0
  90. package/.vscode/mcp.json +0 -9
  91. package/MIGRATION.md +0 -389
  92. package/PLUGIN_MIGRATION.md +0 -222
  93. package/PROMPT_CACHE.md +0 -200
  94. package/SDK_LOGGING.md +0 -222
  95. package/SDK_MIGRATION.md +0 -474
  96. package/SDK_README.md +0 -1122
  97. package/debug-screenshot-1763401388589.png +0 -0
  98. package/examples/run-tests-with-recording.sh +0 -70
  99. package/examples/screenshot-example.js +0 -63
  100. package/examples/sdk-awesome-logs-demo.js +0 -177
  101. package/examples/sdk-cache-thresholds.js +0 -96
  102. package/examples/sdk-element-properties.js +0 -155
  103. package/examples/sdk-simple-example.js +0 -65
  104. package/examples/test-recording-example.test.js +0 -166
  105. package/mcp-server/AI_GUIDELINES.md +0 -57
  106. package/test-find-api.js +0 -73
  107. package/test-prompt-cache.js +0 -96
  108. package/test-sandbox-render.js +0 -28
  109. package/test-sdk-methods.js +0 -15
  110. package/test-sdk-refactor.js +0 -53
  111. package/test-stack-trace.mjs +0 -57
  112. package/testdriver/acceptance-sdk/setup/lifecycleHelpers.mjs +0 -239
@@ -0,0 +1,526 @@
1
+ ---
2
+ title: "Troubleshooting"
3
+ description: "Common issues and solutions"
4
+ icon: "circle-question"
5
+ ---
6
+
7
+ ## Installation Issues
8
+
9
+ ### Module Not Found
10
+
11
+ **Error:** `Cannot find module 'testdriverai'`
12
+
13
+ **Solution:**
14
+ ```bash
15
+ # Verify installation
16
+ npm list testdriverai
17
+
18
+ # Reinstall
19
+ npm install testdriverai --save-dev
20
+
21
+ # Clear cache and reinstall
22
+ rm -rf node_modules package-lock.json
23
+ npm install
24
+ ```
25
+
26
+ ### Version Mismatch
27
+
28
+ **Error:** `TestDriver requires Node 16+`
29
+
30
+ **Solution:**
31
+ ```bash
32
+ # Check Node version
33
+ node --version
34
+
35
+ # Update Node
36
+ nvm install 18
37
+ nvm use 18
38
+ ```
39
+
40
+ ## Authentication Issues
41
+
42
+ ### API Key Not Found
43
+
44
+ **Error:** `API key required`
45
+
46
+ **Solution:**
47
+ ```bash
48
+ # Create .env file
49
+ echo "TD_API_KEY=your_api_key_here" > .env
50
+
51
+ # Verify it loads
52
+ node -e "require('dotenv').config(); console.log(process.env.TD_API_KEY)"
53
+ ```
54
+
55
+ ### Invalid API Key
56
+
57
+ **Error:** `Authentication failed: Invalid API key`
58
+
59
+ **Solution:**
60
+ 1. Verify key at [app.testdriver.ai/team](https://app.testdriver.ai/team)
61
+ 2. Check for typos or extra spaces
62
+ 3. Regenerate key if needed
63
+
64
+ ```javascript
65
+ // Remove quotes, spaces, newlines
66
+ const apiKey = process.env.TD_API_KEY.trim();
67
+ ```
68
+
69
+ ## Connection Issues
70
+
71
+ ### Sandbox Connection Timeout
72
+
73
+ **Error:** `Connection timeout after 60000ms`
74
+
75
+ **Solution:**
76
+ ```javascript
77
+ // Increase connection timeout
78
+ const client = await TestDriver.create({
79
+ apiKey: process.env.TD_API_KEY,
80
+ connectionTimeout: 120000 // 2 minutes
81
+ });
82
+
83
+ // Or retry connection
84
+ let attempts = 0;
85
+ while (attempts < 3) {
86
+ try {
87
+ await client.connect({ newSandbox: true });
88
+ break;
89
+ } catch (error) {
90
+ attempts++;
91
+ if (attempts === 3) throw error;
92
+ await new Promise(r => setTimeout(r, 5000));
93
+ }
94
+ }
95
+ ```
96
+
97
+ ### Sandbox Quota Exceeded
98
+
99
+ **Error:** `Sandbox limit reached`
100
+
101
+ **Solution:**
102
+ 1. Check your [quota](https://app.testdriver.ai/team)
103
+ 2. Disconnect old sandboxes
104
+ 3. Upgrade plan if needed
105
+
106
+ ```javascript
107
+ // Ensure cleanup in all tests
108
+ afterAll(async () => {
109
+ await testdriver?.disconnect();
110
+ });
111
+ ```
112
+
113
+ ## Element Finding Issues
114
+
115
+ ### Element Not Found
116
+
117
+ **Error:** Element returns `found() === false`
118
+
119
+ **Solutions:**
120
+
121
+ **1. Be more specific:**
122
+ ```javascript
123
+ // ❌ Too vague
124
+ await testdriver.find('button');
125
+
126
+ // ✅ Specific
127
+ await testdriver.find('blue submit button at bottom right of login form');
128
+ ```
129
+
130
+ **2. Wait for element to appear:**
131
+ ```javascript
132
+ async function waitFor(testdriver, description, timeout = 30000) {
133
+ const start = Date.now();
134
+ while (Date.now() - start < timeout) {
135
+ const element = await testdriver.find(description);
136
+ if (element.found()) return element;
137
+ await new Promise(r => setTimeout(r, 1000));
138
+ }
139
+ throw new Error(`Timeout waiting for: ${description}`);
140
+ }
141
+
142
+ const button = await waitFor(testdriver, 'submit button');
143
+ ```
144
+
145
+ **3. Check if page loaded:**
146
+ ```javascript
147
+ // Verify page is ready
148
+ await testdriver.assert('page fully loaded');
149
+ await testdriver.find('submit button');
150
+ ```
151
+
152
+ **4. Try alternative descriptions:**
153
+ ```javascript
154
+ const descriptions = [
155
+ 'submit button',
156
+ 'blue button at bottom',
157
+ 'button with text Submit',
158
+ 'primary button in form'
159
+ ];
160
+
161
+ let button;
162
+ for (const desc of descriptions) {
163
+ button = await testdriver.find(desc);
164
+ if (button.found()) break;
165
+ }
166
+ ```
167
+
168
+ ### Wrong Element Found
169
+
170
+ **Issue:** Finds wrong element or multiple matches
171
+
172
+ **Solutions:**
173
+
174
+ **1. Add more context:**
175
+ ```javascript
176
+ // ❌ Ambiguous
177
+ await testdriver.find('delete button');
178
+
179
+ // ✅ Specific location
180
+ await testdriver.find('delete button in the row for user John Doe');
181
+ await testdriver.find('red delete button next to email field');
182
+ ```
183
+
184
+ **2. Check confidence:**
185
+ ```javascript
186
+ const element = await testdriver.find('button');
187
+ console.log('Confidence:', element.confidence);
188
+
189
+ if (element.confidence < 0.8) {
190
+ console.warn('Low confidence, trying alternative');
191
+ element = await testdriver.find('more specific button description');
192
+ }
193
+ ```
194
+
195
+ ## Cache Issues
196
+
197
+ ### Stale Cache
198
+
199
+ **Issue:** Using outdated cached element
200
+
201
+ **Solutions:**
202
+
203
+ **1. Bypass cache:**
204
+ ```javascript
205
+ // Force fresh lookup
206
+ const element = await testdriver.find('button', { threshold: -1 });
207
+ ```
208
+
209
+ **2. Clear cache:**
210
+ ```bash
211
+ # Clear prompt cache
212
+ rm -rf .testdriver/.cache/*.yaml
213
+
214
+ # Clear selector cache via console
215
+ # Visit https://console.testdriver.ai
216
+ ```
217
+
218
+ **3. Adjust threshold:**
219
+ ```javascript
220
+ // More lenient (90% similarity)
221
+ await testdriver.find('button', { threshold: 0.10 });
222
+
223
+ // Stricter (99% similarity)
224
+ await testdriver.find('button', { threshold: 0.01 });
225
+ ```
226
+
227
+ ### Cache Not Working
228
+
229
+ **Issue:** No cache hits despite repeated calls
230
+
231
+ **Solutions:**
232
+
233
+ **1. Use consistent prompts:**
234
+ ```javascript
235
+ // ❌ Different prompts
236
+ await testdriver.find('submit button');
237
+ await testdriver.find('the submit button');
238
+
239
+ // ✅ Consistent
240
+ const desc = 'submit button';
241
+ await testdriver.find(desc);
242
+ await testdriver.find(desc); // Cache hit
243
+ ```
244
+
245
+ **2. Check cache is enabled:**
246
+ ```javascript
247
+ // Verify cache not disabled
248
+ console.log('Prompt cache:', !process.env.TD_NO_PROMPT_CACHE);
249
+ console.log('Selector cache:', !process.env.TD_NO_SELECTOR_CACHE);
250
+ ```
251
+
252
+ ## Command Execution Issues
253
+
254
+ ### exec() Timeout
255
+
256
+ **Error:** `Command timeout after 30000ms`
257
+
258
+ **Solutions:**
259
+
260
+ **1. Increase timeout:**
261
+ ```javascript
262
+ await testdriver.exec('sh', 'slow-command', 120000); // 2 minutes
263
+ ```
264
+
265
+ **2. Run in background:**
266
+ ```javascript
267
+ // Add & for background execution
268
+ await testdriver.exec('sh', 'long-running-process &', 5000);
269
+ ```
270
+
271
+ **3. Check command exists:**
272
+ ```javascript
273
+ // Verify command available
274
+ const result = await testdriver.exec('sh', 'which google-chrome', 5000, true);
275
+ console.log('Chrome path:', result);
276
+ ```
277
+
278
+ ### Command Failed
279
+
280
+ **Error:** Command returns non-zero exit code
281
+
282
+ **Solutions:**
283
+
284
+ **1. Ignore errors:**
285
+ ```javascript
286
+ // Last parameter ignores errors
287
+ await testdriver.exec('sh', 'risky-command', 30000, true);
288
+ ```
289
+
290
+ **2. Check output:**
291
+ ```javascript
292
+ try {
293
+ const output = await testdriver.exec('sh', 'command', 30000, false);
294
+ console.log('Output:', output);
295
+ } catch (error) {
296
+ console.error('Command failed:', error.message);
297
+ }
298
+ ```
299
+
300
+ **3. Use correct shell:**
301
+ ```javascript
302
+ // Linux/Mac
303
+ await testdriver.exec('sh', 'echo "test"', 5000);
304
+
305
+ // Windows
306
+ await testdriver.exec('pwsh', 'Write-Output "test"', 5000);
307
+ ```
308
+
309
+ ## Test Execution Issues
310
+
311
+ ### Test Timeout
312
+
313
+ **Error:** `Test timed out after 60000ms`
314
+
315
+ **Solutions:**
316
+
317
+ **1. Increase test timeout:**
318
+ ```javascript
319
+ // vitest.config.mjs
320
+ export default defineConfig({
321
+ test: {
322
+ testTimeout: 300000 // 5 minutes
323
+ }
324
+ });
325
+
326
+ // Or per test
327
+ test('slow test', async () => {
328
+ // ...
329
+ }, 300000); // 5 minutes
330
+ ```
331
+
332
+ **2. Optimize test:**
333
+ ```javascript
334
+ // Use faster actions
335
+ await testdriver.find('button').then(el => el.click());
336
+
337
+ // Instead of
338
+ await testdriver.ai('click the button');
339
+ ```
340
+
341
+ ### Tests Fail in CI
342
+
343
+ **Issue:** Tests pass locally but fail in CI
344
+
345
+ **Solutions:**
346
+
347
+ **1. Check environment variables:**
348
+ ```yaml
349
+ # .github/workflows/test.yml
350
+ env:
351
+ TD_API_KEY: ${{ secrets.TD_API_KEY }}
352
+ TD_DEFAULT_OS: linux
353
+ ```
354
+
355
+ **2. Increase timeouts for CI:**
356
+ ```javascript
357
+ const timeout = process.env.CI ? 600000 : 300000;
358
+
359
+ export default defineConfig({
360
+ test: {
361
+ testTimeout: timeout
362
+ }
363
+ });
364
+ ```
365
+
366
+ **3. Reduce concurrency:**
367
+ ```javascript
368
+ // CI might have resource limits
369
+ export default defineConfig({
370
+ test: {
371
+ maxConcurrency: process.env.CI ? 2 : 5
372
+ }
373
+ });
374
+ ```
375
+
376
+ ## Dashcam Issues
377
+
378
+ ### No Replay URL
379
+
380
+ **Issue:** `dashcam.url` is `null`
381
+
382
+ **Solutions:**
383
+
384
+ **1. Ensure dashcam started:**
385
+ ```javascript
386
+ const dashcam = new Dashcam(client);
387
+ await dashcam.auth();
388
+ await dashcam.start(); // Must call start!
389
+
390
+ // Run test
391
+
392
+ const url = await dashcam.stop();
393
+ console.log('Replay:', url);
394
+ ```
395
+
396
+ **2. Check dashcam installed:**
397
+ ```javascript
398
+ // Verify dashcam CLI available
399
+ await testdriver.exec('sh', 'dashcam version', 5000);
400
+ ```
401
+
402
+ **3. Use preset:**
403
+ ```javascript
404
+ // Presets handle dashcam automatically
405
+ const { testdriver, dashcam } = await chrome(context, {
406
+ dashcam: true
407
+ });
408
+ ```
409
+
410
+ ### Recording Not Started
411
+
412
+ **Issue:** Dashcam doesn't record
413
+
414
+ **Solutions:**
415
+
416
+ **1. Check authentication:**
417
+ ```javascript
418
+ await dashcam.auth(process.env.TD_API_KEY);
419
+ const recording = await dashcam.isRecording();
420
+ console.log('Recording:', recording);
421
+ ```
422
+
423
+ **2. Wait after start:**
424
+ ```javascript
425
+ await dashcam.start();
426
+ await new Promise(r => setTimeout(r, 2000)); // Wait 2s
427
+ ```
428
+
429
+ ## Performance Issues
430
+
431
+ ### Slow Test Execution
432
+
433
+ **Solutions:**
434
+
435
+ **1. Reuse sandboxes:**
436
+ ```javascript
437
+ // ✅ One sandbox per suite
438
+ beforeAll(async () => {
439
+ testdriver = await TestDriver.create(...);
440
+ });
441
+
442
+ // ❌ One per test (slow!)
443
+ beforeEach(async () => {
444
+ testdriver = await TestDriver.create(...);
445
+ });
446
+ ```
447
+
448
+ **2. Use caching:**
449
+ ```javascript
450
+ // Enable caching for repeated elements
451
+ await testdriver.find('button'); // First call
452
+ await testdriver.find('button'); // Cached (faster!)
453
+ ```
454
+
455
+ **3. Run in parallel:**
456
+ ```javascript
457
+ // vitest.config.mjs
458
+ export default defineConfig({
459
+ test: {
460
+ maxConcurrency: 5,
461
+ fileParallelism: true
462
+ }
463
+ });
464
+ ```
465
+
466
+ ### High Memory Usage
467
+
468
+ **Solutions:**
469
+
470
+ **1. Reduce concurrency:**
471
+ ```javascript
472
+ maxConcurrency: 2 // Lower for resource-constrained environments
473
+ ```
474
+
475
+ **2. Cleanup sandboxes:**
476
+ ```javascript
477
+ afterAll(async () => {
478
+ await testdriver?.disconnect();
479
+ });
480
+ ```
481
+
482
+ **3. Monitor resources:**
483
+ ```javascript
484
+ console.log('Memory:', process.memoryUsage());
485
+ ```
486
+
487
+ ## Getting Help
488
+
489
+ If issues persist:
490
+
491
+ 1. **Check Dashcam recording** - See what actually happened
492
+ 2. **Enable debug logging** - `verbosity: 2`
493
+ 3. **Search Discord** - [discord.com/invite/cWDFW8DzPm](https://discord.com/invite/cWDFW8DzPm)
494
+ 4. **Check docs** - [docs.testdriver.ai](https://docs.testdriver.ai)
495
+ 5. **Report bug** - [github.com/testdriverai/testdriverai/issues](https://github.com/testdriverai/testdriverai/issues)
496
+
497
+ ### Information to Include
498
+
499
+ When reporting issues:
500
+
501
+ - TestDriver version: `npm list testdriverai`
502
+ - Node version: `node --version`
503
+ - OS: `uname -a` or `$PSVersionTable.OS`
504
+ - Error message (full stack trace)
505
+ - Dashcam URL
506
+ - Minimal reproduction code
507
+
508
+ ## See Also
509
+
510
+ <CardGroup cols={2}>
511
+ <Card title="Debugging" icon="bug" href="/v7/guides/debugging">
512
+ Debug failing tests
513
+ </Card>
514
+
515
+ <Card title="Best Practices" icon="star" href="/v7/guides/best-practices">
516
+ Testing patterns
517
+ </Card>
518
+
519
+ <Card title="Configuration" icon="gear" href="/v7/getting-started/configuration">
520
+ Configure TestDriver
521
+ </Card>
522
+
523
+ <Card title="FAQ" icon="question" href="/v7/guides/faq">
524
+ Frequently asked questions
525
+ </Card>
526
+ </CardGroup>