testdriverai 7.3.17 → 7.3.19
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/.github/workflows/acceptance.yaml +2 -2
- package/CHANGELOG.md +8 -0
- package/agent/lib/sandbox.js +16 -3
- package/docs/_data/examples-manifest.json +78 -46
- package/docs/v7/examples/ai.mdx +1 -1
- package/docs/v7/examples/chrome-extension.mdx +1 -1
- package/docs/v7/examples/drag-and-drop.mdx +1 -1
- package/docs/v7/examples/element-not-found.mdx +1 -1
- package/docs/v7/examples/hover-image.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/match-image.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-until-image.mdx +1 -1
- package/docs/v7/examples/scroll-until-text.mdx +1 -1
- package/docs/v7/examples/scroll.mdx +1 -1
- package/docs/v7/examples/type.mdx +1 -1
- package/docs/v7/examples/windows-installer.mdx +1 -1
- package/interfaces/vitest-plugin.mjs +12 -45
- package/lib/sentry.js +24 -3
- package/mcp-server/dist/server.mjs +14 -1
- package/mcp-server/src/server.ts +21 -1
- package/package.json +1 -1
|
@@ -14,7 +14,7 @@ concurrency:
|
|
|
14
14
|
|
|
15
15
|
jobs:
|
|
16
16
|
test-linux:
|
|
17
|
-
runs-on:
|
|
17
|
+
runs-on: testdriver-32
|
|
18
18
|
|
|
19
19
|
steps:
|
|
20
20
|
- uses: actions/checkout@v4
|
|
@@ -31,7 +31,7 @@ jobs:
|
|
|
31
31
|
run: npm ci
|
|
32
32
|
|
|
33
33
|
- name: Run Linux tests
|
|
34
|
-
run: set -o pipefail && npx vitest run examples/*.test.mjs 2>&1 | tee test-output.log
|
|
34
|
+
run: set -o pipefail && npx vitest run examples/*.test.mjs --maxWorkers 32 2>&1 | tee test-output.log
|
|
35
35
|
env:
|
|
36
36
|
TD_API_KEY: ${{ secrets.TD_API_KEY }}
|
|
37
37
|
TWOCAPTCHA_API_KEY: ${{ secrets.TWOCAPTCHA_API_KEY }}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## [7.3.19](https://github.com/testdriverai/testdriverai/compare/v7.3.17...v7.3.19) (2026-02-19)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
## [7.3.18](https://github.com/testdriverai/testdriverai/compare/v7.3.17...v7.3.18) (2026-02-19)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
1
9
|
## [7.3.17](https://github.com/testdriverai/testdriverai/compare/v7.3.16...v7.3.17) (2026-02-18)
|
|
2
10
|
|
|
3
11
|
|
package/agent/lib/sandbox.js
CHANGED
|
@@ -71,7 +71,9 @@ const createSandbox = (emitter, analytics, sessionInstance) => {
|
|
|
71
71
|
let resolvePromise;
|
|
72
72
|
let rejectPromise;
|
|
73
73
|
|
|
74
|
-
if
|
|
74
|
+
// Check if socket exists and is actually open before sending
|
|
75
|
+
// This prevents sending to a closed connection (e.g., sandbox killed due to test failure)
|
|
76
|
+
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
|
|
75
77
|
this.messageId++;
|
|
76
78
|
message.requestId = `${this.uniqueId}-${this.messageId}`;
|
|
77
79
|
|
|
@@ -150,8 +152,16 @@ const createSandbox = (emitter, analytics, sessionInstance) => {
|
|
|
150
152
|
return p;
|
|
151
153
|
}
|
|
152
154
|
|
|
153
|
-
// Return a rejected promise if socket is not available
|
|
154
|
-
|
|
155
|
+
// Return a rejected promise if socket is not available or not open
|
|
156
|
+
// This can happen when the sandbox is killed (e.g., due to test failure)
|
|
157
|
+
const state = this.socket?.readyState;
|
|
158
|
+
const stateMap = {
|
|
159
|
+
[WebSocket.CONNECTING]: "connecting",
|
|
160
|
+
[WebSocket.CLOSING]: "closing",
|
|
161
|
+
[WebSocket.CLOSED]: "closed",
|
|
162
|
+
};
|
|
163
|
+
const stateDesc = stateMap[state] || "unavailable";
|
|
164
|
+
return Promise.reject(new Error(`Sandbox socket not connected (state: ${stateDesc})`));
|
|
155
165
|
}
|
|
156
166
|
|
|
157
167
|
async auth(apiKey) {
|
|
@@ -355,6 +365,9 @@ const createSandbox = (emitter, analytics, sessionInstance) => {
|
|
|
355
365
|
this.socket.on("close", () => {
|
|
356
366
|
clearInterval(this.heartbeat);
|
|
357
367
|
this.apiSocketConnected = false;
|
|
368
|
+
// Also mark instance socket as disconnected to prevent sending messages
|
|
369
|
+
// to a closed connection (e.g., when sandbox is killed due to test failure)
|
|
370
|
+
this.instanceSocketConnected = false;
|
|
358
371
|
// Reset reconnecting flag so handleConnectionLoss can run for this new disconnection
|
|
359
372
|
this.reconnecting = false;
|
|
360
373
|
this.handleConnectionLoss();
|
|
@@ -6,100 +6,100 @@
|
|
|
6
6
|
"lastUpdated": "2026-02-13T19:55:05.949Z"
|
|
7
7
|
},
|
|
8
8
|
"drag-and-drop.test.mjs": {
|
|
9
|
-
"url": "https://console.testdriver.ai/runs/
|
|
10
|
-
"lastUpdated": "2026-02-
|
|
9
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965983d4ec641ec13c81ff",
|
|
10
|
+
"lastUpdated": "2026-02-19T00:58:04.014Z"
|
|
11
11
|
},
|
|
12
12
|
"exec-pwsh.test.mjs": {
|
|
13
|
-
"url": "https://console.testdriver.ai/runs/
|
|
14
|
-
"lastUpdated": "2026-02-
|
|
13
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965985d4ec641ec13c8203",
|
|
14
|
+
"lastUpdated": "2026-02-19T00:58:04.014Z"
|
|
15
15
|
},
|
|
16
16
|
"match-image.test.mjs": {
|
|
17
|
-
"url": "https://console.testdriver.ai/runs/
|
|
18
|
-
"lastUpdated": "2026-02-
|
|
17
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965986d4ec641ec13c8204",
|
|
18
|
+
"lastUpdated": "2026-02-19T00:58:04.014Z"
|
|
19
19
|
},
|
|
20
20
|
"scroll-until-text.test.mjs": {
|
|
21
|
-
"url": "https://console.testdriver.ai/runs/
|
|
22
|
-
"lastUpdated": "2026-02-
|
|
21
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965a12d4ec641ec13c8240",
|
|
22
|
+
"lastUpdated": "2026-02-19T00:58:04.014Z"
|
|
23
23
|
},
|
|
24
24
|
"hover-text-with-description.test.mjs": {
|
|
25
|
-
"url": "https://console.testdriver.ai/runs/
|
|
26
|
-
"lastUpdated": "2026-02-
|
|
25
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965a26d4ec641ec13c8252",
|
|
26
|
+
"lastUpdated": "2026-02-19T00:58:04.015Z"
|
|
27
27
|
},
|
|
28
28
|
"windows-installer.test.mjs": {
|
|
29
|
-
"url": "https://console.testdriver.ai/runs/
|
|
30
|
-
"lastUpdated": "2026-02-
|
|
29
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965a28887d56872d5c968f",
|
|
30
|
+
"lastUpdated": "2026-02-19T00:58:04.015Z"
|
|
31
31
|
},
|
|
32
32
|
"exec-output.test.mjs": {
|
|
33
|
-
"url": "https://console.testdriver.ai/runs/
|
|
34
|
-
"lastUpdated": "2026-02-
|
|
33
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965a29887d56872d5c9690",
|
|
34
|
+
"lastUpdated": "2026-02-19T00:58:04.015Z"
|
|
35
35
|
},
|
|
36
36
|
"chrome-extension.test.mjs": {
|
|
37
|
-
"url": "https://console.testdriver.ai/runs/
|
|
38
|
-
"lastUpdated": "2026-02-
|
|
37
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965a95887d56872d5c96bf",
|
|
38
|
+
"lastUpdated": "2026-02-19T00:58:04.016Z"
|
|
39
39
|
},
|
|
40
40
|
"launch-vscode-linux.test.mjs": {
|
|
41
|
-
"url": "https://console.testdriver.ai/runs/
|
|
42
|
-
"lastUpdated": "2026-02-
|
|
41
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965a87887d56872d5c96b9",
|
|
42
|
+
"lastUpdated": "2026-02-19T00:58:04.016Z"
|
|
43
43
|
},
|
|
44
44
|
"hover-image.test.mjs": {
|
|
45
|
-
"url": "https://console.testdriver.ai/runs/
|
|
46
|
-
"lastUpdated": "2026-02-
|
|
45
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965a99d4ec641ec13c827c",
|
|
46
|
+
"lastUpdated": "2026-02-19T00:58:04.016Z"
|
|
47
47
|
},
|
|
48
48
|
"installer.test.mjs": {
|
|
49
|
-
"url": "https://console.testdriver.ai/runs/
|
|
50
|
-
"lastUpdated": "2026-02-
|
|
49
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965af2887d56872d5c96e5",
|
|
50
|
+
"lastUpdated": "2026-02-19T00:58:04.017Z"
|
|
51
51
|
},
|
|
52
52
|
"type.test.mjs": {
|
|
53
|
-
"url": "https://console.testdriver.ai/runs/
|
|
54
|
-
"lastUpdated": "2026-02-
|
|
53
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965b5c887d56872d5c96fc",
|
|
54
|
+
"lastUpdated": "2026-02-19T00:58:04.018Z"
|
|
55
55
|
},
|
|
56
56
|
"press-keys.test.mjs": {
|
|
57
|
-
"url": "https://console.testdriver.ai/runs/
|
|
58
|
-
"lastUpdated": "2026-02-
|
|
57
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965bee24aebb4a0ca062f3",
|
|
58
|
+
"lastUpdated": "2026-02-19T00:58:04.019Z"
|
|
59
59
|
},
|
|
60
60
|
"scroll-keyboard.test.mjs": {
|
|
61
|
-
"url": "https://console.testdriver.ai/runs/
|
|
62
|
-
"lastUpdated": "2026-02-
|
|
61
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965b7124aebb4a0ca062d9",
|
|
62
|
+
"lastUpdated": "2026-02-19T00:58:04.018Z"
|
|
63
63
|
},
|
|
64
64
|
"scroll.test.mjs": {
|
|
65
|
-
"url": "https://console.testdriver.ai/runs/
|
|
66
|
-
"lastUpdated": "2026-02-
|
|
65
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965b3a887d56872d5c96f6",
|
|
66
|
+
"lastUpdated": "2026-02-19T00:58:04.017Z"
|
|
67
67
|
},
|
|
68
68
|
"scroll-until-image.test.mjs": {
|
|
69
|
-
"url": "https://console.testdriver.ai/runs/
|
|
70
|
-
"lastUpdated": "2026-02-
|
|
69
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965bd0887d56872d5c9715",
|
|
70
|
+
"lastUpdated": "2026-02-19T00:58:04.018Z"
|
|
71
71
|
},
|
|
72
72
|
"prompt.test.mjs": {
|
|
73
|
-
"url": "https://console.testdriver.ai/runs/
|
|
74
|
-
"lastUpdated": "2026-02-
|
|
73
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965bd2887d56872d5c9718",
|
|
74
|
+
"lastUpdated": "2026-02-19T00:58:04.018Z"
|
|
75
75
|
},
|
|
76
76
|
"focus-window.test.mjs": {
|
|
77
|
-
"url": "https://console.testdriver.ai/runs/
|
|
78
|
-
"lastUpdated": "2026-02-
|
|
77
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965bd3887d56872d5c9719",
|
|
78
|
+
"lastUpdated": "2026-02-19T00:58:04.018Z"
|
|
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.testdriver.ai/runs/
|
|
86
|
-
"lastUpdated": "2026-02-
|
|
85
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965c3724aebb4a0ca0630a",
|
|
86
|
+
"lastUpdated": "2026-02-19T00:58:04.019Z"
|
|
87
87
|
},
|
|
88
88
|
"formatted-logging.test.mjs": {
|
|
89
|
-
"url": "https://console.testdriver.ai/runs/
|
|
90
|
-
"lastUpdated": "2026-02-
|
|
89
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965c2424aebb4a0ca06301",
|
|
90
|
+
"lastUpdated": "2026-02-19T00:58:04.019Z"
|
|
91
91
|
},
|
|
92
92
|
"hover-text.test.mjs": {
|
|
93
|
-
"url": "https://console.testdriver.ai/runs/
|
|
94
|
-
"lastUpdated": "2026-02-
|
|
93
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965caa24aebb4a0ca0632a",
|
|
94
|
+
"lastUpdated": "2026-02-19T00:58:04.022Z"
|
|
95
95
|
},
|
|
96
96
|
"no-provision.test.mjs": {
|
|
97
|
-
"url": "https://console.testdriver.ai/runs/
|
|
98
|
-
"lastUpdated": "2026-02-
|
|
97
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965cc5887d56872d5c9766",
|
|
98
|
+
"lastUpdated": "2026-02-19T00:58:04.022Z"
|
|
99
99
|
},
|
|
100
100
|
"ai.test.mjs": {
|
|
101
|
-
"url": "https://console.testdriver.ai/runs/
|
|
102
|
-
"lastUpdated": "2026-02-
|
|
101
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965caa24aebb4a0ca06329",
|
|
102
|
+
"lastUpdated": "2026-02-19T00:58:04.021Z"
|
|
103
103
|
},
|
|
104
104
|
"popup-loading.test.mjs": {
|
|
105
105
|
"url": "https://console.testdriver.ai/runs/698bc89f7140c3fa7daaca8d/698bca7f7140c3fa7daacbf7",
|
|
@@ -132,6 +132,38 @@
|
|
|
132
132
|
"z_flake-noredraw-nocache.test.mjs": {
|
|
133
133
|
"url": "https://console.testdriver.ai/runs/698f7df69e27ce1528d7d087/698f816ed3b320ad547d9d8c",
|
|
134
134
|
"lastUpdated": "2026-02-13T19:55:05.953Z"
|
|
135
|
+
},
|
|
136
|
+
"findall-coffee-icons.test.mjs": {
|
|
137
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965c48887d56872d5c973b",
|
|
138
|
+
"lastUpdated": "2026-02-19T00:58:04.019Z"
|
|
139
|
+
},
|
|
140
|
+
"parse.test.mjs": {
|
|
141
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965d0a887d56872d5c977a",
|
|
142
|
+
"lastUpdated": "2026-02-19T00:58:04.023Z"
|
|
143
|
+
},
|
|
144
|
+
"flake-diffthreshold-001.test.mjs": {
|
|
145
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965e0a24aebb4a0ca0636f",
|
|
146
|
+
"lastUpdated": "2026-02-19T00:58:04.025Z"
|
|
147
|
+
},
|
|
148
|
+
"flake-noredraw-cache.test.mjs": {
|
|
149
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965f1324aebb4a0ca06389",
|
|
150
|
+
"lastUpdated": "2026-02-19T00:58:04.025Z"
|
|
151
|
+
},
|
|
152
|
+
"flake-noredraw-nocache.test.mjs": {
|
|
153
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965f17887d56872d5c97e0",
|
|
154
|
+
"lastUpdated": "2026-02-19T00:58:04.025Z"
|
|
155
|
+
},
|
|
156
|
+
"flake-diffthreshold-05.test.mjs": {
|
|
157
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/69965f4524aebb4a0ca06393",
|
|
158
|
+
"lastUpdated": "2026-02-19T00:58:04.025Z"
|
|
159
|
+
},
|
|
160
|
+
"flake-redraw-cache.test.mjs": {
|
|
161
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/6996600ffca9f9c4cff8040b",
|
|
162
|
+
"lastUpdated": "2026-02-19T00:58:04.026Z"
|
|
163
|
+
},
|
|
164
|
+
"flake-redraw-nocache.test.mjs": {
|
|
165
|
+
"url": "https://console.testdriver.ai/runs/69965981887d56872d5c9640/699660116613a14398ff482e",
|
|
166
|
+
"lastUpdated": "2026-02-19T00:58:04.026Z"
|
|
135
167
|
}
|
|
136
168
|
}
|
|
137
169
|
}
|
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://testdriver-api.onrender.com/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/69965caa24aebb4a0ca06329/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://testdriver-api.onrender.com/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/69965a95887d56872d5c96bf/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
|
{/* drag-and-drop.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
|
-
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/69965983d4ec641ec13c81ff/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://testdriver-api.onrender.com/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/69965c3724aebb4a0ca0630a/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
|
{/* hover-image.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
|
-
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/69965a99d4ec641ec13c827c/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
|
{/* hover-text.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
|
-
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/69965caa24aebb4a0ca0632a/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://testdriver-api.onrender.com/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/69965af2887d56872d5c96e5/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://testdriver-api.onrender.com/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/69965a87887d56872d5c96b9/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
|
{/* match-image.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
|
-
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/69965986d4ec641ec13c8204/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
|
{/* press-keys.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
|
-
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/69965bee24aebb4a0ca062f3/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://testdriver-api.onrender.com/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/69965b7124aebb4a0ca062d9/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-until-image.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
|
-
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/69965bd0887d56872d5c9715/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-until-text.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
|
-
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/69965a12d4ec641ec13c8240/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://testdriver-api.onrender.com/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/69965b3a887d56872d5c96f6/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://testdriver-api.onrender.com/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/69965b5c887d56872d5c96fc/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
|
{/* windows-installer.test.mjs output */}
|
|
14
14
|
<iframe
|
|
15
|
-
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/
|
|
15
|
+
src="https://testdriver-api.onrender.com/api/v1/testdriver/testcase/69965a28887d56872d5c968f/replay"
|
|
16
16
|
width="100%"
|
|
17
17
|
height="390"
|
|
18
18
|
style={{ border: "1px solid #333", borderRadius: "8px" }}
|
|
@@ -68,52 +68,19 @@ function initializeSentry() {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* @param {
|
|
76
|
-
* @
|
|
77
|
-
* @param {string} [params.sessionId] - Session ID if available
|
|
78
|
-
* @param {string} [params.platform] - Platform (windows, mac, linux)
|
|
79
|
-
* @param {number} [params.duration] - Test duration in ms
|
|
71
|
+
* Previously captured test failures in Sentry.
|
|
72
|
+
* Now disabled - test failures are expected behavior, not crashes.
|
|
73
|
+
* We only want to report actual exceptions and crashes to Sentry.
|
|
74
|
+
*
|
|
75
|
+
* @param {Object} _params - Test failure parameters (ignored)
|
|
76
|
+
* @deprecated This function no longer sends data to Sentry.
|
|
80
77
|
*/
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
error.name = "TestFailure";
|
|
88
|
-
if (errorStack) {
|
|
89
|
-
error.stack = errorStack;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
Sentry.withScope((scope) => {
|
|
93
|
-
scope.setTag("test.name", testName);
|
|
94
|
-
scope.setTag("test.file", testFile);
|
|
95
|
-
scope.setTag("test.status", "failed");
|
|
96
|
-
|
|
97
|
-
if (sessionId) {
|
|
98
|
-
scope.setTag("session", sessionId);
|
|
99
|
-
}
|
|
100
|
-
if (platform) {
|
|
101
|
-
scope.setTag("platform", platform);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
scope.setContext("test", {
|
|
105
|
-
name: testName,
|
|
106
|
-
file: testFile,
|
|
107
|
-
duration: duration,
|
|
108
|
-
sessionId: sessionId,
|
|
109
|
-
platform: platform,
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
Sentry.captureException(error);
|
|
113
|
-
});
|
|
114
|
-
} catch (err) {
|
|
115
|
-
logger.debug("Failed to capture test failure in Sentry:", err.message);
|
|
116
|
-
}
|
|
78
|
+
// eslint-disable-next-line no-unused-vars
|
|
79
|
+
function captureTestFailure(_params) {
|
|
80
|
+
// Test failures are expected behavior - they indicate a test found a bug.
|
|
81
|
+
// We should only report actual exceptions and crashes to Sentry, not every failed test.
|
|
82
|
+
// This function is now a no-op to prevent flooding Sentry with test failures.
|
|
83
|
+
return;
|
|
117
84
|
}
|
|
118
85
|
|
|
119
86
|
/**
|
package/lib/sentry.js
CHANGED
|
@@ -51,12 +51,33 @@ if (isEnabled()) {
|
|
|
51
51
|
nodeVersion: process.version,
|
|
52
52
|
},
|
|
53
53
|
},
|
|
54
|
-
// Filter out common non-errors
|
|
54
|
+
// Filter out common non-errors and expected test failures
|
|
55
|
+
// Only report actual exceptions and crashes, not failed tests or element lookups
|
|
55
56
|
beforeSend(event, hint) {
|
|
56
57
|
const error = hint.originalException;
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
if (error && error.message) {
|
|
60
|
+
const message = error.message;
|
|
61
|
+
|
|
62
|
+
// Don't send user-initiated exits
|
|
63
|
+
if (message.includes("User cancelled")) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Don't send expected test/element failures - these are normal test outcomes, not crashes
|
|
68
|
+
if (
|
|
69
|
+
message.includes("Element not found") ||
|
|
70
|
+
message.includes("No elements found") ||
|
|
71
|
+
message.includes("No element found") ||
|
|
72
|
+
message.includes("Assertion failed") ||
|
|
73
|
+
message.includes("assertion failed")
|
|
74
|
+
) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Filter out TestFailure errors (test failures, not crashes)
|
|
80
|
+
if (error && error.name === "TestFailure") {
|
|
60
81
|
return null;
|
|
61
82
|
}
|
|
62
83
|
|
|
@@ -50,14 +50,27 @@ if (isSentryEnabled()) {
|
|
|
50
50
|
nodeVersion: process.version,
|
|
51
51
|
},
|
|
52
52
|
},
|
|
53
|
+
// Filter out expected test/element failures - only report actual exceptions and crashes
|
|
53
54
|
beforeSend(event, hint) {
|
|
54
55
|
const error = hint.originalException;
|
|
55
|
-
// Don't send user-initiated exits
|
|
56
56
|
if (error && typeof error === "object" && "message" in error) {
|
|
57
57
|
const msg = error.message;
|
|
58
|
+
// Don't send user-initiated exits
|
|
58
59
|
if (msg.includes("User cancelled")) {
|
|
59
60
|
return null;
|
|
60
61
|
}
|
|
62
|
+
// Don't send expected test/element failures - these are normal test outcomes, not crashes
|
|
63
|
+
if (msg.includes("Element not found") ||
|
|
64
|
+
msg.includes("No elements found") ||
|
|
65
|
+
msg.includes("No element found") ||
|
|
66
|
+
msg.includes("Assertion failed") ||
|
|
67
|
+
msg.includes("assertion failed")) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Filter out TestFailure errors (test failures, not crashes)
|
|
72
|
+
if (error && typeof error === "object" && "name" in error && error.name === "TestFailure") {
|
|
73
|
+
return null;
|
|
61
74
|
}
|
|
62
75
|
return event;
|
|
63
76
|
},
|
package/mcp-server/src/server.ts
CHANGED
|
@@ -60,15 +60,35 @@ if (isSentryEnabled()) {
|
|
|
60
60
|
nodeVersion: process.version,
|
|
61
61
|
},
|
|
62
62
|
},
|
|
63
|
+
// Filter out expected test/element failures - only report actual exceptions and crashes
|
|
63
64
|
beforeSend(event, hint) {
|
|
64
65
|
const error = hint.originalException;
|
|
65
|
-
|
|
66
|
+
|
|
66
67
|
if (error && typeof error === "object" && "message" in error) {
|
|
67
68
|
const msg = (error as { message: string }).message;
|
|
69
|
+
|
|
70
|
+
// Don't send user-initiated exits
|
|
68
71
|
if (msg.includes("User cancelled")) {
|
|
69
72
|
return null;
|
|
70
73
|
}
|
|
74
|
+
|
|
75
|
+
// Don't send expected test/element failures - these are normal test outcomes, not crashes
|
|
76
|
+
if (
|
|
77
|
+
msg.includes("Element not found") ||
|
|
78
|
+
msg.includes("No elements found") ||
|
|
79
|
+
msg.includes("No element found") ||
|
|
80
|
+
msg.includes("Assertion failed") ||
|
|
81
|
+
msg.includes("assertion failed")
|
|
82
|
+
) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Filter out TestFailure errors (test failures, not crashes)
|
|
88
|
+
if (error && typeof error === "object" && "name" in error && (error as { name: string }).name === "TestFailure") {
|
|
89
|
+
return null;
|
|
71
90
|
}
|
|
91
|
+
|
|
72
92
|
return event;
|
|
73
93
|
},
|
|
74
94
|
});
|