skip to content

In Selenium 4's WebDriver BiDi, what do event names like `log.entryAdded` and `network.beforeRequestSent` tell you?

level: juniorimportance: should knowfreq 38%

answer

  1. Names come in two halves
  2. The first half is not decoration
  3. Something owns entryAdded and beforeRequestSent
  4. You can subscribe to the prefix alone
  5. Modules: session, browsingContext, network, log

basics

~20 s

Every BiDi name is module dot member. The prefix names the module that owns it, so log owns entryAdded and network owns beforeRequestSent. The same prefixes cover commands, which is how the protocol is organised.

solid answer

~30 s

WebDriver BiDi in Selenium 4 is organised into **modules**, and every command and event is named `module.member`. So `log.entryAdded` is the `entryAdded` event of the `log` module, and `network.beforeRequestSent` is the `beforeRequestSent` event of the `network` module. The main modules are `session` (subscribe, unsubscribe, status), `browsingContext` (contexts and navigation, with events such as `contextCreated`, `domContentLoaded` and `load`), `network` (`beforeRequestSent`, `responseStarted`, `responseCompleted`, `fetchError`, `authRequired`), `log` (`entryAdded`), plus `script`, `input`, `storage` and `browser`. The prefix is not cosmetic: `session.subscribe` accepts a bare module name, so subscribing to `network` takes every event that module defines rather than listing them one by one.

go deeper

for a junior

Be ready to read a BiDi name aloud as module dot member and say which module owns it. Knowing that log owns entryAdded and network owns beforeRequestSent is the level of recall interviewers expect here.

for a middle

Explain what the module split buys: whole-module subscription, a shared payload vocabulary across a module's events, and the request id that lets you match a request event to its response event.

for a senior

Show that you treat the catalogue as closed. Diagnose an empty capture as a subscription that named an event the remote end does not define, rather than assuming the browser produced nothing worth pushing.

for a principal

Own the convention: which modules a suite subscribes to as standard, whether whole-module subscriptions are acceptable given their volume, and how the team avoids inventing names copied from other debugging protocols.

## Every name is `module.member` **WebDriver BiDi** in Selenium 4 is not a flat list of messages. It is split into **modules**, and every command and every event is named as the module, a dot, and the member. Read `log.entryAdded` as "the `entryAdded` event of the `log` module" and `network.beforeRequestSent` as "the `beforeRequestSent` event of the `network` module". Once you see the pattern, an unfamiliar name tells you where to look before you have read a line of documentation. The same naming covers commands. `session.subscribe` is a command of the `session` module, `browsingContext.navigate` a command of the `browsingContext` module, `script.evaluate` a command of the `script` module. Commands and events share one namespace per module, so a module is the complete story about one concern: `network` holds both the events that report a request and the commands that act on one, and you never have to remember two different vocabularies for the same area. ## The module catalogue | Module | Concern | Representative members | |---|---|---| | `session` | the channel itself | `session.status`, `session.subscribe`, `session.unsubscribe` | | `browsingContext` | tabs, frames, navigation | `browsingContext.contextCreated`, `browsingContext.navigationStarted`, `browsingContext.domContentLoaded`, `browsingContext.load` | | `network` | requests and responses | `network.beforeRequestSent`, `network.responseStarted`, `network.responseCompleted`, `network.fetchError`, `network.authRequired` | | `log` | console and script records | `log.entryAdded` | | `script` | evaluating in page realms | `script.evaluate`, `script.addPreloadScript` | | `input` | synthesised pointer and key input | `input.performActions` | | `storage` | cookies and stored state | `storage.getCookies` | | `browser` | the browser instance itself | `browser.createUserContext` | ## Reading the names against a real page Put a hotel room-booking calendar behind it. A tester pages the calendar from September to October, and the page fetches that month's nightly rates. The names line up with what happens: - The tab the calendar lives in announced itself as `browsingContext.contextCreated` when it was opened, and will announce its closing as `browsingContext.contextDestroyed`. - The first load of the calendar produced `browsingContext.navigationStarted`, then `browsingContext.domContentLoaded`, then `browsingContext.load`. - The rates fetch appears first as `network.beforeRequestSent`, carrying the request's method, URL and headers. - The reply appears as `network.responseStarted` and then `network.responseCompleted`; a request that never completed appears as `network.fetchError` instead, and one that hit an authentication challenge as `network.authRequired`. - A warning the date grid writes while re-rendering arrives as `log.entryAdded`, with the record's level, text and timestamp. Every one of those is a separate pushed frame. None of them is an answer to a command the client sent, which is why they all carry a `method` and no command id. ## Why the prefix is load-bearing The module half of the name is not decoration; three behaviours hang off it. 1. **Subscription granularity.** `session.subscribe` accepts a bare module name in its `events` list. Subscribing to `network` takes every event that module defines, which is much shorter than naming five members and is stable when the module gains a sixth. 2. **Payload shape.** Members of a module share vocabulary. The `network` events all describe the same request through its life, so a request id seen on `network.beforeRequestSent` is the one to match against `network.responseCompleted` when you want the pair. 3. **Where to look.** An unknown member is a lookup inside one module's section of the specification rather than a search of the whole protocol. ## A name that does not exist is a defect, not a guess BiDi's catalogue is closed: the modules and members are the ones the specification defines. Names borrowed from other debugging protocols do not work, and neither do plausible inventions. There is no `page` module, no `dom` module and no `window` module in BiDi. Navigation and load belong to `browsingContext`; console records belong to `log`. A subscribe command naming an event the remote end does not know is rejected, and the practical symptom is the one people misread most often: **an empty capture that looks like the browser produced nothing**, when in fact the subscription never took. ## What to take away - BiDi names are always `module.member`, for commands as well as events. - The module prefix is what you subscribe to when you want a whole area. - The common modules are `session`, `browsingContext`, `network`, `log`, `script`, `input`, `storage` and `browser`. - `log.entryAdded` and `network.beforeRequestSent` are the two names most worth memorising, because they are the ones an interviewer will actually ask you to place.

  • Which module owns the events for a tab opening and a page finishing loading in the booking calendar?
    The `browsingContext` module. It owns the browsing contexts themselves — tabs and frames — so `browsingContext.contextCreated` fires when the calendar's tab appears and `browsingContext.contextDestroyed` when it closes. Navigation through that context produces `browsingContext.navigationStarted`, then `browsingContext.domContentLoaded`, then `browsingContext.load`. There is no separate page or window module in BiDi; all of it lives under this one prefix.
  • Why would you subscribe to `network` rather than listing its individual events?
    Because `session.subscribe` accepts a bare module name and expands it to every event the module defines. That is shorter than naming `beforeRequestSent`, `responseStarted`, `responseCompleted`, `fetchError` and `authRequired`, and it keeps working when the module gains a member. The tradeoff is volume: on a page that fetches an image per room thumbnail, a whole-module subscription delivers far more than a targeted one, and the client pays to read it.

saying these in an interview costs you the question

  • Guessing event names instead of using the defined catalogue
  • Assuming BiDi has a page or dom module
  • Thinking the module prefix is only a naming convention
  • Believing modules carry events but never commands
  • Reading an empty capture as the browser producing nothing