Initial commit
This commit is contained in:
175
skills/website-debug/scripts/browser-console.js
Executable file
175
skills/website-debug/scripts/browser-console.js
Executable file
@@ -0,0 +1,175 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* browser-console.js - Get console messages from page
|
||||
*
|
||||
* Usage:
|
||||
* ./browser-console.js # Get all console messages
|
||||
* ./browser-console.js --errors # Only errors
|
||||
* ./browser-console.js --warnings # Errors and warnings
|
||||
* ./browser-console.js --watch # Watch for new messages
|
||||
*/
|
||||
|
||||
import puppeteer from "puppeteer-core";
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
const errorsOnly = args.includes("--errors");
|
||||
const warningsPlus = args.includes("--warnings");
|
||||
const watch = args.includes("--watch");
|
||||
const port = args.find(a => a.startsWith("--port="))?.split("=")[1] || "9222";
|
||||
|
||||
if (args.includes("--help") || args.includes("-h")) {
|
||||
console.log(`
|
||||
browser-console.js - Capture console messages
|
||||
|
||||
Usage:
|
||||
./browser-console.js [options]
|
||||
|
||||
Options:
|
||||
--errors Show only errors
|
||||
--warnings Show errors and warnings
|
||||
--watch Watch for new messages in real-time
|
||||
--port=PORT Connect to custom debug port (default: 9222)
|
||||
|
||||
Message Types:
|
||||
[ERR] - console.error, exceptions
|
||||
[WARN] - console.warn
|
||||
[LOG] - console.log
|
||||
[INFO] - console.info
|
||||
[DBG] - console.debug
|
||||
|
||||
Examples:
|
||||
./browser-console.js
|
||||
./browser-console.js --errors
|
||||
./browser-console.js --watch
|
||||
`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
try {
|
||||
const browser = await puppeteer.connect({
|
||||
browserURL: `http://localhost:${port}`,
|
||||
defaultViewport: null
|
||||
});
|
||||
|
||||
const pages = await browser.pages();
|
||||
const page = pages[pages.length - 1];
|
||||
|
||||
if (!page) {
|
||||
console.error("✗ No active tab found");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (watch) {
|
||||
console.log("Watching console... (Ctrl+C to stop)\n");
|
||||
|
||||
const shouldShow = (type) => {
|
||||
if (errorsOnly) return type === "error";
|
||||
if (warningsPlus) return type === "error" || type === "warning";
|
||||
return true;
|
||||
};
|
||||
|
||||
const typeLabels = {
|
||||
error: "[ERR] ",
|
||||
warning: "[WARN]",
|
||||
log: "[LOG] ",
|
||||
info: "[INFO]",
|
||||
debug: "[DBG] "
|
||||
};
|
||||
|
||||
page.on("console", msg => {
|
||||
const type = msg.type();
|
||||
if (shouldShow(type)) {
|
||||
const label = typeLabels[type] || `[${type.toUpperCase()}]`;
|
||||
const text = msg.text();
|
||||
console.log(`${label} ${text}`);
|
||||
}
|
||||
});
|
||||
|
||||
page.on("pageerror", err => {
|
||||
console.log(`[ERR] Uncaught: ${err.message}`);
|
||||
});
|
||||
|
||||
// Keep alive
|
||||
await new Promise(() => {});
|
||||
} else {
|
||||
// Get existing console messages by injecting capture
|
||||
const messages = await page.evaluate(() => {
|
||||
// Return any cached messages if we have them
|
||||
return window.__consoleMessages || [];
|
||||
});
|
||||
|
||||
// Also get any runtime exceptions
|
||||
const client = await page.target().createCDPSession();
|
||||
await client.send("Runtime.enable");
|
||||
|
||||
// Collect current console messages by re-evaluating with capture
|
||||
const capturedMessages = await page.evaluate(() => {
|
||||
const msgs = [];
|
||||
const originalConsole = {
|
||||
log: console.log,
|
||||
error: console.error,
|
||||
warn: console.warn,
|
||||
info: console.info,
|
||||
debug: console.debug
|
||||
};
|
||||
|
||||
// This is for future messages - we can't capture past ones without this being set up earlier
|
||||
// So we'll note that limitation
|
||||
return msgs;
|
||||
});
|
||||
|
||||
// Get recent exceptions from CDP
|
||||
const { result } = await client.send("Runtime.evaluate", {
|
||||
expression: `
|
||||
(function() {
|
||||
// Check for any unhandled errors stored in window
|
||||
const errors = window.__webdebugErrors || [];
|
||||
return errors;
|
||||
})()
|
||||
`,
|
||||
returnByValue: true
|
||||
});
|
||||
|
||||
if (messages.length === 0 && (!result.value || result.value.length === 0)) {
|
||||
console.log("No console messages captured.");
|
||||
console.log("\nTip: Use --watch to capture messages in real-time, or inject capture script:");
|
||||
console.log(' ./browser-eval.js "window.__consoleMessages=[];[\'log\',\'error\',\'warn\',\'info\'].forEach(t=>{const o=console[t];console[t]=(...a)=>{window.__consoleMessages.push({type:t,text:a.join(\' \'),time:Date.now()});o.apply(console,a)}});"');
|
||||
} else {
|
||||
const allMessages = [...messages, ...(result.value || [])];
|
||||
|
||||
const typeLabels = {
|
||||
error: "[ERR] ",
|
||||
warning: "[WARN]",
|
||||
warn: "[WARN]",
|
||||
log: "[LOG] ",
|
||||
info: "[INFO]",
|
||||
debug: "[DBG] "
|
||||
};
|
||||
|
||||
allMessages.forEach(msg => {
|
||||
const type = msg.type || "log";
|
||||
const shouldShow = () => {
|
||||
if (errorsOnly) return type === "error";
|
||||
if (warningsPlus) return type === "error" || type === "warning" || type === "warn";
|
||||
return true;
|
||||
};
|
||||
|
||||
if (shouldShow()) {
|
||||
const label = typeLabels[type] || `[${type.toUpperCase()}]`;
|
||||
console.log(`${label} ${msg.text || msg.message || JSON.stringify(msg)}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!watch) {
|
||||
await browser.disconnect();
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.message?.includes("ECONNREFUSED")) {
|
||||
console.error("✗ Cannot connect to browser. Run: ./browser-start.js");
|
||||
} else {
|
||||
console.error(`✗ Console capture failed: ${e.message}`);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
Reference in New Issue
Block a user