From 806072aaceacaf9d80fce2b7df5926b18166d697 Mon Sep 17 00:00:00 2001 From: Mohammad Saddam Hossain Date: Sun, 25 Oct 2026 07:03:29 +0530 Subject: [PATCH] feat(tracing): show browser console errors in the trace file Console errors were already collected per test but never rendered in the trace. Add a Console Errors section (HTML-escaped), omitted when empty. Refs #130 Co-Authored-By: Claude Sonnet 5.5 --- CHANGELOG.md | 2 ++ docs-site/docs/changelog.md | 2 ++ .../com/seleniumboot/tracing/TraceRecorder.java | 12 ++++++++++++ .../seleniumboot/unit/TraceRecorderTest.java | 17 +++++++++++++++++ 4 files changed, 33 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba4d1ba..568322f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/). ### Unreleased +- **Trace shows browser console errors** — when `browser.captureConsoleErrors: true`, the JS errors collected for a test now appear in its trace file under "Console Errors", next to the steps and failure details, so a shared trace includes what the browser logged. No change when the option is off. (#130) + - **Network mocking on Firefox via WebDriver BiDi** — `networkMock().stub(...)` now uses WebDriver BiDi network interception under the hood when supported by the driver (including Firefox and BiDi-enabled drivers), falling back to Chrome DevTools Protocol (CDP) for Chromium-based drivers. The existing stubbing API (`returnJson`, `returnBody`, `returnStatus`, `delay`, `clear`) works identically across Chrome and Firefox. (#196) --- diff --git a/docs-site/docs/changelog.md b/docs-site/docs/changelog.md index 596dda9..0e75984 100644 --- a/docs-site/docs/changelog.md +++ b/docs-site/docs/changelog.md @@ -11,6 +11,8 @@ All notable changes to Selenium Boot are documented here. ## [Unreleased] +- **Trace shows browser console errors** — when `browser.captureConsoleErrors: true`, the JS errors collected for a test now appear in its trace file under "Console Errors", next to the steps and failure details, so a shared trace includes what the browser logged. No change when the option is off. (#130) + - **Network mocking on Firefox via WebDriver BiDi** — `networkMock().stub(...)` now uses WebDriver BiDi network interception under the hood when supported by the driver (including Firefox and BiDi-enabled drivers), falling back to Chrome DevTools Protocol (CDP) for Chromium-based drivers. The existing stubbing API (`returnJson`, `returnBody`, `returnStatus`, `delay`, `clear`) works identically across Chrome and Firefox. (#196) --- diff --git a/src/main/java/com/seleniumboot/tracing/TraceRecorder.java b/src/main/java/com/seleniumboot/tracing/TraceRecorder.java index 6a78c23..48d7ea6 100644 --- a/src/main/java/com/seleniumboot/tracing/TraceRecorder.java +++ b/src/main/java/com/seleniumboot/tracing/TraceRecorder.java @@ -28,6 +28,7 @@ *
  • Named step timeline — each step logged via {@code StepLogger} as a clickable block
  • *
  • Per-step screenshots — click a step to reveal its screenshot
  • *
  • Final-state screenshot — taken at the moment of failure
  • + *
  • Browser console errors — when {@code browser.captureConsoleErrors} is on
  • *
  • Error message + full stack trace
  • * * @@ -196,6 +197,17 @@ public static String buildHtml(TestTiming timing, String testName, String finalS sb.append(" \n\n"); } + // ── Console errors ── + List consoleErrors = timing.getConsoleErrors(); + if (!consoleErrors.isEmpty()) { + sb.append("
    \n"); + sb.append("
    Console Errors"); + sb.append(" (").append(consoleErrors.size()).append(")
    \n"); + sb.append("
    ");
    +            for (String e : consoleErrors) sb.append(escHtml(e)).append('\n');
    +            sb.append("
    \n
    \n"); + } + // ── Error section ── if (errorMsg != null || stackTrace != null) { sb.append("
    \n"); diff --git a/src/test/java/com/seleniumboot/unit/TraceRecorderTest.java b/src/test/java/com/seleniumboot/unit/TraceRecorderTest.java index 6cc3073..483f48f 100644 --- a/src/test/java/com/seleniumboot/unit/TraceRecorderTest.java +++ b/src/test/java/com/seleniumboot/unit/TraceRecorderTest.java @@ -186,6 +186,23 @@ public void buildHtml_escapesHtmlInErrorMessage() { // Helper // ------------------------------------------------------------------ + @Test + public void buildHtml_rendersConsoleErrors_escaped() { + TestTiming t = timing("jsErrTest"); + t.setConsoleErrors(List.of("TypeError: x is undefined", "")); + String html = TraceRecorder.buildHtml(t, "jsErrTest", null); + Assert.assertTrue(html.contains("Console Errors"), "console section expected"); + Assert.assertTrue(html.contains("TypeError: x is undefined")); + Assert.assertTrue(html.contains("<script>alert(1)</script>"), "must be HTML-escaped"); + Assert.assertFalse(html.contains("")); + } + + @Test + public void buildHtml_omitsConsoleSection_whenNoErrors() { + String html = TraceRecorder.buildHtml(timing("cleanJs"), "cleanJs", null); + Assert.assertFalse(html.contains("Console Errors")); + } + private static TestTiming timing(String testName) { TestTiming t = new TestTiming(testName, "test-thread"); t.setStatus("FAILED");