Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

---
Expand Down
2 changes: 2 additions & 0 deletions docs-site/docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

---
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/com/seleniumboot/tracing/TraceRecorder.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
* <li>Named step timeline — each step logged via {@code StepLogger} as a clickable block</li>
* <li>Per-step screenshots — click a step to reveal its screenshot</li>
* <li>Final-state screenshot — taken at the moment of failure</li>
* <li>Browser console errors — when {@code browser.captureConsoleErrors} is on</li>
* <li>Error message + full stack trace</li>
* </ul>
*
Expand Down Expand Up @@ -196,6 +197,17 @@ public static String buildHtml(TestTiming timing, String testName, String finalS
sb.append(" </div>\n</div>\n");
}

// ── Console errors ──
List<String> consoleErrors = timing.getConsoleErrors();
if (!consoleErrors.isEmpty()) {
sb.append("<div class=\"section\">\n");
sb.append(" <div class=\"section-title\">Console Errors");
sb.append(" <span class=\"step-count\">(").append(consoleErrors.size()).append(")</span></div>\n");
sb.append(" <pre class=\"stack-trace console-errors\">");
for (String e : consoleErrors) sb.append(escHtml(e)).append('\n');
sb.append("</pre>\n</div>\n");
}

// ── Error section ──
if (errorMsg != null || stackTrace != null) {
sb.append("<div class=\"section error-section\">\n");
Expand Down
17 changes: 17 additions & 0 deletions src/test/java/com/seleniumboot/unit/TraceRecorderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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", "<script>alert(1)</script>"));
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("&lt;script&gt;alert(1)&lt;/script&gt;"), "must be HTML-escaped");
Assert.assertFalse(html.contains("<script>alert(1)</script>"));
}

@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");
Expand Down
Loading