cbrowser 18.55.1 → 18.57.0
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/README.md +4 -4
- package/dist/analysis/accessibility-empathy.d.ts.map +1 -1
- package/dist/analysis/accessibility-empathy.js +4 -34
- package/dist/analysis/accessibility-empathy.js.map +1 -1
- package/dist/analysis/agent-ready-audit.d.ts.map +1 -1
- package/dist/analysis/agent-ready-audit.js +37 -32
- package/dist/analysis/agent-ready-audit.js.map +1 -1
- package/dist/analysis/competitive-benchmark.d.ts.map +1 -1
- package/dist/analysis/competitive-benchmark.js +4 -13
- package/dist/analysis/competitive-benchmark.js.map +1 -1
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +97 -46
- package/dist/browser.js.map +1 -1
- package/dist/cli.js +90 -1
- package/dist/cli.js.map +1 -1
- package/dist/mcp-server-remote.d.ts.map +1 -1
- package/dist/mcp-server-remote.js +93 -118
- package/dist/mcp-server-remote.js.map +1 -1
- package/dist/mcp-tools/base/advanced-interaction-tools.d.ts +14 -0
- package/dist/mcp-tools/base/advanced-interaction-tools.d.ts.map +1 -0
- package/dist/mcp-tools/base/advanced-interaction-tools.js +174 -0
- package/dist/mcp-tools/base/advanced-interaction-tools.js.map +1 -0
- package/dist/mcp-tools/base/audit-tools.d.ts +3 -3
- package/dist/mcp-tools/base/audit-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/audit-tools.js +179 -47
- package/dist/mcp-tools/base/audit-tools.js.map +1 -1
- package/dist/mcp-tools/base/browser-management-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/browser-management-tools.js +62 -0
- package/dist/mcp-tools/base/browser-management-tools.js.map +1 -1
- package/dist/mcp-tools/base/browser-state-tools.d.ts +14 -0
- package/dist/mcp-tools/base/browser-state-tools.d.ts.map +1 -0
- package/dist/mcp-tools/base/browser-state-tools.js +229 -0
- package/dist/mcp-tools/base/browser-state-tools.js.map +1 -0
- package/dist/mcp-tools/base/cognitive-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/cognitive-tools.js +10 -5
- package/dist/mcp-tools/base/cognitive-tools.js.map +1 -1
- package/dist/mcp-tools/base/index.d.ts +2 -0
- package/dist/mcp-tools/base/index.d.ts.map +1 -1
- package/dist/mcp-tools/base/index.js +10 -2
- package/dist/mcp-tools/base/index.js.map +1 -1
- package/dist/mcp-tools/base/navigation-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/navigation-tools.js +9 -2
- package/dist/mcp-tools/base/navigation-tools.js.map +1 -1
- package/dist/mcp-tools/base/persona-comparison-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/persona-comparison-tools.js +27 -2
- package/dist/mcp-tools/base/persona-comparison-tools.js.map +1 -1
- package/dist/mcp-tools/base/visual-testing-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/visual-testing-tools.js +3 -1
- package/dist/mcp-tools/base/visual-testing-tools.js.map +1 -1
- package/dist/mcp-tools/tool-categories.d.ts.map +1 -1
- package/dist/mcp-tools/tool-categories.js +12 -0
- package/dist/mcp-tools/tool-categories.js.map +1 -1
- package/dist/remediation/llms-txt.js +4 -14
- package/dist/remediation/llms-txt.js.map +1 -1
- package/dist/remediation/structured-data.js +4 -13
- package/dist/remediation/structured-data.js.map +1 -1
- package/dist/types.d.ts +16 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/visual/cognitive-transport-chain.d.ts +6 -0
- package/dist/visual/cognitive-transport-chain.d.ts.map +1 -1
- package/dist/visual/cognitive-transport-chain.js +41 -0
- package/dist/visual/cognitive-transport-chain.js.map +1 -1
- package/dist/visual/cognitive-transport.d.ts +6 -0
- package/dist/visual/cognitive-transport.d.ts.map +1 -1
- package/dist/visual/cognitive-transport.js +164 -0
- package/dist/visual/cognitive-transport.js.map +1 -1
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -392,9 +392,15 @@ For more help: https://playwright.dev/docs/browsers
|
|
|
392
392
|
};
|
|
393
393
|
contextOptions.permissions = ["geolocation"];
|
|
394
394
|
}
|
|
395
|
-
// Apply locale if configured
|
|
395
|
+
// Apply locale if configured — sets navigator.language AND Accept-Language header
|
|
396
|
+
// This makes sites that respect Accept-Language serve localized content
|
|
396
397
|
if (this.config.locale) {
|
|
397
398
|
contextOptions.locale = this.config.locale;
|
|
399
|
+
const lang = this.config.locale.split("-")[0];
|
|
400
|
+
contextOptions.extraHTTPHeaders = {
|
|
401
|
+
...contextOptions.extraHTTPHeaders,
|
|
402
|
+
"Accept-Language": `${this.config.locale},${lang};q=0.9,en;q=0.5`,
|
|
403
|
+
};
|
|
398
404
|
}
|
|
399
405
|
// Apply timezone if configured
|
|
400
406
|
if (this.config.timezone) {
|
|
@@ -1427,59 +1433,103 @@ For more help: https://playwright.dev/docs/browsers
|
|
|
1427
1433
|
const waitStrategy = options.waitStrategy || "auto";
|
|
1428
1434
|
const waitTimeout = options.waitTimeout ?? 10000;
|
|
1429
1435
|
const waitForStability = options.waitForStability ?? (waitStrategy === "auto" || waitStrategy === "domcontentloaded");
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1436
|
+
// Helper to detect proxy tunnel errors and provide actionable messages
|
|
1437
|
+
const wrapProxyError = (e) => {
|
|
1438
|
+
const errMsg = e.message || "";
|
|
1439
|
+
if (errMsg.includes("ERR_TUNNEL_CONNECTION_FAILED") || errMsg.includes("ERR_PROXY_CONNECTION_FAILED")) {
|
|
1440
|
+
const proxyServer = this.config.proxy?.server || "configured proxy";
|
|
1441
|
+
throw new Error(`Proxy tunnel rejected by ${url}. The target site is blocking proxy/VPN connections ` +
|
|
1442
|
+
`(proxy: ${proxyServer}). This is the site's anti-bot defense, not a CBrowser issue.\n\n` +
|
|
1443
|
+
`Recommendations:\n` +
|
|
1444
|
+
`1. Re-run without the proxy to test from your direct IP\n` +
|
|
1445
|
+
`2. Try a different geo region — the site may block specific IP ranges\n` +
|
|
1446
|
+
`3. Some sites (Stripe, GitHub, banking) aggressively block residential proxies`);
|
|
1447
|
+
}
|
|
1448
|
+
if (errMsg.includes("ERR_NETWORK_CHANGED") && this.config.proxy) {
|
|
1449
|
+
throw new Error(`Network changed during proxy connection to ${url}. The residential proxy IP may have rotated mid-request ` +
|
|
1450
|
+
`or the site detected and dropped the proxy tunnel.\n\n` +
|
|
1451
|
+
`Recommendations:\n` +
|
|
1452
|
+
`1. Retry — residential proxy IPs rotate and the next one may work\n` +
|
|
1453
|
+
`2. Re-run without the proxy to test from your direct IP\n` +
|
|
1454
|
+
`3. Use a sticky session proxy for sites that are sensitive to IP changes`);
|
|
1455
|
+
}
|
|
1456
|
+
throw e;
|
|
1457
|
+
};
|
|
1458
|
+
try {
|
|
1459
|
+
if (waitStrategy === "commit") {
|
|
1460
|
+
// Fastest: don't wait at all after navigation commits
|
|
1461
|
+
await page.goto(url, { waitUntil: "commit", timeout: this.config.timeout || 30000 });
|
|
1462
|
+
}
|
|
1463
|
+
else if (waitStrategy === "load") {
|
|
1464
|
+
// Standard: wait for load event
|
|
1465
|
+
await page.goto(url, { waitUntil: "load", timeout: this.config.timeout || 30000 });
|
|
1466
|
+
}
|
|
1467
|
+
else if (waitStrategy === "domcontentloaded") {
|
|
1468
|
+
// Fast: wait only for DOM
|
|
1469
|
+
await page.goto(url, { waitUntil: "domcontentloaded", timeout: this.config.timeout || 30000 });
|
|
1470
|
+
if (waitForStability) {
|
|
1471
|
+
await this.waitForStability(page, 2000);
|
|
1472
|
+
}
|
|
1443
1473
|
}
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
await page.goto(url, { waitUntil: "networkidle", timeout: this.config.timeout || 30000 });
|
|
1448
|
-
}
|
|
1449
|
-
else {
|
|
1450
|
-
// "auto" (default): Progressive loading strategy
|
|
1451
|
-
// Many SPAs (GitHub, NYT, BBC, etc.) never reach networkidle
|
|
1452
|
-
const networkIdleTimeout = Math.min(waitTimeout, this.config.timeout || 30000);
|
|
1453
|
-
try {
|
|
1454
|
-
// Try networkidle first with short timeout
|
|
1455
|
-
await page.goto(url, {
|
|
1456
|
-
waitUntil: "networkidle",
|
|
1457
|
-
timeout: networkIdleTimeout,
|
|
1458
|
-
});
|
|
1474
|
+
else if (waitStrategy === "networkidle") {
|
|
1475
|
+
// Strict: wait for network idle, may fail on SPAs
|
|
1476
|
+
await page.goto(url, { waitUntil: "networkidle", timeout: this.config.timeout || 30000 });
|
|
1459
1477
|
}
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
}
|
|
1467
|
-
// Fallback to domcontentloaded (rethrows on failure)
|
|
1478
|
+
else {
|
|
1479
|
+
// "auto" (default): Progressive loading strategy
|
|
1480
|
+
// Many SPAs (GitHub, NYT, BBC, etc.) never reach networkidle
|
|
1481
|
+
const networkIdleTimeout = Math.min(waitTimeout, this.config.timeout || 30000);
|
|
1482
|
+
try {
|
|
1483
|
+
// Try networkidle first with short timeout
|
|
1468
1484
|
await page.goto(url, {
|
|
1469
|
-
waitUntil: "
|
|
1470
|
-
timeout:
|
|
1485
|
+
waitUntil: "networkidle",
|
|
1486
|
+
timeout: networkIdleTimeout,
|
|
1471
1487
|
});
|
|
1472
|
-
// Wait for page to stabilize (no major DOM changes for 500ms)
|
|
1473
|
-
if (waitForStability) {
|
|
1474
|
-
await this.waitForStability(page, 2000);
|
|
1475
|
-
}
|
|
1476
1488
|
}
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1489
|
+
catch (e) {
|
|
1490
|
+
const error = e;
|
|
1491
|
+
if (error.message?.includes("Timeout") || error.message?.includes("timeout")) {
|
|
1492
|
+
// Fallback: Use domcontentloaded + manual stability check
|
|
1493
|
+
if (this.config.verbose) {
|
|
1494
|
+
console.log(`⚠️ networkidle timeout after ${waitTimeout}ms, falling back to domcontentloaded...`);
|
|
1495
|
+
}
|
|
1496
|
+
// Fallback to domcontentloaded (rethrows on failure)
|
|
1497
|
+
await page.goto(url, {
|
|
1498
|
+
waitUntil: "domcontentloaded",
|
|
1499
|
+
timeout: this.config.timeout || 30000,
|
|
1500
|
+
});
|
|
1501
|
+
// Wait for page to stabilize (no major DOM changes for 500ms)
|
|
1502
|
+
if (waitForStability) {
|
|
1503
|
+
await this.waitForStability(page, 2000);
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
else {
|
|
1507
|
+
// Non-timeout error — proxy detection handled by outer catch
|
|
1508
|
+
wrapProxyError(e);
|
|
1509
|
+
}
|
|
1480
1510
|
}
|
|
1481
1511
|
}
|
|
1482
1512
|
}
|
|
1513
|
+
catch (navError) {
|
|
1514
|
+
// Wrap any proxy-related navigation error with actionable message
|
|
1515
|
+
wrapProxyError(navError);
|
|
1516
|
+
}
|
|
1517
|
+
// Post-navigation waits for dynamic content (translation, deferred rendering)
|
|
1518
|
+
let waitSelectorTimedOut = false;
|
|
1519
|
+
if (options.waitForSelector) {
|
|
1520
|
+
try {
|
|
1521
|
+
await page.waitForSelector(options.waitForSelector, {
|
|
1522
|
+
timeout: options.waitTimeout ?? 10000,
|
|
1523
|
+
});
|
|
1524
|
+
}
|
|
1525
|
+
catch {
|
|
1526
|
+
waitSelectorTimedOut = true;
|
|
1527
|
+
warnings.push(`waitForSelector "${options.waitForSelector}" timed out after ${options.waitTimeout ?? 10000}ms — the expected element never appeared. The page may not have completed the operation you were waiting for (e.g., translation, dynamic render).`);
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
if (options.waitAfterLoad && options.waitAfterLoad > 0) {
|
|
1531
|
+
await page.waitForTimeout(options.waitAfterLoad);
|
|
1532
|
+
}
|
|
1483
1533
|
const loadTime = Date.now() - startTime;
|
|
1484
1534
|
// v11.9.0: Post-navigation verification to detect context desync (issue #84)
|
|
1485
1535
|
const actualUrl = page.url();
|
|
@@ -1526,6 +1576,7 @@ For more help: https://playwright.dev/docs/browsers
|
|
|
1526
1576
|
warnings,
|
|
1527
1577
|
loadTime,
|
|
1528
1578
|
success: true,
|
|
1579
|
+
...(waitSelectorTimedOut ? { waitSelectorTimedOut: true } : {}),
|
|
1529
1580
|
};
|
|
1530
1581
|
}
|
|
1531
1582
|
/**
|