skip to content

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

level: middleimportance: nice to knowfreq 38%

answer

  1. It is set before the session exists
  2. A type paired with a severity floor
  3. The key is not vendor-neutral
  4. Chrome and Edge spell it differently
  5. One type is off until asked for

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.

solid answer

~40 s

`LoggingPreferences` is a map from log type to minimum `java.util.logging.Level`, built with `enable(LogType.PERFORMANCE, Level.ALL)` and attached to the options object before the session starts. Because logging is not in the WebDriver standard, there is no standard capability key: Chrome takes `goog:loggingPrefs`, exposed as `ChromeOptions.LOGGING_PREFS`, and Edge takes `ms:loggingPrefs` as `EdgeOptions.LOGGING_PREFS`. In Selenium 4 the `CapabilityType` interface has no logging constant at all, so old samples using `CapabilityType.LOGGING_PREFS` will not compile. Practically, preferences do two things: turn on the performance log, which ChromeDriver leaves off by default, and raise the severity floor on the browser log so routine `INFO` chatter from a bicycle-share station map's feed poller is never buffered in the first place.

code

java · 26 lines
java
import java.util.logging.Level;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;

public class StationMapLogPrefs {
  public static void main(String[] args) {
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.BROWSER, Level.WARNING);
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);

    ChromeOptions options = new ChromeOptions();
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    WebDriver driver = new ChromeDriver(options);
    try {
      driver.get("https://example.com/bike-share/stations");
      System.out.println(driver.manage().logs().getAvailableLogTypes());
      System.out.println(driver.manage().logs().get(LogType.PERFORMANCE).getAll().size());
    } finally {
      driver.quit();
    }
  }
}

go deeper

for a junior

Know that the browser log needs no configuration on Chrome, and that anything beyond it has to be requested when the driver is created rather than later.

for a middle

Explain the mechanics: a type-to-level map set as a capability at session creation, sent under goog:loggingPrefs for Chrome, with the performance log off until enabled.

for a senior

Show the operational angle: preferences raise the severity floor at the source, a wrong key fails silently, and the only reliable confirmation is what getAvailableLogTypes reports afterwards.

for a principal

Own whether a suite should depend on a vendor-prefixed logging capability at all, given it binds evidence collection to one browser family.

