testdriverai 7.3.3 → 7.3.5

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 (32) hide show
  1. package/.github/workflows/acceptance-linux-scheduled.yaml +1 -1
  2. package/.github/workflows/acceptance.yaml +38 -1
  3. package/.github/workflows/windows-self-hosted.yaml +9 -1
  4. package/CHANGELOG.md +8 -0
  5. package/docs/_data/examples-manifest.json +105 -0
  6. package/docs/_data/examples-manifest.schema.json +41 -0
  7. package/docs/_scripts/extract-example-urls.js +165 -0
  8. package/docs/_scripts/generate-examples.js +534 -0
  9. package/docs/docs.json +242 -212
  10. package/docs/v7/aws-setup.mdx +1 -1
  11. package/docs/v7/examples/ai.mdx +72 -0
  12. package/docs/v7/examples/assert.mdx +72 -0
  13. package/docs/v7/examples/captcha-api.mdx +92 -0
  14. package/docs/v7/examples/chrome-extension.mdx +132 -0
  15. package/docs/v7/examples/drag-and-drop.mdx +100 -0
  16. package/docs/v7/examples/element-not-found.mdx +67 -0
  17. package/docs/v7/examples/hover-image.mdx +94 -0
  18. package/docs/v7/examples/hover-text.mdx +69 -0
  19. package/docs/v7/examples/installer.mdx +91 -0
  20. package/docs/v7/examples/launch-vscode-linux.mdx +101 -0
  21. package/docs/v7/examples/match-image.mdx +96 -0
  22. package/docs/v7/examples/press-keys.mdx +92 -0
  23. package/docs/v7/examples/scroll-keyboard.mdx +79 -0
  24. package/docs/v7/examples/scroll-until-image.mdx +81 -0
  25. package/docs/v7/examples/scroll-until-text.mdx +109 -0
  26. package/docs/v7/examples/scroll.mdx +81 -0
  27. package/docs/v7/examples/type.mdx +92 -0
  28. package/docs/v7/examples/windows-installer.mdx +89 -0
  29. package/interfaces/vitest-plugin.mjs +50 -18
  30. package/package.json +3 -1
  31. package/docs/v7/examples.mdx +0 -5
  32. package/jsconfig.json +0 -26
