skip to content

Browser Console Output

Pulling console entries back with driver.manage().logs(). Interviewers probe it because log retrieval never entered the W3C standard, so Chrome has it and Firefox does not.

on this pageshow

explore

questions

3

A Selenium suite reads browser console entries on Chrome but the same code throws on Firefox. Why, and how do you handle it?

level: seniorimportance: must knowfreq 62%

answer

  1. Check the specification's endpoint list
  2. The path segment gives it away
  3. It compiles, it just fails later
  4. One method asks before the other reads
  5. Unknown command maps to an exception

basics

~10 s

Log retrieval was never standardised in W3C WebDriver, so Selenium routes it to its own extension endpoint. ChromeDriver implements that endpoint and geckodriver does not, so the call throws UnsupportedCommandException on Firefox.

solid answer

~40 s

The W3C WebDriver specification defines no log-retrieval endpoint, so `driver.manage().logs()` is a vendor extension: Selenium 4 sends `POST /session/{id}/se/log`, and the `se/` prefix marks it as Selenium's own route rather than a standard one. ChromeDriver serves it; geckodriver has no such route and answers 404 with the W3C error `unknown command`, which Selenium maps to `UnsupportedCommandException`. The call compiles on Firefox because `logs()` is declared on `WebDriver.Options`, so the break is purely at run time. The fix is to ask before you read: `logs().getAvailableLogTypes()` returns the set the remote end will actually serve, so the harness can skip console collection for that session and record that it was unavailable, rather than swallowing the exception or hard-coding a list of supported browsers.

go deeper

for a junior

Know that reading the browser console is not available in every browser through Selenium, and that the call can throw rather than simply return an empty result.

for a middle

Explain the mechanism: no standard endpoint exists, Selenium posts to its own se/log route, and a driver without that route answers unknown command, which surfaces as UnsupportedCommandException.

for a senior

Show the production handling: probe getAvailableLogTypes per session, degrade gracefully, record that console evidence was unavailable, and resist both blanket catches and retry loops.

for a principal

Own the tradeoff of a cross-browser matrix whose evidence differs by browser, and decide how much the organisation invests in a vendor extension versus the standard-track direction.

