testdriverai 7.0.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 (324) hide show
  1. package/.env.example +2 -0
  2. package/.github/workflows/linux-tests.yml +28 -0
  3. package/README.md +126 -0
  4. package/agent/index.js +7 -9
  5. package/agent/interface.js +13 -2
  6. package/agent/lib/commands.js +795 -136
  7. package/agent/lib/redraw.js +124 -39
  8. package/agent/lib/sandbox.js +40 -3
  9. package/agent/lib/sdk.js +21 -0
  10. package/agent/lib/valid-version.js +2 -2
  11. package/debugger/index.html +1 -1
  12. package/docs/docs.json +86 -71
  13. package/docs/guide/best-practices-polling.mdx +154 -0
  14. package/docs/v6/getting-started/self-hosting.mdx +3 -2
  15. package/docs/v7/_drafts/agents.mdx +852 -0
  16. package/docs/v7/_drafts/auto-cache-key.mdx +167 -0
  17. package/docs/v7/_drafts/best-practices.mdx +486 -0
  18. package/docs/v7/_drafts/caching-ai.mdx +215 -0
  19. package/docs/v7/_drafts/caching-selectors.mdx +400 -0
  20. package/docs/v7/_drafts/caching.mdx +366 -0
  21. package/docs/v7/_drafts/cli-to-sdk-migration.mdx +425 -0
  22. package/docs/v7/_drafts/core.mdx +459 -0
  23. package/docs/v7/_drafts/dashcam-title-feature.mdx +89 -0
  24. package/docs/v7/_drafts/debugging.mdx +349 -0
  25. package/docs/v7/_drafts/error-handling.mdx +501 -0
  26. package/docs/v7/_drafts/faq.mdx +393 -0
  27. package/docs/v7/_drafts/hooks.mdx +360 -0
  28. package/docs/v7/_drafts/implementation-plan.mdx +994 -0
  29. package/docs/v7/_drafts/init-command.mdx +95 -0
  30. package/docs/v7/_drafts/optimal-sdk-design.mdx +1348 -0
  31. package/docs/v7/_drafts/performance.mdx +517 -0
  32. package/docs/v7/_drafts/presets.mdx +210 -0
  33. package/docs/v7/_drafts/progressive-disclosure.mdx +230 -0
  34. package/docs/v7/_drafts/provision.mdx +266 -0
  35. package/docs/{QUICK_START_TEST_RECORDING.md → v7/_drafts/quick-start-test-recording.mdx} +3 -3
  36. package/docs/v7/_drafts/sdk-v7-complete.mdx +345 -0
  37. package/docs/v7/{guides → _drafts}/self-hosting.mdx +1 -1
  38. package/docs/v7/_drafts/troubleshooting.mdx +526 -0
  39. package/docs/v7/_drafts/vitest-plugin.mdx +477 -0
  40. package/docs/v7/_drafts/vitest.mdx +535 -0
  41. package/docs/v7/api/{ai.mdx → act.mdx} +24 -24
  42. package/docs/v7/api/client.mdx +1 -1
  43. package/docs/v7/api/dashcam.mdx +497 -0
  44. package/docs/v7/api/doubleClick.mdx +102 -0
  45. package/docs/v7/api/elements.mdx +143 -41
  46. package/docs/v7/api/find.mdx +258 -0
  47. package/docs/v7/api/mouseDown.mdx +161 -0
  48. package/docs/v7/api/mouseUp.mdx +164 -0
  49. package/docs/v7/api/rightClick.mdx +123 -0
  50. package/docs/v7/api/type.mdx +51 -7
  51. package/docs/v7/features/ai-native.mdx +427 -0
  52. package/docs/v7/features/easy-to-write.mdx +351 -0
  53. package/docs/v7/features/enterprise.mdx +540 -0
  54. package/docs/v7/features/fast.mdx +424 -0
  55. package/docs/v7/features/observable.mdx +623 -0
  56. package/docs/v7/features/powerful.mdx +531 -0
  57. package/docs/v7/features/scalable.mdx +417 -0
  58. package/docs/v7/features/stable.mdx +514 -0
  59. package/docs/v7/getting-started/configuration.mdx +380 -0
  60. package/docs/v7/getting-started/generating-tests.mdx +525 -0
  61. package/docs/v7/getting-started/installation.mdx +486 -0
  62. package/docs/v7/getting-started/quickstart.mdx +320 -141
  63. package/docs/v7/getting-started/running-and-debugging.mdx +511 -0
  64. package/docs/v7/getting-started/setting-up-in-ci.mdx +612 -0
  65. package/docs/v7/getting-started/writing-tests.mdx +535 -0
  66. package/docs/v7/overview/what-is-testdriver.mdx +398 -0
  67. package/docs/v7/platforms/linux.mdx +308 -0
  68. package/docs/v7/platforms/macos.mdx +433 -0
  69. package/docs/v7/platforms/windows.mdx +430 -0
  70. package/docs/v7/playwright.mdx +3 -3
  71. package/docs/v7/presets/chrome-extension.mdx +223 -0
  72. package/docs/v7/presets/chrome.mdx +303 -0
  73. package/docs/v7/presets/electron.mdx +453 -0
  74. package/docs/v7/presets/vscode.mdx +417 -0
  75. package/docs/v7/presets/webapp.mdx +396 -0
  76. package/examples/run-tests-with-recording.sh +2 -2
  77. package/interfaces/cli/commands/init.js +358 -0
  78. package/interfaces/vitest-plugin.mjs +393 -103
  79. package/lib/core/Dashcam.js +506 -0
  80. package/lib/core/index.d.ts +150 -0
  81. package/lib/core/index.js +12 -0
  82. package/lib/presets/index.mjs +331 -0
  83. package/lib/vitest/hooks.d.ts +119 -0
  84. package/lib/vitest/hooks.mjs +316 -0
  85. package/lib/vitest/setup.mjs +44 -0
  86. package/package.json +13 -3
  87. package/sdk.d.ts +350 -44
  88. package/sdk.js +818 -105
  89. package/{self-hosted.yml → setup/aws/self-hosted.yml} +1 -1
  90. package/test/manual/test-console-logs.test.mjs +42 -0
  91. package/test/manual/test-init.sh +54 -0
  92. package/test/manual/test-provision-auth.mjs +22 -0
  93. package/test/testdriver/assert.test.mjs +41 -0
  94. package/test/testdriver/auto-cache-key-demo.test.mjs +56 -0
  95. package/test/testdriver/chrome-extension.test.mjs +89 -0
  96. package/{testdriver/acceptance-sdk → test/testdriver}/drag-and-drop.test.mjs +7 -19
  97. package/{testdriver/acceptance-sdk → test/testdriver}/element-not-found.test.mjs +6 -19
  98. package/{testdriver/acceptance-sdk → test/testdriver}/exec-js.test.mjs +6 -18
  99. package/{testdriver/acceptance-sdk → test/testdriver}/exec-output.test.mjs +9 -21
  100. package/{testdriver/acceptance-sdk → test/testdriver}/exec-pwsh.test.mjs +14 -26
  101. package/{testdriver/acceptance-sdk → test/testdriver}/focus-window.test.mjs +8 -20
  102. package/{testdriver/acceptance-sdk → test/testdriver}/formatted-logging.test.mjs +5 -20
  103. package/{testdriver/acceptance-sdk → test/testdriver}/hover-image.test.mjs +10 -19
  104. package/{testdriver/acceptance-sdk → test/testdriver}/hover-text-with-description.test.mjs +7 -19
  105. package/{testdriver/acceptance-sdk → test/testdriver}/hover-text.test.mjs +5 -19
  106. package/{testdriver/acceptance-sdk → test/testdriver}/match-image.test.mjs +7 -19
  107. package/{testdriver/acceptance-sdk → test/testdriver}/press-keys.test.mjs +5 -19
  108. package/{testdriver/acceptance-sdk → test/testdriver}/prompt.test.mjs +7 -19
  109. package/{testdriver/acceptance-sdk → test/testdriver}/scroll-keyboard.test.mjs +6 -20
  110. package/{testdriver/acceptance-sdk → test/testdriver}/scroll-until-image.test.mjs +6 -18
  111. package/test/testdriver/scroll-until-text.test.mjs +28 -0
  112. package/{testdriver/acceptance-sdk → test/testdriver}/scroll.test.mjs +12 -21
  113. package/test/testdriver/setup/lifecycleHelpers.mjs +262 -0
  114. package/{testdriver/acceptance-sdk → test/testdriver}/setup/testHelpers.mjs +25 -20
  115. package/test/testdriver/type.test.mjs +45 -0
  116. package/vitest.config.mjs +11 -56
  117. package/.github/dependabot.yml +0 -11
  118. package/.github/workflows/acceptance-linux.yml +0 -75
  119. package/.github/workflows/acceptance-sdk-tests.yml +0 -133
  120. package/.github/workflows/acceptance-tests.yml +0 -130
  121. package/.github/workflows/lint.yml +0 -27
  122. package/.github/workflows/publish-canary.yml +0 -40
  123. package/.github/workflows/publish-latest.yml +0 -61
  124. package/.github/workflows/test-install.yml +0 -29
  125. package/.vscode/extensions.json +0 -3
  126. package/.vscode/launch.json +0 -22
  127. package/.vscode/mcp.json +0 -9
  128. package/.vscode/settings.json +0 -14
  129. package/CODEOWNERS +0 -3
  130. package/MIGRATION.md +0 -389
  131. package/SDK_README.md +0 -1122
  132. package/_testdriver/acceptance/assert.yaml +0 -7
  133. package/_testdriver/acceptance/dashcam.yaml +0 -9
  134. package/_testdriver/acceptance/drag-and-drop.yaml +0 -49
  135. package/_testdriver/acceptance/embed.yaml +0 -9
  136. package/_testdriver/acceptance/exec-js.yaml +0 -29
  137. package/_testdriver/acceptance/exec-output.yaml +0 -43
  138. package/_testdriver/acceptance/exec-shell.yaml +0 -40
  139. package/_testdriver/acceptance/focus-window.yaml +0 -16
  140. package/_testdriver/acceptance/hover-image.yaml +0 -18
  141. package/_testdriver/acceptance/hover-text-with-description.yaml +0 -29
  142. package/_testdriver/acceptance/hover-text.yaml +0 -14
  143. package/_testdriver/acceptance/if-else.yaml +0 -31
  144. package/_testdriver/acceptance/match-image.yaml +0 -15
  145. package/_testdriver/acceptance/press-keys.yaml +0 -35
  146. package/_testdriver/acceptance/prompt.yaml +0 -11
  147. package/_testdriver/acceptance/remember.yaml +0 -27
  148. package/_testdriver/acceptance/screenshots/cart.png +0 -0
  149. package/_testdriver/acceptance/scroll-keyboard.yaml +0 -34
  150. package/_testdriver/acceptance/scroll-until-image.yaml +0 -26
  151. package/_testdriver/acceptance/scroll-until-text.yaml +0 -20
  152. package/_testdriver/acceptance/scroll.yaml +0 -33
  153. package/_testdriver/acceptance/snippets/login.yaml +0 -29
  154. package/_testdriver/acceptance/snippets/match-cart.yaml +0 -8
  155. package/_testdriver/acceptance/type.yaml +0 -29
  156. package/_testdriver/behavior/failure.yaml +0 -7
  157. package/_testdriver/behavior/hover-text.yaml +0 -13
  158. package/_testdriver/behavior/lifecycle/postrun.yaml +0 -10
  159. package/_testdriver/behavior/lifecycle/prerun.yaml +0 -8
  160. package/_testdriver/behavior/lifecycle/provision.yaml +0 -8
  161. package/_testdriver/behavior/secrets.yaml +0 -7
  162. package/_testdriver/edge-cases/dashcam-chrome.yaml +0 -8
  163. package/_testdriver/edge-cases/exec-pwsh-multiline.yaml +0 -10
  164. package/_testdriver/edge-cases/js-exception.yaml +0 -8
  165. package/_testdriver/edge-cases/js-promise.yaml +0 -19
  166. package/_testdriver/edge-cases/lifecycle/postrun.yaml +0 -10
  167. package/_testdriver/edge-cases/prompt-in-middle.yaml +0 -23
  168. package/_testdriver/edge-cases/prompt-nested.yaml +0 -7
  169. package/_testdriver/edge-cases/success-test.yaml +0 -9
  170. package/_testdriver/examples/android/example.yaml +0 -12
  171. package/_testdriver/examples/android/lifecycle/postrun.yaml +0 -11
  172. package/_testdriver/examples/android/lifecycle/provision.yaml +0 -47
  173. package/_testdriver/examples/android/readme.md +0 -7
  174. package/_testdriver/examples/chrome-extension/lifecycle/provision.yaml +0 -74
  175. package/_testdriver/examples/desktop/lifecycle/prerun.yaml +0 -0
  176. package/_testdriver/examples/desktop/lifecycle/provision.yaml +0 -64
  177. package/_testdriver/examples/vscode-extension/lifecycle/provision.yaml +0 -73
  178. package/_testdriver/examples/web/lifecycle/postrun.yaml +0 -7
  179. package/_testdriver/examples/web/lifecycle/prerun.yaml +0 -22
  180. package/_testdriver/lifecycle/postrun.yaml +0 -8
  181. package/_testdriver/lifecycle/prerun.yaml +0 -15
  182. package/_testdriver/lifecycle/provision.yaml +0 -25
  183. package/debug-screenshot-1763401388589.png +0 -0
  184. package/mcp-server/AI_GUIDELINES.md +0 -57
  185. package/scripts/view-test-results.mjs +0 -96
  186. package/styles/.vale-config/2-MDX.ini +0 -5
  187. package/styles/Microsoft/AMPM.yml +0 -9
  188. package/styles/Microsoft/Accessibility.yml +0 -30
  189. package/styles/Microsoft/Acronyms.yml +0 -64
  190. package/styles/Microsoft/Adverbs.yml +0 -272
  191. package/styles/Microsoft/Auto.yml +0 -11
  192. package/styles/Microsoft/Avoid.yml +0 -14
  193. package/styles/Microsoft/Contractions.yml +0 -50
  194. package/styles/Microsoft/Dashes.yml +0 -13
  195. package/styles/Microsoft/DateFormat.yml +0 -8
  196. package/styles/Microsoft/DateNumbers.yml +0 -40
  197. package/styles/Microsoft/DateOrder.yml +0 -8
  198. package/styles/Microsoft/Ellipses.yml +0 -9
  199. package/styles/Microsoft/FirstPerson.yml +0 -16
  200. package/styles/Microsoft/Foreign.yml +0 -13
  201. package/styles/Microsoft/Gender.yml +0 -8
  202. package/styles/Microsoft/GenderBias.yml +0 -42
  203. package/styles/Microsoft/GeneralURL.yml +0 -11
  204. package/styles/Microsoft/HeadingAcronyms.yml +0 -7
  205. package/styles/Microsoft/HeadingColons.yml +0 -8
  206. package/styles/Microsoft/HeadingPunctuation.yml +0 -13
  207. package/styles/Microsoft/Headings.yml +0 -28
  208. package/styles/Microsoft/Hyphens.yml +0 -14
  209. package/styles/Microsoft/Negative.yml +0 -13
  210. package/styles/Microsoft/Ordinal.yml +0 -13
  211. package/styles/Microsoft/OxfordComma.yml +0 -8
  212. package/styles/Microsoft/Passive.yml +0 -183
  213. package/styles/Microsoft/Percentages.yml +0 -7
  214. package/styles/Microsoft/Plurals.yml +0 -7
  215. package/styles/Microsoft/Quotes.yml +0 -7
  216. package/styles/Microsoft/RangeTime.yml +0 -13
  217. package/styles/Microsoft/Semicolon.yml +0 -8
  218. package/styles/Microsoft/SentenceLength.yml +0 -6
  219. package/styles/Microsoft/Spacing.yml +0 -8
  220. package/styles/Microsoft/Suspended.yml +0 -7
  221. package/styles/Microsoft/Terms.yml +0 -42
  222. package/styles/Microsoft/URLFormat.yml +0 -9
  223. package/styles/Microsoft/Units.yml +0 -16
  224. package/styles/Microsoft/Vocab.yml +0 -25
  225. package/styles/Microsoft/We.yml +0 -11
  226. package/styles/Microsoft/Wordiness.yml +0 -127
  227. package/styles/Microsoft/meta.json +0 -4
  228. package/styles/alex/Ablist.yml +0 -274
  229. package/styles/alex/Condescending.yml +0 -16
  230. package/styles/alex/Gendered.yml +0 -110
  231. package/styles/alex/LGBTQ.yml +0 -55
  232. package/styles/alex/OCD.yml +0 -10
  233. package/styles/alex/Press.yml +0 -12
  234. package/styles/alex/ProfanityLikely.yml +0 -1289
  235. package/styles/alex/ProfanityMaybe.yml +0 -282
  236. package/styles/alex/ProfanityUnlikely.yml +0 -251
  237. package/styles/alex/README.md +0 -27
  238. package/styles/alex/Race.yml +0 -85
  239. package/styles/alex/Suicide.yml +0 -26
  240. package/styles/alex/meta.json +0 -4
  241. package/styles/config/vocabularies/Docs/accept.txt +0 -47
  242. package/styles/config/vocabularies/Docs/reject.txt +0 -4
  243. package/styles/proselint/Airlinese.yml +0 -8
  244. package/styles/proselint/AnimalLabels.yml +0 -48
  245. package/styles/proselint/Annotations.yml +0 -9
  246. package/styles/proselint/Apologizing.yml +0 -8
  247. package/styles/proselint/Archaisms.yml +0 -52
  248. package/styles/proselint/But.yml +0 -8
  249. package/styles/proselint/Cliches.yml +0 -782
  250. package/styles/proselint/CorporateSpeak.yml +0 -30
  251. package/styles/proselint/Currency.yml +0 -5
  252. package/styles/proselint/Cursing.yml +0 -15
  253. package/styles/proselint/DateCase.yml +0 -7
  254. package/styles/proselint/DateMidnight.yml +0 -7
  255. package/styles/proselint/DateRedundancy.yml +0 -10
  256. package/styles/proselint/DateSpacing.yml +0 -7
  257. package/styles/proselint/DenizenLabels.yml +0 -52
  258. package/styles/proselint/Diacritical.yml +0 -95
  259. package/styles/proselint/GenderBias.yml +0 -45
  260. package/styles/proselint/GroupTerms.yml +0 -39
  261. package/styles/proselint/Hedging.yml +0 -8
  262. package/styles/proselint/Hyperbole.yml +0 -6
  263. package/styles/proselint/Jargon.yml +0 -11
  264. package/styles/proselint/LGBTOffensive.yml +0 -13
  265. package/styles/proselint/LGBTTerms.yml +0 -15
  266. package/styles/proselint/Malapropisms.yml +0 -8
  267. package/styles/proselint/Needless.yml +0 -358
  268. package/styles/proselint/Nonwords.yml +0 -38
  269. package/styles/proselint/Oxymorons.yml +0 -22
  270. package/styles/proselint/P-Value.yml +0 -6
  271. package/styles/proselint/RASSyndrome.yml +0 -30
  272. package/styles/proselint/README.md +0 -12
  273. package/styles/proselint/Skunked.yml +0 -13
  274. package/styles/proselint/Spelling.yml +0 -17
  275. package/styles/proselint/Typography.yml +0 -11
  276. package/styles/proselint/Uncomparables.yml +0 -50
  277. package/styles/proselint/Very.yml +0 -6
  278. package/styles/proselint/meta.json +0 -15
  279. package/styles/write-good/Cliches.yml +0 -702
  280. package/styles/write-good/E-Prime.yml +0 -32
  281. package/styles/write-good/Illusions.yml +0 -11
  282. package/styles/write-good/Passive.yml +0 -183
  283. package/styles/write-good/README.md +0 -27
  284. package/styles/write-good/So.yml +0 -5
  285. package/styles/write-good/ThereIs.yml +0 -6
  286. package/styles/write-good/TooWordy.yml +0 -221
  287. package/styles/write-good/Weasel.yml +0 -29
  288. package/styles/write-good/meta.json +0 -4
  289. package/test/mcp-example-test.yaml +0 -27
  290. package/test/test_parser.js +0 -47
  291. package/testdriver/acceptance-sdk/QUICK_REFERENCE.md +0 -61
  292. package/testdriver/acceptance-sdk/README.md +0 -128
  293. package/testdriver/acceptance-sdk/TEST_REPORTING.md +0 -245
  294. package/testdriver/acceptance-sdk/assert.test.mjs +0 -44
  295. package/testdriver/acceptance-sdk/scroll-until-text.test.mjs +0 -42
  296. package/testdriver/acceptance-sdk/setup/lifecycleHelpers.mjs +0 -239
  297. package/testdriver/acceptance-sdk/type-checking-demo.js +0 -49
  298. package/testdriver/acceptance-sdk/type.test.mjs +0 -84
  299. package/vale.ini +0 -18
  300. package/vitest.config.example.js +0 -19
  301. package/vitest.config.mjs.bak +0 -44
  302. /package/docs/{ARCHITECTURE.md → v7/_drafts/architecture.mdx} +0 -0
  303. /package/docs/{AWESOME_LOGS_QUICK_REF.md → v7/_drafts/awesome-logs-quick-ref.mdx} +0 -0
  304. /package/{CONTRIBUTING.md → docs/v7/_drafts/contributing.mdx} +0 -0
  305. /package/docs/v7/{guides → _drafts}/migration.mdx +0 -0
  306. /package/{PLUGIN_MIGRATION.md → docs/v7/_drafts/plugin-migration.mdx} +0 -0
  307. /package/{PROMPT_CACHE.md → docs/v7/_drafts/prompt-cache.mdx} +0 -0
  308. /package/docs/{SDK_AWESOME_LOGS.md → v7/_drafts/sdk-awesome-logs.mdx} +0 -0
  309. /package/docs/{sdk-browser-rendering.md → v7/_drafts/sdk-browser-rendering.mdx} +0 -0
  310. /package/{SDK_LOGGING.md → docs/v7/_drafts/sdk-logging.mdx} +0 -0
  311. /package/{SDK_MIGRATION.md → docs/v7/_drafts/sdk-migration.mdx} +0 -0
  312. /package/docs/{TEST_RECORDING.md → v7/_drafts/test-recording.mdx} +0 -0
  313. /package/docs/v7/{README.md → overview/readme.mdx} +0 -0
  314. /package/{debug-locate-response.js → test/manual/debug-locate-response.js} +0 -0
  315. /package/{test-find-api.js → test/manual/test-find-api.js} +0 -0
  316. /package/{test-prompt-cache.js → test/manual/test-prompt-cache.js} +0 -0
  317. /package/{test-sandbox-render.js → test/manual/test-sandbox-render.js} +0 -0
  318. /package/{test-sdk-methods.js → test/manual/test-sdk-methods.js} +0 -0
  319. /package/{test-sdk-refactor.js → test/manual/test-sdk-refactor.js} +0 -0
  320. /package/{test-stack-trace.mjs → test/manual/test-stack-trace.mjs} +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}/setup/globalTeardown.mjs +0 -0
  324. /package/{testdriver/acceptance-sdk → test/testdriver}/setup/vitestSetup.mjs +0 -0
