testdriverai 7.3.41 → 7.3.43
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/CHANGELOG.md +8 -0
- package/lib/core/Dashcam.js +5 -3
- package/lib/vitest/hooks.mjs +51 -0
- package/package.json +1 -1
- package/sdk.js +18 -22
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## [7.3.43](https://github.com/testdriverai/testdriverai/compare/v7.3.42...v7.3.43) (2026-02-25)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
## [7.3.42](https://github.com/testdriverai/testdriverai/compare/v7.3.41...v7.3.42) (2026-02-25)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
1
9
|
## [7.3.41](https://github.com/testdriverai/testdriverai/compare/v7.3.40...v7.3.41) (2026-02-25)
|
|
2
10
|
|
|
3
11
|
|
package/lib/core/Dashcam.js
CHANGED
|
@@ -108,6 +108,11 @@ class Dashcam {
|
|
|
108
108
|
*/
|
|
109
109
|
async _getDashcamPath() {
|
|
110
110
|
const shell = this._getShell();
|
|
111
|
+
|
|
112
|
+
if (this.client.os === "windows") {
|
|
113
|
+
return "C:\\Program Files\\nodejs\\dashcam.cmd";
|
|
114
|
+
}
|
|
115
|
+
|
|
111
116
|
const npmPrefix = await this.client.exec(
|
|
112
117
|
shell,
|
|
113
118
|
"npm prefix -g",
|
|
@@ -115,9 +120,6 @@ class Dashcam {
|
|
|
115
120
|
process.env.DEBUG == "true" ? false : true,
|
|
116
121
|
);
|
|
117
122
|
|
|
118
|
-
if (this.client.os === "windows") {
|
|
119
|
-
return "C:\\Program Files\\nodejs\\dashcam.cmd";
|
|
120
|
-
}
|
|
121
123
|
return npmPrefix.trim() + "/bin/dashcam";
|
|
122
124
|
}
|
|
123
125
|
|
package/lib/vitest/hooks.mjs
CHANGED
|
@@ -217,6 +217,47 @@ function cleanupConsoleSpy(client) {
|
|
|
217
217
|
const testDriverInstances = new WeakMap();
|
|
218
218
|
const lifecycleHandlers = new WeakMap();
|
|
219
219
|
|
|
220
|
+
/**
|
|
221
|
+
* Known log file paths on the Windows test runner.
|
|
222
|
+
* These are written by pyautogui-cli.py and related services.
|
|
223
|
+
*/
|
|
224
|
+
const WINDOWS_RUNNER_LOG_PATHS = [
|
|
225
|
+
"C:\\Windows\\Temp\\pyautogui-cli.log",
|
|
226
|
+
];
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Fetch log files from the Windows test runner via exec() and save them locally.
|
|
230
|
+
* This runs before disconnect so we can still communicate with the sandbox.
|
|
231
|
+
*
|
|
232
|
+
* @param {import('../../sdk.js').default} client - TestDriver SDK instance
|
|
233
|
+
* @param {string} testName - Test file name (used for local directory naming)
|
|
234
|
+
*/
|
|
235
|
+
async function fetchRunnerLogs(client, testName) {
|
|
236
|
+
if (!client.connected) return;
|
|
237
|
+
if (client.os !== "windows") return;
|
|
238
|
+
|
|
239
|
+
for (const remotePath of WINDOWS_RUNNER_LOG_PATHS) {
|
|
240
|
+
const localName = path.basename(remotePath);
|
|
241
|
+
try {
|
|
242
|
+
// Read the log file contents via PowerShell
|
|
243
|
+
const cmd = `if (Test-Path '${remotePath}') { Get-Content -Path '${remotePath}' -Raw } else { Write-Output '__FILE_NOT_FOUND__' }`;
|
|
244
|
+
const result = await Promise.race([
|
|
245
|
+
client.exec("pwsh", cmd, 10000, true),
|
|
246
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), 15000)),
|
|
247
|
+
]);
|
|
248
|
+
|
|
249
|
+
if (result && typeof result === "string" && !result.includes("__FILE_NOT_FOUND__")) {
|
|
250
|
+
console.log(`\n[TestDriver] === Runner Log: ${localName} ===`);
|
|
251
|
+
console.log(result);
|
|
252
|
+
console.log(`[TestDriver] === End Runner Log ===\n`);
|
|
253
|
+
}
|
|
254
|
+
} catch (err) {
|
|
255
|
+
// Fire-and-forget — don't let log retrieval break cleanup
|
|
256
|
+
console.warn(`[TestDriver] Could not fetch runner log ${remotePath}: ${err.message}`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
220
261
|
/**
|
|
221
262
|
* Upload buffered SDK + console logs directly to S3 via the existing Log system.
|
|
222
263
|
* Extracts the replayId from the dashcam URL, calls POST /api/v1/logs to create
|
|
@@ -632,6 +673,16 @@ export function TestDriver(context, options = {}) {
|
|
|
632
673
|
context.task.meta.dashcamUrl = null;
|
|
633
674
|
}
|
|
634
675
|
|
|
676
|
+
// Fetch runner logs before disconnecting (Windows only)
|
|
677
|
+
// This grabs pyautogui-cli logs from the runner while we still have a connection
|
|
678
|
+
try {
|
|
679
|
+
const logTestName = testFile.replace(/[/\\]/g, "_").replace(/\.test\.m?js$/, "");
|
|
680
|
+
await fetchRunnerLogs(currentInstance, logTestName);
|
|
681
|
+
} catch (err) {
|
|
682
|
+
// Never let log retrieval block cleanup
|
|
683
|
+
console.warn("[TestDriver] Runner log fetch failed:", err.message);
|
|
684
|
+
}
|
|
685
|
+
|
|
635
686
|
// Clean up console spies
|
|
636
687
|
cleanupConsoleSpy(currentInstance);
|
|
637
688
|
|
package/package.json
CHANGED
package/sdk.js
CHANGED
|
@@ -615,11 +615,10 @@ class Element {
|
|
|
615
615
|
|
|
616
616
|
// Track find interaction once at the end (fire-and-forget, don't block)
|
|
617
617
|
const sessionId = this.sdk.getSessionId();
|
|
618
|
-
if (sessionId && this.sdk.
|
|
619
|
-
|
|
620
|
-
.
|
|
621
|
-
type: "
|
|
622
|
-
interactionType: "find",
|
|
618
|
+
if (sessionId && this.sdk.apiClient) {
|
|
619
|
+
this.sdk.apiClient
|
|
620
|
+
.req("interaction/track", {
|
|
621
|
+
type: "find",
|
|
623
622
|
session: sessionId,
|
|
624
623
|
prompt: description,
|
|
625
624
|
timestamp: absoluteTimestamp, // Absolute epoch timestamp - frontend calculates relative using clientStartDate
|
|
@@ -1896,7 +1895,7 @@ class TestDriverSDK {
|
|
|
1896
1895
|
// Add web log tracking with domain wildcard pattern, then start dashcam
|
|
1897
1896
|
if (this.dashcamEnabled) {
|
|
1898
1897
|
const domainPattern = this._getUrlDomainPattern(url);
|
|
1899
|
-
await this.dashcam.addWebLog(domainPattern, "Web Logs");
|
|
1898
|
+
// await this.dashcam.addWebLog(domainPattern, "Web Logs");
|
|
1900
1899
|
|
|
1901
1900
|
// Start dashcam recording after logs are configured
|
|
1902
1901
|
if (!(await this.dashcam.isRecording())) {
|
|
@@ -2463,7 +2462,7 @@ with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
|
|
|
2463
2462
|
const pattern = this._provisionedChromeUrl
|
|
2464
2463
|
? this._getUrlDomainPattern(this._provisionedChromeUrl)
|
|
2465
2464
|
: "**";
|
|
2466
|
-
await this.dashcam.addWebLog(pattern, "Web Logs");
|
|
2465
|
+
// await this.dashcam.addWebLog(pattern, "Web Logs");
|
|
2467
2466
|
}
|
|
2468
2467
|
|
|
2469
2468
|
// Start recording if not already recording
|
|
@@ -3173,11 +3172,10 @@ CAPTCHA_SOLVER_EOF`,
|
|
|
3173
3172
|
|
|
3174
3173
|
// Track successful findAll interaction (fire-and-forget, don't block)
|
|
3175
3174
|
const sessionId = this.getSessionId();
|
|
3176
|
-
if (sessionId && this.
|
|
3177
|
-
this.
|
|
3178
|
-
.
|
|
3179
|
-
type: "
|
|
3180
|
-
interactionType: "findAll",
|
|
3175
|
+
if (sessionId && this.apiClient) {
|
|
3176
|
+
this.apiClient
|
|
3177
|
+
.req("interaction/track", {
|
|
3178
|
+
type: "findAll",
|
|
3181
3179
|
session: sessionId,
|
|
3182
3180
|
prompt: description,
|
|
3183
3181
|
timestamp: absoluteTimestamp, // Absolute epoch timestamp - frontend calculates relative using clientStartDate
|
|
@@ -3229,11 +3227,10 @@ CAPTCHA_SOLVER_EOF`,
|
|
|
3229
3227
|
|
|
3230
3228
|
// No elements found - track interaction (fire-and-forget, don't block)
|
|
3231
3229
|
const sessionId = this.getSessionId();
|
|
3232
|
-
if (sessionId && this.
|
|
3233
|
-
this.
|
|
3234
|
-
.
|
|
3235
|
-
type: "
|
|
3236
|
-
interactionType: "findAll",
|
|
3230
|
+
if (sessionId && this.apiClient) {
|
|
3231
|
+
this.apiClient
|
|
3232
|
+
.req("interaction/track", {
|
|
3233
|
+
type: "findAll",
|
|
3237
3234
|
session: sessionId,
|
|
3238
3235
|
prompt: description,
|
|
3239
3236
|
timestamp: absoluteTimestamp, // Absolute epoch timestamp - frontend calculates relative using clientStartDate
|
|
@@ -3274,11 +3271,10 @@ CAPTCHA_SOLVER_EOF`,
|
|
|
3274
3271
|
|
|
3275
3272
|
// Track findAll error interaction (fire-and-forget, don't block)
|
|
3276
3273
|
const sessionId = this.getSessionId();
|
|
3277
|
-
if (sessionId && this.
|
|
3278
|
-
this.
|
|
3279
|
-
.
|
|
3280
|
-
type: "
|
|
3281
|
-
interactionType: "findAll",
|
|
3274
|
+
if (sessionId && this.apiClient) {
|
|
3275
|
+
this.apiClient
|
|
3276
|
+
.req("interaction/track", {
|
|
3277
|
+
type: "findAll",
|
|
3282
3278
|
session: sessionId,
|
|
3283
3279
|
prompt: description,
|
|
3284
3280
|
timestamp: absoluteTimestamp, // Absolute epoch timestamp - frontend calculates relative using clientStartDate
|