testdriverai 7.9.56-test → 7.9.57-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.
- package/docs/_data/examples-manifest.json +42 -42
- package/docs/v7/examples/ai.mdx +1 -1
- package/docs/v7/examples/assert.mdx +1 -1
- package/docs/v7/examples/chrome-extension.mdx +1 -1
- package/docs/v7/examples/element-not-found.mdx +1 -1
- package/docs/v7/examples/findall-coffee-icons.mdx +1 -1
- package/docs/v7/examples/hover-image.mdx +1 -1
- package/docs/v7/examples/hover-text-with-description.mdx +1 -1
- package/docs/v7/examples/hover-text.mdx +1 -1
- package/docs/v7/examples/installer.mdx +1 -1
- package/docs/v7/examples/launch-vscode-linux.mdx +1 -1
- package/docs/v7/examples/parse.mdx +1 -1
- package/docs/v7/examples/press-keys.mdx +1 -1
- package/docs/v7/examples/scroll-keyboard.mdx +1 -1
- package/docs/v7/examples/scroll.mdx +1 -1
- package/docs/v7/examples/type.mdx +1 -1
- package/interfaces/vitest-plugin.mjs +7 -1
- package/lib/vitest/hooks.mjs +11 -0
- package/mcp-server/dist/env-utils.d.ts +45 -0
- package/mcp-server/dist/env-utils.js +63 -0
- package/mcp-server/dist/provision-types.d.ts +6 -2
- package/mcp-server/dist/provision-types.js +3 -1
- package/mcp-server/dist/server.mjs +20 -3
- package/mcp-server/package-lock.json +384 -1
- package/mcp-server/package.json +4 -2
- package/mcp-server/src/env-utils.test.ts +82 -0
- package/mcp-server/src/env-utils.ts +77 -0
- package/mcp-server/src/provision-types.ts +4 -1
- package/mcp-server/src/server.ts +22 -3
- package/mcp-server/tsconfig.json +1 -1
- package/mcp-server/vitest.config.ts +7 -0
- package/package.json +1 -1
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
"$schema": "./examples-manifest.schema.json",
|
|
3
3
|
"examples": {
|
|
4
4
|
"assert.test.mjs": {
|
|
5
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
6
|
-
"lastUpdated": "2026-04-
|
|
5
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a6d87a2d41022ee5b1e2",
|
|
6
|
+
"lastUpdated": "2026-04-30T01:19:25.897Z"
|
|
7
7
|
},
|
|
8
8
|
"drag-and-drop.test.mjs": {
|
|
9
9
|
"url": "https://console.testdriver.ai/runs/69a62b3aaa712ecd3dea730a/69a62b42fc0ac3cc632a918b",
|
|
10
10
|
"lastUpdated": "2026-03-03T00:32:25.275Z"
|
|
11
11
|
},
|
|
12
12
|
"exec-pwsh.test.mjs": {
|
|
13
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
14
|
-
"lastUpdated": "2026-04-
|
|
13
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a5ef7a2d41022ee5b1bc",
|
|
14
|
+
"lastUpdated": "2026-04-30T00:58:41.912Z"
|
|
15
15
|
},
|
|
16
16
|
"match-image.test.mjs": {
|
|
17
17
|
"url": "https://console-test.testdriver.ai/runs/69c8738614b73310c7839412/69c8738c14b73310c783941d",
|
|
@@ -22,84 +22,84 @@
|
|
|
22
22
|
"lastUpdated": "2026-03-03T00:32:25.282Z"
|
|
23
23
|
},
|
|
24
24
|
"hover-text-with-description.test.mjs": {
|
|
25
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
26
|
-
"lastUpdated": "2026-04-
|
|
25
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a6077a2d41022ee5b1c3",
|
|
26
|
+
"lastUpdated": "2026-04-30T00:44:55.391Z"
|
|
27
27
|
},
|
|
28
28
|
"windows-installer.test.mjs": {
|
|
29
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
30
|
-
"lastUpdated": "2026-04-
|
|
29
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a6367a2d41022ee5b1d2",
|
|
30
|
+
"lastUpdated": "2026-04-30T00:59:51.732Z"
|
|
31
31
|
},
|
|
32
32
|
"exec-output.test.mjs": {
|
|
33
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
34
|
-
"lastUpdated": "2026-04-
|
|
33
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a6377a2d41022ee5b1d3",
|
|
34
|
+
"lastUpdated": "2026-04-30T00:59:53.210Z"
|
|
35
35
|
},
|
|
36
36
|
"chrome-extension.test.mjs": {
|
|
37
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
38
|
-
"lastUpdated": "2026-04-
|
|
37
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a5ed7a2d41022ee5b1ba",
|
|
38
|
+
"lastUpdated": "2026-04-30T00:51:39.144Z"
|
|
39
39
|
},
|
|
40
40
|
"launch-vscode-linux.test.mjs": {
|
|
41
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
42
|
-
"lastUpdated": "2026-04-
|
|
41
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a62a7a2d41022ee5b1cb",
|
|
42
|
+
"lastUpdated": "2026-04-30T01:10:15.313Z"
|
|
43
43
|
},
|
|
44
44
|
"hover-image.test.mjs": {
|
|
45
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
46
|
-
"lastUpdated": "2026-04-
|
|
45
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a6507a2d41022ee5b1d8",
|
|
46
|
+
"lastUpdated": "2026-04-30T00:53:17.284Z"
|
|
47
47
|
},
|
|
48
48
|
"installer.test.mjs": {
|
|
49
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
50
|
-
"lastUpdated": "2026-04-
|
|
49
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a6717a2d41022ee5b1dd",
|
|
50
|
+
"lastUpdated": "2026-04-30T00:46:31.574Z"
|
|
51
51
|
},
|
|
52
52
|
"type.test.mjs": {
|
|
53
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
54
|
-
"lastUpdated": "2026-04-
|
|
53
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a6a77a2d41022ee5b1e0",
|
|
54
|
+
"lastUpdated": "2026-04-30T00:54:49.081Z"
|
|
55
55
|
},
|
|
56
56
|
"press-keys.test.mjs": {
|
|
57
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
58
|
-
"lastUpdated": "2026-04-
|
|
57
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a6c07a2d41022ee5b1e1",
|
|
58
|
+
"lastUpdated": "2026-04-30T01:18:20.140Z"
|
|
59
59
|
},
|
|
60
60
|
"scroll-keyboard.test.mjs": {
|
|
61
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
62
|
-
"lastUpdated": "2026-04-
|
|
61
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a7097a2d41022ee5b1e4",
|
|
62
|
+
"lastUpdated": "2026-04-30T01:03:12.683Z"
|
|
63
63
|
},
|
|
64
64
|
"scroll.test.mjs": {
|
|
65
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
66
|
-
"lastUpdated": "2026-04-
|
|
65
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a7257a2d41022ee5b1e8",
|
|
66
|
+
"lastUpdated": "2026-04-30T01:24:19.091Z"
|
|
67
67
|
},
|
|
68
68
|
"scroll-until-image.test.mjs": {
|
|
69
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
70
|
-
"lastUpdated": "2026-04-
|
|
69
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a70a7a2d41022ee5b1e5",
|
|
70
|
+
"lastUpdated": "2026-04-30T00:49:14.652Z"
|
|
71
71
|
},
|
|
72
72
|
"prompt.test.mjs": {
|
|
73
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
74
|
-
"lastUpdated": "2026-04-
|
|
73
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a70c7a2d41022ee5b1e6",
|
|
74
|
+
"lastUpdated": "2026-04-30T01:03:15.901Z"
|
|
75
75
|
},
|
|
76
76
|
"focus-window.test.mjs": {
|
|
77
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
78
|
-
"lastUpdated": "2026-04-
|
|
77
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a70d7a2d41022ee5b1e7",
|
|
78
|
+
"lastUpdated": "2026-04-30T00:49:17.532Z"
|
|
79
79
|
},
|
|
80
80
|
"captcha-api.test.mjs": {
|
|
81
81
|
"url": "https://console.testdriver.ai/runs/698f7df69e27ce1528d7d087/698f7fb0d3b320ad547d9d44",
|
|
82
82
|
"lastUpdated": "2026-02-13T19:55:05.951Z"
|
|
83
83
|
},
|
|
84
84
|
"element-not-found.test.mjs": {
|
|
85
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
86
|
-
"lastUpdated": "2026-04-
|
|
85
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a73d7a2d41022ee5b1e9",
|
|
86
|
+
"lastUpdated": "2026-04-30T01:04:02.664Z"
|
|
87
87
|
},
|
|
88
88
|
"formatted-logging.test.mjs": {
|
|
89
89
|
"url": "https://console-test.testdriver.ai/runs/69c8738614b73310c7839412/69c873a714b73310c7839450",
|
|
90
90
|
"lastUpdated": "2026-03-29T00:36:10.628Z"
|
|
91
91
|
},
|
|
92
92
|
"hover-text.test.mjs": {
|
|
93
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
94
|
-
"lastUpdated": "2026-04-
|
|
93
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a76b7a2d41022ee5b1eb",
|
|
94
|
+
"lastUpdated": "2026-04-30T00:50:51.700Z"
|
|
95
95
|
},
|
|
96
96
|
"no-provision.test.mjs": {
|
|
97
97
|
"url": "https://console.testdriver.ai/runs/69a62b3aaa712ecd3dea730a/69a62b7706a177a05bccd1cf",
|
|
98
98
|
"lastUpdated": "2026-03-03T00:32:25.279Z"
|
|
99
99
|
},
|
|
100
100
|
"ai.test.mjs": {
|
|
101
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
102
|
-
"lastUpdated": "2026-04-
|
|
101
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a7537a2d41022ee5b1ea",
|
|
102
|
+
"lastUpdated": "2026-04-30T01:27:43.771Z"
|
|
103
103
|
},
|
|
104
104
|
"popup-loading.test.mjs": {
|
|
105
105
|
"url": "https://console.testdriver.ai/runs/698bc89f7140c3fa7daaca8d/698bca7f7140c3fa7daacbf7",
|
|
@@ -134,12 +134,12 @@
|
|
|
134
134
|
"lastUpdated": "2026-02-13T19:55:05.953Z"
|
|
135
135
|
},
|
|
136
136
|
"findall-coffee-icons.test.mjs": {
|
|
137
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
138
|
-
"lastUpdated": "2026-04-
|
|
137
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a6f07a2d41022ee5b1e3",
|
|
138
|
+
"lastUpdated": "2026-04-30T00:55:57.472Z"
|
|
139
139
|
},
|
|
140
140
|
"parse.test.mjs": {
|
|
141
|
-
"url": "https://console-test.testdriver.ai/runs/
|
|
142
|
-
"lastUpdated": "2026-04-
|
|
141
|
+
"url": "https://console-test.testdriver.ai/runs/69f2a5d47a2d41022ee5b19e/69f2a7837a2d41022ee5b1ec",
|
|
142
|
+
"lastUpdated": "2026-04-30T01:05:14.790Z"
|
|
143
143
|
},
|
|
144
144
|
"flake-diffthreshold-001.test.mjs": {
|
|
145
145
|
"url": "https://console.testdriver.ai/runs/69a62b3aaa712ecd3dea730a/69a62bcafc0ac3cc632a91aa",
|
package/docs/v7/examples/ai.mdx
CHANGED
|
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
|
|
|
12
12
|
|
|
13
13
|
{/* ai.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
|
-
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69f2a7537a2d41022ee5b1ea/replay"
|
|
16
16
|
width="100%"
|
|
17
17
|
height="390"
|
|
18
18
|
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
|
|
|
12
12
|
|
|
13
13
|
{/* assert.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
|
-
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69f2a6d87a2d41022ee5b1e2/replay"
|
|
16
16
|
width="100%"
|
|
17
17
|
height="390"
|
|
18
18
|
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
|
|
|
12
12
|
|
|
13
13
|
{/* chrome-extension.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
|
-
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69f2a5ed7a2d41022ee5b1ba/replay"
|
|
16
16
|
width="100%"
|
|
17
17
|
height="390"
|
|
18
18
|
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
|
|
|
12
12
|
|
|
13
13
|
{/* element-not-found.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
|
-
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69f2a73d7a2d41022ee5b1e9/replay"
|
|
16
16
|
width="100%"
|
|
17
17
|
height="390"
|
|
18
18
|
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
@@ -18,7 +18,7 @@ Watch this test execute in a real sandbox environment:
|
|
|
18
18
|
|
|
19
19
|
{/* findall-coffee-icons.test.mjs output */}
|
|
20
20
|
<iframe
|
|
21
|
-
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/
|
|
21
|
+
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69f2a6f07a2d41022ee5b1e3/replay"
|
|
22
22
|
width="100%"
|
|
23
23
|
height="600"
|
|
24
24
|
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
|
|
|
12
12
|
|
|
13
13
|
{/* hover-image.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
|
-
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69f2a6507a2d41022ee5b1d8/replay"
|
|
16
16
|
width="100%"
|
|
17
17
|
height="390"
|
|
18
18
|
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
@@ -18,7 +18,7 @@ Watch this test execute in a real sandbox environment:
|
|
|
18
18
|
|
|
19
19
|
{/* hover-text-with-description.test.mjs output */}
|
|
20
20
|
<iframe
|
|
21
|
-
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/
|
|
21
|
+
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69f2a6077a2d41022ee5b1c3/replay"
|
|
22
22
|
width="100%"
|
|
23
23
|
height="600"
|
|
24
24
|
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
|
|
|
12
12
|
|
|
13
13
|
{/* hover-text.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
|
-
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69f2a76b7a2d41022ee5b1eb/replay"
|
|
16
16
|
width="100%"
|
|
17
17
|
height="390"
|
|
18
18
|
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
|
|
|
12
12
|
|
|
13
13
|
{/* installer.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
|
-
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69f2a6717a2d41022ee5b1dd/replay"
|
|
16
16
|
width="100%"
|
|
17
17
|
height="390"
|
|
18
18
|
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
|
|
|
12
12
|
|
|
13
13
|
{/* launch-vscode-linux.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
|
-
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69f2a62a7a2d41022ee5b1cb/replay"
|
|
16
16
|
width="100%"
|
|
17
17
|
height="390"
|
|
18
18
|
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
@@ -18,7 +18,7 @@ Watch this test execute in a real sandbox environment:
|
|
|
18
18
|
|
|
19
19
|
{/* parse.test.mjs output */}
|
|
20
20
|
<iframe
|
|
21
|
-
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/
|
|
21
|
+
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69f2a7837a2d41022ee5b1ec/replay"
|
|
22
22
|
width="100%"
|
|
23
23
|
height="600"
|
|
24
24
|
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
|
|
|
12
12
|
|
|
13
13
|
{/* press-keys.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
|
-
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69f2a6c07a2d41022ee5b1e1/replay"
|
|
16
16
|
width="100%"
|
|
17
17
|
height="390"
|
|
18
18
|
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
|
|
|
12
12
|
|
|
13
13
|
{/* scroll-keyboard.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
|
-
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69f2a7097a2d41022ee5b1e4/replay"
|
|
16
16
|
width="100%"
|
|
17
17
|
height="390"
|
|
18
18
|
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
|
|
|
12
12
|
|
|
13
13
|
{/* scroll.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
|
-
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69f2a7257a2d41022ee5b1e8/replay"
|
|
16
16
|
width="100%"
|
|
17
17
|
height="390"
|
|
18
18
|
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
|
|
|
12
12
|
|
|
13
13
|
{/* type.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
|
-
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69f2a6a77a2d41022ee5b1e0/replay"
|
|
16
16
|
width="100%"
|
|
17
17
|
height="390"
|
|
18
18
|
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
@@ -1187,7 +1187,13 @@ class TestDriverReporter {
|
|
|
1187
1187
|
// Include per-attempt replay URLs for retry visibility
|
|
1188
1188
|
if (dashcamUrls.length > 0) {
|
|
1189
1189
|
const attemptUrls = dashcamUrls
|
|
1190
|
-
.map(a => ({
|
|
1190
|
+
.map(a => ({
|
|
1191
|
+
attempt: a.attempt,
|
|
1192
|
+
url: a.url || null,
|
|
1193
|
+
sessionId: a.sessionId || null,
|
|
1194
|
+
errorMessage: a.errorMessage || null,
|
|
1195
|
+
errorStack: a.errorStack || null,
|
|
1196
|
+
}));
|
|
1191
1197
|
testCaseData.replayUrls = attemptUrls;
|
|
1192
1198
|
}
|
|
1193
1199
|
|
package/lib/vitest/hooks.mjs
CHANGED
|
@@ -597,6 +597,11 @@ export function TestDriver(context, options = {}) {
|
|
|
597
597
|
const isRetry = attemptNumber > 1;
|
|
598
598
|
const attemptLabel = isRetry ? ` (attempt ${attemptNumber})` : "";
|
|
599
599
|
|
|
600
|
+
// Capture the current attempt's test error (before retry resets result)
|
|
601
|
+
const attemptResult = context.task.result?.errors?.[0];
|
|
602
|
+
const attemptErrorMessage = attemptResult?.message || null;
|
|
603
|
+
const attemptErrorStack = attemptResult?.stack || null;
|
|
604
|
+
|
|
600
605
|
// Stop dashcam if it was started - with timeout to prevent hanging
|
|
601
606
|
if (currentInstance._dashcam && currentInstance._dashcam.recording) {
|
|
602
607
|
try {
|
|
@@ -607,6 +612,8 @@ export function TestDriver(context, options = {}) {
|
|
|
607
612
|
attempt: attemptNumber,
|
|
608
613
|
url: dashcamUrl || null,
|
|
609
614
|
sessionId: currentInstance.getSessionId?.() || null,
|
|
615
|
+
errorMessage: attemptErrorMessage,
|
|
616
|
+
errorStack: attemptErrorStack,
|
|
610
617
|
});
|
|
611
618
|
|
|
612
619
|
// Keep backward compatibility - last attempt's URL
|
|
@@ -660,6 +667,8 @@ export function TestDriver(context, options = {}) {
|
|
|
660
667
|
url: null,
|
|
661
668
|
sessionId: currentInstance.getSessionId?.() || null,
|
|
662
669
|
error: error.message,
|
|
670
|
+
errorMessage: attemptErrorMessage,
|
|
671
|
+
errorStack: attemptErrorStack,
|
|
663
672
|
});
|
|
664
673
|
// Ensure dashcamUrl is set to null if stop failed
|
|
665
674
|
context.task.meta.dashcamUrl = null;
|
|
@@ -670,6 +679,8 @@ export function TestDriver(context, options = {}) {
|
|
|
670
679
|
attempt: attemptNumber,
|
|
671
680
|
url: null,
|
|
672
681
|
sessionId: currentInstance.getSessionId?.() || null,
|
|
682
|
+
errorMessage: attemptErrorMessage,
|
|
683
|
+
errorStack: attemptErrorStack,
|
|
673
684
|
});
|
|
674
685
|
context.task.meta.dashcamUrl = null;
|
|
675
686
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for resolving TestDriver environment variables.
|
|
3
|
+
*
|
|
4
|
+
* These helpers centralise the "param > env var > default" fallback logic
|
|
5
|
+
* so the server handler stays clean and the logic can be unit-tested
|
|
6
|
+
* independently.
|
|
7
|
+
*/
|
|
8
|
+
declare const VALID_OS_VALUES: readonly ["linux", "windows"];
|
|
9
|
+
export type SandboxOs = (typeof VALID_OS_VALUES)[number];
|
|
10
|
+
/**
|
|
11
|
+
* Resolve the sandbox OS with the following priority:
|
|
12
|
+
* 1. Explicit `os` parameter passed to session_start
|
|
13
|
+
* 2. `TD_OS` environment variable (validated against supported values)
|
|
14
|
+
* 3. `"linux"` default
|
|
15
|
+
*
|
|
16
|
+
* Mirrors the behaviour in `hooks.mjs` so the MCP server and the
|
|
17
|
+
* Vitest integration are consistent.
|
|
18
|
+
*
|
|
19
|
+
* @param explicitOs - The value passed explicitly by the caller (may be undefined)
|
|
20
|
+
* @param env - The environment variables map (defaults to `process.env`)
|
|
21
|
+
* @returns - The resolved OS and a warning message if TD_OS was invalid
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveOs(explicitOs: SandboxOs | undefined, env?: NodeJS.ProcessEnv): {
|
|
24
|
+
os: SandboxOs;
|
|
25
|
+
warning?: string;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Resolve the E2B template ID with the following priority:
|
|
29
|
+
* 1. Explicit `e2bTemplateId` parameter passed to session_start
|
|
30
|
+
* 2. `TD_E2B_TEMPLATE_ID` environment variable
|
|
31
|
+
* 3. `undefined` (let the SDK use its own default)
|
|
32
|
+
*
|
|
33
|
+
* Mirrors the behaviour in `hooks.mjs`:
|
|
34
|
+
* ```js
|
|
35
|
+
* if (!config.e2bTemplateId && process.env.TD_E2B_TEMPLATE_ID) {
|
|
36
|
+
* config.e2bTemplateId = process.env.TD_E2B_TEMPLATE_ID;
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @param explicitId - The value passed explicitly by the caller (may be undefined)
|
|
41
|
+
* @param env - The environment variables map (defaults to `process.env`)
|
|
42
|
+
* @returns - The resolved template ID, or undefined if none is set
|
|
43
|
+
*/
|
|
44
|
+
export declare function resolveE2bTemplateId(explicitId: string | undefined, env?: NodeJS.ProcessEnv): string | undefined;
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for resolving TestDriver environment variables.
|
|
3
|
+
*
|
|
4
|
+
* These helpers centralise the "param > env var > default" fallback logic
|
|
5
|
+
* so the server handler stays clean and the logic can be unit-tested
|
|
6
|
+
* independently.
|
|
7
|
+
*/
|
|
8
|
+
// ============================================================
|
|
9
|
+
// OS resolution
|
|
10
|
+
// ============================================================
|
|
11
|
+
const VALID_OS_VALUES = ["linux", "windows"];
|
|
12
|
+
/**
|
|
13
|
+
* Resolve the sandbox OS with the following priority:
|
|
14
|
+
* 1. Explicit `os` parameter passed to session_start
|
|
15
|
+
* 2. `TD_OS` environment variable (validated against supported values)
|
|
16
|
+
* 3. `"linux"` default
|
|
17
|
+
*
|
|
18
|
+
* Mirrors the behaviour in `hooks.mjs` so the MCP server and the
|
|
19
|
+
* Vitest integration are consistent.
|
|
20
|
+
*
|
|
21
|
+
* @param explicitOs - The value passed explicitly by the caller (may be undefined)
|
|
22
|
+
* @param env - The environment variables map (defaults to `process.env`)
|
|
23
|
+
* @returns - The resolved OS and a warning message if TD_OS was invalid
|
|
24
|
+
*/
|
|
25
|
+
export function resolveOs(explicitOs, env = process.env) {
|
|
26
|
+
if (explicitOs) {
|
|
27
|
+
return { os: explicitOs };
|
|
28
|
+
}
|
|
29
|
+
const envOs = env.TD_OS;
|
|
30
|
+
if (envOs) {
|
|
31
|
+
if (VALID_OS_VALUES.includes(envOs)) {
|
|
32
|
+
return { os: envOs };
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
os: "linux",
|
|
36
|
+
warning: `TD_OS has unsupported value "${envOs}" (supported: ${VALID_OS_VALUES.join(", ")}), ignoring`,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
return { os: "linux" };
|
|
40
|
+
}
|
|
41
|
+
// ============================================================
|
|
42
|
+
// E2B template ID resolution
|
|
43
|
+
// ============================================================
|
|
44
|
+
/**
|
|
45
|
+
* Resolve the E2B template ID with the following priority:
|
|
46
|
+
* 1. Explicit `e2bTemplateId` parameter passed to session_start
|
|
47
|
+
* 2. `TD_E2B_TEMPLATE_ID` environment variable
|
|
48
|
+
* 3. `undefined` (let the SDK use its own default)
|
|
49
|
+
*
|
|
50
|
+
* Mirrors the behaviour in `hooks.mjs`:
|
|
51
|
+
* ```js
|
|
52
|
+
* if (!config.e2bTemplateId && process.env.TD_E2B_TEMPLATE_ID) {
|
|
53
|
+
* config.e2bTemplateId = process.env.TD_E2B_TEMPLATE_ID;
|
|
54
|
+
* }
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* @param explicitId - The value passed explicitly by the caller (may be undefined)
|
|
58
|
+
* @param env - The environment variables map (defaults to `process.env`)
|
|
59
|
+
* @returns - The resolved template ID, or undefined if none is set
|
|
60
|
+
*/
|
|
61
|
+
export function resolveE2bTemplateId(explicitId, env = process.env) {
|
|
62
|
+
return explicitId || env.TD_E2B_TEMPLATE_ID;
|
|
63
|
+
}
|
|
@@ -147,7 +147,7 @@ export declare const SessionStartInputSchema: z.ZodObject<{
|
|
|
147
147
|
/** Electron args (for electron) */
|
|
148
148
|
electronArgs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
149
149
|
/** Operating system for the sandbox */
|
|
150
|
-
os: z.
|
|
150
|
+
os: z.ZodOptional<z.ZodEnum<["linux", "windows"]>>;
|
|
151
151
|
/** Keep sandbox alive duration in ms (default: 5 minutes) */
|
|
152
152
|
keepAlive: z.ZodDefault<z.ZodNumber>;
|
|
153
153
|
/** Path to test file - when provided, you MUST append generated code to this file after each action */
|
|
@@ -158,11 +158,12 @@ export declare const SessionStartInputSchema: z.ZodObject<{
|
|
|
158
158
|
apiRoot: z.ZodOptional<z.ZodString>;
|
|
159
159
|
/** Direct IP address of self-hosted instance (bypasses cloud provisioning) */
|
|
160
160
|
ip: z.ZodOptional<z.ZodString>;
|
|
161
|
+
/** E2B sandbox template ID (overrides TD_E2B_TEMPLATE_ID env var) */
|
|
162
|
+
e2bTemplateId: z.ZodOptional<z.ZodString>;
|
|
161
163
|
/** Sandbox ID to connect to (for debug-on-failure mode). When provided, connects to an existing sandbox instead of creating a new one. Skip provisioning. */
|
|
162
164
|
sandboxId: z.ZodOptional<z.ZodString>;
|
|
163
165
|
}, "strip", z.ZodTypeAny, {
|
|
164
166
|
type: "chrome" | "chromeExtension" | "vscode" | "installer" | "electron";
|
|
165
|
-
os: "linux" | "windows";
|
|
166
167
|
keepAlive: number;
|
|
167
168
|
reconnect: boolean;
|
|
168
169
|
url?: string | undefined;
|
|
@@ -178,9 +179,11 @@ export declare const SessionStartInputSchema: z.ZodObject<{
|
|
|
178
179
|
installerUrl?: string | undefined;
|
|
179
180
|
installerFilename?: string | undefined;
|
|
180
181
|
electronArgs?: string[] | undefined;
|
|
182
|
+
os?: "linux" | "windows" | undefined;
|
|
181
183
|
testFile?: string | undefined;
|
|
182
184
|
apiRoot?: string | undefined;
|
|
183
185
|
ip?: string | undefined;
|
|
186
|
+
e2bTemplateId?: string | undefined;
|
|
184
187
|
sandboxId?: string | undefined;
|
|
185
188
|
}, {
|
|
186
189
|
url?: string | undefined;
|
|
@@ -203,6 +206,7 @@ export declare const SessionStartInputSchema: z.ZodObject<{
|
|
|
203
206
|
reconnect?: boolean | undefined;
|
|
204
207
|
apiRoot?: string | undefined;
|
|
205
208
|
ip?: string | undefined;
|
|
209
|
+
e2bTemplateId?: string | undefined;
|
|
206
210
|
sandboxId?: string | undefined;
|
|
207
211
|
}>;
|
|
208
212
|
export type SessionStartInput = z.infer<typeof SessionStartInputSchema>;
|
|
@@ -118,7 +118,7 @@ export const SessionStartInputSchema = z.object({
|
|
|
118
118
|
electronArgs: z.array(z.string()).optional().describe("Additional Electron arguments"),
|
|
119
119
|
// Common session options
|
|
120
120
|
/** Operating system for the sandbox */
|
|
121
|
-
os: z.enum(["linux", "windows"]).
|
|
121
|
+
os: z.enum(["linux", "windows"]).optional().describe("Sandbox OS (default: 'linux', or TD_OS environment variable if set)"),
|
|
122
122
|
/** Keep sandbox alive duration in ms (default: 5 minutes) */
|
|
123
123
|
keepAlive: z.number().default(300000).describe("Keep sandbox alive for this many ms"),
|
|
124
124
|
/** Path to test file - when provided, you MUST append generated code to this file after each action */
|
|
@@ -130,6 +130,8 @@ export const SessionStartInputSchema = z.object({
|
|
|
130
130
|
// Self-hosted connection options
|
|
131
131
|
/** Direct IP address of self-hosted instance (bypasses cloud provisioning) */
|
|
132
132
|
ip: z.string().optional().describe("Direct IP address of self-hosted Windows instance (e.g., from AWS). When provided, connects directly to this IP instead of using cloud provisioning."),
|
|
133
|
+
/** E2B sandbox template ID (overrides TD_E2B_TEMPLATE_ID env var) */
|
|
134
|
+
e2bTemplateId: z.string().optional().describe("E2B sandbox template ID. Overrides the TD_E2B_TEMPLATE_ID environment variable when provided."),
|
|
133
135
|
// Debug mode - connect to existing sandbox
|
|
134
136
|
/** Sandbox ID to connect to (for debug-on-failure mode). When provided, connects to an existing sandbox instead of creating a new one. Skip provisioning. */
|
|
135
137
|
sandboxId: z.string().optional().describe("Existing sandbox ID to connect to (from debug-on-failure mode). Skips provisioning."),
|
|
@@ -17,6 +17,7 @@ import * as path from "path";
|
|
|
17
17
|
import { fileURLToPath, pathToFileURL } from "url";
|
|
18
18
|
import { z } from "zod";
|
|
19
19
|
import { generateActionCode } from "./codegen.js";
|
|
20
|
+
import { resolveE2bTemplateId, resolveOs } from "./env-utils.js";
|
|
20
21
|
import { getProvisionOptions, SessionStartInputSchema } from "./provision-types.js";
|
|
21
22
|
import { sessionManager } from "./session.js";
|
|
22
23
|
// =============================================================================
|
|
@@ -412,10 +413,25 @@ Debug mode (connect to existing sandbox):
|
|
|
412
413
|
_meta: { ui: { resourceUri: RESOURCE_URI, expanded: true } },
|
|
413
414
|
}, async (params) => {
|
|
414
415
|
const startTime = Date.now();
|
|
416
|
+
// Resolve OS with priority: explicit param > TD_OS env var > "linux" default
|
|
417
|
+
// This mirrors the behavior of the Vitest hooks (hooks.mjs) which also reads TD_OS
|
|
418
|
+
const { os: resolvedOs, warning: osWarning } = resolveOs(params.os);
|
|
419
|
+
if (osWarning) {
|
|
420
|
+
logger.warn(`session_start: ${osWarning}`);
|
|
421
|
+
}
|
|
422
|
+
else if (!params.os && resolvedOs !== "linux") {
|
|
423
|
+
logger.info("session_start: Using TD_OS environment variable", { os: resolvedOs });
|
|
424
|
+
}
|
|
425
|
+
// Resolve E2B template ID with priority: explicit param > TD_E2B_TEMPLATE_ID env var
|
|
426
|
+
// This mirrors the behavior of the Vitest hooks (hooks.mjs) which also reads TD_E2B_TEMPLATE_ID
|
|
427
|
+
const resolvedE2bTemplateId = resolveE2bTemplateId(params.e2bTemplateId);
|
|
428
|
+
if (!params.e2bTemplateId && resolvedE2bTemplateId) {
|
|
429
|
+
logger.info("session_start: Using TD_E2B_TEMPLATE_ID environment variable", { e2bTemplateId: resolvedE2bTemplateId });
|
|
430
|
+
}
|
|
415
431
|
logger.info("session_start: Starting", {
|
|
416
432
|
type: params.type,
|
|
417
433
|
url: params.url,
|
|
418
|
-
os:
|
|
434
|
+
os: resolvedOs,
|
|
419
435
|
reconnect: params.reconnect,
|
|
420
436
|
sandboxId: params.sandboxId,
|
|
421
437
|
});
|
|
@@ -431,7 +447,7 @@ Debug mode (connect to existing sandbox):
|
|
|
431
447
|
}
|
|
432
448
|
// Create new session
|
|
433
449
|
const newSession = sessionManager.createSession({
|
|
434
|
-
os:
|
|
450
|
+
os: resolvedOs,
|
|
435
451
|
keepAlive: params.keepAlive,
|
|
436
452
|
testFile: params.testFile,
|
|
437
453
|
});
|
|
@@ -469,11 +485,12 @@ Debug mode (connect to existing sandbox):
|
|
|
469
485
|
keyPrefix: apiKey.substring(0, 7) + "..."
|
|
470
486
|
});
|
|
471
487
|
sdk = new TestDriverSDK(apiKey, {
|
|
472
|
-
os:
|
|
488
|
+
os: resolvedOs,
|
|
473
489
|
logging: false,
|
|
474
490
|
apiRoot,
|
|
475
491
|
preview: previewMode,
|
|
476
492
|
ip: instanceIp,
|
|
493
|
+
e2bTemplateId: resolvedE2bTemplateId,
|
|
477
494
|
});
|
|
478
495
|
// Handle sandboxId mode - connect to existing sandbox (debug-on-failure mode)
|
|
479
496
|
if (params.sandboxId) {
|