## What `LoggingPreferences` is for `LoggingPreferences` is a small Selenium class that maps a **log type** to a **minimum severity**. You build one, call `enable(String logType, Level level)` once per type you want, and hand it to the browser as a capability when the session is created. Internally it is just a `Map<String, Level>`, with `getEnabledLogTypes()` returning the keys and `getLevel(type)` returning the level — or `Level.OFF` for a type you never enabled. It is a **session-creation** setting, not something you can change mid-run. The remote end reads it once while starting the session and uses it to decide what it will buffer for the rest of that session, which means a bicycle-share station map suite that wants performance records has to ask for them before the first `driver.get()`, not after the map fails to load. ## The capability key is vendor-prefixed This is the part that trips people. In Selenium 4 there is **no standard capability key** for logging preferences, because logging is not in the WebDriver standard at all. Each Chromium-family options class carries its own prefixed constant: | Options class | Constant | Capability key | |---|---|---| | `ChromeOptions` | `ChromeOptions.LOGGING_PREFS` | `goog:loggingPrefs` | | `EdgeOptions` | `EdgeOptions.LOGGING_PREFS` | `ms:loggingPrefs` | | `CapabilityType` | — | none; **`CapabilityType` declares no logging constant in Selenium 4** | The last row matters. The Javadoc on `LoggingPreferences` still shows an old sample using `CapabilityType.LOGGING_PREFS` alongside `DesiredCapabilities`, but that constant is not in Selenium 4's `CapabilityType` interface, whose eleven constants are all standard W3C keys plus `se:downloadsEnabled`. Copying that sample will not compile. The Selenium 4 spelling is: ```java LoggingPreferences logPrefs = new LoggingPreferences(); logPrefs.enable(LogType.PERFORMANCE, Level.ALL); ChromeOptions options = new ChromeOptions(); options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs); WebDriver driver = new ChromeDriver(options); ``` ## What is already on, and what is not Against ChromeDriver with no preferences set at all: - **`browser` is available by default.** `getAvailableLogTypes()` contains `LogType.BROWSER` on a plain session, so console errors from `station-map.js` need no configuration. - **`driver` is available by default** as well, carrying records the remote end itself emits over the same endpoint. - **`performance` is not.** Selenium's `PerformanceLogTypeTest` asserts that `getAvailableLogTypes()` does *not* contain `LogType.PERFORMANCE` on an unconfigured session. So the honest one-line summary is: preferences are mostly about **turning on what is off** (the performance log) and **raising the floor on what is on** (asking for `Level.WARNING` so the browser log stops buffering routine `INFO` chatter from the station-feed poller). ## How the preference is serialised `LoggingPreferences.toJson()` produces a flat object of type name to level name, so the two-entry example below travels as `{"browser": "WARNING", "driver": "ALL"}`. Two details are worth knowing: 1. **Levels are normalised.** `LogLevelMapping.normalize` folds any JDK level onto one of `ALL`, `FINE`, `INFO`, `WARNING`, `SEVERE`, `OFF`, so an unusual custom level does not travel verbatim. 2. **`Level.FINE` is written as `"DEBUG"`.** That is the one name that is not the JDK's own; reading in the other direction, `LogLevelMapping.toLevel("DEBUG")` returns `Level.FINE`. There is also `addPreferences(LoggingPreferences)`, which merges another set in with the incoming values winning — useful when a base test class sets a default and one suite wants to override a single type. `LoggingPreferences` implements `equals` and `hashCode` over its map, so two independently built objects enabling the same types at the same levels compare equal, which makes them easy to assert on in a harness's own tests. ## The failure mode is silence Nothing about this API tells you it did not work. A remote end that does not recognise a vendor-prefixed capability simply ignores it, so a misspelled key, the wrong vendor's prefix, or a preference set on the wrong options object all produce the same picture: a session that starts perfectly, a `getAvailableLogTypes()` set that quietly lacks the type you asked for, and a `get()` returning an empty `LogEntries` that reads as "nothing happened". There is no exception to catch and no warning in the client's output. That is why the confirmation step is worth its one line. Printing `driver.manage().logs().getAvailableLogTypes()` immediately after the driver is created turns a silent misconfiguration into an obvious one, and it costs a single round trip per session. ## Putting it together for the station map 1. Decide which types the run needs: `browser` for page errors, `performance` only when the run is investigating the station-feed timings. 2. Build a `LoggingPreferences` and `enable()` each of those with the lowest severity you actually want buffered. 3. Set it on the options object under the **vendor-prefixed key for the browser you are launching**, then create the driver. 4. After the failure, confirm with `getAvailableLogTypes()` and read the types that appear. Get any of those steps wrong and the failure mode is quiet: no error, just a log type that never shows up in `getAvailableLogTypes()` and a `get()` that returns nothing to attach.

  • Can you change logging preferences on a session that is already running?
    No. The preferences travel as a capability in the new-session request, and the remote end reads them once while creating the session to decide what it will buffer. There is no command to alter them afterwards, so a run that discovers mid-test that it wanted performance records has to be restarted with the preference set.
  • How does a LoggingPreferences object look on the wire?
    As a flat JSON object of type name to level name — enabling `browser` at `Level.WARNING` and `driver` at `Level.ALL` serialises to `{"browser": "WARNING", "driver": "ALL"}`. Levels are normalised onto `ALL`, `FINE`, `INFO`, `WARNING`, `SEVERE` and `OFF` first, and `Level.FINE` is written with the non-JDK name `DEBUG`.
  • What is the symptom when the capability key is wrong?
    Silence. An unrecognised capability with a vendor prefix is simply ignored by the remote end, so the session starts normally, `getAvailableLogTypes()` never lists the type you asked for, and `get()` returns nothing. There is no error to catch, which is why checking the available types after session creation is worth the one line.

saying these in an interview costs you the question

  • Uses CapabilityType.LOGGING_PREFS, which Selenium 4 no longer declares
  • Assumes one vendor-neutral loggingPrefs key works for every browser
  • Believes the performance log is available without being enabled
  • Tries to change logging preferences after the session has started
  • Expects an error when the capability key is misspelled