testdriverai 7.9.43-test → 7.9.44-test

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.
@@ -54,33 +54,48 @@ const createSystem = (emitter, sandbox, config) => {
54
54
  };
55
55
 
56
56
  const screenshot = async (options) => {
57
- let response = await sandbox.send({
58
- type: "system.screenshot",
59
- });
57
+ const MAX_RETRIES = 3;
58
+ let lastError;
60
59
 
61
- let base64;
60
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
61
+ try {
62
+ let response = await sandbox.send({
63
+ type: "system.screenshot",
64
+ });
62
65
 
63
- // Runner returns { s3Key } for Ably (screenshots too large for 64KB limit)
64
- // Runner returns { base64 } for direct/local connections
65
- if (response.s3Key) {
66
- base64 = await downloadFromS3(response.s3Key);
67
- } else {
68
- base64 = response.base64;
69
- }
66
+ let base64;
70
67
 
71
- if (!base64) {
72
- throw new Error("Failed to take screenshot: sandbox returned empty data");
73
- }
74
-
75
- let image = Buffer.from(base64, "base64");
76
-
77
- // Verify we got actual image data (PNG header starts with these bytes)
78
- if (image.length < 100) {
79
- throw new Error(`Failed to take screenshot: received only ${image.length} bytes`);
68
+ // Runner returns { s3Key } for Ably (screenshots too large for 64KB limit)
69
+ // Runner returns { base64 } for direct/local connections
70
+ if (response.s3Key) {
71
+ base64 = await downloadFromS3(response.s3Key);
72
+ } else {
73
+ base64 = response.base64;
74
+ }
75
+
76
+ if (!base64) {
77
+ throw new Error("Failed to take screenshot: sandbox returned empty data");
78
+ }
79
+
80
+ let image = Buffer.from(base64, "base64");
81
+
82
+ // Verify we got actual image data (PNG header starts with these bytes)
83
+ if (image.length < 100) {
84
+ throw new Error(`Failed to take screenshot: received only ${image.length} bytes`);
85
+ }
86
+
87
+ fs.writeFileSync(options.filename, image);
88
+ return { filename: options.filename };
89
+ } catch (error) {
90
+ lastError = error;
91
+ if (attempt < MAX_RETRIES) {
92
+ const delay = 1000 * Math.pow(2, attempt);
93
+ await new Promise((resolve) => setTimeout(resolve, delay));
94
+ }
95
+ }
80
96
  }
81
-
82
- fs.writeFileSync(options.filename, image);
83
- return { filename: options.filename };
97
+
98
+ throw lastError;
84
99
  };
85
100
 
86
101
  let primaryDisplay = null;
@@ -21,6 +21,16 @@ const MANIFEST_PATH = path.join(__dirname, "../_data/examples-manifest.json");
21
21
  const OUTPUT_DIR = path.join(__dirname, "../v7/examples");
22
22
  const DOCS_JSON_PATH = path.join(__dirname, "../docs.json");
23
23
 
24
+ // Examples to exclude from docs generation (filenames without path)
25
+ const EXCLUDE_FROM_DOCS = [
26
+ "exec-output.test.mjs",
27
+ "exec-pwsh.test.mjs",
28
+ "focus-window.test.mjs",
29
+ "prompt.test.mjs",
30
+ "scroll-until-image.test.mjs",
31
+ "windows-installer.test.mjs",
32
+ ];
33
+
24
34
  // Icon mapping based on test type/content
