Why does `ExecuteCdpCommand` not work when using `WebDriver` instead of `ChromeDriver` in Selenium?

In a Selenium C# regression suite, ExecuteCdpCommand is used to set the timezone for Chrome via the Chrome DevTools Protocol (CDP). This works perfectly when using ChromeDriver. However, after modifying the code to use WebDriver as a generic type to support both Chrome and Edge, the compiler throws an error stating that 'WebDriver' does not contain a definition for 'ExecuteCdpCommand'. The issue arises because ExecuteCdpCommand is specific to Chromium-based drivers like ChromeDriver or EdgeDriver, and not part of the base WebDriver interface. The challenge is finding a way to execute CDP commands when the driver type is determined dynamically at runtime.

Having dealt with this exact problem a few times myself…

The main reason executecdpcommand doesn’t work when using WebDriver is because the method only exists in Chromium-specific drivers like ChromeDriver and EdgeDriver. The generic IWebDriver interface doesn’t expose any CDP-related methods, so the moment you store your driver as IWebDriver, the compiler loses awareness that it might actually be a Chrome or Edge instance.

A simple and reliable fix is to cast your driver at runtime:

if (driver is ChromeDriver chromeDriver)
{
    chromeDriver.ExecuteCdpCommand("Emulation.setTimezoneOverride", new Dictionary<string, object>
    {
        { "timezoneId", "Europe/Berlin" }
    });
}
else if (driver is EdgeDriver edgeDriver)
{
    edgeDriver.ExecuteCdpCommand("Emulation.setTimezoneOverride", new Dictionary<string, object>
    {
        { "timezoneId", "Europe/Berlin" }
    });
}

This way, you still keep type safety while enabling CDP commands when the browser actually supports them.

Yeah, I’ve run into that pattern as well over the years… To add on to @akanshasrivastava.1121 point the generic WebDriver layer simply isn’t designed to expose Chromium protocols, which is why executecdpcommand disappears the moment you reference the driver as IWebDriver.

In my own automation setups, I usually keep the variable typed as ChromeDriver or EdgeDriver whenever I know CDP commands will be used. It saves a lot of confusion. But even in cross-browser suites, the casting approach Tom mentioned is the cleanest middle ground. You get flexibility while still retaining full access to executecdpcommand whenever the underlying driver supports it.

Right, and just to build a bit further from both of your experiences… If you often end up calling executecdpcommand but don’t want to keep repeating type checks or casts everywhere, you can wrap the whole logic inside a reusable helper method.

Something like:

public static void RunCdp(IWebDriver driver, string command, Dictionary<string, object> parameters)
{
    if (driver is ChromeDriver chrome)
        chrome.ExecuteCdpCommand(command, parameters);
    else if (driver is EdgeDriver edge)
        edge.ExecuteCdpCommand(command, parameters);
}

This allows your test code to stay clean and driver-agnostic while still enabling CDP features whenever the browser supports them. It’s a small abstraction, but it keeps things organized when you scale your automation.