selenium: RemoteWebDriver cannot be cast to HasDevTools

🐛 Bug Report

It’s not possible to use the DevTools with the RemoteDriver. I was told to use the HasDevTools Interface but it still not working when using a RemoteWebDriver (with a Grid)

java.lang.ClassCastException: class org.openqa.selenium.remote.RemoteWebDriver cannot be cast to class org.openqa.selenium.devtools.HasDevTools (org.openqa.selenium.remote.RemoteWebDriver and org.openqa.selenium.devtools.HasDevTools are in unnamed module of loader 'app')

Detailed steps to reproduce the behavior:

webDriver is RemoteWebDriver which is used in a SeleniumGrid Environment.

Java: DevTools devTools = ((HasDevTools) webDriver).getDevTools();

Kotlin: val devTools: DevTools = (webDriver as HasDevTools).devTools

Used Selenium Version: 4.0.0-rc-1 (also tested with beta-3 and beta-4)

Environment

OS: Ubuntu 21 Browser: Chrome Browser version: > 87 Browser Driver version: >87 Language Bindings version: Java

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 37 (21 by maintainers)

Commits related to this issue

Most upvoted comments

This issue actually refers to two different situations: “RemoteWebDriver cannot be cast to HasDevTools” and the “Unable to establish websocket connection to http…”. The commit fixes the latter. For the earlier, if you are facing that, please open a new issue with all the information requested in the template.

The fix allows the websocket connection when interacting with WebDriver BiDi or CDP over Grid, which seems to be the actual issue being faced by the OP.

Here is some context for the fix… In an conventional Grid setup, things work well because the Node receiving the WebDriver BiDi or CDP request, is running on the same host where the browser is running. This is not the case with Dynamic Grid (with Docker), because the Node is running in one container, and a new container is started to run the session. Therefore, the browser is running in one container, and the Node in a different one. That is why we need to forward one hop more the websocket request.

It is important to note, that doing WebDriver BiDi or CDP over Dynamic Grid is only supported when all components are running in Docker. A mix is not possible due to the network complexities of Docker.

This fix will be included in a bug release that will happen in the following days.

I have shared the issue comment above with Diego. He is the core contributor and expert for selenium-docker. He mentioned he is aware of the issue and will help on the same.

I was able to get debugger address at Selenoid with String sessionId = ((RemoteWebDriver) WebDriverRunner.getWebDriver()).getSessionId().toString(); String debuggerUrl = String.format(“http://<selenoid_address>/devtools/%s/page”, sessionId); URI uri = new URI(debuggerUrl);

Then create a connection HttpClient.Factory clientFactory= HttpClient.Factory.createDefault(); Capabilities originalCapabilities = driver.getCapabilities(); Optional<Connection> connection = Optional.of(new Connection( clientFactory.createClient(ClientConfig.defaultConfig().baseUri(uri)), uri.toString()));

And get DevTools with it CdpInfo cdpInfo = (new CdpVersionFinder()).match(originalCapabilities.getBrowserVersion()).orElseGet(NoOpCdpInfo::new); Optional<DevTools> devTools = connection.map((conn) -> { Objects.requireNonNull(cdpInfo); return new DevTools(cdpInfo::getDomains, conn); });

Had a problem with new CdpVersionFinder()).match(…) tho. For my browser originalCapabilities.getBrowserVersion() returned “90.XXX” and matcher could not find suitable cdpInfo for that. I used v96 instead.