testdriverai 6.2.2 → 7.0.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 (264) hide show
  1. package/.github/workflows/acceptance-linux.yml +75 -0
  2. package/.github/workflows/acceptance-sdk-tests.yml +133 -0
  3. package/.vscode/settings.json +5 -1
  4. package/MIGRATION.md +389 -0
  5. package/PLUGIN_MIGRATION.md +222 -0
  6. package/PROMPT_CACHE.md +200 -0
  7. package/SDK_LOGGING.md +222 -0
  8. package/SDK_MIGRATION.md +474 -0
  9. package/SDK_README.md +1122 -0
  10. package/{testdriver → _testdriver}/acceptance/drag-and-drop.yaml +2 -2
  11. package/{testdriver → _testdriver}/acceptance/snippets/login.yaml +1 -1
  12. package/_testdriver/examples/desktop/lifecycle/prerun.yaml +0 -0
  13. package/{testdriver → _testdriver}/examples/web/lifecycle/prerun.yaml +6 -1
  14. package/{testdriver → _testdriver}/lifecycle/postrun.yaml +3 -2
  15. package/_testdriver/lifecycle/prerun.yaml +15 -0
  16. package/{testdriver → _testdriver}/lifecycle/provision.yaml +7 -2
  17. package/agent/index.js +258 -68
  18. package/agent/interface.js +15 -0
  19. package/agent/lib/cache.js +142 -0
  20. package/agent/lib/commander.js +1 -39
  21. package/agent/lib/commands.js +143 -188
  22. package/agent/lib/redraw.js +6 -3
  23. package/agent/lib/sandbox.js +19 -5
  24. package/agent/lib/sdk.js +1 -0
  25. package/agent/lib/system.js +0 -3
  26. package/agent/lib/validation.js +1 -7
  27. package/debug-locate-response.js +82 -0
  28. package/debug-screenshot-1763401388589.png +0 -0
  29. package/debugger/index.html +15 -4
  30. package/docs/ARCHITECTURE.md +424 -0
  31. package/docs/AWESOME_LOGS_QUICK_REF.md +100 -0
  32. package/docs/QUICK_START_TEST_RECORDING.md +215 -0
  33. package/docs/SDK_AWESOME_LOGS.md +468 -0
  34. package/docs/TEST_RECORDING.md +388 -0
  35. package/docs/docs.json +232 -152
  36. package/docs/sdk-browser-rendering.md +167 -0
  37. package/docs/v6/getting-started/self-hosting.mdx +407 -0
  38. package/docs/{guide → v6/guide}/dashcam.mdx +1 -1
  39. package/docs/{guide → v6/guide}/environment-variables.mdx +4 -5
  40. package/docs/{guide → v6/guide}/lifecycle.mdx +1 -1
  41. package/docs/v6/overview/comparison.mdx +101 -0
  42. package/docs/v7/README.md +135 -0
  43. package/docs/v7/api/ai.mdx +205 -0
  44. package/docs/v7/api/assert.mdx +285 -0
  45. package/docs/v7/api/assertions.mdx +403 -0
  46. package/docs/v7/api/click.mdx +287 -0
  47. package/docs/v7/api/client.mdx +322 -0
  48. package/docs/v7/api/elements.mdx +479 -0
  49. package/docs/v7/api/exec.mdx +346 -0
  50. package/docs/v7/api/find.mdx +316 -0
  51. package/docs/v7/api/focusApplication.mdx +294 -0
  52. package/docs/v7/api/hover.mdx +279 -0
  53. package/docs/v7/api/pressKeys.mdx +349 -0
  54. package/docs/v7/api/sandbox.mdx +404 -0
  55. package/docs/v7/api/scroll.mdx +300 -0
  56. package/docs/v7/api/type.mdx +314 -0
  57. package/docs/v7/commands/assert.mdx +45 -0
  58. package/docs/v7/commands/exec.mdx +282 -0
  59. package/docs/v7/commands/focus-application.mdx +44 -0
  60. package/docs/v7/commands/hover-image.mdx +69 -0
  61. package/docs/v7/commands/hover-text.mdx +47 -0
  62. package/docs/v7/commands/if.mdx +53 -0
  63. package/docs/v7/commands/match-image.mdx +67 -0
  64. package/docs/v7/commands/press-keys.mdx +87 -0
  65. package/docs/v7/commands/remember.mdx +49 -0
  66. package/docs/v7/commands/run.mdx +44 -0
  67. package/docs/v7/commands/scroll-until-image.mdx +66 -0
  68. package/docs/v7/commands/scroll-until-text.mdx +60 -0
  69. package/docs/v7/commands/scroll.mdx +69 -0
  70. package/docs/v7/commands/type.mdx +45 -0
  71. package/docs/v7/commands/wait-for-image.mdx +54 -0
  72. package/docs/v7/commands/wait-for-text.mdx +48 -0
  73. package/docs/v7/commands/wait.mdx +45 -0
  74. package/docs/v7/getting-started/quickstart.mdx +199 -0
  75. package/docs/v7/guides/migration.mdx +562 -0
  76. package/docs/{getting-started → v7/guides}/self-hosting.mdx +11 -12
  77. package/docs/v7/playwright.mdx +342 -0
  78. package/eslint.config.js +19 -1
  79. package/examples/run-tests-with-recording.sh +70 -0
  80. package/examples/screenshot-example.js +63 -0
  81. package/examples/sdk-awesome-logs-demo.js +177 -0
  82. package/examples/sdk-cache-thresholds.js +96 -0
  83. package/examples/sdk-element-properties.js +155 -0
  84. package/examples/sdk-simple-example.js +65 -0
  85. package/examples/test-recording-example.test.js +166 -0
  86. package/interfaces/cli/lib/base.js +10 -4
  87. package/interfaces/logger.js +2 -1
  88. package/interfaces/shared-test-state.mjs +69 -0
  89. package/interfaces/vitest-plugin.mjs +744 -0
  90. package/mcp-server/AI_GUIDELINES.md +57 -0
  91. package/package.json +18 -5
  92. package/schema.json +8 -29
  93. package/scripts/view-test-results.mjs +96 -0
  94. package/sdk-log-formatter.js +714 -0
  95. package/sdk.d.ts +735 -0
  96. package/sdk.js +1906 -0
  97. package/{.github/workflows/self-hosted.yml → self-hosted.yml} +13 -4
  98. package/setup/aws/cloudformation.yaml +9 -2
  99. package/test/mcp-example-test.yaml +27 -0
  100. package/test-find-api.js +73 -0
  101. package/test-prompt-cache.js +96 -0
  102. package/test-sandbox-render.js +28 -0
  103. package/test-sdk-methods.js +15 -0
  104. package/test-sdk-refactor.js +53 -0
  105. package/test-stack-trace.mjs +57 -0
  106. package/testdriver/acceptance-sdk/QUICK_REFERENCE.md +61 -0
  107. package/testdriver/acceptance-sdk/README.md +128 -0
  108. package/testdriver/acceptance-sdk/TEST_REPORTING.md +245 -0
  109. package/testdriver/acceptance-sdk/assert.test.mjs +44 -0
  110. package/testdriver/acceptance-sdk/drag-and-drop.test.mjs +70 -0
  111. package/testdriver/acceptance-sdk/element-not-found.test.mjs +38 -0
  112. package/testdriver/acceptance-sdk/exec-js.test.mjs +55 -0
  113. package/testdriver/acceptance-sdk/exec-output.test.mjs +71 -0
  114. package/testdriver/acceptance-sdk/exec-pwsh.test.mjs +69 -0
  115. package/testdriver/acceptance-sdk/focus-window.test.mjs +48 -0
  116. package/testdriver/acceptance-sdk/formatted-logging.test.mjs +41 -0
  117. package/testdriver/acceptance-sdk/hover-image.test.mjs +43 -0
  118. package/testdriver/acceptance-sdk/hover-text-with-description.test.mjs +50 -0
  119. package/testdriver/acceptance-sdk/hover-text.test.mjs +41 -0
  120. package/testdriver/acceptance-sdk/match-image.test.mjs +48 -0
  121. package/testdriver/acceptance-sdk/press-keys.test.mjs +64 -0
  122. package/testdriver/acceptance-sdk/prompt.test.mjs +45 -0
  123. package/testdriver/acceptance-sdk/scroll-keyboard.test.mjs +52 -0
  124. package/testdriver/acceptance-sdk/scroll-until-image.test.mjs +51 -0
  125. package/testdriver/acceptance-sdk/scroll-until-text.test.mjs +42 -0
  126. package/testdriver/acceptance-sdk/scroll.test.mjs +50 -0
  127. package/testdriver/acceptance-sdk/setup/globalTeardown.mjs +11 -0
  128. package/testdriver/acceptance-sdk/setup/lifecycleHelpers.mjs +239 -0
  129. package/testdriver/acceptance-sdk/setup/testHelpers.mjs +648 -0
  130. package/testdriver/acceptance-sdk/setup/vitestSetup.mjs +40 -0
  131. package/testdriver/acceptance-sdk/type-checking-demo.js +49 -0
  132. package/testdriver/acceptance-sdk/type.test.mjs +84 -0
  133. package/verify-element-api.js +89 -0
  134. package/verify-types.js +0 -0
  135. package/vitest.config.example.js +19 -0
  136. package/vitest.config.mjs +65 -0
  137. package/vitest.config.mjs.bak +44 -0
  138. package/.github/workflows/acceptance-v6.yml +0 -169
  139. package/docs/overview/comparison.mdx +0 -82
  140. package/testdriver/lifecycle/prerun.yaml +0 -17
  141. /package/{testdriver/examples/desktop/lifecycle/prerun.yaml → .env.example} +0 -0
  142. /package/{testdriver → _testdriver}/acceptance/assert.yaml +0 -0
  143. /package/{testdriver → _testdriver}/acceptance/dashcam.yaml +0 -0
  144. /package/{testdriver → _testdriver}/acceptance/embed.yaml +0 -0
  145. /package/{testdriver → _testdriver}/acceptance/exec-js.yaml +0 -0
  146. /package/{testdriver → _testdriver}/acceptance/exec-output.yaml +0 -0
  147. /package/{testdriver → _testdriver}/acceptance/exec-shell.yaml +0 -0
  148. /package/{testdriver → _testdriver}/acceptance/focus-window.yaml +0 -0
  149. /package/{testdriver → _testdriver}/acceptance/hover-image.yaml +0 -0
  150. /package/{testdriver → _testdriver}/acceptance/hover-text-with-description.yaml +0 -0
  151. /package/{testdriver → _testdriver}/acceptance/hover-text.yaml +0 -0
  152. /package/{testdriver → _testdriver}/acceptance/if-else.yaml +0 -0
  153. /package/{testdriver → _testdriver}/acceptance/match-image.yaml +0 -0
  154. /package/{testdriver → _testdriver}/acceptance/press-keys.yaml +0 -0
  155. /package/{testdriver → _testdriver}/acceptance/prompt.yaml +0 -0
  156. /package/{testdriver → _testdriver}/acceptance/remember.yaml +0 -0
  157. /package/{testdriver → _testdriver}/acceptance/screenshots/cart.png +0 -0
  158. /package/{testdriver → _testdriver}/acceptance/scroll-keyboard.yaml +0 -0
  159. /package/{testdriver → _testdriver}/acceptance/scroll-until-image.yaml +0 -0
  160. /package/{testdriver → _testdriver}/acceptance/scroll-until-text.yaml +0 -0
  161. /package/{testdriver → _testdriver}/acceptance/scroll.yaml +0 -0
  162. /package/{testdriver → _testdriver}/acceptance/snippets/match-cart.yaml +0 -0
  163. /package/{testdriver → _testdriver}/acceptance/type.yaml +0 -0
  164. /package/{testdriver → _testdriver}/behavior/failure.yaml +0 -0
  165. /package/{testdriver → _testdriver}/behavior/hover-text.yaml +0 -0
  166. /package/{testdriver → _testdriver}/behavior/lifecycle/postrun.yaml +0 -0
  167. /package/{testdriver → _testdriver}/behavior/lifecycle/prerun.yaml +0 -0
  168. /package/{testdriver → _testdriver}/behavior/lifecycle/provision.yaml +0 -0
  169. /package/{testdriver → _testdriver}/behavior/secrets.yaml +0 -0
  170. /package/{testdriver → _testdriver}/edge-cases/dashcam-chrome.yaml +0 -0
  171. /package/{testdriver → _testdriver}/edge-cases/exec-pwsh-multiline.yaml +0 -0
  172. /package/{testdriver → _testdriver}/edge-cases/js-exception.yaml +0 -0
  173. /package/{testdriver → _testdriver}/edge-cases/js-promise.yaml +0 -0
  174. /package/{testdriver → _testdriver}/edge-cases/lifecycle/postrun.yaml +0 -0
  175. /package/{testdriver → _testdriver}/edge-cases/prompt-in-middle.yaml +0 -0
  176. /package/{testdriver → _testdriver}/edge-cases/prompt-nested.yaml +0 -0
  177. /package/{testdriver → _testdriver}/edge-cases/success-test.yaml +0 -0
  178. /package/{testdriver → _testdriver}/examples/android/example.yaml +0 -0
  179. /package/{testdriver → _testdriver}/examples/android/lifecycle/postrun.yaml +0 -0
  180. /package/{testdriver → _testdriver}/examples/android/lifecycle/provision.yaml +0 -0
  181. /package/{testdriver → _testdriver}/examples/android/readme.md +0 -0
  182. /package/{testdriver → _testdriver}/examples/chrome-extension/lifecycle/provision.yaml +0 -0
  183. /package/{testdriver → _testdriver}/examples/desktop/lifecycle/provision.yaml +0 -0
  184. /package/{testdriver → _testdriver}/examples/vscode-extension/lifecycle/provision.yaml +0 -0
  185. /package/{testdriver → _testdriver}/examples/web/lifecycle/postrun.yaml +0 -0
  186. /package/docs/{account → v6/account}/dashboard.mdx +0 -0
  187. /package/docs/{account → v6/account}/enterprise.mdx +0 -0
  188. /package/docs/{account → v6/account}/pricing.mdx +0 -0
  189. /package/docs/{account → v6/account}/projects.mdx +0 -0
  190. /package/docs/{account → v6/account}/team.mdx +0 -0
  191. /package/docs/{action → v6/action}/ami.mdx +0 -0
  192. /package/docs/{action → v6/action}/performance.mdx +0 -0
  193. /package/docs/{action → v6/action}/secrets.mdx +0 -0
  194. /package/docs/{apps → v6/apps}/chrome-extensions.mdx +0 -0
  195. /package/docs/{apps → v6/apps}/desktop-apps.mdx +0 -0
  196. /package/docs/{apps → v6/apps}/mobile-apps.mdx +0 -0
  197. /package/docs/{apps → v6/apps}/static-websites.mdx +0 -0
  198. /package/docs/{apps → v6/apps}/tauri-apps.mdx +0 -0
  199. /package/docs/{bugs → v6/bugs}/jira.mdx +0 -0
  200. /package/docs/{cli → v6/cli}/overview.mdx +0 -0
  201. /package/docs/{commands → v6/commands}/assert.mdx +0 -0
  202. /package/docs/{commands → v6/commands}/exec.mdx +0 -0
  203. /package/docs/{commands → v6/commands}/focus-application.mdx +0 -0
  204. /package/docs/{commands → v6/commands}/hover-image.mdx +0 -0
  205. /package/docs/{commands → v6/commands}/hover-text.mdx +0 -0
  206. /package/docs/{commands → v6/commands}/if.mdx +0 -0
  207. /package/docs/{commands → v6/commands}/match-image.mdx +0 -0
  208. /package/docs/{commands → v6/commands}/press-keys.mdx +0 -0
  209. /package/docs/{commands → v6/commands}/remember.mdx +0 -0
  210. /package/docs/{commands → v6/commands}/run.mdx +0 -0
  211. /package/docs/{commands → v6/commands}/scroll-until-image.mdx +0 -0
  212. /package/docs/{commands → v6/commands}/scroll-until-text.mdx +0 -0
  213. /package/docs/{commands → v6/commands}/scroll.mdx +0 -0
  214. /package/docs/{commands → v6/commands}/type.mdx +0 -0
  215. /package/docs/{commands → v6/commands}/wait-for-image.mdx +0 -0
  216. /package/docs/{commands → v6/commands}/wait-for-text.mdx +0 -0
  217. /package/docs/{commands → v6/commands}/wait.mdx +0 -0
  218. /package/docs/{exporting → v6/exporting}/junit.mdx +0 -0
  219. /package/docs/{exporting → v6/exporting}/playwright.mdx +0 -0
  220. /package/docs/{features → v6/features}/auto-healing.mdx +0 -0
  221. /package/docs/{features → v6/features}/generation.mdx +0 -0
  222. /package/docs/{features → v6/features}/parallel-testing.mdx +0 -0
  223. /package/docs/{features → v6/features}/reusable-snippets.mdx +0 -0
  224. /package/docs/{features → v6/features}/selectorless.mdx +0 -0
  225. /package/docs/{features → v6/features}/visual-assertions.mdx +0 -0
  226. /package/docs/{getting-started → v6/getting-started}/ci.mdx +0 -0
  227. /package/docs/{getting-started → v6/getting-started}/cli.mdx +0 -0
  228. /package/docs/{getting-started → v6/getting-started}/editing.mdx +0 -0
  229. /package/docs/{getting-started → v6/getting-started}/playwright.mdx +0 -0
  230. /package/docs/{getting-started → v6/getting-started}/running.mdx +0 -0
  231. /package/docs/{getting-started → v6/getting-started}/vscode.mdx +0 -0
  232. /package/docs/{guide → v6/guide}/assertions.mdx +0 -0
  233. /package/docs/{guide → v6/guide}/authentication.mdx +0 -0
  234. /package/docs/{guide → v6/guide}/code.mdx +0 -0
  235. /package/docs/{guide → v6/guide}/locating.mdx +0 -0
  236. /package/docs/{guide → v6/guide}/protips.mdx +0 -0
  237. /package/docs/{guide → v6/guide}/variables.mdx +0 -0
  238. /package/docs/{guide → v6/guide}/waiting.mdx +0 -0
  239. /package/docs/{importing → v6/importing}/csv.mdx +0 -0
  240. /package/docs/{importing → v6/importing}/gherkin.mdx +0 -0
  241. /package/docs/{importing → v6/importing}/jira.mdx +0 -0
  242. /package/docs/{importing → v6/importing}/testrail.mdx +0 -0
  243. /package/docs/{integrations → v6/integrations}/electron.mdx +0 -0
  244. /package/docs/{integrations → v6/integrations}/netlify.mdx +0 -0
  245. /package/docs/{integrations → v6/integrations}/vercel.mdx +0 -0
  246. /package/docs/{interactive → v6/interactive}/explore.mdx +0 -0
  247. /package/docs/{interactive → v6/interactive}/run.mdx +0 -0
  248. /package/docs/{interactive → v6/interactive}/save.mdx +0 -0
  249. /package/docs/{overview → v6/overview}/faq.mdx +0 -0
  250. /package/docs/{overview → v6/overview}/performance.mdx +0 -0
  251. /package/docs/{overview → v6/overview}/quickstart.mdx +0 -0
  252. /package/docs/{overview → v6/overview}/what-is-testdriver.mdx +0 -0
  253. /package/docs/{scenarios → v6/scenarios}/ai-chatbot.mdx +0 -0
  254. /package/docs/{scenarios → v6/scenarios}/cookie-banner.mdx +0 -0
  255. /package/docs/{scenarios → v6/scenarios}/file-upload.mdx +0 -0
  256. /package/docs/{scenarios → v6/scenarios}/form-filling.mdx +0 -0
  257. /package/docs/{scenarios → v6/scenarios}/log-in.mdx +0 -0
  258. /package/docs/{scenarios → v6/scenarios}/pdf-generation.mdx +0 -0
  259. /package/docs/{scenarios → v6/scenarios}/spell-check.mdx +0 -0
  260. /package/docs/{security → v6/security}/action.mdx +0 -0
  261. /package/docs/{security → v6/security}/agent.mdx +0 -0
  262. /package/docs/{security → v6/security}/platform.mdx +0 -0
  263. /package/docs/{tutorials → v6/tutorials}/advanced-test.mdx +0 -0
  264. /package/docs/{tutorials → v6/tutorials}/basic-test.mdx +0 -0
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Type Checking Demo
5
+ *
6
+ * This file demonstrates the strict type checking and autocomplete features
7
+ * of the TestDriver SDK. Open this file in VS Code and notice:
8
+ *
9
+ * 1. Method autocomplete when you type `client.`
10
+ * 2. Parameter autocomplete for enum values like action, direction, method
11
+ * 3. Inline documentation showing parameter types and descriptions
12
+ * 4. Type warnings if you use invalid values
13
+ */
14
+
15
+ const TestDriver = require("../../sdk.js");
16
+
17
+ async function typeCheckingDemo() {
18
+ const client = new TestDriver(process.env.TD_API_KEY);
19
+
20
+ await client.auth();
21
+ await client.connect();
22
+
23
+ // Try typing these and see the autocomplete:
24
+
25
+ // 1. Action parameter - should autocomplete: 'click', 'right-click', 'double-click', 'hover', 'drag-start', 'drag-end'
26
+ await client.hoverText("Submit", null, "click");
27
+
28
+ // 2. Scroll direction - should autocomplete: 'up', 'down', 'left', 'right'
29
+ await client.scroll("asdf", 300);
30
+
31
+ // 3. Text match method - should autocomplete: 'ai', 'turbo'
32
+ await client.waitForText("Welcome", 5000, "turbo");
33
+
34
+ // 4. Keyboard keys - should autocomplete all valid keys
35
+ await client.pressKeys(["enter", "tab", "escape"]);
36
+
37
+ // 5. Exec language - should autocomplete: 'js', 'pwsh'
38
+ await client.exec("js", 'console.log("Hello")', 5000);
39
+
40
+ // 6. Scroll method - should autocomplete: 'keyboard', 'mouse'
41
+ await client.scrollUntilText("Contact", "down", 10000);
42
+
43
+ await client.disconnect();
44
+ }
45
+
46
+ // Uncomment to run:
47
+ // typeCheckingDemo().catch(console.error);
48
+
49
+ module.exports = typeCheckingDemo;
@@ -0,0 +1,84 @@
1
+ import {
2
+ afterAll,
3
+ afterEach,
4
+ beforeAll,
5
+ beforeEach,
6
+ describe,
7
+ expect,
8
+ it,
9
+ } from "vitest";
10
+ import {
11
+ addDashcamLog,
12
+ authDashcam,
13
+ createTestClient,
14
+ launchChrome,
15
+ setupTest,
16
+ startDashcam,
17
+ stopDashcam,
18
+ teardownTest,
19
+ waitForPage,
20
+ } from "./setup/testHelpers.mjs";
21
+
22
+ describe.sequential("Type Test", () => {
23
+ let testdriver;
24
+
25
+ beforeAll(async () => {
26
+ testdriver = createTestClient({ task: { id: "type-test-suite" } });
27
+ await setupTest(testdriver, { prerun: false }); // Skip prerun, we'll handle dashcam manually
28
+
29
+ // One-time dashcam setup (auth and add logs)
30
+ await authDashcam(testdriver);
31
+ await addDashcamLog(testdriver);
32
+ await launchChrome(testdriver);
33
+ await waitForPage(testdriver, "TestDriver.ai Sandbox");
34
+ });
35
+
36
+ beforeEach(async () => {
37
+ await startDashcam(testdriver);
38
+ }, 60000);
39
+
40
+ afterEach(async (context) => {
41
+ // Stop dashcam first to get the URL
42
+ const dashcamUrl = await stopDashcam(testdriver);
43
+ console.log("📤 Dashcam URL:", dashcamUrl);
44
+
45
+ // Use teardownTest to track results, but skip postrun (already stopped dashcam) and disconnect
46
+ await teardownTest(testdriver, {
47
+ task: context.task,
48
+ dashcamUrl: dashcamUrl, // Pass the dashcam URL we already got
49
+ postrun: false, // Skip postrun since we manually stopped dashcam
50
+ disconnect: false, // Don't disconnect, we'll do that in afterAll
51
+ });
52
+ });
53
+
54
+ afterAll(async () => {
55
+ await testdriver.disconnect();
56
+ });
57
+
58
+ it("should enter standard_user in username field", async () => {
59
+ await testdriver.focusApplication("Google Chrome");
60
+ const usernameField = await testdriver.find(
61
+ "Username, input field for username",
62
+ );
63
+ await usernameField.click();
64
+ await testdriver.type("standard_user");
65
+
66
+ const result = await testdriver.assert(
67
+ 'the username field contains "standard_user"',
68
+ );
69
+ expect(result).toBeTruthy();
70
+ });
71
+
72
+ it("should show validation message when clicking Sign In without password", async () => {
73
+ const signInButton = await testdriver.find(
74
+ "Sign in, black button below the password field",
75
+ );
76
+ await signInButton.click();
77
+
78
+ await testdriver.focusApplication("Google Chrome");
79
+ const result = await testdriver.assert(
80
+ "Please fill out this field is visible near the password field",
81
+ );
82
+ expect(result).toBeTruthy();
83
+ });
84
+ });
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Verify Element class API
5
+ * Tests that all expected methods and properties are available
6
+ */
7
+
8
+ async function verify() {
9
+ // Create a test element instance - need to access Element class directly
10
+ const { Element } = require("./sdk.js");
11
+ const elem = new Element("test", null, null, null);
12
+
13
+ console.log("Verifying Element class API...\n");
14
+
15
+ // Check methods exist
16
+ const methods = [
17
+ "find",
18
+ "found",
19
+ "click",
20
+ "hover",
21
+ "doubleClick",
22
+ "rightClick",
23
+ "mouseDown",
24
+ "mouseUp",
25
+ "getCoordinates",
26
+ "getResponse",
27
+ ];
28
+
29
+ let passed = 0;
30
+ let failed = 0;
31
+
32
+ console.log("Testing methods:");
33
+ methods.forEach((method) => {
34
+ if (typeof elem[method] === "function") {
35
+ console.log(` ✓ ${method}()`);
36
+ passed++;
37
+ } else {
38
+ console.log(` ✗ ${method}() - MISSING`);
39
+ failed++;
40
+ }
41
+ });
42
+
43
+ // Test property getters (should return null when element not found)
44
+ const props = [
45
+ "x",
46
+ "y",
47
+ "centerX",
48
+ "centerY",
49
+ "width",
50
+ "height",
51
+ "confidence",
52
+ "screenshot",
53
+ "boundingBox",
54
+ "text",
55
+ "label",
56
+ ];
57
+
58
+ console.log("\nTesting properties (should be null when not found):");
59
+ props.forEach((prop) => {
60
+ if (prop in elem) {
61
+ const value = elem[prop];
62
+ if (value === null) {
63
+ console.log(` ✓ ${prop} = null`);
64
+ passed++;
65
+ } else {
66
+ console.log(` ✗ ${prop} = ${value} (expected null)`);
67
+ failed++;
68
+ }
69
+ } else {
70
+ console.log(` ✗ ${prop} - MISSING`);
71
+ failed++;
72
+ }
73
+ });
74
+
75
+ console.log("\n" + "=".repeat(50));
76
+ console.log(`Results: ${passed} passed, ${failed} failed`);
77
+ console.log("=".repeat(50));
78
+
79
+ if (failed > 0) {
80
+ process.exit(1);
81
+ } else {
82
+ console.log("\n✅ All Element API verification tests passed!");
83
+ }
84
+ }
85
+
86
+ verify().catch((err) => {
87
+ console.error("Error:", err);
88
+ process.exit(1);
89
+ });
File without changes
@@ -0,0 +1,19 @@
1
+ import { defineConfig } from "vitest/config";
2
+ import testDriverPlugin from "./interfaces/vitest-plugin.mjs";
3
+
4
+ export default defineConfig({
5
+ plugins: [
6
+ testDriverPlugin({
7
+ apiKey: process.env.TD_API_KEY,
8
+ apiRoot: process.env.TD_API_ROOT || "https://testdriver-api.onrender.com",
9
+ }),
10
+ ],
11
+
12
+ test: {
13
+ // Optional: Configure test timeout
14
+ testTimeout: 30000,
15
+
16
+ // Optional: Configure hooks timeout
17
+ hookTimeout: 30000,
18
+ },
19
+ });
@@ -0,0 +1,65 @@
1
+ import { config } from "dotenv";
2
+ import { defineConfig } from "vitest/config";
3
+ import testDriverPlugin from "./interfaces/vitest-plugin.mjs";
4
+
5
+ // Load environment variables from .env file
6
+ config();
7
+
8
+ export default defineConfig({
9
+ plugins: [
10
+ testDriverPlugin({
11
+ apiKey: process.env.TD_API_KEY,
12
+ apiRoot: process.env.TD_API_ROOT || "https://testdriver-api.onrender.com",
13
+ }),
14
+ ],
15
+
16
+ test: {
17
+ // Test file patterns
18
+ include: ["**/testdriver/acceptance-sdk/*.test.mjs"],
19
+
20
+ // Setup file to initialize plugin in worker processes
21
+ setupFiles: ["./testdriver/acceptance-sdk/setup/vitestSetup.mjs"],
22
+
23
+ // Timeout settings
24
+ testTimeout: 600000, // 10 minutes per test
25
+ hookTimeout: 600000, // 10 minutes for setup/teardown
26
+ teardownTimeout: 120000, // 2 minutes for teardown specifically
27
+
28
+ globalTeardown: "./testdriver/acceptance-sdk/setup/globalTeardown.mjs",
29
+
30
+ // Reporter configuration
31
+ reporters: [
32
+ "verbose", // Detailed console output with full logs
33
+ ["junit", { outputFile: "test-results/junit.xml" }],
34
+ ["json", { outputFile: "test-results/results.json" }],
35
+ ["html", { outputFile: "test-results/index.html" }],
36
+ [
37
+ "./interfaces/vitest-plugin.mjs",
38
+ {
39
+ apiKey: process.env.TD_API_KEY,
40
+ apiRoot:
41
+ process.env.TD_API_ROOT || "https://testdriver-api.onrender.com",
42
+ },
43
+ ], // TestDriver test recording
44
+ ],
45
+
46
+ // Use forks for isolation, run tests in parallel
47
+ pool: "forks",
48
+ poolOptions: {
49
+ forks: {
50
+ singleFork: false,
51
+ maxForks: 5, // Reduced from 10 to prevent resource contention
52
+ minForks: 1,
53
+ },
54
+ },
55
+
56
+ // Enable parallel execution
57
+ sequence: {
58
+ concurrent: true,
59
+ shuffle: false,
60
+ },
61
+
62
+ fileParallelism: true,
63
+ maxConcurrency: 5, // Reduced from 10 to match maxForks
64
+ },
65
+ });
@@ -0,0 +1,44 @@
1
+ import { config } from "dotenv";
2
+ import { defineConfig } from "vitest/config";
3
+
4
+ // Load environment variables from .env file
5
+ config();
6
+
7
+ export default defineConfig({
8
+ test: {
9
+ // Test file patterns
10
+ include: ["**/testdriver/acceptance-sdk/*.test.mjs"],
11
+
12
+ // Timeout settings
13
+ testTimeout: 600000, // 2 minutes per test
14
+ hookTimeout: 600000, // 1 minute for setup/teardown
15
+
16
+ globalTeardown: "./testdriver/acceptance-sdk/setup/globalTeardown.mjs",
17
+
18
+ // Reporter configuration
19
+ reporters: [
20
+ "verbose", // Detailed console output with full logs
21
+ ["junit", { outputFile: "test-results/junit.xml" }],
22
+ ["json", { outputFile: "test-results/results.json" }],
23
+ ["html", { outputFile: "test-results/index.html" }],
24
+ ],
25
+
26
+ // Use forks for isolation, run tests in parallel
27
+ pool: "forks",
28
+ poolOptions: {
29
+ forks: {
30
+ singleFork: false,
31
+ maxForks: 10, // Run up to 10 tests in parallel
32
+ },
33
+ },
34
+
35
+ // Enable parallel execution
36
+ sequence: {
37
+ concurrent: true,
38
+ shuffle: false,
39
+ },
40
+
41
+ fileParallelism: true,
42
+ maxConcurrency: 10,
43
+ },
44
+ });
@@ -1,169 +0,0 @@
1
- name: v6 Acceptance [disabled]
2
-
3
- on:
4
- workflow_dispatch:
5
- push:
6
- branches:
7
- - main
8
- paths-ignore:
9
- - "docs/**"
10
- pull_request:
11
- branches:
12
- - main
13
-
14
- schedule:
15
- - cron: "0 0 * * *"
16
-
17
- jobs:
18
- # Job to gather all test files
19
- test-setup:
20
- runs-on: ubuntu-latest
21
- outputs:
22
- testmo-run-id: ${{ steps.run-tests.outputs.testmo-run-id }}
23
- steps:
24
- - uses: actions/checkout@v3
25
- - uses: actions/setup-node@v3
26
- with:
27
- node-version: 22
28
- cache: npm
29
- - run: npm ci
30
-
31
- # Optionally add a couple of fields such as the git hash and link to the build
32
- - run: |
33
- npx @testmo/testmo-cli automation:resources:add-field --name git --type string \
34
- --value ${GITHUB_SHA:0:7} --resources resources.json
35
- RUN_URL="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"
36
- npx @testmo/testmo-cli automation:resources:add-link --name build \
37
- --url $RUN_URL --resources resources.json
38
-
39
- # Create test run
40
- - run: |
41
- npx @testmo/testmo-cli automation:run:create \
42
- --instance "$TESTMO_URL" \
43
- --project-id 1 \
44
- --name "TestDriver Acceptance Tests" \
45
- --resources resources.json \
46
- --source "TestDriver" > testmo-run-id.txt
47
- ID=$(cat testmo-run-id.txt)
48
- echo "testmo-run-id=$ID" >> $GITHUB_OUTPUT
49
- env:
50
- TESTMO_URL: ${{ secrets.TESTMO_URL }}
51
- TESTMO_TOKEN: ${{ secrets.TESTMO_TOKEN }}
52
- id: run-tests
53
- gather:
54
- name: Gather Test Files
55
- runs-on: ubuntu-latest
56
- outputs:
57
- test_files: ${{ steps.test_list.outputs.files }}
58
- steps:
59
- - name: Check out repository
60
- uses: actions/checkout@v2
61
-
62
- - name: Find all test files
63
- id: test_list
64
- run: |
65
- FILES=$(ls ./testdriver/acceptance/*.yaml)
66
- FILENAMES=$(basename -a $FILES)
67
- FILES_JSON=$(echo "$FILENAMES" | jq -R -s -c 'split("\n")[:-1]')
68
- echo "files=$FILES_JSON" >> $GITHUB_OUTPUT
69
- test:
70
- needs:
71
- - gather
72
- - test-setup
73
- runs-on: ubuntu-latest
74
- strategy:
75
- matrix:
76
- test: ${{ fromJson(needs.gather.outputs.test_files) }}
77
- max-parallel: 8
78
- fail-fast: false
79
- steps:
80
- - name: Checkout repository
81
- uses: actions/checkout@v4
82
- with:
83
- fetch-depth: 0
84
-
85
- - name: Set up Node.js
86
- uses: actions/setup-node@v4
87
- with:
88
- node-version: "20"
89
- cache: "npm"
90
-
91
- - name: Install dependencies
92
- run: NODE_ENV=production npm ci
93
- - name: Run test in headless mode
94
- run: node bin/testdriverai.js run testdriver/acceptance/${{ matrix.test }} --junit=out.xml
95
- env:
96
- FORCE_COLOR: 3
97
- TD_API_KEY: ${{ secrets.TESTDRIVER_API_KEY }}
98
- TD_WEBSITE: https://testdriver-sandbox.vercel.app
99
- TD_THIS_FILE: ${{ matrix.test }}
100
- - run: ls
101
- - name: Upload JUnit report to Testmo
102
- if: always()
103
- run: |
104
- npx @testmo/testmo-cli automation:run:submit-thread \
105
- --instance "$TESTMO_URL" \
106
- --run-id "${{ needs.test-setup.outputs.testmo-run-id }}" \
107
- --results out.xml \
108
- env:
109
- TESTMO_URL: ${{ secrets.TESTMO_URL }}
110
- TESTMO_TOKEN: ${{ secrets.TESTMO_TOKEN }}
111
-
112
- - name: Upload test results as artifact
113
- if: always()
114
- uses: actions/upload-artifact@v4
115
- with:
116
- name: test-results-${{ matrix.test }}
117
- path: out.xml
118
- retention-days: 30
119
-
120
- test-complete:
121
- needs: [test-setup, test]
122
- if: always()
123
- runs-on: ubuntu-latest
124
-
125
- steps:
126
- - uses: actions/checkout@v3
127
- - uses: actions/setup-node@v3
128
- with:
129
- node-version: 19
130
- cache: npm
131
- - run: npm ci
132
-
133
- # Download all test result artifacts
134
- - name: Download test results
135
- uses: actions/download-artifact@v4
136
- with:
137
- pattern: test-results-*
138
- path: test-results
139
- merge-multiple: true
140
-
141
- # Debug: Check what files were downloaded
142
- - name: Debug downloaded files
143
- run: |
144
- echo "=== Contents of test-results directory ==="
145
- find test-results -type f -name "*.xml" -ls
146
- echo "=== Directory structure ==="
147
- ls -la test-results/
148
- echo "=== XML file contents preview ==="
149
- for file in test-results/*.xml; do
150
- if [ -f "$file" ]; then
151
- echo "--- Content of $file ---"
152
- head -10 "$file"
153
- echo ""
154
- fi
155
- done
156
-
157
- # Mark test run completed
158
- - run: |
159
- npx @testmo/testmo-cli automation:run:complete \
160
- --instance "$TESTMO_URL" \
161
- --run-id "${{ needs.test-setup.outputs.testmo-run-id }}"
162
- env:
163
- TESTMO_URL: ${{ secrets.TESTMO_URL }}
164
- TESTMO_TOKEN: ${{ secrets.TESTMO_TOKEN }}
165
- - name: Test Summary
166
- uses: test-summary/action@v2
167
- with:
168
- paths: "test-results/**/*.xml"
169
- if: always()
@@ -1,82 +0,0 @@
1
- ---
2
- title: Comparison
3
- sidebarTitle: "Comparison"
4
- description: "TestDriver vs Playwright vs Selenium"
5
- icon: boxing-glove
6
- ---
7
-
8
- ## Application support
9
-
10
- TestDriver operates a full desktop environment, so it can run any application.
11
-
12
- <div className="comparison-table">
13
- | Application | TestDriver | Playwright | Selenium |
14
- |:-----------------:|:---------:|:-----------:|:--------:| | Web Apps | ✅ |
15
- ✅ | ✅ | | Mobile Apps | ✅ | ✅ | ✅ | | VS Code | ✅ | ✅ | ✅ | | Desktop
16
- Apps | ✅ | | | | Chrome Extensions | ✅ | | |
17
- </div>
18
-
19
- ## Testing features
20
-
21
- TestDriver is AI first.
22
-
23
- <div className="comparison-table">
24
- | Feature | TestDriver | Playwright | Selenium |
25
- |:--------------------:|:---------:|:----------:|:--------:| | Test Generation
26
- | ✅ | | | | Adaptive Testing | ✅ | | | | Visual Assertions | ✅ | | | | Self
27
- Healing | ✅ | | | | Application Switching | ✅ | | | | GitHub Actions | ✅ |
28
- ✅ | | | Team Dashboard | ✅ | | | | Team Collaboration | ✅ | | |
29
- </div>
30
-
31
- ## Test coverage
32
-
33
- TestDriver has more coverage than selector-based frameworks.
34
-
35
- <div className="comparison-table">
36
- | Feature | TestDriver | Playwright | Selenium |
37
- |:------------------:|:----------:|:----------:|:--------:|
38
- | Browser Viewport | ✅ | ✅ | ✅ |
39
- | Browser App | ✅ | | |
40
- | Operating System | ✅ | | |
41
- | PDFs | ✅ | | |
42
- | File System | ✅ | | |
43
- | Push Notifications | ✅ | | |
44
- | Image Content | ✅ | | |
45
- | Video Content | ✅ | | |
46
- | `<iframe>` | ✅ | | |
47
- | `<canvas>` | ✅ | | |
48
- | `<video>` | ✅ | | |
49
- </div>
50
-
51
- ## Debugging features
52
-
53
- Debugging features are powered by [Dashcam.io](https://dashcam.io).
54
-
55
- <div className="comparison-table">
56
- | Feature | TestDriver | Playwright | Selenium |
57
- |:------------------:|:----------:|:----------:|:--------:| | AI Summary | ✅
58
- | | | | Video Replay | ✅ | ✅ | | | Browser Logs | ✅ | ✅ | | | Desktop Logs
59
- | ✅ | | | | Network Requests | ✅ | ✅ | | | Team Dashboard | ✅ | | | | Team
60
- Collaboration | ✅ | | |
61
- </div>
62
-
63
- ## Web browser support
64
-
65
- TestDriver is browser agnostic and supports any version of any browser.
66
-
67
- <div className="comparison-table">
68
- | Feature | TestDriver | Playwright | Selenium |
69
- |:--------:|:----------:|:----------:|:--------:| | Chrome | ✅ | ✅ | ✅ | |
70
- Firefox | ✅ | ✅ | ✅ | | Webkit | ✅ | ✅ | ✅ | | IE | ✅ | | ✅ | | Edge |
71
- ✅ | ✅ | ✅ | | Opera | ✅ | | ✅ | | Safari | ✅ | | ✅ |
72
- </div>
73
-
74
- ## Operating system support
75
-
76
- TestDriver currently supports Mac and Windows!
77
-
78
- <div className="comparison-table">
79
- | Feature | TestDriver | Playwright | Selenium |
80
- |:--------:|:----------:|:----------:|:--------:| | Windows | ✅ | ✅ | ✅ | |
81
- Mac | ✅ | ✅ | ✅ | | Linux | | ✅ | ✅ |
82
- </div>
@@ -1,17 +0,0 @@
1
- version: 6.0.0
2
- steps:
3
- - prompt: launch chrome
4
- commands:
5
- - command: exec
6
- lang: pwsh
7
- code: dashcam track --name=TestDriver --type=application --pattern="C:\Users\testdriver\Documents\testdriver.log"
8
- - command: exec
9
- lang: pwsh
10
- code: dashcam start
11
- - command: exec
12
- lang: pwsh
13
- code: |
14
- Start-Process "C:/Program Files/Google/Chrome/Application/chrome.exe" -ArgumentList "--start-maximized", "--guest", "https://testdriver-sandbox.vercel.app/login"
15
- - command: wait-for-text
16
- text: "TestDriver.ai Sandbox"
17
- timeout: 60000