25
35
  const ICON_MAP = {
26
36
  ai: "wand-magic-sparkles",
@@ -74,11 +84,11 @@ function saveDocsJson(docsJson) {
74
84
  fs.writeFileSync(DOCS_JSON_PATH, JSON.stringify(docsJson, null, 2) + "\n", "utf-8");
75
85
  }
76
86
 
77
- // Get all example files
87
+ // Get all example files (excluding ones in EXCLUDE_FROM_DOCS)
78
88
  function getExampleFiles() {
79
89
  return fs
80
90
  .readdirSync(EXAMPLES_DIR)
81
- .filter((f) => f.endsWith(".test.mjs"))
91
+ .filter((f) => f.endsWith(".test.mjs") && !EXCLUDE_FROM_DOCS.includes(f))
82
92
  .sort();
83
93
  }
84
94
 
package/docs/docs.json CHANGED
@@ -29,10 +29,7 @@
29
29
  "/v7/examples/assert",
30
30
  "/v7/examples/chrome-extension",
31
31
  "/v7/examples/element-not-found",
32
- "/v7/examples/exec-output",
33
- "/v7/examples/exec-pwsh",
34
32
  "/v7/examples/findall-coffee-icons",
35
- "/v7/examples/focus-window",
36
33
  "/v7/examples/hover-image",
37
34
  "/v7/examples/hover-text-with-description",
38
35
  "/v7/examples/hover-text",
@@ -40,12 +37,9 @@
40
37
  "/v7/examples/launch-vscode-linux",
41
38
  "/v7/examples/parse",
42
39
  "/v7/examples/press-keys",
43
- "/v7/examples/prompt",
44
40
  "/v7/examples/scroll-keyboard",
45
- "/v7/examples/scroll-until-image",
46
41
  "/v7/examples/scroll",
47
- "/v7/examples/type",
48
- "/v7/examples/windows-installer"
42
+ "/v7/examples/type"
49
43
  ]
50
44
  },
