testdriverai 6.2.1 → 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 +16 -5
  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,43 @@
1
+ /**
2
+ * TestDriver SDK - Hover Image Test (Vitest)
3
+ * Converted from: testdriver/acceptance/hover-image.yaml
4
+ */
5
+
6
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
7
+ import {
8
+ createTestClient,
9
+ performLogin,
10
+ setupTest,
11
+ teardownTest,
12
+ } from "./setup/testHelpers.mjs";
13
+
14
+ describe("Hover Image Test", () => {
15
+ let testdriver;
16
+
17
+ beforeEach(async (context) => {
18
+ testdriver = createTestClient({ task: context.task });
19
+
20
+ await setupTest(testdriver);
21
+ });
22
+
23
+ afterEach(async (context) => {
24
+ await teardownTest(testdriver, { task: context.task });
25
+ });
26
+
27
+ it("should click on shopping cart icon and verify empty cart", async () => {
28
+ // Perform login first
29
+ await performLogin(testdriver);
30
+
31
+ // Click on the shopping cart icon
32
+ await testdriver.focusApplication("Google Chrome");
33
+ const cartIcon = await testdriver.find(
34
+ "shopping cart icon next to the Cart text in the top right corner",
35
+ );
36
+
37
+ await cartIcon.click();
38
+
39
+ // Assert that you see an empty shopping cart
40
+ const result = await testdriver.assert("Your cart is empty");
41
+ expect(result).toBeTruthy();
42
+ });
43
+ });
@@ -0,0 +1,50 @@
1
+ /**
2
+ * TestDriver SDK - Hover Text With Description Test (Vitest)
3
+ * Converted from: testdriver/acceptance/hover-text-with-description.yaml
4
+ */
5
+
6
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
7
+ import {
8
+ createTestClient,
9
+ performLogin,
10
+ setupTest,
11
+ teardownTest,
12
+ } from "./setup/testHelpers.mjs";
13
+
14
+ describe("Hover Text With Description Test", () => {
15
+ let testdriver;
16
+
17
+ beforeEach(async (context) => {
18
+ testdriver = createTestClient({ task: context.task });
19
+
20
+ await setupTest(testdriver);
21
+ });
22
+
23
+ afterEach(async (context) => {
24
+ await teardownTest(testdriver, { task: context.task });
25
+ });
26
+
27
+ it("should add TestDriver Hat to cart and verify", async () => {
28
+ // Perform login first
29
+ await performLogin(testdriver);
30
+
31
+ // Click on "Add to Cart" under TestDriver Hat
32
+ await testdriver.focusApplication("Google Chrome");
33
+ const addToCartButton = await testdriver.find(
34
+ "Add to Cart, add to cart button under TestDriver Hat",
35
+ );
36
+ await addToCartButton.click();
37
+
38
+ // Click on the cart
39
+ await testdriver.focusApplication("Google Chrome");
40
+ const cartButton = await testdriver.find(
41
+ "Cart, cart button in the top right corner",
42
+ );
43
+ await cartButton.click();
44
+
45
+ // Assert the TestDriver Hat is in the cart
46
+ await testdriver.focusApplication("Google Chrome");
47
+ const result = await testdriver.assert("TestDriver Hat is in the cart");
48
+ expect(result).toBeTruthy();
49
+ });
50
+ });
@@ -0,0 +1,41 @@
1
+ /**
2
+ * TestDriver SDK - Hover Text Test (Vitest)
3
+ * Converted from: testdriver/acceptance/hover-text.yaml
4
+ */
5
+
6
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
7
+ import {
8
+ createTestClient,
9
+ setupTest,
10
+ teardownTest,
11
+ } from "./setup/testHelpers.mjs";
12
+
13
+ describe("Hover Text Test", () => {
14
+ let testdriver;
15
+
16
+ beforeEach(async (context) => {
17
+ testdriver = createTestClient({ task: context.task });
18
+
19
+ await setupTest(testdriver);
20
+ });
21
+
22
+ afterEach(async (context) => {
23
+ await teardownTest(testdriver, { task: context.task });
24
+ });
25
+
26
+ it("should click Sign In and verify error message", async () => {
27
+ // Click on Sign In button using new find() API
28
+ await testdriver.focusApplication("Google Chrome");
29
+
30
+ const signInButton = await testdriver.find(
31
+ "Sign In, black button below the password field",
32
+ );
33
+ await signInButton.click();
34
+
35
+ // Assert that an error shows that fields are required
36
+ const result = await testdriver.assert(
37
+ "an error shows that fields are required",
38
+ );
39
+ expect(result).toBeTruthy();
40
+ });
41
+ });
@@ -0,0 +1,48 @@
1
+ /**
2
+ * TestDriver SDK - Match Image Test (Vitest)
3
+ * Converted from: testdriver/acceptance/match-image.yaml
4
+ */
5
+
6
+ import path, { dirname } from "path";
7
+ import { fileURLToPath } from "url";
8
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
9
+ import {
10
+ createTestClient,
11
+ performLogin,
12
+ setupTest,
13
+ teardownTest,
14
+ } from "./setup/testHelpers.mjs";
15
+
16
+ // Get the directory of the current module
17
+ const __filename = fileURLToPath(import.meta.url);
18
+ const __dirname = dirname(__filename);
19
+
20
+ describe("Match Image Test", () => {
21
+ let testdriver;
22
+
23
+ beforeEach(async (context) => {
24
+ testdriver = createTestClient({ task: context.task });
25
+
26
+ await setupTest(testdriver);
27
+ });
28
+
29
+ afterEach(async (context) => {
30
+ await teardownTest(testdriver, { task: context.task });
31
+ });
32
+
33
+ it("should match shopping cart image and verify empty cart", async () => {
34
+ // Perform login first
35
+ await performLogin(testdriver);
36
+
37
+ // Match and click the shopping cart icon
38
+ const cartImagePath = path.resolve(
39
+ __dirname,
40
+ "../../_testdriver/acceptance/screenshots/cart.png",
41
+ );
42
+ await testdriver.matchImage(cartImagePath, "click");
43
+
44
+ // Assert that you see an empty shopping cart
45
+ const result = await testdriver.assert("Your cart is empty");
46
+ expect(result).toBeTruthy();
47
+ });
48
+ });
@@ -0,0 +1,64 @@
1
+ /**
2
+ * TestDriver SDK - Press Keys Test (Vitest)
3
+ * Converted from: testdriver/acceptance/press-keys.yaml
4
+ */
5
+
6
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
7
+ import {
8
+ createTestClient,
9
+ setupTest,
10
+ teardownTest,
11
+ } from "./setup/testHelpers.mjs";
12
+
13
+ describe("Press Keys Test", () => {
14
+ let testdriver;
15
+
16
+ beforeEach(async (context) => {
17
+ testdriver = createTestClient({ task: context.task });
18
+
19
+ await setupTest(testdriver);
20
+ });
21
+
22
+ afterEach(async (context) => {
23
+ await teardownTest(testdriver, { task: context.task });
24
+ });
25
+
26
+ it("should create tabs and navigate using keyboard shortcuts", async () => {
27
+ await testdriver.focusApplication("Google Chrome");
28
+ const signInButton = await testdriver.find(
29
+ "Sign In, black button below the password field",
30
+ );
31
+ await signInButton.click();
32
+
33
+ // Open new tab
34
+ await testdriver.pressKeys(["ctrl", "t"]);
35
+
36
+ // Poll for "Learn more" to appear
37
+ let learnMore = await testdriver.find("Learn more");
38
+ for (let i = 0; i < 10; i++) {
39
+ learnMore = await learnMore.find();
40
+ if (learnMore.found()) break;
41
+ await new Promise((resolve) => setTimeout(resolve, 500));
42
+ }
43
+
44
+ // Open DevTools
45
+ await testdriver.pressKeys(["ctrl", "shift", "i"]);
46
+
47
+ // Poll for "Elements" to appear
48
+ let elements = await testdriver.find("Elements");
49
+ for (let i = 0; i < 10; i++) {
50
+ elements = await elements.find();
51
+ if (elements.found()) break;
52
+ await new Promise((resolve) => setTimeout(resolve, 500));
53
+ }
54
+
55
+ // Open another tab and navigate
56
+ await testdriver.pressKeys(["ctrl", "t"]);
57
+ await testdriver.type("google.com");
58
+ await testdriver.pressKeys(["enter"]);
59
+
60
+ // Assert Google appears
61
+ const result = await testdriver.assert("google appears");
62
+ expect(result).toBeTruthy();
63
+ });
64
+ });
@@ -0,0 +1,45 @@
1
+ /**
2
+ * TestDriver SDK - Prompt Test (Vitest)
3
+ * Converted from: testdriver/acceptance/prompt.yaml
4
+ */
5
+
6
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
7
+ import {
8
+ createTestClient,
9
+ setupTest,
10
+ teardownTest,
11
+ } from "./setup/testHelpers.mjs";
12
+
13
+ describe.skip("Prompt Test", () => {
14
+ let testdriver;
15
+
16
+ beforeEach(async (context) => {
17
+ testdriver = createTestClient({ task: context.task });
18
+
19
+ await setupTest(testdriver);
20
+ });
21
+
22
+ afterEach(async (context) => {
23
+ await teardownTest(testdriver, { task: context.task });
24
+ });
25
+
26
+ it("should execute AI-driven prompts", async () => {
27
+ // Note: The SDK doesn't have a direct equivalent to YAML prompts without commands.
28
+ // This would typically be handled by the AI agent interpreting natural language.
29
+ // For SDK usage, you need to use explicit commands.
30
+
31
+ // Original prompts were:
32
+ // 1. "log in"
33
+ // 2. "add an item to the cart"
34
+ // 3. "click on the cart icon"
35
+ // 4. "complete checkout"
36
+
37
+ // This test is skipped as it requires explicit SDK implementation
38
+ // You would need to implement these as explicit SDK calls
39
+
40
+ await testdriver.ai("log in");
41
+
42
+ const result = await testdriver.assert("the testdriver sandbox is visible");
43
+ expect(result).toBeTruthy();
44
+ });
45
+ });
@@ -0,0 +1,52 @@
1
+ /**
2
+ * TestDriver SDK - Scroll Keyboard Test (Vitest)
3
+ * Converted from: testdriver/acceptance/scroll-keyboard.yaml
4
+ */
5
+
6
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
7
+ import {
8
+ createTestClient,
9
+ setupTest,
10
+ teardownTest,
11
+ } from "./setup/testHelpers.mjs";
12
+
13
+ describe("Scroll Keyboard Test", () => {
14
+ let testdriver;
15
+
16
+ beforeEach(async (context) => {
17
+ testdriver = createTestClient({
18
+ task: context.task,
19
+ redrawThreshold: 0.5, // Higher threshold for scroll test
20
+ });
21
+ await setupTest(testdriver);
22
+ });
23
+
24
+ afterEach(async (context) => {
25
+ await teardownTest(testdriver, { task: context.task });
26
+ });
27
+
28
+ it("should navigate to webhamster.com and scroll with keyboard", async () => {
29
+ // Navigate to https://www.webhamster.com/
30
+ await testdriver.focusApplication("Google Chrome");
31
+ const urlBar = await testdriver.find(
32
+ "testdriver-sandbox.vercel.app/login, the URL in the omnibox showing the current page",
33
+ );
34
+ await urlBar.click();
35
+ await testdriver.pressKeys(["ctrl", "a"]);
36
+ await testdriver.type("https://www.webhamster.com/");
37
+ await testdriver.pressKeys(["enter"]);
38
+
39
+ // Scroll down with keyboard 1000 pixels
40
+ const heading = await testdriver.find(
41
+ "The Hamster Dance, large heading at top of page",
42
+ );
43
+ await heading.click();
44
+ await testdriver.scroll("down", 1000);
45
+
46
+ // Assert the page is scrolled down
47
+ const result = await testdriver.assert(
48
+ "the hamster dance heading is not visible",
49
+ );
50
+ expect(result).toBeTruthy();
51
+ });
52
+ });
@@ -0,0 +1,51 @@
1
+ /**
2
+ * TestDriver SDK - Scroll Until Image Test (Vitest)
3
+ * Converted from: testdriver/acceptance/scroll-until-image.yaml
4
+ */
5
+
6
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
7
+ import {
8
+ createTestClient,
9
+ setupTest,
10
+ teardownTest,
11
+ } from "./setup/testHelpers.mjs";
12
+
13
+ describe("Scroll Until Image Test", () => {
14
+ let testdriver;
15
+
16
+ beforeEach(async (context) => {
17
+ testdriver = createTestClient({ task: context.task });
18
+
19
+ await setupTest(testdriver);
20
+ });
21
+
22
+ afterEach(async (context) => {
23
+ await teardownTest(testdriver, { task: context.task });
24
+ });
25
+
26
+ it("should scroll until brown colored house image appears", async () => {
27
+ // Navigate to Wikipedia page
28
+ await testdriver.pressKeys(["ctrl", "l"]);
29
+ await testdriver.type("https://en.wikipedia.org/wiki/Leonardo_da_Vinci");
30
+ await testdriver.pressKeys(["enter"]);
31
+
32
+ // sleep for 5 seconds
33
+ await new Promise((r) => setTimeout(r, 5000));
34
+
35
+ // Click on heading
36
+ const heading = await testdriver.find(
37
+ "Leonardo Da Vinci, the page heading",
38
+ 0,
39
+ );
40
+ await heading.click();
41
+
42
+ // Scroll until image appears
43
+ await testdriver.scrollUntilImage("a brown colored house", "down", 10000);
44
+
45
+ // Assert image of brown colored house appears on screen
46
+ const result = await testdriver.assert(
47
+ "image of brown colored house appears on screen",
48
+ );
49
+ expect(result).toBeTruthy();
50
+ });
51
+ });
@@ -0,0 +1,42 @@
1
+ /**
2
+ * TestDriver SDK - Scroll Until Text Test (Vitest)
3
+ * Converted from: testdriver/acceptance/scroll-until-text.yaml
4
+ */
5
+
6
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
7
+ import {
8
+ createTestClient,
9
+ performLogin,
10
+ setupTest,
11
+ teardownTest,
12
+ } from "./setup/testHelpers.mjs";
13
+
14
+ describe("Scroll Until Text Test", () => {
15
+ let testdriver;
16
+
17
+ beforeEach(async (context) => {
18
+ testdriver = createTestClient({ task: context.task });
19
+
20
+ await setupTest(testdriver);
21
+ });
22
+
23
+ afterEach(async (context) => {
24
+ await teardownTest(testdriver, { task: context.task });
25
+ });
26
+
27
+ it('should scroll until "testdriver socks" appears', async () => {
28
+ // Perform login first
29
+ await performLogin(testdriver);
30
+
31
+ // Scroll until text appears
32
+ await testdriver.focusApplication("Google Chrome");
33
+ await testdriver.scrollUntilText("testdriver socks", "down");
34
+
35
+ // Assert testdriver socks appears on screen
36
+ await testdriver.focusApplication("Google Chrome");
37
+ const result = await testdriver.assert(
38
+ "TestDriver Socks appears on screen",
39
+ );
40
+ expect(result).toBeTruthy();
41
+ });
42
+ });
@@ -0,0 +1,50 @@
1
+ /**
2
+ * TestDriver SDK - Scroll Test (Vitest)
3
+ * Converted from: testdriver/acceptance/scroll.yaml
4
+ */
5
+
6
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
7
+ import {
8
+ createTestClient,
9
+ setupTest,
10
+ teardownTest,
11
+ } from "./setup/testHelpers.mjs";
12
+
13
+ describe("Scroll Test", () => {
14
+ let testdriver;
15
+
16
+ beforeEach(async (context) => {
17
+ testdriver = createTestClient({ task: context.task });
18
+
19
+ await setupTest(testdriver);
20
+ });
21
+
22
+ afterEach(async (context) => {
23
+ await teardownTest(testdriver, { task: context.task });
24
+ });
25
+
26
+ it("should navigate and scroll down the page", async () => {
27
+ // Navigate to webhamster.com
28
+ await testdriver.focusApplication("Google Chrome");
29
+ const urlBar = await testdriver.find(
30
+ "testdriver-sandbox.vercel.app/login, the URL in the omnibox showing the current page",
31
+ );
32
+ await urlBar.click();
33
+ await testdriver.pressKeys(["ctrl", "a"]);
34
+ await testdriver.type("https://www.webhamster.com/");
35
+ await testdriver.pressKeys(["enter"]);
36
+
37
+ // Wait for page to load and click heading
38
+ const heading = await testdriver.find(
39
+ "The Hamster Dance, large heading at top of page",
40
+ );
41
+ await heading.click();
42
+
43
+ // Scroll down
44
+ await testdriver.scroll("down", 1000);
45
+
46
+ // Assert page is scrolled
47
+ const result = await testdriver.assert("the page is scrolled down");
48
+ expect(result).toBeTruthy();
49
+ });
50
+ });
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Vitest Global Teardown
3
+ * Saves test results and dashcam URLs after all tests complete
4
+ */
5
+
6
+ import { saveTestResults } from "./testHelpers.mjs";
7
+
8
+ export default async function globalTeardown() {
9
+ console.log("\n🎬 Saving test results and dashcam URLs...");
10
+ saveTestResults();
11
+ }