testdriverai 7.0.0 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/AGENTS.md +550 -0
  2. package/CODEOWNERS +0 -1
  3. package/README.md +126 -0
  4. package/agent/index.js +43 -18
  5. package/agent/lib/commands.js +794 -135
  6. package/agent/lib/redraw.js +124 -39
  7. package/agent/lib/sandbox.js +10 -1
  8. package/agent/lib/sdk.js +21 -0
  9. package/docs/MIGRATION.md +425 -0
  10. package/docs/PRESETS.md +210 -0
  11. package/docs/docs.json +91 -37
  12. package/docs/guide/best-practices-polling.mdx +154 -0
  13. package/docs/v7/api/dashcam.mdx +497 -0
  14. package/docs/v7/api/doubleClick.mdx +102 -0
  15. package/docs/v7/api/mouseDown.mdx +161 -0
  16. package/docs/v7/api/mouseUp.mdx +164 -0
  17. package/docs/v7/api/rightClick.mdx +123 -0
  18. package/docs/v7/getting-started/configuration.mdx +380 -0
  19. package/docs/v7/getting-started/quickstart.mdx +273 -140
  20. package/docs/v7/guides/best-practices.mdx +486 -0
  21. package/docs/v7/guides/caching-ai.mdx +215 -0
  22. package/docs/v7/guides/caching-selectors.mdx +292 -0
  23. package/docs/v7/guides/caching.mdx +366 -0
  24. package/docs/v7/guides/ci-cd/azure.mdx +587 -0
  25. package/docs/v7/guides/ci-cd/circleci.mdx +523 -0
  26. package/docs/v7/guides/ci-cd/github-actions.mdx +457 -0
  27. package/docs/v7/guides/ci-cd/gitlab.mdx +498 -0
  28. package/docs/v7/guides/ci-cd/jenkins.mdx +664 -0
  29. package/docs/v7/guides/ci-cd/travis.mdx +438 -0
  30. package/docs/v7/guides/debugging.mdx +349 -0
  31. package/docs/v7/guides/faq.mdx +393 -0
  32. package/docs/v7/guides/performance.mdx +517 -0
  33. package/docs/v7/guides/troubleshooting.mdx +526 -0
  34. package/docs/v7/guides/vitest-plugin.mdx +477 -0
  35. package/docs/v7/guides/vitest.mdx +535 -0
  36. package/docs/v7/platforms/linux.mdx +308 -0
  37. package/docs/v7/platforms/macos.mdx +433 -0
  38. package/docs/v7/platforms/windows.mdx +430 -0
  39. package/docs/v7/presets/chrome-extension.mdx +223 -0
  40. package/docs/v7/presets/chrome.mdx +287 -0
  41. package/docs/v7/presets/electron.mdx +435 -0
  42. package/docs/v7/presets/vscode.mdx +398 -0
  43. package/docs/v7/presets/webapp.mdx +396 -0
  44. package/docs/v7/progressive-apis/CORE.md +459 -0
  45. package/docs/v7/progressive-apis/HOOKS.md +360 -0
  46. package/docs/v7/progressive-apis/PROGRESSIVE_DISCLOSURE.md +230 -0
  47. package/docs/v7/progressive-apis/PROVISION.md +266 -0
  48. package/interfaces/vitest-plugin.mjs +186 -100
  49. package/package.json +12 -1
  50. package/sdk.d.ts +335 -42
  51. package/sdk.js +756 -95
  52. package/src/core/Dashcam.js +469 -0
  53. package/src/core/index.d.ts +150 -0
  54. package/src/core/index.js +12 -0
  55. package/src/presets/index.mjs +331 -0
  56. package/src/vitest/extended.mjs +108 -0
  57. package/src/vitest/hooks.d.ts +119 -0
  58. package/src/vitest/hooks.mjs +298 -0
  59. package/src/vitest/index.mjs +64 -0
  60. package/src/vitest/lifecycle.mjs +277 -0
  61. package/src/vitest/utils.mjs +150 -0
  62. package/test/dashcam.test.js +137 -0
  63. package/testdriver/acceptance-sdk/assert.test.mjs +13 -31
  64. package/testdriver/acceptance-sdk/auto-cache-key-demo.test.mjs +56 -0
  65. package/testdriver/acceptance-sdk/chrome-extension.test.mjs +89 -0
  66. package/testdriver/acceptance-sdk/drag-and-drop.test.mjs +7 -19
  67. package/testdriver/acceptance-sdk/element-not-found.test.mjs +6 -19
  68. package/testdriver/acceptance-sdk/exec-js.test.mjs +6 -18
  69. package/testdriver/acceptance-sdk/exec-output.test.mjs +8 -20
  70. package/testdriver/acceptance-sdk/exec-pwsh.test.mjs +13 -25
  71. package/testdriver/acceptance-sdk/focus-window.test.mjs +8 -20
  72. package/testdriver/acceptance-sdk/formatted-logging.test.mjs +5 -20
  73. package/testdriver/acceptance-sdk/hooks-example.test.mjs +38 -0
  74. package/testdriver/acceptance-sdk/hover-image.test.mjs +10 -19
  75. package/testdriver/acceptance-sdk/hover-text-with-description.test.mjs +7 -19
  76. package/testdriver/acceptance-sdk/hover-text.test.mjs +5 -19
  77. package/testdriver/acceptance-sdk/match-image.test.mjs +7 -19
  78. package/testdriver/acceptance-sdk/presets-example.test.mjs +87 -0
  79. package/testdriver/acceptance-sdk/press-keys.test.mjs +5 -19
  80. package/testdriver/acceptance-sdk/prompt.test.mjs +6 -18
  81. package/testdriver/acceptance-sdk/scroll-keyboard.test.mjs +6 -20
  82. package/testdriver/acceptance-sdk/scroll-until-image.test.mjs +6 -18
  83. package/testdriver/acceptance-sdk/scroll-until-text.test.mjs +9 -23
  84. package/testdriver/acceptance-sdk/scroll.test.mjs +12 -21
  85. package/testdriver/acceptance-sdk/setup/testHelpers.mjs +124 -352
  86. package/testdriver/acceptance-sdk/sully-ai.test.mjs +234 -0
  87. package/testdriver/acceptance-sdk/test-console-logs.test.mjs +42 -0
  88. package/testdriver/acceptance-sdk/type.test.mjs +19 -58
  89. package/vitest.config.mjs +1 -0
  90. package/.vscode/mcp.json +0 -9
  91. package/MIGRATION.md +0 -389
  92. package/PLUGIN_MIGRATION.md +0 -222
  93. package/PROMPT_CACHE.md +0 -200
  94. package/SDK_LOGGING.md +0 -222
  95. package/SDK_MIGRATION.md +0 -474
  96. package/SDK_README.md +0 -1122
  97. package/debug-screenshot-1763401388589.png +0 -0
  98. package/examples/run-tests-with-recording.sh +0 -70
  99. package/examples/screenshot-example.js +0 -63
  100. package/examples/sdk-awesome-logs-demo.js +0 -177
  101. package/examples/sdk-cache-thresholds.js +0 -96
  102. package/examples/sdk-element-properties.js +0 -155
  103. package/examples/sdk-simple-example.js +0 -65
  104. package/examples/test-recording-example.test.js +0 -166
  105. package/mcp-server/AI_GUIDELINES.md +0 -57
  106. package/test-find-api.js +0 -73
  107. package/test-prompt-cache.js +0 -96
  108. package/test-sandbox-render.js +0 -28
  109. package/test-sdk-methods.js +0 -15
  110. package/test-sdk-refactor.js +0 -53
  111. package/test-stack-trace.mjs +0 -57
  112. package/testdriver/acceptance-sdk/setup/lifecycleHelpers.mjs +0 -239
