testdriverai 7.3.11 → 7.3.13
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/skills/testdriver:ai/SKILL.md +204 -0
- package/.github/skills/testdriver:assert/SKILL.md +284 -0
- package/.github/skills/testdriver:aws-setup/SKILL.md +515 -0
- package/.github/skills/testdriver:caching/SKILL.md +124 -0
- package/.github/skills/testdriver:captcha/SKILL.md +159 -0
- package/.github/skills/testdriver:ci-cd/SKILL.md +602 -0
- package/.github/skills/testdriver:click/SKILL.md +286 -0
- package/.github/skills/testdriver:client/SKILL.md +339 -0
- package/.github/skills/testdriver:cloud/SKILL.md +119 -0
- package/.github/skills/testdriver:customizing-devices/SKILL.md +153 -0
- package/.github/skills/testdriver:dashcam/SKILL.md +418 -0
- package/.github/skills/testdriver:debugging-with-screenshots/SKILL.md +271 -0
- package/.github/skills/testdriver:device-config/SKILL.md +317 -0
- package/.github/skills/testdriver:double-click/SKILL.md +102 -0
- package/.github/skills/testdriver:elements/SKILL.md +605 -0
- package/.github/skills/testdriver:enterprise/SKILL.md +114 -0
- package/.github/skills/testdriver:examples/SKILL.md +7 -0
- package/.github/skills/testdriver:exec/SKILL.md +345 -0
- package/.github/skills/testdriver:find/SKILL.md +721 -0
- package/.github/skills/testdriver:focus-application/SKILL.md +293 -0
- package/.github/skills/testdriver:generating-tests/SKILL.md +36 -0
- package/.github/skills/testdriver:hover/SKILL.md +278 -0
- package/.github/skills/testdriver:locating-elements/SKILL.md +71 -0
- package/.github/skills/testdriver:making-assertions/SKILL.md +32 -0
- package/.github/skills/testdriver:mcp-workflow/SKILL.md +410 -0
- package/.github/skills/testdriver:mouse-down/SKILL.md +161 -0
- package/.github/skills/testdriver:mouse-up/SKILL.md +164 -0
- package/.github/skills/testdriver:performing-actions/SKILL.md +51 -0
- package/.github/skills/testdriver:press-keys/SKILL.md +348 -0
- package/.github/skills/testdriver:quickstart/SKILL.md +161 -0
- package/.github/skills/testdriver:reusable-code/SKILL.md +240 -0
- package/.github/skills/testdriver:right-click/SKILL.md +123 -0
- package/.github/skills/testdriver:running-tests/SKILL.md +181 -0
- package/.github/skills/testdriver:screenshot/SKILL.md +167 -0
- package/.github/skills/testdriver:scroll/SKILL.md +299 -0
- package/.github/skills/testdriver:secrets/SKILL.md +115 -0
- package/.github/skills/testdriver:self-hosted/SKILL.md +65 -0
- package/.github/skills/testdriver:test-writer/SKILL.md +451 -0
- package/.github/skills/testdriver:testdriver/SKILL.md +523 -0
- package/.github/skills/testdriver:testdriver-mechanic/SKILL.md +165 -0
- package/.github/skills/testdriver:type/SKILL.md +357 -0
- package/.github/skills/testdriver:variables/SKILL.md +111 -0
- package/.github/skills/testdriver:waiting-for-elements/SKILL.md +66 -0
- package/.github/skills/testdriver:what-is-testdriver/SKILL.md +54 -0
- package/.github/workflows/acceptance-windows-scheduled.yaml +6 -1
- package/.github/workflows/acceptance.yaml +0 -36
- package/.github/workflows/update-examples.yaml +53 -0
- package/CHANGELOG.md +8 -0
- package/agent/events.js +1 -0
- package/agent/index.js +8 -0
- package/agent/lib/commands.js +48 -29
- package/agent/lib/redraw.js +3 -1
- package/agent/lib/sandbox.js +166 -14
- package/agent/lib/sdk.js +142 -3
- package/agent/lib/system.js +4 -6
- package/ai/skills/testdriver:ai/SKILL.md +204 -0
- package/ai/skills/testdriver:assert/SKILL.md +315 -0
- package/ai/skills/testdriver:aws-setup/SKILL.md +448 -0
- package/ai/skills/testdriver:caching/SKILL.md +124 -0
- package/ai/skills/testdriver:captcha/SKILL.md +159 -0
- package/ai/skills/testdriver:ci-cd/SKILL.md +602 -0
- package/ai/skills/testdriver:click/SKILL.md +286 -0
- package/ai/skills/testdriver:client/SKILL.md +372 -0
- package/ai/skills/testdriver:cloud/SKILL.md +119 -0
- package/ai/skills/testdriver:customizing-devices/SKILL.md +153 -0
- package/ai/skills/testdriver:dashcam/SKILL.md +418 -0
- package/ai/skills/testdriver:debugging-with-screenshots/SKILL.md +401 -0
- package/ai/skills/testdriver:device-config/SKILL.md +317 -0
- package/ai/skills/testdriver:double-click/SKILL.md +102 -0
- package/ai/skills/testdriver:elements/SKILL.md +605 -0
- package/ai/skills/testdriver:enterprise/SKILL.md +114 -0
- package/ai/skills/testdriver:examples/SKILL.md +7 -0
- package/ai/skills/testdriver:exec/SKILL.md +345 -0
- package/ai/skills/testdriver:find/SKILL.md +745 -0
- package/ai/skills/testdriver:focus-application/SKILL.md +293 -0
- package/ai/skills/testdriver:generating-tests/SKILL.md +36 -0
- package/ai/skills/testdriver:hover/SKILL.md +278 -0
- package/ai/skills/testdriver:locating-elements/SKILL.md +71 -0
- package/ai/skills/testdriver:making-assertions/SKILL.md +32 -0
- package/ai/skills/testdriver:mcp-workflow/SKILL.md +410 -0
- package/ai/skills/testdriver:mouse-down/SKILL.md +161 -0
- package/ai/skills/testdriver:mouse-up/SKILL.md +164 -0
- package/ai/skills/testdriver:ocr/SKILL.md +235 -0
- package/ai/skills/testdriver:performing-actions/SKILL.md +51 -0
- package/ai/skills/testdriver:press-keys/SKILL.md +348 -0
- package/ai/skills/testdriver:quickstart/SKILL.md +146 -0
- package/ai/skills/testdriver:reusable-code/SKILL.md +240 -0
- package/ai/skills/testdriver:right-click/SKILL.md +123 -0
- package/ai/skills/testdriver:running-tests/SKILL.md +185 -0
- package/ai/skills/testdriver:screenshot/SKILL.md +248 -0
- package/ai/skills/testdriver:scroll/SKILL.md +335 -0
- package/ai/skills/testdriver:secrets/SKILL.md +115 -0
- package/ai/skills/testdriver:self-hosted/SKILL.md +65 -0
- package/ai/skills/testdriver:test-writer/SKILL.md +451 -0
- package/ai/skills/testdriver:testdriver/SKILL.md +631 -0
- package/ai/skills/testdriver:testdriver-mechanic/SKILL.md +165 -0
- package/ai/skills/testdriver:type/SKILL.md +357 -0
- package/ai/skills/testdriver:variables/SKILL.md +111 -0
- package/ai/skills/testdriver:waiting-for-elements/SKILL.md +66 -0
- package/ai/skills/testdriver:what-is-testdriver/SKILL.md +54 -0
- package/debugger/index.html +12 -2
- package/docs/v7/examples/scroll-keyboard.mdx +1 -1
- package/docs/v7/find.mdx +1 -0
- package/examples/config.mjs +1 -1
- package/examples/findall-coffee-icons.test.mjs +42 -0
- package/examples/flake-diffthreshold-001.test.mjs +9 -0
- package/examples/flake-diffthreshold-01.test.mjs +9 -0
- package/examples/flake-diffthreshold-05.test.mjs +9 -0
- package/examples/{z_flake-noredraw-cache.test.mjs → flake-noredraw-cache.test.mjs} +2 -2
- package/examples/{z_flake-noredraw-nocache.test.mjs → flake-noredraw-nocache.test.mjs} +2 -2
- package/examples/{z_flake-redraw-cache.test.mjs → flake-redraw-cache.test.mjs} +2 -2
- package/examples/{z_flake-redraw-nocache.test.mjs → flake-redraw-nocache.test.mjs} +2 -2
- package/examples/flake-rocket-match.test.mjs +30 -0
- package/examples/{z_flake-shared.mjs → flake-shared.mjs} +2 -2
- package/examples/parse.test.mjs +19 -0
- package/examples/scroll-keyboard.test.mjs +1 -1
- package/interfaces/cli/lib/base.js +6 -0
- package/interfaces/logger.js +51 -13
- package/interfaces/vitest-plugin.mjs +137 -0
- package/lib/core/index.d.ts +22 -0
- package/lib/init-project.js +105 -6
- package/lib/vitest/hooks.mjs +2 -5
- package/lib/vitest/setup-disable-defender.mjs +52 -0
- package/package.json +2 -1
- package/sdk-log-formatter.js +90 -0
- package/sdk.d.ts +88 -51
- package/sdk.js +128 -21
- package/setup/aws/disable-defender.sh +42 -0
- package/vitest.config.mjs +1 -3
- package/examples/z_flake-diffthreshold-001.test.mjs +0 -9
- package/examples/z_flake-diffthreshold-01.test.mjs +0 -9
- package/examples/z_flake-diffthreshold-05.test.mjs +0 -9
- /package/{examples → manual}/captcha-api.test.mjs +0 -0
package/sdk.js
CHANGED
|
@@ -515,7 +515,7 @@ class Element {
|
|
|
515
515
|
} else if (cacheKey) {
|
|
516
516
|
// cacheKey provided - enable cache with threshold
|
|
517
517
|
// Per-command thresholds > legacy cacheThreshold > global config
|
|
518
|
-
threshold = perCommandThresholds?.screen ?? cacheThreshold ?? this.sdk.cacheConfig?.thresholds?.find?.screen ?? 0.
|
|
518
|
+
threshold = perCommandThresholds?.screen ?? cacheThreshold ?? this.sdk.cacheConfig?.thresholds?.find?.screen ?? 0.05;
|
|
519
519
|
elementSimilarity = perCommandThresholds?.element ?? this.sdk.cacheConfig?.thresholds?.find?.element ?? 0.8;
|
|
520
520
|
} else if (cacheThreshold !== null) {
|
|
521
521
|
// Explicit threshold provided without cacheKey
|
|
@@ -1325,6 +1325,34 @@ function createChainablePromise(promise) {
|
|
|
1325
1325
|
return chainablePromise;
|
|
1326
1326
|
}
|
|
1327
1327
|
|
|
1328
|
+
/**
|
|
1329
|
+
* Normalize redraw options from new thresholds format or legacy format to internal format.
|
|
1330
|
+
* New: { enabled: true, thresholds: { screen: 0.05, network: true } }
|
|
1331
|
+
* Legacy: { enabled: true, diffThreshold: 0.1, screenRedraw: true, networkMonitor: true }
|
|
1332
|
+
* Internal: { enabled: true, screenRedraw: true, networkMonitor: false }
|
|
1333
|
+
* @param {Object} opts - raw redraw options
|
|
1334
|
+
* @returns {Object} normalised options the redraw subsystem expects
|
|
1335
|
+
*/
|
|
1336
|
+
function normalizeRedrawOptions(opts) {
|
|
1337
|
+
if (!opts || typeof opts !== "object") {
|
|
1338
|
+
return { enabled: !!opts };
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
const result = { enabled: opts.enabled !== false };
|
|
1342
|
+
|
|
1343
|
+
// New thresholds format takes precedence
|
|
1344
|
+
if (opts.thresholds && typeof opts.thresholds === "object") {
|
|
1345
|
+
result.screenRedraw = opts.thresholds.screen !== false;
|
|
1346
|
+
result.networkMonitor = !!opts.thresholds.network;
|
|
1347
|
+
} else {
|
|
1348
|
+
// Legacy format fallback
|
|
1349
|
+
result.screenRedraw = opts.screenRedraw !== undefined ? opts.screenRedraw : true;
|
|
1350
|
+
result.networkMonitor = opts.networkMonitor !== undefined ? opts.networkMonitor : false;
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
return result;
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1328
1356
|
/**
|
|
1329
1357
|
* TestDriver SDK
|
|
1330
1358
|
*
|
|
@@ -1376,15 +1404,14 @@ class TestDriverSDK {
|
|
|
1376
1404
|
// Handle preview mode with backwards compatibility for headless option
|
|
1377
1405
|
// Preview can be "browser" (default), "ide", or "none" (headless)
|
|
1378
1406
|
let previewMode = options.preview || process.env.TD_PREVIEW;
|
|
1379
|
-
console.log("[DEBUG SDK constructor] options.preview:", options.preview, "previewMode:", previewMode);
|
|
1380
1407
|
|
|
1381
1408
|
// Backwards compatibility: headless: true maps to preview: "none"
|
|
1382
|
-
|
|
1409
|
+
// headless: true takes precedence over any preview setting
|
|
1410
|
+
if (options.headless === true) {
|
|
1383
1411
|
previewMode = "none";
|
|
1384
1412
|
} else if (!previewMode) {
|
|
1385
1413
|
previewMode = "browser"; // default
|
|
1386
1414
|
}
|
|
1387
|
-
console.log("[DEBUG SDK constructor] final previewMode:", previewMode);
|
|
1388
1415
|
|
|
1389
1416
|
// Set up environment with API key
|
|
1390
1417
|
const environment = {
|
|
@@ -1471,7 +1498,7 @@ class TestDriverSDK {
|
|
|
1471
1498
|
},
|
|
1472
1499
|
};
|
|
1473
1500
|
} else {
|
|
1474
|
-
// Support cache object format: { cache: { thresholds: { find: { screen: 0.
|
|
1501
|
+
// Support cache object format: { cache: { thresholds: { find: { screen: 0.05, element: 0.8 }, assert: 0.05 } } }
|
|
1475
1502
|
const cacheOpts = typeof options.cache === "object" ? options.cache : {};
|
|
1476
1503
|
const thresholds = cacheOpts.thresholds || {};
|
|
1477
1504
|
const findThresholds = typeof thresholds.find === "object" ? thresholds.find : {};
|
|
@@ -1480,7 +1507,7 @@ class TestDriverSDK {
|
|
|
1480
1507
|
enabled: cacheOpts.enabled !== false,
|
|
1481
1508
|
thresholds: {
|
|
1482
1509
|
find: {
|
|
1483
|
-
screen: findThresholds.screen ?? 0.
|
|
1510
|
+
screen: findThresholds.screen ?? 0.05, // Default: 5% pixel diff allowed
|
|
1484
1511
|
element: findThresholds.element ?? 0.8, // Default: 80% OpenCV correlation
|
|
1485
1512
|
},
|
|
1486
1513
|
assert: thresholds.assert ?? 0.05, // Default: 5% pixel diff for assertions
|
|
@@ -1507,22 +1534,23 @@ class TestDriverSDK {
|
|
|
1507
1534
|
} : {};
|
|
1508
1535
|
|
|
1509
1536
|
// Redraw configuration
|
|
1510
|
-
// Supports
|
|
1511
|
-
// - redraw: { enabled: true,
|
|
1512
|
-
// -
|
|
1513
|
-
//
|
|
1537
|
+
// Supports:
|
|
1538
|
+
// - redraw: { enabled: true, thresholds: { screen: 0.05, network: true } } (new)
|
|
1539
|
+
// - redraw: true/false (shorthand)
|
|
1540
|
+
// - redraw: { enabled: true, diffThreshold: 0.1, screenRedraw: true, networkMonitor: true } (legacy)
|
|
1541
|
+
// - redrawThreshold: 0.1 (legacy, deprecated)
|
|
1514
1542
|
if (options.redraw !== undefined) {
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1543
|
+
if (typeof options.redraw === "object") {
|
|
1544
|
+
this.redrawOptions = normalizeRedrawOptions(options.redraw);
|
|
1545
|
+
} else {
|
|
1546
|
+
this.redrawOptions = { enabled: !!options.redraw };
|
|
1547
|
+
}
|
|
1520
1548
|
} else if (options.redrawThreshold !== undefined) {
|
|
1521
|
-
// Legacy API: redrawThreshold number or object
|
|
1549
|
+
// Legacy API: redrawThreshold number or object (deprecated)
|
|
1522
1550
|
this.redrawOptions =
|
|
1523
1551
|
typeof options.redrawThreshold === "object"
|
|
1524
|
-
? options.redrawThreshold
|
|
1525
|
-
: {
|
|
1552
|
+
? normalizeRedrawOptions(options.redrawThreshold)
|
|
1553
|
+
: { enabled: true, screenRedraw: true, networkMonitor: false };
|
|
1526
1554
|
} else {
|
|
1527
1555
|
// Default: disabled (as of v7.3)
|
|
1528
1556
|
this.redrawOptions = { enabled: false };
|
|
@@ -1648,6 +1676,24 @@ class TestDriverSDK {
|
|
|
1648
1676
|
return "C:\\PROGRA~1\\nodejs\\node_modules\\dashcam-chrome\\build";
|
|
1649
1677
|
}
|
|
1650
1678
|
|
|
1679
|
+
/**
|
|
1680
|
+
* Extract domain pattern from a URL for web log tracking
|
|
1681
|
+
* @param {string} url - The URL to extract domain from
|
|
1682
|
+
* @returns {string} Domain pattern (e.g., "*://example.com/*")
|
|
1683
|
+
* @private
|
|
1684
|
+
*/
|
|
1685
|
+
_getUrlDomainPattern(url) {
|
|
1686
|
+
try {
|
|
1687
|
+
const parsed = new URL(url);
|
|
1688
|
+
// Use wildcard scheme and path to match all pages on the domain
|
|
1689
|
+
return `*://${parsed.hostname}*`;
|
|
1690
|
+
} catch (e) {
|
|
1691
|
+
// Fallback to ** if URL parsing fails
|
|
1692
|
+
console.warn(`[_getUrlDomainPattern] Failed to parse URL "${url}", using ** pattern`);
|
|
1693
|
+
return "**";
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1651
1697
|
/**
|
|
1652
1698
|
* Wait for Chrome DevTools Protocol debugger to be ready on port 9222,
|
|
1653
1699
|
* then wait for a page to report loaded.
|
|
@@ -1712,6 +1758,9 @@ class TestDriverSDK {
|
|
|
1712
1758
|
guest = false,
|
|
1713
1759
|
} = options;
|
|
1714
1760
|
|
|
1761
|
+
// Store the URL for domain-specific web log tracking
|
|
1762
|
+
self._provisionedChromeUrl = url;
|
|
1763
|
+
|
|
1715
1764
|
// Set up Chrome profile with preferences
|
|
1716
1765
|
const shell = this.os === "windows" ? "pwsh" : "sh";
|
|
1717
1766
|
const userDataDir =
|
|
@@ -1814,6 +1863,17 @@ class TestDriverSDK {
|
|
|
1814
1863
|
// Wait for Chrome debugger port and page to be ready
|
|
1815
1864
|
await this._waitForChromeDebuggerReady();
|
|
1816
1865
|
await this.focusApplication("Google Chrome");
|
|
1866
|
+
|
|
1867
|
+
// Add web log tracking with domain wildcard pattern, then start dashcam
|
|
1868
|
+
if (this.dashcamEnabled) {
|
|
1869
|
+
const domainPattern = this._getUrlDomainPattern(url);
|
|
1870
|
+
await this.dashcam.addWebLog(domainPattern, "Web Logs");
|
|
1871
|
+
|
|
1872
|
+
// Start dashcam recording after logs are configured
|
|
1873
|
+
if (!(await this.dashcam.isRecording())) {
|
|
1874
|
+
await this.dashcam.start();
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1817
1877
|
},
|
|
1818
1878
|
|
|
1819
1879
|
/**
|
|
@@ -2072,6 +2132,11 @@ with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
|
|
|
2072
2132
|
// Wait for Chrome debugger port and page to be ready
|
|
2073
2133
|
await this._waitForChromeDebuggerReady();
|
|
2074
2134
|
await this.focusApplication("Google Chrome");
|
|
2135
|
+
|
|
2136
|
+
// Start dashcam recording
|
|
2137
|
+
if (this.dashcamEnabled && !(await this.dashcam.isRecording())) {
|
|
2138
|
+
await this.dashcam.start();
|
|
2139
|
+
}
|
|
2075
2140
|
},
|
|
2076
2141
|
|
|
2077
2142
|
/**
|
|
@@ -2122,6 +2187,11 @@ with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
|
|
|
2122
2187
|
|
|
2123
2188
|
// Wait for VS Code to be ready
|
|
2124
2189
|
await this.focusApplication("Visual Studio Code");
|
|
2190
|
+
|
|
2191
|
+
// Start dashcam recording
|
|
2192
|
+
if (this.dashcamEnabled && !(await this.dashcam.isRecording())) {
|
|
2193
|
+
await this.dashcam.start();
|
|
2194
|
+
}
|
|
2125
2195
|
},
|
|
2126
2196
|
|
|
2127
2197
|
/**
|
|
@@ -2271,6 +2341,11 @@ with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
|
|
|
2271
2341
|
await this.focusApplication(appName);
|
|
2272
2342
|
}
|
|
2273
2343
|
|
|
2344
|
+
// Start dashcam recording
|
|
2345
|
+
if (this.dashcamEnabled && !(await this.dashcam.isRecording())) {
|
|
2346
|
+
await this.dashcam.start();
|
|
2347
|
+
}
|
|
2348
|
+
|
|
2274
2349
|
return actualFilePath;
|
|
2275
2350
|
},
|
|
2276
2351
|
|
|
@@ -2307,6 +2382,11 @@ with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
|
|
|
2307
2382
|
}
|
|
2308
2383
|
|
|
2309
2384
|
await this.focusApplication("Electron");
|
|
2385
|
+
|
|
2386
|
+
// Start dashcam recording
|
|
2387
|
+
if (this.dashcamEnabled && !(await this.dashcam.isRecording())) {
|
|
2388
|
+
await this.dashcam.start();
|
|
2389
|
+
}
|
|
2310
2390
|
},
|
|
2311
2391
|
|
|
2312
2392
|
/**
|
|
@@ -2349,8 +2429,12 @@ with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
|
|
|
2349
2429
|
await this.dashcam.addFileLog(actualLogPath, logName);
|
|
2350
2430
|
|
|
2351
2431
|
// Add web log tracking if enabled
|
|
2432
|
+
// Use domain pattern from provisioned Chrome URL if available
|
|
2352
2433
|
if (webLogs) {
|
|
2353
|
-
|
|
2434
|
+
const pattern = this._provisionedChromeUrl
|
|
2435
|
+
? this._getUrlDomainPattern(this._provisionedChromeUrl)
|
|
2436
|
+
: "**";
|
|
2437
|
+
await this.dashcam.addWebLog(pattern, "Web Logs");
|
|
2354
2438
|
}
|
|
2355
2439
|
|
|
2356
2440
|
// Start recording if not already recording
|
|
@@ -2767,14 +2851,37 @@ CAPTCHA_SOLVER_EOF`,
|
|
|
2767
2851
|
this.analytics.track("sdk.disconnect");
|
|
2768
2852
|
}
|
|
2769
2853
|
|
|
2854
|
+
// Clean up redraw interval if active
|
|
2855
|
+
if (this.agent?.redraw?.cleanup) {
|
|
2856
|
+
try {
|
|
2857
|
+
this.agent.redraw.cleanup();
|
|
2858
|
+
} catch (err) {
|
|
2859
|
+
// Ignore cleanup errors
|
|
2860
|
+
}
|
|
2861
|
+
}
|
|
2862
|
+
|
|
2863
|
+
// Stop the debugger server (HTTP + WebSocket server) to release the port
|
|
2864
|
+
try {
|
|
2865
|
+
const { stopDebugger } = require("./agent/lib/debugger-server.js");
|
|
2866
|
+
stopDebugger();
|
|
2867
|
+
} catch (err) {
|
|
2868
|
+
// Ignore if debugger wasn't started
|
|
2869
|
+
}
|
|
2870
|
+
|
|
2770
2871
|
// Always close the sandbox WebSocket connection to clean up resources
|
|
2771
2872
|
// This ensures we don't leave orphaned connections even if connect() failed
|
|
2772
2873
|
if (this.sandbox && typeof this.sandbox.close === "function") {
|
|
2773
2874
|
this.sandbox.close();
|
|
2774
2875
|
}
|
|
2775
2876
|
|
|
2877
|
+
// Remove all event listeners on the emitter to release references
|
|
2878
|
+
if (this.emitter && typeof this.emitter.removeAllListeners === "function") {
|
|
2879
|
+
this.emitter.removeAllListeners();
|
|
2880
|
+
}
|
|
2881
|
+
|
|
2776
2882
|
this.connected = false;
|
|
2777
2883
|
this.instance = null;
|
|
2884
|
+
this.commands = null;
|
|
2778
2885
|
}
|
|
2779
2886
|
|
|
2780
2887
|
/**
|
|
@@ -2821,7 +2928,7 @@ CAPTCHA_SOLVER_EOF`,
|
|
|
2821
2928
|
*
|
|
2822
2929
|
* @example
|
|
2823
2930
|
* // Find with custom cache threshold (legacy)
|
|
2824
|
-
* const element = await client.find('login button', 0.
|
|
2931
|
+
* const element = await client.find('login button', 0.05);
|
|
2825
2932
|
*
|
|
2826
2933
|
* @example
|
|
2827
2934
|
* // Poll until element is found
|
|
@@ -2987,7 +3094,7 @@ CAPTCHA_SOLVER_EOF`,
|
|
|
2987
3094
|
cacheKey = null; // Clear any cacheKey to ensure cache is truly disabled
|
|
2988
3095
|
} else if (cacheKey) {
|
|
2989
3096
|
// cacheKey provided - enable cache with threshold (findAll only uses screen, no element)
|
|
2990
|
-
threshold = perCommandThresholds?.screen ?? cacheThreshold ?? this.cacheConfig?.thresholds?.find?.screen ?? 0.
|
|
3097
|
+
threshold = perCommandThresholds?.screen ?? cacheThreshold ?? this.cacheConfig?.thresholds?.find?.screen ?? 0.05;
|
|
2991
3098
|
} else if (cacheThreshold !== null) {
|
|
2992
3099
|
// Explicit threshold provided without cacheKey
|
|
2993
3100
|
threshold = perCommandThresholds?.screen ?? cacheThreshold;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# --- Disable Windows Defender ---
|
|
5
|
+
# This script disables Windows Defender on a running AWS instance via SSM.
|
|
6
|
+
# Requires: AWS_REGION, INSTANCE_ID environment variables
|
|
7
|
+
|
|
8
|
+
: "${AWS_REGION:?Set AWS_REGION}"
|
|
9
|
+
: "${INSTANCE_ID:?Set INSTANCE_ID}"
|
|
10
|
+
|
|
11
|
+
echo "Disabling Windows Defender..."
|
|
12
|
+
DEFENDER_CMD=$(aws ssm send-command \
|
|
13
|
+
--region "$AWS_REGION" \
|
|
14
|
+
--instance-ids "$INSTANCE_ID" \
|
|
15
|
+
--document-name "AWS-RunPowerShellScript" \
|
|
16
|
+
--parameters 'commands=["Set-MpPreference -DisableRealtimeMonitoring $true", "Set-MpPreference -DisableIOAVProtection $true", "Set-MpPreference -DisableBehaviorMonitoring $true", "Set-MpPreference -DisableBlockAtFirstSeen $true", "Set-MpPreference -DisableScriptScanning $true", "Write-Output \"Windows Defender disabled successfully\""]' \
|
|
17
|
+
--output json)
|
|
18
|
+
|
|
19
|
+
DEFENDER_CMD_ID=$(jq -r '.Command.CommandId' <<<"$DEFENDER_CMD")
|
|
20
|
+
echo "Defender disable command ID: $DEFENDER_CMD_ID"
|
|
21
|
+
|
|
22
|
+
echo "Waiting for Defender disable command to complete..."
|
|
23
|
+
if aws ssm wait command-executed --region "$AWS_REGION" --command-id "$DEFENDER_CMD_ID" --instance-id "$INSTANCE_ID" 2>/dev/null; then
|
|
24
|
+
DEFENDER_STATUS=$(aws ssm get-command-invocation \
|
|
25
|
+
--region "$AWS_REGION" \
|
|
26
|
+
--command-id "$DEFENDER_CMD_ID" \
|
|
27
|
+
--instance-id "$INSTANCE_ID" \
|
|
28
|
+
--output json)
|
|
29
|
+
DEFENDER_OUTPUT=$(jq -r '.StandardOutputContent // ""' <<<"$DEFENDER_STATUS")
|
|
30
|
+
DEFENDER_ERROR=$(jq -r '.StandardErrorContent // ""' <<<"$DEFENDER_STATUS")
|
|
31
|
+
DEFENDER_CMD_STATUS=$(jq -r '.Status // ""' <<<"$DEFENDER_STATUS")
|
|
32
|
+
|
|
33
|
+
echo "Defender disable status: $DEFENDER_CMD_STATUS"
|
|
34
|
+
if [ -n "$DEFENDER_OUTPUT" ] && [ "$DEFENDER_OUTPUT" != "null" ]; then
|
|
35
|
+
echo "✓ $DEFENDER_OUTPUT"
|
|
36
|
+
fi
|
|
37
|
+
if [ -n "$DEFENDER_ERROR" ] && [ "$DEFENDER_ERROR" != "null" ]; then
|
|
38
|
+
echo "⚠ Defender stderr: $DEFENDER_ERROR"
|
|
39
|
+
fi
|
|
40
|
+
else
|
|
41
|
+
echo "⚠ Defender disable command may have timed out, continuing anyway..."
|
|
42
|
+
fi
|
package/vitest.config.mjs
CHANGED
|
@@ -6,15 +6,13 @@ import { defineConfig } from "vitest/config";
|
|
|
6
6
|
const setupFiles = [
|
|
7
7
|
"testdriverai/vitest/setup",
|
|
8
8
|
"testdriverai/vitest/setup-aws",
|
|
9
|
+
'testdriverai/vitest/setup-disable-defender'
|
|
9
10
|
];
|
|
10
11
|
|
|
11
12
|
export default defineConfig({
|
|
12
13
|
test: {
|
|
13
|
-
retry: 1,
|
|
14
14
|
testTimeout: 900000,
|
|
15
15
|
hookTimeout: 900000,
|
|
16
|
-
disableConsoleIntercept: true,
|
|
17
|
-
maxConcurrency: 100,
|
|
18
16
|
reporters: [
|
|
19
17
|
"default",
|
|
20
18
|
TestDriver(),
|
|
File without changes
|