@@ -0,0 +1,92 @@
1
+ ---
2
+ title: "Typing Test Example"
3
+ sidebarTitle: "Typing"
4
+ description: "Example test demonstrating how to type text into input fields and verify the content."
5
+ icon: "keyboard"
6
+ mode: "wide"
7
+ ---
8
+
9
+ ## Demo Test Run
10
+
11
+ Watch this test execute in a real sandbox environment:
12
+
13
+ {/* type.test.mjs output */}
14
+ <iframe
15
+ src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/69852d10eae78746d7ac0c2e/replay"
16
+ width="100%"
17
+ height="390"
18
+ style={{ border: "1px solid #333", borderRadius: "8px" }}
19
+ allow="fullscreen"
20
+ />
21
+
22
+ ## Source Code
23
+
24
+ ```javascript title="type.test.mjs" {13}
25
+ /**
26
+ * TestDriver SDK - Type Test
27
+ */
28
+
29
+ import { describe, expect, it } from "vitest";
30
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
31
+
32
+ describe("Type Test", () => {
33
+ it("should enter standard_user in username field", async (context) => {
34
+ const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
35
+ await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
36
+
37
+ //
38
+ const usernameField = await testdriver.find(
39
+ "Username, input field for username",
40
+ );
41
+ await usernameField.click();
42
+ await testdriver.type("standard_user");
43
+
44
+ const result = await testdriver.assert(
45
+ 'the username field contains "standard_user"',
46
+ );
47
+ expect(result).toBeTruthy();
48
+ });
49
+
50
+ it("should show validation message when clicking Sign In without password", async (context) => {
51
+ const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
52
+ await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
53
+
54
+ // First fill in username
55
+ const usernameField = await testdriver.find(
56
+ "Username, input field for username",
57
+ );
58
+ await usernameField.click();
59
+ await testdriver.type("standard_user");
60
+
61
+ //
62
+ const signInButton = await testdriver.find(
63
+ "Sign in, black button below the password field",
64
+ );
65
+ await signInButton.click();
66
+
67
+ await testdriver.focusApplication("Google Chrome");
68
+ const result = await testdriver.assert(
69
+ "Please fill out this field is visible near the password field",
70
+ );
71
+ expect(result).toBeTruthy();
72
+ });
73
+ });
74
+ ```
75
+
76
+ ## Running This Example
77
+
78
+ ```bash
79
+ # Clone the TestDriver repository
80
+ git clone https://github.com/testdriverai/testdriverai
81
+
82
+ # Install dependencies
83
+ cd testdriverai
84
+ npm install
85
+
86
+ # Run this specific example
87
+ npx vitest run examples/type.test.mjs
88
+ ```
89
+
90
+ <Note>
91
+ Make sure you have `TD_API_KEY` set in your environment. Get one at [testdriver.ai](https://testdriver.ai).
92
+ </Note>
@@ -0,0 +1,89 @@
1
+ ---
2
+ title: "Windows App Installation"
3
+ sidebarTitle: "Windows Installer"
4
+ description: "Example test showing how to download and install Windows applications using MSI installers."
5
+ icon: "download"
6
+ mode: "wide"
7
+ ---
8
+
9
+ ## Demo Test Run
10
+
11
+ Watch this test execute in a real sandbox environment:
12
+
13
+ {/* windows-installer.test.mjs output */}
14
+ <iframe
15
+ src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/69852931eae78746d7ac0be6/replay"
16
+ width="100%"
17
+ height="390"
18
+ style={{ border: "1px solid #333", borderRadius: "8px" }}
19
+ allow="fullscreen"
20
+ />
21
+
22
+ ## Source Code
23
+
24
+ ```javascript title="windows-installer.test.mjs" {22-25}
25
+ /**
26
+ * TestDriver SDK - Windows Installer Example
27
+ */
28
+
29
+ import { describe, it } from "vitest";
30
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
31
+
32
+ const isLinux = (process.env.TD_OS || "linux") === "linux";
33
+
34
+ describe("Windows App Installation", () => {
35
+
36
+ it.skipIf(isLinux)("should download, install, and launch GitButler on Windows", async (context) => {
37
+ // Alternative approach using provision.installer helper
38
+ const testdriver = TestDriver(context, {
39
+ ip: context.ip || process.env.TD_IP,
40
+ os: 'windows'
41
+ });
42
+
43
+ // Download the MSI installer
44
+ const installerPath = await testdriver.provision.installer({
45
+ url: 'https://app.gitbutler.com/downloads/release/windows/x86_64/msi',
46
+ launch: false, // Don't auto-launch, we'll install manually
47
+ });
48
+
49
+ console.log('Installer downloaded to:', installerPath);
50
+
51
+ // Install the MSI silently (the file might not have an extension, so we try MSI first)
52
+ await testdriver.exec('pwsh',
53
+ `Start-Process msiexec.exe -ArgumentList "/i \`"${installerPath}\`" /qn /norestart" -Wait`,
54
+ 120000
55
+ );
56
+
57
+ // Verify installation by checking if executable exists
58
+ const verifyScript = `
59
+ $exePath = "C:\\Program Files\\GitButler\\gitbutler-tauri.exe"
60
+ if (Test-Path $exePath) {
61
+ Write-Host "GitButler installed successfully at $exePath"
62
+ } else {
63
+ Write-Error "GitButler not found"
64
+ exit 1
65
+ }
66
+ `;
67
+
68
+ await testdriver.exec('pwsh', verifyScript, 5000);
69
+ });
70
+ });
71
+ ```
72
+
73
+ ## Running This Example
74
+
75
+ ```bash
76
+ # Clone the TestDriver repository
77
+ git clone https://github.com/testdriverai/testdriverai
78
+
79
+ # Install dependencies
80
+ cd testdriverai
81
+ npm install
82
+
83
+ # Run this specific example
84
+ npx vitest run examples/windows-installer.test.mjs
85
+ ```
86
+
87
+ <Note>
88
+ Make sure you have `TD_API_KEY` set in your environment. Get one at [testdriver.ai](https://testdriver.ai).
89
+ </Note>
@@ -14,30 +14,54 @@ const require = createRequire(import.meta.url);
14
14
  */
15
15
  const MINIMUM_VITEST_VERSION = 4;
16
16
 
17
+ /**
18
+ * Try to read vitest's package.json version using multiple resolution strategies.
19
+ * Vitest's Vite-based transform pipeline can rewrite import.meta.url, causing
20
+ * createRequire to resolve from the wrong location. We fall back to resolving
21
+ * from process.cwd() and then to reading directly from node_modules.
22
+ * @returns {string|null} The vitest version string, or null if not found
23
+ */
24
+ function resolveVitestVersion() {
25
+ // Strategy 1: createRequire from import.meta.url (standard CJS interop)
26
+ try {
27
+ return require("vitest/package.json").version;
28
+ } catch {}
29
+
30
+ // Strategy 2: createRequire from process.cwd() (works when import.meta.url is rewritten)
31
+ try {
32
+ const cwdRequire = createRequire(path.join(process.cwd(), "package.json"));
33
+ return cwdRequire("vitest/package.json").version;
34
+ } catch {}
35
+
36
+ // Strategy 3: read directly from node_modules on disk
37
+ try {
38
+ const vitestPkgPath = path.join(process.cwd(), "node_modules", "vitest", "package.json");
39
+ return JSON.parse(fs.readFileSync(vitestPkgPath, "utf8")).version;
40
+ } catch {}
41
+
42
+ return null;
43
+ }
44
+
17
45
  /**
18
46
  * Check that Vitest version meets minimum requirements
19
47
  * @throws {Error} if Vitest version is below minimum or not installed
20
48
  */
21
49
  function checkVitestVersion() {
22
- try {
23
- const vitestPkg = require("vitest/package.json");
24
- const version = vitestPkg.version;
25
- const major = parseInt(version.split(".")[0], 10);
50
+ const version = resolveVitestVersion();
26
51
 
27
- if (major < MINIMUM_VITEST_VERSION) {
28
- throw new Error(
29
- `TestDriver requires Vitest >= ${MINIMUM_VITEST_VERSION}.0.0, but found ${version}. ` +
30
- `Please upgrade Vitest: npm install vitest@latest`,
31
- );
32
- }
33
- } catch (err) {
34
- if (err.code === "MODULE_NOT_FOUND") {
35
- throw new Error(
36
- "TestDriver requires Vitest to be installed. " +
37
- "Please install it: npm install vitest@latest",
38
- );
39
- }
40
- throw err;
52
+ if (!version) {
53
+ throw new Error(
54
+ "TestDriver requires Vitest to be installed. " +
55
+ "Please install it: npm install vitest@latest",
56
+ );
57
+ }
58
+
59
+ const major = parseInt(version.split(".")[0], 10);
60
+ if (major < MINIMUM_VITEST_VERSION) {
61
+ throw new Error(
62
+ `TestDriver requires Vitest >= ${MINIMUM_VITEST_VERSION}.0.0, but found ${version}. ` +
63
+ `Please upgrade Vitest: npm install vitest@latest`,
64
+ );
41
65
  }
42
66
  }
43
67
 
@@ -1013,6 +1037,14 @@ class TestDriverReporter {
1013
1037
  console.log(
1014
1038
  `🔗 Test Report: ${getConsoleUrl(pluginState.apiRoot)}/runs/${testRunDbId}/${testCaseDbId}`,
1015
1039
  );
1040
+
1041
+ // Output parseable format for docs generation (examples only)
1042
+ if (testFile.startsWith("examples/")) {
1043
+ const testFileName = path.basename(testFile);
1044
+ console.log(
1045
+ `TESTDRIVER_EXAMPLE_URL::${testFileName}::${getConsoleUrl(pluginState.apiRoot)}/runs/${testRunDbId}/${testCaseDbId}`,
1046
+ );
1047
+ }
1016
1048
  } catch (error) {
1017
1049
  logger.error("Failed to report test case:", error.message);
1018
1050
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testdriverai",
3
- "version": "7.3.3",
3
+ "version": "7.3.5",
4
4
  "description": "Next generation autonomous AI agent for end-to-end testing of web & desktop",
5
5
  "main": "sdk.js",
6
6
  "types": "sdk.d.ts",
@@ -42,6 +42,8 @@
42
42
  "docs:build": "npm run docs:skills && cd docs && npx mint@latest build",
43
43
  "docs:links": "node docs/_scripts/link-replacer.js",
44
44
  "docs:skills": "node docs/_scripts/generate-skills.js",
45
+ "docs:examples": "node docs/_scripts/generate-examples.js",
46
+ "docs:extract-urls": "node docs/_scripts/extract-example-urls.js",
45
47
  "bundle": "node build.mjs",
46
48
  "test": "mocha test/*",
47
49
  "test:sdk": "vitest run",
@@ -1,5 +0,0 @@
1
- ---
2
- title: "Examples"
3
- url: "https://github.com/testdriverai/testdriverai/tree/main/examples"
4
- icon: 'code'
5
- ---
package/jsconfig.json DELETED
@@ -1,26 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "module": "ESNext",
4
- "moduleResolution": "bundler",
5
- "target": "ES2022",
6
- "checkJs": true,
7
- "strict": false,
8
- "allowSyntheticDefaultImports": true,
9
- "esModuleInterop": true,
10
- "baseUrl": ".",
11
- "typeRoots": ["."]
12
- },
13
- "include": [
14
- "**/*.js",
15
- "**/*.mjs",
16
- "**/*.d.ts",
17
- "sdk.d.ts",
18
- "lib/**/*.d.ts",
19
- "interfaces/**/*.d.ts"
20
- ],
21
- "exclude": [
22
- "node_modules",
23
- "dist",
24
- "build"
25
- ]
26
- }