Selenium 4 and the W3C WebDriver Protocol: What Changed
Selenium 4 standardized on W3C WebDriver and dropped legacy JSON Wire Protocol support. Learn what changed and how to check your Selenium 3 migration.
Direct answer: Selenium 4 uses the W3C WebDriver protocol and removes support for the legacy JSON Wire Protocol. Most code that was already W3C-compliant in a recent Selenium 3 release should continue to work. During an upgrade, review browser capabilities and Actions interactions first: malformed capabilities can prevent a session from starting, and interaction behavior can expose differences.
The protocol change concerns communication between a local Selenium client and a browser or remote end. It does not mean Selenium 4 requires a new programming language API, and it is separate from WebDriver BiDi, which adds bidirectional browser-event communication.
What changed in Selenium 4?
Selenium 3 supported both the emerging W3C WebDriver protocol and the older JSON Wire Protocol while the standard was being developed. Selenium 4 completed the move to W3C WebDriver and dropped the legacy protocol. The Selenium project explained that maintaining conversion and handshake logic between the two dialects added complexity and edge cases. The exact transition differed by binding and Grid version: Ruby, JavaScript, and .NET removed handshake code for Selenium 4.0, while Java and Python had later transition details; remaining legacy support was removed in Java Selenium 4.9 and Grid 4.9. Check the versions in your own stack rather than assuming every binding changed at the same release. Selenium’s legacy protocol chronology explains the transition.
| Area | JSON Wire Protocol | W3C WebDriver |
|---|---|---|
| Status in Selenium 4 | Legacy protocol; no longer supported | Standard protocol |
| Capabilities | Older clients and servers could rely on legacy formats | Standard names and structured vendor namespaces are expected |
| Session setup | Some Selenium 3 combinations used handshakes or translation between dialects | Client and remote end communicate using the standardized protocol |
| Migration impact | Legacy assumptions may fail when translation is gone | Recent W3C-compliant Selenium 3 code generally carries forward |
The W3C WebDriver specification defines a platform- and language-neutral remote control interface. It standardizes the remote end’s HTTP wire protocol and command endpoints; it does not prescribe how each language binding must implement its local API.
Does Selenium 4 still support JSON Wire Protocol?
No. Selenium 4’s supported protocol is W3C WebDriver. If an old client, browser driver, or Grid setup depended on JSON Wire Protocol conversion, that dependency can surface as a session-creation failure or incompatible command behavior after upgrading. Selenium’s migration guidance says code compliant with W3C WebDriver in the latest Selenium 3 should work as expected in Selenium 4, but it calls out capabilities and Actions for review. See the Selenium 4 upgrade guide.
Migration checklist: Selenium 3 to Selenium 4
- Upgrade the language binding and related dependencies. Follow the official instructions for your binding, and record the exact Selenium client, browser driver, browser, and Grid versions. This makes version-specific protocol behavior diagnosable.
- Move to browser Options classes where appropriate. Replace deprecated Desired Capabilities patterns with the binding’s browser-specific Options API. Use the capabilities the browser and remote service document.
- Check standard capability names. Use
browserVersioninstead ofversion, andplatformNameinstead ofplatform. - Namespace non-standard capabilities. Browser or cloud-provider capabilities should use the vendor’s documented prefix or options namespace. Do not send arbitrary unprefixed keys and assume the remote end will accept them.
- Run a minimal session test. Start the browser with only the necessary options, navigate to a known page, and quit. Add your project’s capabilities back incrementally if the session fails.
- Exercise Actions interactions. Re-run tests using pointer, keyboard, drag-and-drop, or other complex actions. If an interaction changes, isolate it in a small test and inspect the action sequence and browser behavior.
- Audit legacy Grid paths. If a Selenium 2 or 3 client talks through Grid, confirm the exact client and Grid versions. Do not assume Selenium 4.9 or Grid 4.9 will translate the old protocol.
- Keep BiDi migration separate. First establish that classic WebDriver sessions and commands work. Consider BiDi only when you need its bidirectional event capabilities.
Capability examples and configuration
Use the Options class supported by your binding and keep standard WebDriver capabilities separate from provider-specific settings. The exact API syntax varies by Selenium version and language, so treat this Java example as a pattern and check your binding’s current API documentation.
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class W3cSession {
public static void main(String[] args) {
ChromeOptions options = new ChromeOptions();
options.setBrowserVersion("stable");
options.setPlatformName("linux");
WebDriver driver = new ChromeDriver(options);
try {
driver.get("https://example.com");
System.out.println(driver.getTitle());
} finally {
driver.quit();
}
}
}
For a remote browser, pass the Options object to the remote driver and add provider settings only in the namespace that provider documents. For example, cloud services commonly use a vendor options object; the name and accepted keys are provider-specific, so copy them from that provider’s current documentation rather than guessing.
Capability review
browserName: identify the requested browser.browserVersion: request a browser version; do not use legacyversion.platformName: request the platform; do not use legacyplatform.- Vendor-specific settings: use the supported vendor prefix or options namespace.
- Unknown or misspelled keys: remove them while diagnosing. Non-W3C capabilities can cause session creation to fail.
What to check when Actions tests change
The migration guide calls out Actions as an area to review, but it does not mean every action changes. Focus on tests that combine devices or depend on precise input timing, such as pointer movement followed by a click, key modifiers held across actions, or drag-and-drop. Reduce a failing interaction to the smallest reproducible sequence, verify the target element is interactable, then check whether the client, browser driver, or browser version changed along with Selenium. Avoid attributing a failure to the protocol until those variables are isolated.
WebDriver BiDi is a separate protocol capability
Classic W3C WebDriver provides the standardized command interface used to control browsers. WebDriver BiDi is related but distinct: Selenium describes it as bidirectional communication over WebSocket, enabling browser events to flow back to the client. Moving from JSON Wire Protocol to W3C WebDriver does not itself enable BiDi, and a classic WebDriver migration does not require adopting BiDi. See Selenium’s WebDriver documentation.
Troubleshooting common migration errors
| Symptom | Likely cause | What to do |
|---|---|---|
| Session will not start; remote end rejects capabilities | Legacy names such as version or platform, malformed capability structure, or unsupported unprefixed vendor keys |
Use browserVersion and platformName; move provider options into the documented namespace. Start with a minimal Options object and add settings one at a time. |
| Old client works locally but fails through Grid | The client/Grid combination relied on legacy protocol translation that is no longer present | Identify exact versions of the client, Grid, browser driver, and browser. Upgrade the client to a W3C-compliant release and confirm Grid compatibility. |
| Browser starts, but an interaction test fails | Actions behavior, browser behavior, or timing changed during the upgrade | Reduce the interaction to a minimal test, confirm element state and action ordering, and compare the browser and driver versions. |
| Capabilities work with one browser but not another | A browser-specific option or vendor extension was sent as if it were standard | Keep standard WebDriver keys distinct from browser-specific Options and documented vendor namespaces. |
| Migration advice appears inconsistent by language | Bindings removed handshake or translation behavior on different release timelines | Use the Selenium chronology for the binding and Grid versions in your project; do not generalize one binding’s transition date to all bindings. |
Performance, reliability, and cost considerations
The protocol migration is primarily about standardization and compatibility; the cited Selenium sources do not establish a general speed improvement or provide a benchmark. Do not budget for a performance gain based on the protocol change alone. For reliability, pin and record client, browser, driver, and Grid versions, keep capability configuration small, and test session creation plus representative interactions after upgrades. Selenium itself is software; costs for remote browsers or cloud execution depend on the infrastructure or provider you choose, and the protocol standard does not set those prices.
Or skip the browser setup
If your goal is to get a visual record of a page rather than interactively test it, ScreenshotNeo is a website screenshot API and MCP server. It does not replace Selenium for browser automation, but it can return a screenshot or PDF with one GET request. See the ScreenshotNeo API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo accepts cookie and consent banners like a visitor, then removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. Every feature is on every plan.
Sign up free for 1,000 screenshots a month, with no card required.
FAQ
Will every Selenium 3 project work unchanged in Selenium 4?
No. Recent W3C-compliant code is expected to work, but legacy capabilities, protocol translation dependencies, and some Actions usage need review.
Does using Selenium 4 mean my tests use WebDriver BiDi?
No. Selenium 4’s classic WebDriver support uses W3C WebDriver. BiDi is a distinct bidirectional protocol for browser events.
Does the W3C standard define my language binding’s API?
No. It defines the remote communication protocol. Local client APIs are implemented by each binding.