## Log retrieval never entered the WebDriver standard The W3C WebDriver specification defines the endpoints every conforming remote end must implement: navigation, element retrieval, actions, cookies, screenshots, timeouts, alerts. **Log retrieval is not among them.** There is no `GET /session/{id}/log`, no console command, no log-entry data type — the word "log" does not appear in the specification's endpoint table at all. Reading the browser console over WebDriver is therefore a **vendor extension**: it exists exactly where a particular driver chose to implement it. That is why the same test code behaves differently by browser. ChromeDriver implements it; geckodriver does not. Selenium's own test suite makes the split visible — `GetLogsTest`, `AvailableLogsTest` and `PerformanceLogTypeTest` all carry `@Ignore(FIREFOX)`, `@Ignore(IE)` and `@Ignore(SAFARI)` annotations, because there is nothing there to test. ## What the Java client sends anyway Selenium 4 still ships the API and routes it to a **Selenium-namespaced extension endpoint**. The `se/` path segment is the tell: it marks a route the Selenium project defined, not one the standard did. | Java call | HTTP request | Standard? | |---|---|---| | `logs().get(logType)` | `POST /session/{id}/se/log` with `{"type": "browser"}` | no — Selenium extension | | `logs().getAvailableLogTypes()` | `GET /session/{id}/se/log/types` | no — Selenium extension | | `getScreenshotAs(...)` | `GET /session/{id}/screenshot` | yes — W3C endpoint | Every binding agrees on those paths, so the behaviour is identical whether the suite is written in Java, Python, JavaScript or C#. ## What happens on Firefox `driver.manage().logs()` is declared on `WebDriver.Options`, which `FirefoxDriver` inherits through `RemoteWebDriver` like every other driver. **The call therefore compiles perfectly** — the failure is a runtime one: 1. The client sends `POST /session/{id}/se/log`. 2. geckodriver has no route for that path and answers with HTTP 404 and the W3C error code `unknown command`. 3. Selenium's error codec maps `unknown command` onto **`UnsupportedCommandException`**, which the client throws. So a suite that works on Chrome fails on Firefox with an exception about an unsupported command, in the teardown hook, on the run where you most wanted the evidence. The symptom usually shows up first in a cross-browser CI matrix rather than on a developer's machine, because most people develop against one browser and only meet the second one in the pipeline. Two details make the failure nastier than it looks. First, the exception is thrown from the **failure-handling path**, so it can mask the assertion failure that triggered it and leave a report blaming the console read rather than the station map. Second, `getAvailableLogTypes()` fails in exactly the same way against geckodriver — the probe is itself an extension call — so a harness cannot use it naively without a guard around the guard, or without knowing that a driver serving neither route will refuse both. ## Detect support, do not assume it The remedy is the other method on the interface. `getAvailableLogTypes()` asks the remote end what it will serve, so the harness can decide per session instead of per browser name: ```java Set<String> available = driver.manage().logs().getAvailableLogTypes(); if (available.contains(LogType.BROWSER)) { attachConsole(driver.manage().logs().get(LogType.BROWSER)); } ``` Points worth making when this comes up in an interview: - **Branch on capability, not on class name.** Checking whether the driver is a `ChromeDriver` bakes a browser list into the harness that goes stale the moment a browser gains or loses the endpoint. - **A blanket `catch (Exception e)` is worse than a check.** It hides genuine failures — a dead session, a crashed driver — behind the same silence as an unimplemented endpoint. - **Do not retry.** `unknown command` is a permanent condition for that remote end; a retry loop only slows the failing run down. - **Say what is missing in the failure record.** "Console entries unavailable on this browser" is a far better artefact than an empty log that reads as "the page logged nothing". - **Accept an asymmetric matrix.** It is legitimate for the Chrome legs of the bicycle-share station map suite to carry console evidence and the Firefox legs not to; pretending otherwise leads to fake parity. ## Where the console lives when the endpoint is missing Selenium 4 also ships a client for **WebDriver BiDi**, the standard-track bidirectional protocol, which is the direction the project has taken for live browser events rather than after-the-fact log retrieval. Where a browser serves no `/se/log` route, that is the surface a modern suite reaches for; the subscription mechanics are a topic of their own. What matters for this question is the shape of the answer: `driver.manage().logs()` is a legacy vendor extension with real coverage gaps, not a portable Selenium feature, and any harness that treats it as portable will fail on the first non-Chromium browser it meets.

  • Why not just wrap the console read in a try/catch and move on?
    Because a blanket catch cannot tell an unimplemented endpoint from a real problem. A dead session, a crashed driver and a browser that never had the route all collapse into the same silent branch, and the failure record ends up claiming the page logged nothing. `getAvailableLogTypes()` answers the question directly, so the harness can record "unavailable on this browser" as a distinct, honest outcome.
  • Which Selenium exception does the Firefox call throw, and where does that mapping come from?
    `UnsupportedCommandException`. geckodriver responds with HTTP 404 and the W3C error code `unknown command`, and Selenium 4's error codec maps `unknown command`, `unknown method` and `unsupported operation` all onto `UnsupportedCommandException`. So the exception type tells you the remote end refused the command, not that the arguments were wrong.
  • Does this gap change what you consider a cross-browser suite?
    It changes what you claim, not what you run. The Firefox legs of a bicycle-share station map suite still exercise the same behaviour; they just carry less diagnostic evidence when they fail. The honest position is an asymmetric evidence matrix that the report states explicitly, rather than a harness that pretends every browser produces the same artefacts.

saying these in an interview costs you the question

  • Claims log retrieval is part of the W3C WebDriver standard
  • Says the Firefox call fails to compile rather than at run time
  • Wraps the read in a blanket catch and reports nothing
  • Hard-codes a list of browsers believed to support logs
  • Retries the call as though it were a transient failure
open as a page

In Selenium's Java client, how do you read a page's browser console output, and what comes back?

level: juniorimportance: should knowfreq 58%

basics

~10 s

Call driver.manage().logs().get(LogType.BROWSER). It returns a LogEntries collection of LogEntry objects, each carrying a level, a timestamp in epoch milliseconds, and the message text. Each call drains the buffer it read.

open as a page

In Selenium 4, what does LoggingPreferences change, and under which capability key is it sent to Chrome?

level: middleimportance: nice to knowfreq 38%

basics

~10 s

LoggingPreferences maps each log type to a minimum severity the remote end should buffer, and it is set at session creation. For Chrome it travels under the vendor-prefixed capability key goog:loggingPrefs.

open as a page