diff --git a/src/commands/stop.ts b/src/commands/stop.ts index 2600ed3..d358252 100644 --- a/src/commands/stop.ts +++ b/src/commands/stop.ts @@ -138,10 +138,36 @@ export async function stopCommand(options: StopOptions): Promise { } // Step 6: Count errors + // Uncaught page errors, as reported by agent-browser's `errors` command. const consoleErrorLines = consoleErrors .split('\n') .filter((l) => l.trim() && l.trim() !== 'No errors'); - const consoleErrorCount = consoleErrorLines.length > 0 && consoleErrors.trim() !== '' ? consoleErrorLines.length : 0; + // Also count console.error output. Modern apps catch most failures and + // report them via console.error (fetch failures, error boundaries, caught + // exceptions), so counting only uncaught errors under-reports the very + // thing the summary labels "Console errors". + // Primary source: timestamped entries. Fallback: the raw console output, + // in case `console --json` was unavailable or returned an unexpected shape. + let loggedErrorLines = consoleEntries + .filter((e) => e.text.startsWith('[error]')) + .map((e) => e.text); + if (loggedErrorLines.length === 0 && consoleOutput.trim()) { + loggedErrorLines = consoleOutput.split('\n').filter((l) => l.startsWith('[error]')); + } + // Dedupe on normalized text so "Error: X" (uncaught) and "[error] Error: X" + // (console entry for the same error) are not double-counted. + const normalize = (l: string) => l.replace(/^\[error\]\s*/, '').trim(); + const seenErrors = new Set(); + const allConsoleErrorLines: string[] = []; + for (const line of [...consoleErrorLines, ...loggedErrorLines]) { + const key = normalize(line); + if (key && !seenErrors.has(key)) { + seenErrors.add(key); + allConsoleErrorLines.push(line); + } + } + const consoleErrorCount = allConsoleErrorLines.length; + const consoleErrorsReport = allConsoleErrorLines.join('\n'); // Extract errors from server log using multi-language patterns const serverErrorLines = extractServerErrors(serverLog); @@ -158,7 +184,7 @@ export async function stopCommand(options: StopOptions): Promise { port: session.port, videoPath: session.videoPath, screenshots, - consoleErrors, + consoleErrors: consoleErrorsReport, consoleErrorCount, serverLog, serverErrorCount, @@ -241,11 +267,11 @@ export async function stopCommand(options: StopOptions): Promise { if (consoleErrorCount > 0) { console.log(''); console.log(chalk.red.bold('Console Errors:')); - for (const line of consoleErrorLines.slice(0, 10)) { + for (const line of allConsoleErrorLines.slice(0, 10)) { console.log(chalk.red(` ${line}`)); } - if (consoleErrorLines.length > 10) { - console.log(chalk.dim(` ... and ${consoleErrorLines.length - 10} more (see SUMMARY.md)`)); + if (allConsoleErrorLines.length > 10) { + console.log(chalk.dim(` ... and ${allConsoleErrorLines.length - 10} more (see SUMMARY.md)`)); } }