testdriverai 7.1.0 → 7.1.1

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 (325) hide show
  1. package/.env.example +2 -0
  2. package/.github/workflows/linux-tests.yml +28 -0
  3. package/agent/index.js +18 -45
  4. package/agent/interface.js +13 -2
  5. package/agent/lib/commands.js +1 -1
  6. package/agent/lib/redraw.js +1 -1
  7. package/agent/lib/sandbox.js +30 -2
  8. package/agent/lib/valid-version.js +2 -2
  9. package/debugger/index.html +1 -1
  10. package/docs/docs.json +86 -125
  11. package/docs/v6/getting-started/self-hosting.mdx +3 -2
  12. package/docs/v7/_drafts/agents.mdx +852 -0
  13. package/docs/v7/_drafts/auto-cache-key.mdx +167 -0
  14. package/docs/v7/{guides → _drafts}/caching-selectors.mdx +125 -17
  15. package/docs/v7/_drafts/dashcam-title-feature.mdx +89 -0
  16. package/docs/v7/_drafts/error-handling.mdx +501 -0
  17. package/docs/v7/_drafts/implementation-plan.mdx +994 -0
  18. package/docs/v7/_drafts/init-command.mdx +95 -0
  19. package/docs/v7/_drafts/optimal-sdk-design.mdx +1348 -0
  20. package/docs/v7/_drafts/plugin-migration.mdx +222 -0
  21. package/docs/v7/_drafts/prompt-cache.mdx +200 -0
  22. package/docs/{QUICK_START_TEST_RECORDING.md → v7/_drafts/quick-start-test-recording.mdx} +3 -3
  23. package/docs/v7/_drafts/sdk-logging.mdx +222 -0
  24. package/docs/v7/_drafts/sdk-migration.mdx +474 -0
  25. package/docs/v7/_drafts/sdk-v7-complete.mdx +345 -0
  26. package/docs/v7/{guides → _drafts}/self-hosting.mdx +1 -1
  27. package/docs/v7/{guides → _drafts}/troubleshooting.mdx +2 -2
  28. package/docs/v7/{guides → _drafts}/vitest-plugin.mdx +4 -4
  29. package/docs/v7/api/{ai.mdx → act.mdx} +24 -24
  30. package/docs/v7/api/client.mdx +1 -1
  31. package/docs/v7/api/dashcam.mdx +2 -2
  32. package/docs/v7/api/elements.mdx +143 -41
  33. package/docs/v7/api/find.mdx +258 -0
  34. package/docs/v7/api/type.mdx +51 -7
  35. package/docs/v7/features/ai-native.mdx +427 -0
  36. package/docs/v7/features/easy-to-write.mdx +351 -0
  37. package/docs/v7/features/enterprise.mdx +540 -0
  38. package/docs/v7/features/fast.mdx +424 -0
  39. package/docs/v7/features/observable.mdx +623 -0
  40. package/docs/v7/features/powerful.mdx +531 -0
  41. package/docs/v7/features/scalable.mdx +417 -0
  42. package/docs/v7/features/stable.mdx +514 -0
  43. package/docs/v7/getting-started/configuration.mdx +1 -1
  44. package/docs/v7/getting-started/generating-tests.mdx +525 -0
  45. package/docs/v7/getting-started/installation.mdx +486 -0
  46. package/docs/v7/getting-started/quickstart.mdx +51 -5
  47. package/docs/v7/getting-started/running-and-debugging.mdx +511 -0
  48. package/docs/v7/getting-started/setting-up-in-ci.mdx +612 -0
  49. package/docs/v7/getting-started/writing-tests.mdx +535 -0
  50. package/docs/v7/overview/what-is-testdriver.mdx +398 -0
  51. package/docs/v7/playwright.mdx +3 -3
  52. package/docs/v7/presets/chrome.mdx +16 -0
  53. package/docs/v7/presets/electron.mdx +18 -0
  54. package/docs/v7/presets/vscode.mdx +19 -0
  55. package/examples/run-tests-with-recording.sh +70 -0
  56. package/examples/screenshot-example.js +63 -0
  57. package/examples/sdk-awesome-logs-demo.js +177 -0
  58. package/examples/sdk-cache-thresholds.js +96 -0
  59. package/examples/sdk-element-properties.js +155 -0
  60. package/examples/sdk-simple-example.js +65 -0
  61. package/examples/test-recording-example.test.js +166 -0
  62. package/interfaces/cli/commands/init.js +358 -0
  63. package/interfaces/vitest-plugin.mjs +214 -10
  64. package/{src → lib}/core/Dashcam.js +41 -4
  65. package/{src → lib}/vitest/hooks.mjs +118 -100
  66. package/lib/vitest/setup.mjs +44 -0
  67. package/package.json +9 -10
  68. package/sdk.d.ts +15 -2
  69. package/sdk.js +70 -18
  70. package/{self-hosted.yml → setup/aws/self-hosted.yml} +1 -1
  71. package/{testdriver/acceptance-sdk → test/manual}/test-console-logs.test.mjs +1 -1
  72. package/test/manual/test-find-api.js +73 -0
  73. package/test/manual/test-init.sh +54 -0
  74. package/test/manual/test-prompt-cache.js +96 -0
  75. package/test/manual/test-provision-auth.mjs +22 -0
  76. package/test/manual/test-sandbox-render.js +28 -0
  77. package/test/manual/test-sdk-methods.js +15 -0
  78. package/test/manual/test-sdk-refactor.js +53 -0
  79. package/test/manual/test-stack-trace.mjs +57 -0
  80. package/test/testdriver/assert.test.mjs +41 -0
  81. package/{testdriver/acceptance-sdk → test/testdriver}/auto-cache-key-demo.test.mjs +1 -1
  82. package/{testdriver/acceptance-sdk → test/testdriver}/drag-and-drop.test.mjs +1 -1
  83. package/{testdriver/acceptance-sdk → test/testdriver}/element-not-found.test.mjs +1 -1
  84. package/{testdriver/acceptance-sdk → test/testdriver}/exec-js.test.mjs +1 -1
  85. package/{testdriver/acceptance-sdk → test/testdriver}/exec-output.test.mjs +3 -3
  86. package/{testdriver/acceptance-sdk → test/testdriver}/exec-pwsh.test.mjs +3 -3
  87. package/{testdriver/acceptance-sdk → test/testdriver}/focus-window.test.mjs +1 -1
  88. package/{testdriver/acceptance-sdk → test/testdriver}/formatted-logging.test.mjs +1 -1
  89. package/{testdriver/acceptance-sdk → test/testdriver}/hover-image.test.mjs +1 -1
  90. package/{testdriver/acceptance-sdk → test/testdriver}/hover-text-with-description.test.mjs +1 -1
  91. package/{testdriver/acceptance-sdk → test/testdriver}/hover-text.test.mjs +1 -1
  92. package/{testdriver/acceptance-sdk → test/testdriver}/match-image.test.mjs +1 -1
  93. package/{testdriver/acceptance-sdk → test/testdriver}/press-keys.test.mjs +1 -1
  94. package/{testdriver/acceptance-sdk → test/testdriver}/prompt.test.mjs +2 -2
  95. package/{testdriver/acceptance-sdk → test/testdriver}/scroll-keyboard.test.mjs +1 -1
  96. package/{testdriver/acceptance-sdk → test/testdriver}/scroll-until-image.test.mjs +1 -1
  97. package/{testdriver/acceptance-sdk → test/testdriver}/scroll-until-text.test.mjs +1 -1
  98. package/{testdriver/acceptance-sdk → test/testdriver}/scroll.test.mjs +1 -1
  99. package/{src/vitest/lifecycle.mjs → test/testdriver/setup/lifecycleHelpers.mjs} +84 -99
  100. package/test/testdriver/setup/testHelpers.mjs +653 -0
  101. package/{testdriver/acceptance-sdk → test/testdriver}/type.test.mjs +1 -1
  102. package/vitest.config.mjs +11 -57
  103. package/.github/dependabot.yml +0 -11
  104. package/.github/workflows/acceptance-linux.yml +0 -75
  105. package/.github/workflows/acceptance-sdk-tests.yml +0 -133
  106. package/.github/workflows/acceptance-tests.yml +0 -130
  107. package/.github/workflows/lint.yml +0 -27
  108. package/.github/workflows/publish-canary.yml +0 -40
  109. package/.github/workflows/publish-latest.yml +0 -61
  110. package/.github/workflows/test-install.yml +0 -29
  111. package/.vscode/extensions.json +0 -3
  112. package/.vscode/launch.json +0 -22
  113. package/.vscode/settings.json +0 -14
  114. package/AGENTS.md +0 -550
  115. package/CODEOWNERS +0 -2
  116. package/_testdriver/acceptance/assert.yaml +0 -7
  117. package/_testdriver/acceptance/dashcam.yaml +0 -9
  118. package/_testdriver/acceptance/drag-and-drop.yaml +0 -49
  119. package/_testdriver/acceptance/embed.yaml +0 -9
  120. package/_testdriver/acceptance/exec-js.yaml +0 -29
  121. package/_testdriver/acceptance/exec-output.yaml +0 -43
  122. package/_testdriver/acceptance/exec-shell.yaml +0 -40
  123. package/_testdriver/acceptance/focus-window.yaml +0 -16
  124. package/_testdriver/acceptance/hover-image.yaml +0 -18
  125. package/_testdriver/acceptance/hover-text-with-description.yaml +0 -29
  126. package/_testdriver/acceptance/hover-text.yaml +0 -14
  127. package/_testdriver/acceptance/if-else.yaml +0 -31
  128. package/_testdriver/acceptance/match-image.yaml +0 -15
  129. package/_testdriver/acceptance/press-keys.yaml +0 -35
  130. package/_testdriver/acceptance/prompt.yaml +0 -11
  131. package/_testdriver/acceptance/remember.yaml +0 -27
  132. package/_testdriver/acceptance/screenshots/cart.png +0 -0
  133. package/_testdriver/acceptance/scroll-keyboard.yaml +0 -34
  134. package/_testdriver/acceptance/scroll-until-image.yaml +0 -26
  135. package/_testdriver/acceptance/scroll-until-text.yaml +0 -20
  136. package/_testdriver/acceptance/scroll.yaml +0 -33
  137. package/_testdriver/acceptance/snippets/login.yaml +0 -29
  138. package/_testdriver/acceptance/snippets/match-cart.yaml +0 -8
  139. package/_testdriver/acceptance/type.yaml +0 -29
  140. package/_testdriver/behavior/failure.yaml +0 -7
  141. package/_testdriver/behavior/hover-text.yaml +0 -13
  142. package/_testdriver/behavior/lifecycle/postrun.yaml +0 -10
  143. package/_testdriver/behavior/lifecycle/prerun.yaml +0 -8
  144. package/_testdriver/behavior/lifecycle/provision.yaml +0 -8
  145. package/_testdriver/behavior/secrets.yaml +0 -7
  146. package/_testdriver/edge-cases/dashcam-chrome.yaml +0 -8
  147. package/_testdriver/edge-cases/exec-pwsh-multiline.yaml +0 -10
  148. package/_testdriver/edge-cases/js-exception.yaml +0 -8
  149. package/_testdriver/edge-cases/js-promise.yaml +0 -19
  150. package/_testdriver/edge-cases/lifecycle/postrun.yaml +0 -10
  151. package/_testdriver/edge-cases/prompt-in-middle.yaml +0 -23
  152. package/_testdriver/edge-cases/prompt-nested.yaml +0 -7
  153. package/_testdriver/edge-cases/success-test.yaml +0 -9
  154. package/_testdriver/examples/android/example.yaml +0 -12
  155. package/_testdriver/examples/android/lifecycle/postrun.yaml +0 -11
  156. package/_testdriver/examples/android/lifecycle/provision.yaml +0 -47
  157. package/_testdriver/examples/android/readme.md +0 -7
  158. package/_testdriver/examples/chrome-extension/lifecycle/provision.yaml +0 -74
  159. package/_testdriver/examples/desktop/lifecycle/prerun.yaml +0 -0
  160. package/_testdriver/examples/desktop/lifecycle/provision.yaml +0 -64
  161. package/_testdriver/examples/vscode-extension/lifecycle/provision.yaml +0 -73
  162. package/_testdriver/examples/web/lifecycle/postrun.yaml +0 -7
  163. package/_testdriver/examples/web/lifecycle/prerun.yaml +0 -22
  164. package/_testdriver/lifecycle/postrun.yaml +0 -8
  165. package/_testdriver/lifecycle/prerun.yaml +0 -15
  166. package/_testdriver/lifecycle/provision.yaml +0 -25
  167. package/docs/v7/guides/ci-cd/azure.mdx +0 -587
  168. package/docs/v7/guides/ci-cd/circleci.mdx +0 -523
  169. package/docs/v7/guides/ci-cd/github-actions.mdx +0 -457
  170. package/docs/v7/guides/ci-cd/gitlab.mdx +0 -498
  171. package/docs/v7/guides/ci-cd/jenkins.mdx +0 -664
  172. package/docs/v7/guides/ci-cd/travis.mdx +0 -438
  173. package/scripts/view-test-results.mjs +0 -96
  174. package/src/vitest/extended.mjs +0 -108
  175. package/src/vitest/index.mjs +0 -64
  176. package/src/vitest/utils.mjs +0 -150
  177. package/styles/.vale-config/2-MDX.ini +0 -5
  178. package/styles/Microsoft/AMPM.yml +0 -9
  179. package/styles/Microsoft/Accessibility.yml +0 -30
  180. package/styles/Microsoft/Acronyms.yml +0 -64
  181. package/styles/Microsoft/Adverbs.yml +0 -272
  182. package/styles/Microsoft/Auto.yml +0 -11
  183. package/styles/Microsoft/Avoid.yml +0 -14
  184. package/styles/Microsoft/Contractions.yml +0 -50
  185. package/styles/Microsoft/Dashes.yml +0 -13
  186. package/styles/Microsoft/DateFormat.yml +0 -8
  187. package/styles/Microsoft/DateNumbers.yml +0 -40
  188. package/styles/Microsoft/DateOrder.yml +0 -8
  189. package/styles/Microsoft/Ellipses.yml +0 -9
  190. package/styles/Microsoft/FirstPerson.yml +0 -16
  191. package/styles/Microsoft/Foreign.yml +0 -13
  192. package/styles/Microsoft/Gender.yml +0 -8
  193. package/styles/Microsoft/GenderBias.yml +0 -42
  194. package/styles/Microsoft/GeneralURL.yml +0 -11
  195. package/styles/Microsoft/HeadingAcronyms.yml +0 -7
  196. package/styles/Microsoft/HeadingColons.yml +0 -8
  197. package/styles/Microsoft/HeadingPunctuation.yml +0 -13
  198. package/styles/Microsoft/Headings.yml +0 -28
  199. package/styles/Microsoft/Hyphens.yml +0 -14
  200. package/styles/Microsoft/Negative.yml +0 -13
  201. package/styles/Microsoft/Ordinal.yml +0 -13
  202. package/styles/Microsoft/OxfordComma.yml +0 -8
  203. package/styles/Microsoft/Passive.yml +0 -183
  204. package/styles/Microsoft/Percentages.yml +0 -7
  205. package/styles/Microsoft/Plurals.yml +0 -7
  206. package/styles/Microsoft/Quotes.yml +0 -7
  207. package/styles/Microsoft/RangeTime.yml +0 -13
  208. package/styles/Microsoft/Semicolon.yml +0 -8
  209. package/styles/Microsoft/SentenceLength.yml +0 -6
  210. package/styles/Microsoft/Spacing.yml +0 -8
  211. package/styles/Microsoft/Suspended.yml +0 -7
  212. package/styles/Microsoft/Terms.yml +0 -42
  213. package/styles/Microsoft/URLFormat.yml +0 -9
  214. package/styles/Microsoft/Units.yml +0 -16
  215. package/styles/Microsoft/Vocab.yml +0 -25
  216. package/styles/Microsoft/We.yml +0 -11
  217. package/styles/Microsoft/Wordiness.yml +0 -127
  218. package/styles/Microsoft/meta.json +0 -4
  219. package/styles/alex/Ablist.yml +0 -274
  220. package/styles/alex/Condescending.yml +0 -16
  221. package/styles/alex/Gendered.yml +0 -110
  222. package/styles/alex/LGBTQ.yml +0 -55
  223. package/styles/alex/OCD.yml +0 -10
  224. package/styles/alex/Press.yml +0 -12
  225. package/styles/alex/ProfanityLikely.yml +0 -1289
  226. package/styles/alex/ProfanityMaybe.yml +0 -282
  227. package/styles/alex/ProfanityUnlikely.yml +0 -251
  228. package/styles/alex/README.md +0 -27
  229. package/styles/alex/Race.yml +0 -85
  230. package/styles/alex/Suicide.yml +0 -26
  231. package/styles/alex/meta.json +0 -4
  232. package/styles/config/vocabularies/Docs/accept.txt +0 -47
  233. package/styles/config/vocabularies/Docs/reject.txt +0 -4
  234. package/styles/proselint/Airlinese.yml +0 -8
  235. package/styles/proselint/AnimalLabels.yml +0 -48
  236. package/styles/proselint/Annotations.yml +0 -9
  237. package/styles/proselint/Apologizing.yml +0 -8
  238. package/styles/proselint/Archaisms.yml +0 -52
  239. package/styles/proselint/But.yml +0 -8
  240. package/styles/proselint/Cliches.yml +0 -782
  241. package/styles/proselint/CorporateSpeak.yml +0 -30
  242. package/styles/proselint/Currency.yml +0 -5
  243. package/styles/proselint/Cursing.yml +0 -15
  244. package/styles/proselint/DateCase.yml +0 -7
  245. package/styles/proselint/DateMidnight.yml +0 -7
  246. package/styles/proselint/DateRedundancy.yml +0 -10
  247. package/styles/proselint/DateSpacing.yml +0 -7
  248. package/styles/proselint/DenizenLabels.yml +0 -52
  249. package/styles/proselint/Diacritical.yml +0 -95
  250. package/styles/proselint/GenderBias.yml +0 -45
  251. package/styles/proselint/GroupTerms.yml +0 -39
  252. package/styles/proselint/Hedging.yml +0 -8
  253. package/styles/proselint/Hyperbole.yml +0 -6
  254. package/styles/proselint/Jargon.yml +0 -11
  255. package/styles/proselint/LGBTOffensive.yml +0 -13
  256. package/styles/proselint/LGBTTerms.yml +0 -15
  257. package/styles/proselint/Malapropisms.yml +0 -8
  258. package/styles/proselint/Needless.yml +0 -358
  259. package/styles/proselint/Nonwords.yml +0 -38
  260. package/styles/proselint/Oxymorons.yml +0 -22
  261. package/styles/proselint/P-Value.yml +0 -6
  262. package/styles/proselint/RASSyndrome.yml +0 -30
  263. package/styles/proselint/README.md +0 -12
  264. package/styles/proselint/Skunked.yml +0 -13
  265. package/styles/proselint/Spelling.yml +0 -17
  266. package/styles/proselint/Typography.yml +0 -11
  267. package/styles/proselint/Uncomparables.yml +0 -50
  268. package/styles/proselint/Very.yml +0 -6
  269. package/styles/proselint/meta.json +0 -15
  270. package/styles/write-good/Cliches.yml +0 -702
  271. package/styles/write-good/E-Prime.yml +0 -32
  272. package/styles/write-good/Illusions.yml +0 -11
  273. package/styles/write-good/Passive.yml +0 -183
  274. package/styles/write-good/README.md +0 -27
  275. package/styles/write-good/So.yml +0 -5
  276. package/styles/write-good/ThereIs.yml +0 -6
  277. package/styles/write-good/TooWordy.yml +0 -221
  278. package/styles/write-good/Weasel.yml +0 -29
  279. package/styles/write-good/meta.json +0 -4
  280. package/test/dashcam.test.js +0 -137
  281. package/test/mcp-example-test.yaml +0 -27
  282. package/test/test_parser.js +0 -47
  283. package/testdriver/acceptance-sdk/QUICK_REFERENCE.md +0 -61
  284. package/testdriver/acceptance-sdk/README.md +0 -128
  285. package/testdriver/acceptance-sdk/TEST_REPORTING.md +0 -245
  286. package/testdriver/acceptance-sdk/assert.test.mjs +0 -26
  287. package/testdriver/acceptance-sdk/hooks-example.test.mjs +0 -38
  288. package/testdriver/acceptance-sdk/presets-example.test.mjs +0 -87
  289. package/testdriver/acceptance-sdk/setup/testHelpers.mjs +0 -420
  290. package/testdriver/acceptance-sdk/sully-ai.test.mjs +0 -234
  291. package/testdriver/acceptance-sdk/type-checking-demo.js +0 -49
  292. package/vale.ini +0 -18
  293. package/vitest.config.example.js +0 -19
  294. package/vitest.config.mjs.bak +0 -44
  295. /package/docs/{ARCHITECTURE.md → v7/_drafts/architecture.mdx} +0 -0
  296. /package/docs/{AWESOME_LOGS_QUICK_REF.md → v7/_drafts/awesome-logs-quick-ref.mdx} +0 -0
  297. /package/docs/v7/{guides → _drafts}/best-practices.mdx +0 -0
  298. /package/docs/v7/{guides → _drafts}/caching-ai.mdx +0 -0
  299. /package/docs/v7/{guides → _drafts}/caching.mdx +0 -0
  300. /package/docs/{MIGRATION.md → v7/_drafts/cli-to-sdk-migration.mdx} +0 -0
  301. /package/{CONTRIBUTING.md → docs/v7/_drafts/contributing.mdx} +0 -0
  302. /package/docs/v7/{progressive-apis/CORE.md → _drafts/core.mdx} +0 -0
  303. /package/docs/v7/{guides → _drafts}/debugging.mdx +0 -0
  304. /package/docs/v7/{guides → _drafts}/faq.mdx +0 -0
  305. /package/docs/v7/{progressive-apis/HOOKS.md → _drafts/hooks.mdx} +0 -0
  306. /package/docs/v7/{guides → _drafts}/migration.mdx +0 -0
  307. /package/docs/v7/{guides → _drafts}/performance.mdx +0 -0
  308. /package/docs/{PRESETS.md → v7/_drafts/presets.mdx} +0 -0
  309. /package/docs/v7/{progressive-apis/PROGRESSIVE_DISCLOSURE.md → _drafts/progressive-disclosure.mdx} +0 -0
  310. /package/docs/v7/{progressive-apis/PROVISION.md → _drafts/provision.mdx} +0 -0
  311. /package/docs/{SDK_AWESOME_LOGS.md → v7/_drafts/sdk-awesome-logs.mdx} +0 -0
  312. /package/docs/{sdk-browser-rendering.md → v7/_drafts/sdk-browser-rendering.mdx} +0 -0
  313. /package/docs/{TEST_RECORDING.md → v7/_drafts/test-recording.mdx} +0 -0
  314. /package/docs/v7/{guides → _drafts}/vitest.mdx +0 -0
  315. /package/docs/v7/{README.md → overview/readme.mdx} +0 -0
  316. /package/{src → lib}/core/index.d.ts +0 -0
  317. /package/{src → lib}/core/index.js +0 -0
  318. /package/{src → lib}/presets/index.mjs +0 -0
  319. /package/{src → lib}/vitest/hooks.d.ts +0 -0
  320. /package/{debug-locate-response.js → test/manual/debug-locate-response.js} +0 -0
  321. /package/{verify-element-api.js → test/manual/verify-element-api.js} +0 -0
  322. /package/{verify-types.js → test/manual/verify-types.js} +0 -0
  323. /package/{testdriver/acceptance-sdk → test/testdriver}/chrome-extension.test.mjs +0 -0
  324. /package/{testdriver/acceptance-sdk → test/testdriver}/setup/globalTeardown.mjs +0 -0
  325. /package/{testdriver/acceptance-sdk → test/testdriver}/setup/vitestSetup.mjs +0 -0
@@ -1,664 +0,0 @@
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>