@@ -0,0 +1,453 @@
1
+ ---
2
+ title: "Desktop Apps"
3
+ sidebarTitle: "Desktop Apps"
4
+ description: "Automatically launch and test Electron applications"
5
+ icon: "atom"
6
+ ---
7
+
8
+ ## Overview
9
+
10
+ The `electron()` preset automatically sets up an Electron application with TestDriver and Dashcam recording. Perfect for testing desktop apps built with Electron.
11
+
12
+ <Note>
13
+ **Recommended Pattern (v7.1+):** Use `TestDriver()` hook + `provision.electron()` for more flexibility:
14
+
15
+ ```javascript
16
+ import { TestDriver } from 'testdriverai/vitest/hooks';
17
+
18
+ test('my test', async (context) => {
19
+ const testdriver = TestDriver(context);
20
+ await testdriver.provision.electron({
21
+ appPath: './dist/my-app'
22
+ });
23
+ // ...
24
+ });
25
+ ```
26
+
27
+ The `electron()` preset is still supported but the direct API provides better control and clearer lifecycle management.
28
+ </Note>
29
+
30
+ ## Quick Start
31
+
32
+ ```javascript
33
+ import { test } from 'vitest';
34
+ import { electron } from 'testdriverai/presets';
35
+
36
+ test('electron app test', async (context) => {
37
+ const { app } = await electron(context, {
38
+ appPath: './dist/my-app'
39
+ });
40
+
41
+ await app.find('main window').click();
42
+ await app.find('File menu').click();
43
+ await app.find('New Document').click();
44
+ });
45
+ ```
46
+
47
+ ## Signature
48
+
49
+ ```typescript
50
+ electron(context, options): Promise<ElectronResult>
51
+ ```
52
+
53
+ ### Parameters
54
+
55
+ <ParamField path="context" type="object" required>
56
+ Vitest test context - automatically passed to your test function
57
+ </ParamField>
58
+
59
+ <ParamField path="options" type="object">
60
+ Configuration options for Electron
61
+
62
+ <Expandable title="properties">
63
+ <ParamField path="appPath" type="string" required>
64
+ Path to your Electron application executable or main file
65
+ </ParamField>
66
+
67
+ <ParamField path="args" type="string[]" default={[]}>
68
+ Additional command-line arguments to pass to Electron
69
+ </ParamField>
70
+
71
+ <ParamField path="dashcam" type="boolean" default={true}>
72
+ Enable Dashcam test recording
73
+ </ParamField>
74
+
75
+ <ParamField path="os" type="'linux' | 'mac' | 'windows'" default="linux">
76
+ Target operating system for the test
77
+ </ParamField>
78
+ </Expandable>
79
+ </ParamField>
80
+
81
+ ### Returns
82
+
83
+ <ResponseField name="testdriver" type="TestDriver" required>
84
+ TestDriver instance ready to use
85
+ </ResponseField>
86
+
87
+ <ResponseField name="app" type="TestDriver" required>
88
+ Alias for testdriver (semantic clarity for Electron apps)
89
+ </ResponseField>
90
+
91
+ <ResponseField name="dashcam" type="Dashcam">
92
+ Dashcam instance for test recording (if enabled)
93
+ </ResponseField>
94
+
95
+ ## Examples
96
+
97
+ ### Basic Electron App
98
+
99
+ ```javascript
100
+ import { test } from 'vitest';
101
+ import { electron } from 'testdriverai/presets';
102
+
103
+ test('opens main window', async (context) => {
104
+ const { app } = await electron(context, {
105
+ appPath: './dist/my-electron-app'
106
+ });
107
+
108
+ await app.assert('Main window is visible');
109
+ await app.find('Welcome message').click();
110
+ });
111
+ ```
112
+
113
+ ### With Command-Line Arguments
114
+
115
+ ```javascript
116
+ import { test } from 'vitest';
117
+ import { electron } from 'testdriverai/presets';
118
+
119
+ test('app with debug mode', async (context) => {
120
+ const { app } = await electron(context, {
121
+ appPath: './dist/app',
122
+ args: [
123
+ '--enable-logging',
124
+ '--debug',
125
+ '--user-data-dir=/tmp/test-data'
126
+ ]
127
+ });
128
+
129
+ await app.find('Debug panel').click();
130
+ await app.assert('Debug information is visible');
131
+ });
132
+ ```
133
+
134
+ ### Menu Navigation
135
+
136
+ ```javascript
137
+ import { test } from 'vitest';
138
+ import { electron } from 'testdriverai/presets';
139
+
140
+ test('file menu operations', async (context) => {
141
+ const { app } = await electron(context, {
142
+ appPath: './dist/editor-app'
143
+ });
144
+
145
+ // Open File menu
146
+ await app.find('File').click();
147
+ await app.find('New File').click();
148
+
149
+ // Verify new file created
150
+ await app.assert('Untitled document is open');
151
+
152
+ // Save file
153
+ await app.find('File').click();
154
+ await app.find('Save As').click();
155
+ await app.type('test-document.txt');
156
+ await app.pressKeys(['enter']);
157
+
158
+ await app.assert('File saved successfully');
159
+ });
160
+ ```
161
+
162
+ ### Testing on Different Platforms
163
+
164
+ ```javascript
165
+ import { test } from 'vitest';
166
+ import { electron } from 'testdriverai/presets';
167
+
168
+ test('windows electron app', async (context) => {
169
+ const { app } = await electron(context, {
170
+ appPath: 'C:\\Program Files\\MyApp\\MyApp.exe',
171
+ os: 'windows'
172
+ });
173
+
174
+ await app.find('Start button').click();
175
+ });
176
+
177
+ test('mac electron app', async (context) => {
178
+ const { app } = await electron(context, {
179
+ appPath: '/Applications/MyApp.app/Contents/MacOS/MyApp',
180
+ os: 'mac'
181
+ });
182
+
183
+ await app.find('Start button').click();
184
+ });
185
+ ```
186
+
187
+ ### Preferences and Settings
188
+
189
+ ```javascript
190
+ import { test } from 'vitest';
191
+ import { electron } from 'testdriverai/presets';
192
+
193
+ test('configure app settings', async (context) => {
194
+ const { app } = await electron(context, {
195
+ appPath: './dist/my-app'
196
+ });
197
+
198
+ // Open preferences
199
+ await app.find('Settings').click();
200
+
201
+ // Change theme
202
+ await app.find('Appearance').click();
203
+ await app.find('Dark mode toggle').click();
204
+
205
+ // Verify change
206
+ await app.assert('Dark mode is enabled');
207
+
208
+ // Save settings
209
+ await app.find('Save button').click();
210
+
211
+ await app.assert('Settings saved');
212
+ });
213
+ ```
214
+
215
+ ### Window Management
216
+
217
+ ```javascript
218
+ import { test } from 'vitest';
219
+ import { electron } from 'testdriverai/presets';
220
+
221
+ test('multiple windows', async (context) => {
222
+ const { app } = await electron(context, {
223
+ appPath: './dist/multi-window-app'
224
+ });
225
+
226
+ // Open new window
227
+ await app.find('File').click();
228
+ await app.find('New Window').click();
229
+
230
+ // Switch between windows
231
+ await app.find('second window').click();
232
+ await app.assert('Second window is focused');
233
+
234
+ // Close window
235
+ await app.find('Close button').click();
236
+
237
+ await app.assert('Window closed');
238
+ });
239
+ ```
240
+
241
+ ### Form Interaction
242
+
243
+ ```javascript
244
+ import { test } from 'vitest';
245
+ import { electron } from 'testdriverai/presets';
246
+
247
+ test('form submission', async (context) => {
248
+ const { app, dashcam } = await electron(context, {
249
+ appPath: './dist/form-app'
250
+ });
251
+
252
+ // Fill form
253
+ await app.find('Name input').type('John Doe');
254
+ await app.find('Email input').type('john@example.com');
255
+ await app.find('Phone input').type('555-1234');
256
+
257
+ // Select dropdown
258
+ await app.find('Country dropdown').click();
259
+ await app.find('United States').click();
260
+
261
+ // Check checkbox
262
+ await app.find('Terms and conditions').click();
263
+
264
+ // Submit
265
+ await app.find('Submit button').click();
266
+
267
+ await app.assert('Form submitted successfully');
268
+
269
+ // Dashcam captures entire interaction
270
+ });
271
+ ```
272
+
273
+ ## What It Does
274
+
275
+ When you call `electron()`, it automatically:
276
+
277
+ 1. **Initializes TestDriver** - Creates and connects to sandbox
278
+ 2. **Sets up Dashcam** - Authenticates and starts recording (if enabled)
279
+ 3. **Launches Electron** - Starts your app with specified arguments
280
+ 4. **Waits for Ready** - Ensures app is focused and windows are loaded
281
+ 5. **Returns Instances** - Provides ready-to-use testdriver, app alias, and dashcam
282
+
283
+ At test end:
284
+ - Dashcam automatically stops and saves replay URL
285
+ - TestDriver automatically disconnects
286
+ - All cleanup is handled for you
287
+
288
+ ## Common Patterns
289
+
290
+ ### IPC Communication Testing
291
+
292
+ ```javascript
293
+ test('ipc events', async (context) => {
294
+ const { app } = await electron(context, {
295
+ appPath: './dist/ipc-app'
296
+ });
297
+
298
+ // Trigger IPC event from renderer
299
+ await app.find('Send Message button').click();
300
+
301
+ // Verify main process response
302
+ await app.assert('Response received from main process');
303
+ });
304
+ ```
305
+
306
+ ### Notification Testing
307
+
308
+ ```javascript
309
+ test('system notifications', async (context) => {
310
+ const { app } = await electron(context, {
311
+ appPath: './dist/notification-app'
312
+ });
313
+
314
+ await app.find('Show Notification').click();
315
+ await app.assert('System notification appears');
316
+ });
317
+ ```
318
+
319
+ ### Tray Icon Interaction
320
+
321
+ ```javascript
322
+ test('system tray', async (context) => {
323
+ const { app } = await electron(context, {
324
+ appPath: './dist/tray-app'
325
+ });
326
+
327
+ // Click tray icon
328
+ await app.find('app tray icon').click();
329
+
330
+ // Interact with tray menu
331
+ await app.find('Show Window').click();
332
+
333
+ await app.assert('Main window appears');
334
+ });
335
+ ```
336
+
337
+ ### Auto-Update Flow
338
+
339
+ ```javascript
340
+ test('app update', async (context) => {
341
+ const { app } = await electron(context, {
342
+ appPath: './dist/updatable-app',
343
+ args: ['--check-updates']
344
+ });
345
+
346
+ await app.find('Check for Updates').click();
347
+ await app.assert('Checking for updates message');
348
+
349
+ // Assuming update is available
350
+ await app.find('Download Update').click();
351
+ await app.assert('Update downloaded');
352
+ });
353
+ ```
354
+
355
+ ## Development Paths
356
+
357
+ ### Common Development Paths
358
+
359
+ ```javascript
360
+ // Electron Forge
361
+ appPath: './out/my-app-linux-x64/my-app'
362
+
363
+ // Electron Builder
364
+ appPath: './dist/linux-unpacked/my-app'
365
+
366
+ // Direct execution
367
+ appPath: './node_modules/.bin/electron'
368
+ args: ['./main.js']
369
+
370
+ // Packaged app (Windows)
371
+ appPath: 'C:\\Program Files\\MyApp\\MyApp.exe'
372
+
373
+ // Packaged app (macOS)
374
+ appPath: '/Applications/MyApp.app/Contents/MacOS/MyApp'
375
+
376
+ // Packaged app (Linux)
377
+ appPath: '/opt/MyApp/my-app'
378
+ ```
379
+
380
+ ## Using with provision()
381
+
382
+ The `electron()` preset can also be called via the unified `provision()` function:
383
+
384
+ ```javascript
385
+ import { provision } from 'testdriverai/presets';
386
+
387
+ test('using provision', async (context) => {
388
+ const { app } = await provision('electron', {
389
+ appPath: './dist/my-app'
390
+ }, context);
391
+
392
+ // Same functionality as electron() directly
393
+ });
394
+ ```
395
+
396
+ ## Error Handling
397
+
398
+ ```javascript
399
+ test('handles missing app path', async (context) => {
400
+ try {
401
+ const { app } = await electron(context, {
402
+ appPath: '/nonexistent/path'
403
+ });
404
+ } catch (error) {
405
+ // Cleanup still happens automatically
406
+ expect(error.message).toContain('appPath');
407
+ }
408
+ });
409
+
410
+ test('handles app crashes', async (context) => {
411
+ const { app } = await electron(context, {
412
+ appPath: './dist/my-app'
413
+ });
414
+
415
+ try {
416
+ // Trigger something that might crash
417
+ await app.find('Crash button').click();
418
+ } catch (error) {
419
+ // Dashcam still saves replay of crash
420
+ console.error('App crashed:', error);
421
+ }
422
+ });
423
+ ```
424
+
425
+ ## Debugging Tips
426
+
427
+ 1. **Enable Electron DevTools** - Pass `--enable-logging` in args
428
+ 2. **Use Dashcam** - Review test recordings to see what happened
429
+ 3. **Custom User Data** - Use `--user-data-dir` for isolated testing
430
+ 4. **Remote Debugging** - Use `--remote-debugging-port=9222`
431
+
432
+ ```javascript
433
+ test('with debugging enabled', async (context) => {
434
+ const { app } = await electron(context, {
435
+ appPath: './dist/my-app',
436
+ args: [
437
+ '--enable-logging',
438
+ '--remote-debugging-port=9222',
439
+ '--user-data-dir=/tmp/test-profile'
440
+ ]
441
+ });
442
+
443
+ // Test with full debugging capabilities
444
+ });
445
+ ```
446
+
447
+ ## See Also
448
+
449
+ - [Provision API](/v7/progressive-apis/PROVISION) - Overview of all presets
450
+ - [Chrome Preset](/v7/presets/chrome) - Testing web applications
451
+ - [VS Code Preset](/v7/presets/vscode) - Testing VS Code extensions
452
+ - [Vitest Integration](/v7/guides/vitest) - Complete Vitest setup guide
453
+ - [Hooks API](/v7/progressive-apis/HOOKS) - Manual lifecycle control