An engineer asked me why Selenium could not tell them which network requests a page had made. They had searched for an hour and found only workarounds.
The answer is in the protocol, and once you know the protocol you stop searching for features that cannot exist.
WebDriver is a W3C standard, not a library. That is the fact everything else follows from.
Your test code does not control the browser. It sends HTTP requests to a driver process, and the driver translates them into browser-specific instructions.
Your test ──HTTP──▶ chromedriver ──internal──▶ Chrome
◀──JSON── ◀──
Every single command is a round trip. findElement is an HTTP POST. click is another. getText is another.
What that predicts about performance. A test doing 50 actions makes at least 50 HTTP round trips. On localhost each is a millisecond or two and invisible. Against a remote Grid across a network, each might be 30ms, and the same test is a second and a half slower before the browser does any work.
This is why Selenium suites slow down disproportionately when moved to a remote Grid, and why chatty test code costs more here than in other tools. Finding an element once and reusing the reference is not micro-optimisation in Selenium; it is one fewer network round trip.
What that predicts about features. The protocol defines a fixed set of commands: find elements, interact, navigate, manage cookies, execute scripts, handle alerts and frames, take screenshots. That is roughly the whole surface.
Network interception is not in it. Neither is response mocking, nor request inspection. Not an oversight and not a missing feature: the protocol was designed to automate user actions, and watching network traffic is not a user action. This is what that engineer was searching for.
Selenium sees the page the way a user does, and no further. Everything senior engineers wish Selenium could do falls into one of two buckets: things the protocol covers, and things it does not. Learning the boundary is worth more than learning any individual API.
The session model. new Builder().build() creates a session: the driver launches a browser and returns a session ID. Every subsequent command carries that ID. quit() ends the session and releases the browser.
Two consequences that cause real production problems, both covered in the next lecture. A session that is never quit leaves a browser process running forever. And a session is a single conversation, so sharing one driver across parallel threads produces interleaved commands and unpredictable results.
Element references are protocol-level handles. When findElement returns, you receive an opaque ID that refers to an element in that browser's current DOM. It is not the element. When the page re-renders, the ID refers to something that no longer exists, and the next command using it returns StaleElementReferenceException.
Staleness is not a Selenium quirk. It is the protocol being honest that your handle expired.
WebDriver BiDi is the current answer to the gap. A newer bidirectional protocol adding what classic WebDriver could not do: listening to browser events, console messages, and network activity. It is arriving in Selenium and browsers now, and it is the right thing to mention when an interviewer asks about Selenium's future. It closes the network-visibility gap without abandoning the standard.
Why the standard is worth the cost. Everything above reads as limitation, so state the other side clearly. Because WebDriver is a W3C standard implemented by browser makers, Selenium works across more browsers, more languages and more platforms than anything else, and it will still work in ten years. A company needing Java tests on Safari and Edge and a legacy internal browser has one realistic option. That reach is what the round trips buy.
Remember this: commands are HTTP round trips to a driver, the protocol defines a fixed surface, and BiDi is what extends it.
Reference: WebDriver specification.