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,664 @@
1
+ ---
2
+ title: "Jenkins"
3
+ description: "Run TestDriver tests in Jenkins"
4
+ icon: "jenkins"
5
+ ---
6
+
7
+ ## Pipeline Setup
8
+
9
+ Create `Jenkinsfile`:
10
+
11
+ ```groovy
12
+ pipeline {
13
+ agent {
14
+ docker {
15
+ image 'node:18'
16
+ }
17
+ }
18
+
19
+ environment {
20
+ TD_API_KEY = credentials('td-api-key')
21
+ }
22
+
23
+ stages {
24
+ stage('Install') {
25
+ steps {
26
+ sh 'npm ci'
27
+ }
28
+ }
29
+
30
+ stage('Test') {
31
+ steps {
32
+ sh 'npx vitest'
33
+ }
34
+ }
35
+ }
36
+
37
+ post {
38
+ always {
39
+ archiveArtifacts artifacts: 'test-results/**', allowEmptyArchive: true
40
+ junit 'test-results/junit.xml'
41
+ }
42
+ }
43
+ }
44
+ ```
45
+
46
+ ## Add API Key
47
+
48
+ ### Using Credentials Plugin
49
+
50
+ 1. Go to **Manage Jenkins** → **Credentials**
51
+ 2. Select domain (usually "Global")
52
+ 3. Click **Add Credentials**
53
+ 4. Kind: **Secret text**
54
+ 5. Secret: Your API key from [dashboard.testdriver.ai](https://dashboard.testdriver.ai)
55
+ 6. ID: `td-api-key`
56
+ 7. Description: "TestDriver API Key"
57
+ 8. Click **OK**
58
+
59
+ ### Using Environment Variables
60
+
61
+ Or set directly in Jenkins:
62
+
63
+ 1. Go to **Manage Jenkins** → **Configure System**
64
+ 2. Find **Global properties**
65
+ 3. Check **Environment variables**
66
+ 4. Add:
67
+ - Name: `TD_API_KEY`
68
+ - Value: Your API key
69
+ 5. Click **Save**
70
+
71
+ ## Parallel Tests
72
+
73
+ Run tests in parallel stages:
74
+
75
+ ```groovy
76
+ pipeline {
77
+ agent {
78
+ docker {
79
+ image 'node:18'
80
+ }
81
+ }
82
+
83
+ environment {
84
+ TD_API_KEY = credentials('td-api-key')
85
+ }
86
+
87
+ stages {
88
+ stage('Install') {
89
+ steps {
90
+ sh 'npm ci'
91
+ }
92
+ }
93
+
94
+ stage('Test') {
95
+ parallel {
96
+ stage('Shard 1') {
97
+ steps {
98
+ sh 'npx vitest --shard=1/4'
99
+ }
100
+ }
101
+ stage('Shard 2') {
102
+ steps {
103
+ sh 'npx vitest --shard=2/4'
104
+ }
105
+ }
106
+ stage('Shard 3') {
107
+ steps {
108
+ sh 'npx vitest --shard=3/4'
109
+ }
110
+ }
111
+ stage('Shard 4') {
112
+ steps {
113
+ sh 'npx vitest --shard=4/4'
114
+ }
115
+ }
116
+ }
117
+ }
118
+ }
119
+
120
+ post {
121
+ always {
122
+ junit 'test-results/junit.xml'
123
+ }
124
+ }
125
+ }
126
+ ```
127
+
128
+ ## Save Dashcam URLs
129
+
130
+ Extract replay URLs from test output:
131
+
132
+ ```groovy
133
+ pipeline {
134
+ agent {
135
+ docker {
136
+ image 'node:18'
137
+ }
138
+ }
139
+
140
+ environment {
141
+ TD_API_KEY = credentials('td-api-key')
142
+ }
143
+
144
+ stages {
145
+ stage('Install') {
146
+ steps {
147
+ sh 'npm ci'
148
+ }
149
+ }
150
+
151
+ stage('Test') {
152
+ steps {
153
+ sh '''
154
+ npx vitest 2>&1 | tee test-output.log
155
+ grep -o 'https://dashcam.testdriver.ai/[a-zA-Z0-9-]*' test-output.log > dashcam-urls.txt || true
156
+ '''
157
+ }
158
+ }
159
+ }
160
+
161
+ post {
162
+ always {
163
+ archiveArtifacts artifacts: 'test-results/**, test-output.log, dashcam-urls.txt', allowEmptyArchive: true
164
+ junit 'test-results/junit.xml'
165
+ }
166
+ failure {
167
+ script {
168
+ def urls = readFile('dashcam-urls.txt').trim()
169
+ echo "Dashcam URLs:\n${urls}"
170
+ }
171
+ }
172
+ }
173
+ }
174
+ ```
175
+
176
+ ## Scheduled Builds
177
+
178
+ Configure build triggers:
179
+
180
+ ```groovy
181
+ pipeline {
182
+ triggers {
183
+ // Poll SCM every 6 hours
184
+ pollSCM('H */6 * * *')
185
+
186
+ // Or schedule directly (2 AM daily)
187
+ cron('0 2 * * *')
188
+ }
189
+
190
+ agent {
191
+ docker {
192
+ image 'node:18'
193
+ }
194
+ }
195
+
196
+ environment {
197
+ TD_API_KEY = credentials('td-api-key')
198
+ }
199
+
200
+ stages {
201
+ stage('Test') {
202
+ steps {
203
+ sh 'npm ci'
204
+ sh 'npx vitest'
205
+ }
206
+ }
207
+ }
208
+ }
209
+ ```
210
+
211
+ ## Multiple Node Versions
212
+
213
+ Test across Node.js versions:
214
+
215
+ ```groovy
216
+ pipeline {
217
+ agent none
218
+
219
+ environment {
220
+ TD_API_KEY = credentials('td-api-key')
221
+ }
222
+
223
+ stages {
224
+ stage('Test') {
225
+ matrix {
226
+ axes {
227
+ axis {
228
+ name 'NODE_VERSION'
229
+ values '16', '18', '20'
230
+ }
231
+ }
232
+ agent {
233
+ docker {
234
+ image "node:${NODE_VERSION}"
235
+ }
236
+ }
237
+ stages {
238
+ stage('Install') {
239
+ steps {
240
+ sh 'npm ci'
241
+ }
242
+ }
243
+ stage('Run Tests') {
244
+ steps {
245
+ sh 'npx vitest'
246
+ }
247
+ }
248
+ }
249
+ }
250
+ }
251
+ }
252
+
253
+ post {
254
+ always {
255
+ junit 'test-results/junit.xml'
256
+ }
257
+ }
258
+ }
259
+ ```
260
+
261
+ ## Conditional Execution
262
+
263
+ Skip tests on documentation changes:
264
+
265
+ ```groovy
266
+ pipeline {
267
+ agent {
268
+ docker {
269
+ image 'node:18'
270
+ }
271
+ }
272
+
273
+ stages {
274
+ stage('Check Changes') {
275
+ steps {
276
+ script {
277
+ def changes = sh(
278
+ script: 'git diff --name-only HEAD~1',
279
+ returnStdout: true
280
+ ).trim()
281
+
282
+ if (changes ==~ /.*\.(md|txt)$/) {
283
+ echo "Only docs changed, skipping tests"
284
+ currentBuild.result = 'SUCCESS'
285
+ return
286
+ }
287
+ }
288
+ }
289
+ }
290
+
291
+ stage('Test') {
292
+ when {
293
+ expression { currentBuild.result != 'SUCCESS' }
294
+ }
295
+ steps {
296
+ sh 'npm ci'
297
+ sh 'npx vitest'
298
+ }
299
+ }
300
+ }
301
+ }
302
+ ```
303
+
304
+ ## Retry Failed Tests
305
+
306
+ Automatically retry on failure:
307
+
308
+ ```groovy
309
+ pipeline {
310
+ agent {
311
+ docker {
312
+ image 'node:18'
313
+ }
314
+ }
315
+
316
+ environment {
317
+ TD_API_KEY = credentials('td-api-key')
318
+ }
319
+
320
+ stages {
321
+ stage('Test') {
322
+ steps {
323
+ retry(3) {
324
+ sh 'npm ci'
325
+ sh 'npx vitest'
326
+ }
327
+ }
328
+ }
329
+ }
330
+ }
331
+ ```
332
+
333
+ Or retry specific stages:
334
+
335
+ ```groovy
336
+ stage('Test') {
337
+ steps {
338
+ sh 'npm ci'
339
+ script {
340
+ try {
341
+ sh 'npx vitest'
342
+ } catch (Exception e) {
343
+ echo 'First attempt failed, retrying...'
344
+ sh 'npx vitest'
345
+ }
346
+ }
347
+ }
348
+ }
349
+ ```
350
+
351
+ ## Build Parameters
352
+
353
+ Allow manual parameter input:
354
+
355
+ ```groovy
356
+ pipeline {
357
+ agent {
358
+ docker {
359
+ image 'node:18'
360
+ }
361
+ }
362
+
363
+ parameters {
364
+ choice(
365
+ name: 'ENVIRONMENT',
366
+ choices: ['staging', 'production'],
367
+ description: 'Environment to test'
368
+ )
369
+ booleanParam(
370
+ name: 'PARALLEL',
371
+ defaultValue: true,
372
+ description: 'Run tests in parallel'
373
+ )
374
+ }
375
+
376
+ environment {
377
+ TD_API_KEY = credentials('td-api-key')
378
+ TEST_URL = "${params.ENVIRONMENT == 'production' ? 'https://example.com' : 'https://staging.example.com'}"
379
+ }
380
+
381
+ stages {
382
+ stage('Test') {
383
+ steps {
384
+ sh 'npm ci'
385
+ script {
386
+ if (params.PARALLEL) {
387
+ sh 'npx vitest --maxConcurrency=5'
388
+ } else {
389
+ sh 'npx vitest --maxConcurrency=1'
390
+ }
391
+ }
392
+ }
393
+ }
394
+ }
395
+ }
396
+ ```
397
+
398
+ ## Notifications
399
+
400
+ Send notifications on failure:
401
+
402
+ ```groovy
403
+ pipeline {
404
+ agent {
405
+ docker {
406
+ image 'node:18'
407
+ }
408
+ }
409
+
410
+ environment {
411
+ TD_API_KEY = credentials('td-api-key')
412
+ }
413
+
414
+ stages {
415
+ stage('Test') {
416
+ steps {
417
+ sh 'npm ci'
418
+ sh 'npx vitest'
419
+ }
420
+ }
421
+ }
422
+
423
+ post {
424
+ failure {
425
+ emailext(
426
+ subject: "Build Failed: ${env.JOB_NAME} - ${env.BUILD_NUMBER}",
427
+ body: """
428
+ Build failed: ${env.BUILD_URL}
429
+
430
+ Check Dashcam URLs in artifacts.
431
+ """,
432
+ to: 'team@example.com'
433
+ )
434
+ }
435
+ success {
436
+ echo 'Tests passed!'
437
+ }
438
+ }
439
+ }
440
+ ```
441
+
442
+ ## Timeout
443
+
444
+ Set build timeout:
445
+
446
+ ```groovy
447
+ pipeline {
448
+ agent {
449
+ docker {
450
+ image 'node:18'
451
+ }
452
+ }
453
+
454
+ options {
455
+ timeout(time: 30, unit: 'MINUTES')
456
+ timestamps()
457
+ buildDiscarder(logRotator(numToKeepStr: '10'))
458
+ }
459
+
460
+ stages {
461
+ stage('Test') {
462
+ steps {
463
+ timeout(time: 20, unit: 'MINUTES') {
464
+ sh 'npm ci'
465
+ sh 'npx vitest'
466
+ }
467
+ }
468
+ }
469
+ }
470
+ }
471
+ ```
472
+
473
+ ## Workspace Cleanup
474
+
475
+ Clean workspace before/after build:
476
+
477
+ ```groovy
478
+ pipeline {
479
+ agent {
480
+ docker {
481
+ image 'node:18'
482
+ }
483
+ }
484
+
485
+ options {
486
+ skipDefaultCheckout()
487
+ }
488
+
489
+ stages {
490
+ stage('Checkout') {
491
+ steps {
492
+ cleanWs()
493
+ checkout scm
494
+ }
495
+ }
496
+
497
+ stage('Test') {
498
+ steps {
499
+ sh 'npm ci'
500
+ sh 'npx vitest'
501
+ }
502
+ }
503
+ }
504
+
505
+ post {
506
+ always {
507
+ cleanWs()
508
+ }
509
+ }
510
+ }
511
+ ```
512
+
513
+ ## Troubleshooting
514
+
515
+ ### Docker permission denied
516
+
517
+ If using Docker agent on self-hosted Jenkins:
518
+
519
+ ```bash
520
+ # Add Jenkins user to docker group
521
+ sudo usermod -aG docker jenkins
522
+ sudo systemctl restart jenkins
523
+ ```
524
+
525
+ ### API key not found
526
+
527
+ Debug credentials:
528
+
529
+ ```groovy
530
+ stage('Debug') {
531
+ steps {
532
+ sh '''
533
+ echo "Has TD_API_KEY: ${TD_API_KEY:+yes}"
534
+ node --version
535
+ npm --version
536
+ '''
537
+ }
538
+ }
539
+ ```
540
+
541
+ ### Tests timeout
542
+
543
+ Increase timeout:
544
+
545
+ ```groovy
546
+ options {
547
+ timeout(time: 60, unit: 'MINUTES')
548
+ }
549
+ ```
550
+
551
+ ## Complete Example
552
+
553
+ Full-featured Jenkinsfile:
554
+
555
+ ```groovy
556
+ pipeline {
557
+ agent {
558
+ docker {
559
+ image 'node:18'
560
+ args '-v /var/run/docker.sock:/var/run/docker.sock'
561
+ }
562
+ }
563
+
564
+ options {
565
+ timeout(time: 30, unit: 'MINUTES')
566
+ timestamps()
567
+ buildDiscarder(logRotator(numToKeepStr: '30'))
568
+ disableConcurrentBuilds()
569
+ }
570
+
571
+ triggers {
572
+ cron('0 2 * * *') // 2 AM daily
573
+ }
574
+
575
+ environment {
576
+ TD_API_KEY = credentials('td-api-key')
577
+ CI = 'true'
578
+ }
579
+
580
+ stages {
581
+ stage('Install') {
582
+ steps {
583
+ sh 'npm ci'
584
+ }
585
+ }
586
+
587
+ stage('Test') {
588
+ parallel {
589
+ stage('Shard 1/4') {
590
+ steps {
591
+ sh 'npx vitest --shard=1/4 2>&1 | tee test-output-1.log'
592
+ }
593
+ }
594
+ stage('Shard 2/4') {
595
+ steps {
596
+ sh 'npx vitest --shard=2/4 2>&1 | tee test-output-2.log'
597
+ }
598
+ }
599
+ stage('Shard 3/4') {
600
+ steps {
601
+ sh 'npx vitest --shard=3/4 2>&1 | tee test-output-3.log'
602
+ }
603
+ }
604
+ stage('Shard 4/4') {
605
+ steps {
606
+ sh 'npx vitest --shard=4/4 2>&1 | tee test-output-4.log'
607
+ }
608
+ }
609
+ }
610
+ }
611
+
612
+ stage('Extract Dashcam URLs') {
613
+ steps {
614
+ sh '''
615
+ cat test-output-*.log | \
616
+ grep -o 'https://dashcam.testdriver.ai/[a-zA-Z0-9-]*' > dashcam-urls.txt || true
617
+ '''
618
+ }
619
+ }
620
+ }
621
+
622
+ post {
623
+ always {
624
+ archiveArtifacts(
625
+ artifacts: 'test-results/**, test-output-*.log, dashcam-urls.txt',
626
+ allowEmptyArchive: true
627
+ )
628
+ junit(
629
+ testResults: 'test-results/junit.xml',
630
+ allowEmptyResults: true
631
+ )
632
+ }
633
+ failure {
634
+ script {
635
+ def urls = readFile('dashcam-urls.txt').trim()
636
+ echo "❌ Tests failed. Dashcam URLs:\n${urls}"
637
+ }
638
+ }
639
+ success {
640
+ echo '✅ All tests passed!'
641
+ }
642
+ }
643
+ }
644
+ ```
645
+
646
+ ## See Also
647
+
648
+ <CardGroup cols={2}>
649
+ <Card title="CI/CD Overview" icon="arrows-spin" href="/v7/guides/ci-cd/overview">
650
+ CI/CD concepts
651
+ </Card>
652
+
653
+ <Card title="Performance" icon="gauge" href="/v7/guides/performance">
654
+ Optimize tests
655
+ </Card>
656
+
657
+ <Card title="Troubleshooting" icon="circle-question" href="/v7/guides/troubleshooting">
658
+ Common issues
659
+ </Card>
660
+
661
+ <Card title="Jenkins Docs" icon="book" href="https://www.jenkins.io/doc/">
662
+ Official docs
663
+ </Card>
664
+ </CardGroup>