51
45
  {
@@ -1,5 +1,5 @@
1
1
  ---
2
- title: "FindAll"
2
+ title: "FindAll Test Example"
3
3
  sidebarTitle: "Findall Coffee Icons"
4
4
  description: "TestDriver SDK - FindAll Coffee Icons Test Loads a random icon grid and uses findAll() to locate and click all 4 coffee cup icons."
5
5
  icon: "play"
@@ -1,5 +1,5 @@
1
1
  ---
2
- title: "Hover Text With Description Test"
2
+ title: "Hover Text With Description Test Example"
3
3
  sidebarTitle: "Hover Text With Description"
4
4
  description: "TestDriver SDK - Hover Text With Description Test (Vitest) Converted from: testdriver/acceptance/hover-text-with-description.yaml."
5
5
  icon: "hand-pointer"
@@ -1,5 +1,5 @@
1
1
  ---
2
- title: "Launching VS Code Example"
2
+ title: "Launching VS Code Test Example"
3
3
  sidebarTitle: "Launch VS Code"
4
4
  description: "Example test demonstrating how to launch VS Code and install extensions on Linux."
5
5
  icon: "play"
@@ -1,8 +1,9 @@
1
1
  ---
2
- title: "Parse Test"
2
+ title: "Parse Test Example"
3
3
  sidebarTitle: "Parse"
4
4
  description: "TestDriver SDK - Parse Test (Vitest) Opens Airbnb and runs the .parse() SDK command to analyze the screen."
5
5
  icon: "play"
6
+ mode: "wide"
6
7
  ---
7
8
 
8
9
  ## Overview
@@ -1,5 +1,5 @@
1
1
  ---
2
- title: "Pressing Keys Test"
2
+ title: "Pressing Keys Test Example"
3
3
  sidebarTitle: "Pressing Keys"
4
4
  description: "Example test demonstrating keyboard shortcuts and key combinations for browser navigation."
5
5
  icon: "keyboard"
@@ -1,5 +1,5 @@
1
1
  ---
2
- title: "Scrolling with Keyboard Test"
2
+ title: "Scrolling with Keyboard Test Example"
3
3
  sidebarTitle: "Scrolling with Keyboard"
4
4
  description: "Example test demonstrating page scrolling using keyboard-based scroll controls."
5
5
  icon: "scroll"
@@ -1,5 +1,5 @@
1
1
  ---
2
- title: "Scroll Until Text Test"
2
+ title: "Scroll Until Text Test Example"
3
3
  sidebarTitle: "Scroll Until Text"
4
4
  description: "Example test demonstrating how to scroll a page until specific text becomes visible."
5
5
  icon: "scroll"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testdriverai",
3
- "version": "7.9.43-test",
3
+ "version": "7.9.44-test",
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",
@@ -1,84 +0,0 @@
1
- ---
2
- title: "Exec Output Test Example"
3
- sidebarTitle: "Exec Output"
4
- description: "Example test demonstrating how to capture and use output from PowerShell exec commands."
5
- icon: "terminal"
6
- mode: "wide"
7
- ---
8
-
9
- ## Demo Test Run
10
-
11
- Watch this test execute in a real sandbox environment:
12
-
13
- {/* exec-output.test.mjs output */}
14
- <iframe
15
- src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69d8456ad5b12767ca15e3cb/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="exec-output.test.mjs" {22-27}
25
- /**
26
- * TestDriver SDK - Exec Output Test (Vitest)
27
- * Converted from: testdriver/acceptance/exec-output.yaml
28
- */
29
-
30
- import { describe, expect, it } from "vitest";
31
- import { TestDriver } from "testdriverai/vitest/hooks";
32
-
33
- describe.skip("Exec Output Test", () => {
34
- it(
35
- "should set date using PowerShell and navigate to calendar",
36
- async (context) => {
37
- const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
38
- await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
39
-
40
- //
41
- // Generate date in query string format
42
- const queryString = await testdriver.exec(
43
- "pwsh",
44
- `
45
- $date = (Get-Date).AddMonths(1)
46
- Write-Output $date.ToString("yyyy-MM-dd")
47
- `,
48
- 10000,
49
- );
50
-
51
- // Assert that the date is valid
52
- const dateValidResult = await testdriver.assert(
53
- `${queryString} is a valid date`,
54
- );
55
- expect(dateValidResult).toBeTruthy();
56
-
57
- // Generate date in display format
58
- const expectedDate = await testdriver.exec(
59
- "pwsh",
60
- `
61
- $date = (Get-Date).AddMonths(1)
62
- Write-Output $date.ToString("ddd MMM d yyyy")
63
- `,
64
- 10000,
65
- );
66
-
67
- // Navigate to calendar with date parameter
68
- await testdriver.focusApplication("Google Chrome");
69
- await testdriver.pressKeys(["ctrl", "l"]);
70
- await testdriver.type(
71
- `https://teamup.com/ks48cf2135e7e080bc?view=d&date=${queryString}`,
72
- );
73
- await testdriver.pressKeys(["enter"]);
74
-
75
- // Assert that the expected date shows
76
- await testdriver.focusApplication("Google Chrome");
77
- const result = await testdriver.assert(
78
- `the text ${expectedDate} is visible on screen`,
79
- );
80
- expect(result).toBeTruthy();
81
- },
82
- );
83
- });
84
- ```
@@ -1,82 +0,0 @@
1
- ---
2
- title: "Exec PowerShell Test Example"
3
- sidebarTitle: "Exec Pwsh"
4
- description: "Example test demonstrating how to generate dynamic data using PowerShell and use it in test interactions."
5
- icon: "terminal"
6
- mode: "wide"
7
- ---
8
-
9
- ## Demo Test Run
10
-
11
- Watch this test execute in a real sandbox environment:
12
-
13
- {/* exec-pwsh.test.mjs output */}
14
- <iframe
15
- src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69d84560d5b12767ca15e3c6/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="exec-pwsh.test.mjs" {20-38}
25
- /**
26
- * TestDriver SDK - Exec Shell Test (Vitest)
27
- * Converted from: testdriver/acceptance/exec-shell.yaml
28
- */
29
-
30
- import { describe, expect, it } from "vitest";
31
- import { TestDriver } from "testdriverai/vitest/hooks";
32
-
33
- describe.skip("Exec PowerShell Test", () => {
34
- it(
35
- "should generate random email using PowerShell and enter it",
36
- async (context) => {
37
- const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
38
- await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
39
-
40
- //
41
- // Generate random email using PowerShell
42
- const randomEmail = await testdriver.exec({
43
- language: "pwsh",
44
- code: `
45
- # Random email generator in PowerShell
46
-
47
- # Arrays of possible names and domains
48
- $firstNames = @("john", "jane", "alex", "chris", "sara", "mike", "lisa", "david", "emma", "ryan")
49
- $lastNames = @("smith", "johnson", "williams", "brown", "jones", "garcia", "miller", "davis", "martin", "lee")
50
- $domains = @("example.com", "testmail.com", "mailinator.com", "demo.org", "company.net")
51
-
52
- # Random selection
53
- $first = Get-Random -InputObject $firstNames
54
- $last = Get-Random -InputObject $lastNames
55
- $domain = Get-Random -InputObject $domains
56
- $number = Get-Random -Minimum 1 -Maximum 1000
57
-
58
- # Generate the email
59
- $email = "$first.$last$number@$domain".ToLower()
60
-
61
- # Output
62
- Write-Output "$email"
63
- `,
64
- timeout: 10000,
65
- });
66
-
67
- // Enter the email in username field
68
- const usernameField = await testdriver.find(
69
- "Username, input field for username",
70
- );
71
- await usernameField.click();
72
- await testdriver.type(randomEmail);
73
-
74
- // Assert that the username field shows a valid email address
75
- const result = await testdriver.assert(
76
- `the username field contains ${randomEmail} which is a valid email address`,
77
- );
78
- expect(result).toBeTruthy();
79
- },
80
- );
81
- });
82
- ```
@@ -1,65 +0,0 @@
1
- ---
2
- title: "Exec Log Streaming"
3
- sidebarTitle: "Exec Stream Logs"
4
- description: "Example: should stream exec logs every second for 20 seconds"
5
- icon: "terminal"
6
- ---
7
-
8
- ## Overview
9
-
10
- This example demonstrates the "Exec Log Streaming" test suite. Specifically, it shows how to should stream exec logs every second for 20 seconds.
11
-
12
- Review the source code below to understand the implementation details and patterns used.
13
-
14
- ## Live Test Run
15
-
16
- <Note>
17
- A live test recording will be available after the next CI run.
18
- </Note>
19
-
20
- ## Source Code
21
-
22
- ```javascript title="exec-stream-logs.test.mjs"
23
- import { describe, expect, it } from "vitest";
24
- import { TestDriver } from "testdriverai/vitest/hooks";
25
-
26
- describe("Exec Log Streaming", () => {
27
- it("should stream exec logs every second for 20 seconds", async (context) => {
28
- const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
29
- await testdriver.provision.chrome({ url: "about:blank" });
30
-
31
- const code = `for i in $(seq 1 20); do echo "log line $i at $(date +%T)"; sleep 1; done`;
32
-
33
- const result = await testdriver.exec({
34
- language: "sh",
35
- code,
36
- timeout: 30000,
37
- });
38
-
39
- console.log("exec result:", result);
40
-
41
- // Verify we got all 20 log lines
42
- for (let i = 1; i <= 20; i++) {
43
- expect(result).toContain(`log line ${i}`);
44
- }
45
- });
46
- });
47
- ```
48
-
49
- ## Running This Example
50
-
51
- ```bash
52
- # Clone the TestDriver repository
53
- git clone https://github.com/testdriverai/testdriverai
54
-
55
- # Install dependencies
56
- cd testdriverai
57
- npm install
58
-
59
- # Run this specific example
60
- npx vitest run examples/exec-stream-logs.test.mjs
61
- ```
62
-
63
- <Note>
64
- Make sure you have `TD_API_KEY` set in your environment. Get one at [testdriver.ai](https://testdriver.ai).
65
- </Note>
@@ -1,61 +0,0 @@
1
- ---
2
- title: "Focus Window Test Example"
3
- sidebarTitle: "Focus Window"
4
- description: "Example test demonstrating how to switch focus between application windows."
5
- icon: "window-maximize"
6
- mode: "wide"
7
- ---
8
-
9
- ## Demo Test Run
10
-
11
- Watch this test execute in a real sandbox environment:
12
-
13
- {/* focus-window.test.mjs output */}
14
- <iframe
15
- src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69d84582d5b12767ca15e3d7/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="focus-window.test.mjs" {23-25}
25
- /**
26
- * TestDriver SDK - Focus Window Test (Vitest)
27
- * Converted from: testdriver/acceptance/focus-window.yaml
28
- */
29
-
30
- import { describe, expect, it } from "vitest";
31
- import { TestDriver } from "testdriverai/vitest/hooks";
32
-
33
- describe("Focus Window Test", () => {
34
- it.skip(
35
- "should click Microsoft Edge icon and focus Google Chrome",
36
- async (context) => {
37
- const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
38
- await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
39
-
40
- //
41
- // Show desktop
42
- await testdriver.pressKeys(["winleft", "d"]);
43
-
44
- // Click on the Microsoft Edge icon
45
- const edgeIcon = await testdriver.find(
46
- "a blue and green swirl icon on the taskbar representing Microsoft Edge",
47
- );
48
- await edgeIcon.click();
49
-
50
- // Focus Google Chrome
51
- await testdriver.focusApplication("Google Chrome");
52
-
53
- // Assert Chrome is focused (implicit through successful focus)
54
- const result = await testdriver.assert(
55
- "Google Chrome is the focused application",
56
- );
57
- expect(result).toBeTruthy();
58
- },
59
- );
60
- });
61
- ```
@@ -1,81 +0,0 @@
1
- ---
2
- title: "Prompt"
3
- sidebarTitle: "Prompt"
4
- description: "TestDriver SDK - Prompt Test (Vitest) Converted from: testdriver/acceptance/prompt.yaml."
5
- icon: "message"
6
- ---
7
-
8
- ## Overview
9
-
10
- TestDriver SDK - Prompt Test (Vitest) Converted from: testdriver/acceptance/prompt.yaml
11
-
12
- Review the source code below to understand the implementation details and patterns used.
13
-
14
- ## Live Test Run
15
-
16
- Watch this test execute in a real sandbox environment:
17
-
18
- {/* prompt.test.mjs output */}
19
- <iframe
20
- src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69d84580d5b12767ca15e3d6/replay"
21
- width="100%"
22
- height="600"
23
- style={{ border: "1px solid #333", borderRadius: "8px" }}
24
- allow="fullscreen"
25
- />
26
-
27
- ## Source Code
28
-
29
- ```javascript title="prompt.test.mjs"
30
- /**
31
- * TestDriver SDK - Prompt Test (Vitest)
32
- * Converted from: testdriver/acceptance/prompt.yaml
33
- */
34
-
35
- import { describe, expect, it } from "vitest";
36
- import { TestDriver } from "testdriverai/vitest/hooks";
37
-
38
- describe.skip("Prompt Test", () => {
39
- it("should execute AI-driven prompts", async (context) => {
40
- const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
41
- await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
42
-
43
- //
44
- // Note: The SDK doesn't have a direct equivalent to YAML prompts without commands.
45
- // This would typically be handled by the AI agent interpreting natural language.
46
- // For SDK usage, you need to use explicit commands.
47
-
48
- // Original prompts were:
49
- // 1. "log in"
50
- // 2. "add an item to the cart"
51
- // 3. "click on the cart icon"
52
- // 4. "complete checkout"
53
-
54
- // This test is skipped as it requires explicit SDK implementation
55
- // You would need to implement these as explicit SDK calls
56
-
57
- await testdriver.act("log in");
58
-
59
- const result = await testdriver.assert("the testdriver sandbox is visible");
60
- expect(result).toBeTruthy();
61
- });
62
- });
63
- ```
64
-
65
- ## Running This Example
66
-
67
- ```bash
68
- # Clone the TestDriver repository
69
- git clone https://github.com/testdriverai/testdriverai
70
-
71
- # Install dependencies
72
- cd testdriverai
73
- npm install
74
-
75
- # Run this specific example
76
- npx vitest run examples/prompt.test.mjs
77
- ```
78
-
79
- <Note>
80
- Make sure you have `TD_API_KEY` set in your environment. Get one at [testdriver.ai](https://testdriver.ai).
81
- </Note>
@@ -1,82 +0,0 @@
1
- ---
2
- title: "Scroll Until Image Test"
3
- sidebarTitle: "Scroll Until Image"
4
- description: "Example test demonstrating how to scroll a page until a specific image becomes visible."
5
- icon: "scroll"
6
- mode: "wide"
7
- ---
8
-
9
- ## Demo Test Run
10
-
11
- Watch this test execute in a real sandbox environment:
12
-
13
- {/* scroll-until-image.test.mjs output */}
14
- <iframe
15
- src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69d8457dd5b12767ca15e3d5/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="scroll-until-image.test.mjs" {26}
25
- /**
26
- * TestDriver SDK - Scroll Until Image Test (Vitest)
27
- * Converted from: testdriver/acceptance/scroll-until-image.yaml
28
- */
29
-
30
- import { describe, expect, it } from "vitest";
31
- import { TestDriver } from "testdriverai/vitest/hooks";
32
-
33
- describe("Scroll Until Image Test", () => {
34
- it.skip("should scroll until brown colored house image appears", async (context) => {
35
- const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
36
- await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
37
-
38
- //
39
- // Navigate to Wikipedia page
40
- await testdriver.pressKeys(["ctrl", "l"]);
41
- await testdriver.type("https://en.wikipedia.org/wiki/Leonardo_da_Vinci");
42
- await testdriver.pressKeys(["enter"]);
43
-
44
- // sleep for 5 seconds
45
- await new Promise((r) => setTimeout(r, 5000));
46
-
47
- // Click on heading
48
- const heading = await testdriver.find(
49
- "Leonardo Da Vinci, the page heading",
50
- 0,
51
- );
52
- await heading.click();
53
-
54
- // Scroll until image appears
55
- await testdriver.scrollUntilImage("a brown colored house", "down", 10000);
56
-
57
- // Assert image of brown colored house appears on screen
58
- const result = await testdriver.assert(
59
- "image of brown colored house appears on screen",
60
- );
61
- expect(result).toBeTruthy();
62
- });
63
- });
64
- ```
65
-
66
- ## Running This Example
67
-
68
- ```bash
69
- # Clone the TestDriver repository
70
- git clone https://github.com/testdriverai/testdriverai
71
-
72
- # Install dependencies
73
- cd testdriverai
74
- npm install
75
-
76
- # Run this specific example
77
- npx vitest run examples/scroll-until-image.test.mjs
78
- ```
79
-
80
- <Note>
81
- Make sure you have `TD_API_KEY` set in your environment. Get one at [testdriver.ai](https://testdriver.ai).
82
- </Note>
@@ -1,95 +0,0 @@
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://api-test.testdriver.ai/api/v1/testdriver/testcase/69d84568d5b12767ca15e3ca/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 (Vitest)
27
- *
28
- * This example demonstrates how to download and install a Windows application
29
- * using PowerShell commands, then launch and interact with it.
30
- *
31
- * Based on the v6 GitButler provisioning workflow.
32
- *
33
- * Run: TD_OS=windows vitest run examples/windows-installer.test.mjs
34
- */
35
-
36
- import { describe, it } from "vitest";
37
- import { TestDriver } from "testdriverai/vitest/hooks";
38
-
39
- const isLinux = (process.env.TD_OS || "linux") === "linux";
40
-
41
- describe("Windows App Installation", () => {
42
-
43
- it.skipIf(isLinux)("should download, install, and launch GitButler on Windows", async (context) => {
44
- // Alternative approach using provision.installer helper
45
- const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP,
46
- os: 'windows'
47
- });
48
-
49
- // Download the MSI installer
50
- const installerPath = await testdriver.provision.installer({
51
- url: 'https://app.gitbutler.com/downloads/release/windows/x86_64/msi',
52
- launch: false, // Don't auto-launch, we'll install manually
53
- });
54
-
55
- console.log('Installer downloaded to:', installerPath);
56
-
57
- // Install the MSI silently (the file might not have an extension, so we try MSI first)
58
- await testdriver.exec('pwsh',
59
- `Start-Process msiexec.exe -ArgumentList "/i \`"${installerPath}\`" /qn /norestart" -Wait`,
60
- 120000
61
- );
62
-
63
- // Verify installation by checking if executable exists
64
- const verifyScript = `
65
- $exePath = "C:\\Program Files\\GitButler\\gitbutler-tauri.exe"
66
- if (Test-Path $exePath) {
67
- Write-Host "GitButler installed successfully at $exePath"
68
- } else {
69
- Write-Error "GitButler not found"
70
- exit 1
71
- }
72
- `;
73
-
74
- await testdriver.exec('pwsh', verifyScript, 5000);
75
- });
76
- });
77
- ```
78
-
79
- ## Running This Example
80
-
81
- ```bash
82
- # Clone the TestDriver repository
83
- git clone https://github.com/testdriverai/testdriverai
84
-
85
- # Install dependencies
86
- cd testdriverai
87
- npm install
88
-
89
- # Run this specific example
90
- npx vitest run examples/windows-installer.test.mjs
91
- ```
92
-
93
- <Note>
94
- Make sure you have `TD_API_KEY` set in your environment. Get one at [testdriver.ai](https://testdriver.ai).
95
- </Note>