@@ -3,29 +3,17 @@
3
3
  * Converted from: testdriver/acceptance/focus-window.yaml
4
4
  */
5
5
 
6
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
7
- import {
8
- createTestClient,
9
- setupTest,
10
- teardownTest,
11
- } from "./setup/testHelpers.mjs";
6
+ import { describe, expect, it } from "vitest";
7
+ import { TestDriver } from "../../src/vitest/hooks.mjs";
12
8
 
13
9
  describe("Focus Window 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.skipIf(() => testdriver.os === "linux")(
10
+ it.skipIf(process.env.TD_OS === "linux")(
27
11
  "should click Microsoft Edge icon and focus Google Chrome",
28
- async () => {
12
+ async (context) => {
13
+ const testdriver = TestDriver(context, { headless: true });
14
+ await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
15
+
16
+ //
29
17
  // Show desktop
30
18
  await testdriver.pressKeys(["winleft", "d"]);
31
19
 
@@ -3,28 +3,13 @@
3
3
  * Demonstrates nice Vitest-style formatted logs for Dashcam replay
4
4
  */
5
5
 
6
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
7
- import {
8
- createTestClient,
9
- setupTest,
10
- teardownTest,
11
- } from "./setup/testHelpers.mjs";
6
+ import { describe, expect, it } from "vitest";
7
+ import { TestDriver } from "../../src/vitest/hooks.mjs";
12
8
 
13
9
  describe("Formatted Logging 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 demonstrate formatted logs in dashcam replay", async () => {
27
- await testdriver.focusApplication("Google Chrome");
10
+ it("should demonstrate formatted logs in dashcam replay", async (context) => {
11
+ const testdriver = TestDriver(context, { headless: true });
12
+ await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
28
13
 
29
14
  // Find and click - logs will be nicely formatted
30
15
  const signInButton = await testdriver.find(
@@ -0,0 +1,38 @@
1
+ /**
2
+ * TestDriver Hooks API Demo
3
+ * Demonstrates the new React-style hooks for Vitest
4
+ *
5
+ * This is the SIMPLEST way to use TestDriver with Vitest!
6
+ */
7
+
8
+ import { describe, expect, it } from "vitest";
9
+ import { TestDriver } from "../../src/vitest/hooks.mjs";
10
+
11
+ describe("Hooks API Demo", () => {
12
+ it("should use hooks for automatic lifecycle management", async (context) => {
13
+ // ✨ One line gets you TestDriver + Dashcam with full auto-lifecycle!
14
+ const testdriver = TestDriver(context, { headless: true });
15
+ await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
16
+
17
+ // Everything is automatic:
18
+ // - Sandbox connection ✅
19
+ // - Dashcam recording ✅
20
+ // - Chrome launch ✅
21
+ // - Recording stop ✅
22
+ // - Cleanup ✅
23
+
24
+ await testdriver.focusApplication("Google Chrome");
25
+
26
+ const signInButton = await testdriver.find(
27
+ "Sign In, black button below the password field",
28
+ );
29
+ await signInButton.click();
30
+
31
+ const result = await testdriver.assert(
32
+ "an error shows that fields are required",
33
+ );
34
+ expect(result).toBeTruthy();
35
+
36
+ // That's it! Dashcam URL automatically registered with the test run
37
+ });
38
+ });
@@ -3,28 +3,19 @@
3
3
  * Converted from: testdriver/acceptance/hover-image.yaml
4
4
  */
5
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";
6
+ import { describe, expect, it } from "vitest";
7
+ import { TestDriver } from "../../src/vitest/hooks.mjs";
8
+ import { performLogin } from "./setup/testHelpers.mjs";
13
9
 
14
10
  describe("Hover Image Test", () => {
15
- let testdriver;
11
+ it("should click on shopping cart icon and verify empty cart", async (context) => {
12
+ const testdriver = TestDriver(context, { headless: true });
13
+
14
+ // provision.chrome() automatically calls ready() and starts dashcam
15
+ await testdriver.provision.chrome({
16
+ url: 'http://testdriver-sandbox.vercel.app/login',
17
+ });
16
18
 
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
19
  // Perform login first
29
20
  await performLogin(testdriver);
30
21
 
@@ -3,28 +3,16 @@
3
3
  * Converted from: testdriver/acceptance/hover-text-with-description.yaml
4
4
  */
5
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";
6
+ import { describe, expect, it } from "vitest";
7
+ import { TestDriver } from "../../src/vitest/hooks.mjs";
8
+ import { performLogin } from "./setup/testHelpers.mjs";
13
9
 
14
10
  describe("Hover Text With Description Test", () => {
15
- let testdriver;
11
+ it("should add TestDriver Hat to cart and verify", async (context) => {
12
+ const testdriver = TestDriver(context, { headless: true });
13
+ await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
16
14
 
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 () => {
15
+ //
28
16
  // Perform login first
29
17
  await performLogin(testdriver);
30
18
 
@@ -3,29 +3,15 @@
3
3
  * Converted from: testdriver/acceptance/hover-text.yaml
4
4
  */
5
5
 
6
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
7
- import {
8
- createTestClient,
9
- setupTest,
10
- teardownTest,
11
- } from "./setup/testHelpers.mjs";
6
+ import { describe, expect, it } from "vitest";
7
+ import { TestDriver } from "../../src/vitest/hooks.mjs";
12
8
 
13
9
  describe("Hover Text Test", () => {
14
- let testdriver;
10
+ it("should click Sign In and verify error message", async (context) => {
11
+ const testdriver = TestDriver(context, { headless: true, newSandbox: true, cacheKey: 'hover-text-test' });
12
+ await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
15
13
 
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
14
  // Click on Sign In button using new find() API
28
- await testdriver.focusApplication("Google Chrome");
29
15
 
30
16
  const signInButton = await testdriver.find(
31
17
  "Sign In, black button below the password field",
@@ -5,32 +5,20 @@
5
5
 
6
6
  import path, { dirname } from "path";
7
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";
8
+ import { describe, expect, it } from "vitest";
9
+ import { TestDriver } from "../../src/vitest/hooks.mjs";
10
+ import { performLogin } from "./setup/testHelpers.mjs";
15
11
 
16
12
  // Get the directory of the current module
17
13
  const __filename = fileURLToPath(import.meta.url);
18
14
  const __dirname = dirname(__filename);
19
15
 
20
16
  describe("Match Image Test", () => {
21
- let testdriver;
17
+ it("should match shopping cart image and verify empty cart", async (context) => {
18
+ const testdriver = TestDriver(context, { headless: true });
19
+ await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
22
20
 
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 () => {
21
+ //
34
22
  // Perform login first
35
23
  await performLogin(testdriver);
36
24
 
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Examples demonstrating TestDriver Presets
3
+ *
4
+ * Presets provide pre-configured setups for common applications,
5
+ * reducing boilerplate and making tests easier to write.
6
+ */
7
+
8
+ import { test } from 'vitest';
9
+ import { chromePreset, createPreset, electronPreset, vscodePreset } from '../../src/presets/index.mjs';
10
+
11
+ test('Chrome preset - simple navigation', async (context) => {
12
+ const { browser } = await chromePreset(context, {
13
+ url: 'http://testdriver-sandbox.vercel.app/',
14
+ });
15
+
16
+ // Browser is already open and focused on the URL
17
+ const result = await browser.find('main heading text');
18
+ console.log('Found heading:', result);
19
+ }, 60000);
20
+
21
+ test('Chrome preset - with custom options', async (context) => {
22
+ const { browser, dashcam } = await chromePreset(context, {
23
+ url: 'https://google.com',
24
+ maximized: false,
25
+ guest: false,
26
+ dashcam: true, // Dashcam auto-starts and auto-stops
27
+ });
28
+
29
+ await browser.find('search box').type('testdriverai');
30
+ console.log('Dashcam recording:', dashcam.isRecording());
31
+ }, 60000);
32
+
33
+ test.skip('VS Code preset - basic usage', async (context) => {
34
+ const { vscode } = await vscodePreset(context, {
35
+ workspace: '/tmp/test-project',
36
+ });
37
+
38
+ // VS Code is already open with the workspace loaded
39
+ await vscode.find('File menu').click();
40
+ await vscode.find('New File').click();
41
+ }, 60000);
42
+
43
+ test.skip('VS Code preset - with extensions', async (context) => {
44
+ const { vscode } = await vscodePreset(context, {
45
+ workspace: '/tmp/test-project',
46
+ extensions: ['ms-python.python'],
47
+ dashcam: true,
48
+ });
49
+
50
+ // Extensions are pre-installed, dashcam auto-recording
51
+ await vscode.find('Python extension').click();
52
+ }, 120000);
53
+
54
+ test.skip('Custom preset - Electron app', async (context) => {
55
+ const { app } = await electronPreset(context, {
56
+ appPath: '/path/to/electron/app',
57
+ args: ['--enable-logging'],
58
+ });
59
+
60
+ await app.find('main window').click();
61
+ }, 60000);
62
+
63
+ test.skip('Custom preset - create your own', async (context) => {
64
+ // Create a custom preset for your application
65
+ const firefoxPreset = createPreset({
66
+ name: 'Firefox Browser',
67
+ defaults: { os: 'linux', dashcam: true },
68
+ async setup(context, client, dashcam, options) {
69
+ const { url } = options;
70
+
71
+ // Launch Firefox
72
+ await client.exec('sh', `firefox "${url}" >/dev/null 2>&1 &`, 30000);
73
+ await client.focusApplication('Firefox');
74
+
75
+ return {
76
+ browser: client,
77
+ };
78
+ },
79
+ });
80
+
81
+ // Use your custom preset
82
+ const { browser } = await firefoxPreset(context, {
83
+ url: 'https://example.com',
84
+ });
85
+
86
+ await browser.find('page content').click();
87
+ }, 60000);
@@ -3,28 +3,14 @@
3
3
  * Converted from: testdriver/acceptance/press-keys.yaml
4
4
  */
5
5
 
6
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
7
- import {
8
- createTestClient,
9
- setupTest,
10
- teardownTest,
11
- } from "./setup/testHelpers.mjs";
6
+ import { describe, expect, it } from "vitest";
7
+ import { TestDriver } from "../../src/vitest/hooks.mjs";
12
8
 
13
9
  describe("Press Keys Test", () => {
14
- let testdriver;
10
+ it("should create tabs and navigate using keyboard shortcuts", async (context) => {
11
+ const testdriver = TestDriver(context, { headless: true });
12
+ await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
15
13
 
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
14
  const signInButton = await testdriver.find(
29
15
  "Sign In, black button below the password field",
30
16
  );
@@ -3,27 +3,15 @@
3
3
  * Converted from: testdriver/acceptance/prompt.yaml
4
4
  */
5
5
 
6
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
7
- import {
8
- createTestClient,
9
- setupTest,
10
- teardownTest,
11
- } from "./setup/testHelpers.mjs";
6
+ import { describe, expect, it } from "vitest";
7
+ import { TestDriver } from "../../src/vitest/hooks.mjs";
12
8
 
13
9
  describe.skip("Prompt Test", () => {
14
- let testdriver;
10
+ it("should execute AI-driven prompts", async (context) => {
11
+ const testdriver = TestDriver(context, { headless: true });
12
+ await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
15
13
 
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 () => {
14
+ //
27
15
  // Note: The SDK doesn't have a direct equivalent to YAML prompts without commands.
28
16
  // This would typically be handled by the AI agent interpreting natural language.
29
17
  // For SDK usage, you need to use explicit commands.
@@ -3,29 +3,15 @@
3
3
  * Converted from: testdriver/acceptance/scroll-keyboard.yaml
4
4
  */
5
5
 
6
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
7
- import {
8
- createTestClient,
9
- setupTest,
10
- teardownTest,
11
- } from "./setup/testHelpers.mjs";
6
+ import { describe, expect, it } from "vitest";
7
+ import { TestDriver } from "../../src/vitest/hooks.mjs";
12
8
 
13
9
  describe("Scroll Keyboard Test", () => {
14
- let testdriver;
10
+ it("should navigate to webhamster.com and scroll with keyboard", async (context) => {
11
+ const testdriver = TestDriver(context, { headless: true });
12
+ await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
15
13
 
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 () => {
14
+ //
29
15
  // Navigate to https://www.webhamster.com/
30
16
  await testdriver.focusApplication("Google Chrome");
31
17
  const urlBar = await testdriver.find(
@@ -3,27 +3,15 @@
3
3
  * Converted from: testdriver/acceptance/scroll-until-image.yaml
4
4
  */
5
5
 
6
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
7
- import {
8
- createTestClient,
9
- setupTest,
10
- teardownTest,
11
- } from "./setup/testHelpers.mjs";
6
+ import { describe, expect, it } from "vitest";
7
+ import { TestDriver } from "../../src/vitest/hooks.mjs";
12
8
 
13
9
  describe("Scroll Until Image Test", () => {
14
- let testdriver;
10
+ it("should scroll until brown colored house image appears", async (context) => {
11
+ const testdriver = TestDriver(context, { headless: true });
12
+ await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
15
13
 
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 () => {
14
+ //
27
15
  // Navigate to Wikipedia page
28
16
  await testdriver.pressKeys(["ctrl", "l"]);
29
17
  await testdriver.type("https://en.wikipedia.org/wiki/Leonardo_da_Vinci");
@@ -3,40 +3,26 @@
3
3
  * Converted from: testdriver/acceptance/scroll-until-text.yaml
4
4
  */
5
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";
6
+ import { describe, expect, it } from "vitest";
7
+ import { TestDriver } from "../../src/vitest/hooks.mjs";
8
+ import { performLogin } from "./setup/testHelpers.mjs";
13
9
 
14
10
  describe("Scroll Until Text Test", () => {
15
- let testdriver;
11
+ it('should scroll until "testdriver socks" appears', async (context) => {
12
+ const testdriver = TestDriver(context, { headless: true });
13
+ await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
16
14
 
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 () => {
15
+ //
28
16
  // Perform login first
29
17
  await performLogin(testdriver);
30
18
 
31
19
  // Scroll until text appears
32
20
  await testdriver.focusApplication("Google Chrome");
33
- await testdriver.scrollUntilText("testdriver socks", "down");
21
+ await testdriver.scrollUntilText({ text: "testdriver socks", direction: "down" });
34
22
 
35
23
  // Assert testdriver socks appears on screen
36
24
  await testdriver.focusApplication("Google Chrome");
37
- const result = await testdriver.assert(
38
- "TestDriver Socks appears on screen",
39
- );
25
+ const result = await testdriver.assert("TestDriver Socks appears on screen");
40
26
  expect(result).toBeTruthy();
41
27
  });
42
28
  });
@@ -1,33 +1,24 @@
1
1
  /**
2
2
  * TestDriver SDK - Scroll Test (Vitest)
3
3
  * Converted from: testdriver/acceptance/scroll.yaml
4
+ *
5
+ * UPDATED: Now using chrome preset for automatic setup
4
6
  */
5
7
 
6
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
7
- import {
8
- createTestClient,
9
- setupTest,
10
- teardownTest,
11
- } from "./setup/testHelpers.mjs";
8
+ import { describe, expect, it } from "vitest";
9
+ import { TestDriver } from "../../src/vitest/hooks.mjs";
12
10
 
13
11
  describe("Scroll Test", () => {
14
- let testdriver;
12
+ it("should navigate and scroll down the page", async (context) => {
13
+ const testdriver = TestDriver(context, { headless: true });
14
+ await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
15
15
 
16
- beforeEach(async (context) => {
17
- testdriver = createTestClient({ task: context.task });
16
+ // Give Chrome a moment to fully render the UI
17
+ await new Promise(resolve => setTimeout(resolve, 2000));
18
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");
19
+ // Navigate to webhamster.com - just look for the domain, not the full path
29
20
  const urlBar = await testdriver.find(
30
- "testdriver-sandbox.vercel.app/login, the URL in the omnibox showing the current page",
21
+ "testdriver-sandbox.vercel.app, the URL in the address bar",
31
22
  );
32
23
  await urlBar.click();
33
24
  await testdriver.pressKeys(["ctrl", "a"]);
@@ -44,7 +35,7 @@ describe("Scroll Test", () => {
44
35
  await testdriver.scroll("down", 1000);
45
36
 
46
37
  // Assert page is scrolled
47
- const result = await testdriver.assert("the page is scrolled down");
38
+ const result = await testdriver.assert("the page is scrolled down, the hamster dance heading is not visible on the page");
48
39
  expect(result).toBeTruthy();
49
40
  });
50
41
  });