Skip to content

[🐛 Bug]: Augmenter fails to work with Selenium Standalone containers in Selenium 4 #14908

@srivishal1

Description

@srivishal1

What happened?

When using Selenium Standalone with the Testcontainers GenericContainer for the Chrome driver, the following issue occurs when trying to use the Augmenter class to enable the BiDi protocol:

The Selenium Standalone container starts correctly, and I am able to access the WebDriver via http://localhost:4444.
However, when I attempt to augment the driver using new Augmenter().augment(driver);, the connection fails with a java.net.ConnectException, indicating that the WebDriver cannot connect to the BiDi WebSocket server, despite being able to access the same URL (http://localhost:4444) from within the container.
This issue occurs only when using Selenium Standalone and does not appear when Selenium Grid is used with the same Augmenter setup.
The connection failure does not occur when bypassing the Augmenter or using other WebDriver methods, but the BiDi functionality is unavailable in this case

How can we reproduce the issue?

Code to Reproduce -

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.Augmenter;
import org.testcontainers.containers.GenericContainer;
import org.testng.annotations.Test;

import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.TimeUnit;

import static org.testcontainers.shaded.org.awaitility.Awaitility.await;

public class SeleniumTestWithWebSockets {

    @Test
    public void testBiDiConnection() throws Exception {
        // Start Selenium container
        System.setProperty("webdriver.http.factory", "jdk-http-client");

        // Start Selenium container
        try (GenericContainer<?> seleniumContainer = new GenericContainer<>("selenium/standalone-chromium:4.25")
                .withExposedPorts(4444)
                .withEnv("SE_NODE_GRID_URL", "http://localhost:4444")
                .withCreateContainerCmdModifier(cmd ->
                        cmd.getHostConfig().withShmSize(2147483648L))) { // Increase shared memory

            seleniumContainer.start();

            // Get Selenium URL
            String seleniumUrl = "http://localhost:" + seleniumContainer.getMappedPort(4444);

            // Wait for Selenium server readiness
            await().atMost(30, TimeUnit.SECONDS).until(() -> {
                try {
                    HttpURLConnection connection = (HttpURLConnection) new URL(seleniumUrl + "/status").openConnection();
                    connection.setRequestMethod("GET");
                    connection.connect();
                    return connection.getResponseCode() == 200;
                } catch (Exception e) {
                    return false;
                }
            });

            System.out.println("Container Logs: " + seleniumContainer.getLogs());
            // Configure ChromeOptions
            ChromeOptions options = new ChromeOptions();
            options.setCapability("se:cdp", true); // Enable WebSocket-based BiDi commands
            options.setExperimentalOption("w3c", true);
            options.setCapability("webSocketUrl", true);

            // Create WebDriver
            WebDriver driver = new RemoteWebDriver(new URL(seleniumUrl), options);
            driver = new Augmenter().augment(driver);

            // Perform a simple test
            driver.get("https://example.com");
            System.out.println("Page Title: " + driver.getTitle());

            // Quit WebDriver
            driver.quit();
        }
    }
}

Dependencies -
org.testcontainers - 1.17.5 (tried with 1.20 as well)
org.seleniumhq.selenium - 4.25.0
org.awaitility - 4.2.2

Pom looks like -
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.example</groupId>
  <artifactId>testcontainer</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>Archetype - testcontainer</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <!-- Testcontainers Selenium -->
    <dependency>
      <groupId>org.testcontainers</groupId>
      <artifactId>selenium</artifactId>
      <version>1.17.5</version> <!-- Or latest version -->
    </dependency>

    <!-- Selenium WebDriver -->
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>4.25.0</version> <!-- Ensure you use a version that supports BiDi -->
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.awaitility/awaitility -->
    <dependency>
      <groupId>org.awaitility</groupId>
      <artifactId>awaitility</artifactId>
      <version>4.2.2</version>
      <scope>test</scope>
    </dependency>

    <!-- JUnit for testing -->
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <version>5.7.0</version> <!-- Or any compatible version -->
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>RELEASE</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
</project>

Relevant log output

Container Logs: 2024-12-17 15:00:17,542 INFO Included extra file "/etc/supervisor/conf.d/chrome-cleanup.conf" during parsing
2024-12-17 15:00:17,543 INFO Included extra file "/etc/supervisor/conf.d/selenium.conf" during parsing
2024-12-17 15:00:17,558 INFO RPC interface 'supervisor' initialized
2024-12-17 15:00:17,558 INFO supervisord started with pid 8
2024-12-17 15:00:18,583 INFO spawned: 'xvfb' with pid 63
2024-12-17 15:00:18,589 INFO spawned: 'vnc' with pid 64
2024-12-17 15:00:18,616 INFO spawned: 'novnc' with pid 65
2024-12-17 15:00:18,618 INFO spawned: 'selenium-standalone' with pid 67
2024-12-17 15:00:18,626 INFO success: xvfb entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
2024-12-17 15:00:18,626 INFO success: vnc entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
2024-12-17 15:00:18,626 INFO success: novnc entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
2024-12-17 15:00:18,626 INFO success: selenium-standalone entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
Appending Selenium option: --heartbeat-period 30
Appending Selenium option: --log-level INFO
Appending Selenium option: --http-logs false
Appending Selenium option: --structured-logs false
Appending Selenium option: --reject-unsupported-caps true
Selenium Grid Standalone configuration: 
[network]
relax-checks = true

[node]
grid-url = "http://localhost:4444"
session-timeout = "300"
override-max-sessions = false
detect-drivers = false
drain-after-session-count = 0
max-sessions = 1

[[node.driver-configuration]]
display-name = "chrome"
stereotype = '{"browserName": "chrome", "browserVersion": "130.0", "platformName": "Linux", "goog:chromeOptions": {"binary": "/usr/bin/chromium"}, "se:containerName": ""}'
max-sessions = 1

Starting Selenium Grid Standalone...
Tracing is enabled
Classpath will be enriched with these external jars :  --ext /external_jars/https/repo1.maven.org/maven2/io/opentelemetry/opentelemetry-exporter-otlp/1.42.1/opentelemetry-exporter-otlp-1.42.1.jar:/external_jars/https/repo1.maven.org/maven2/io/grpc/grpc-netty/1.66.0/grpc-netty-1.66.0.jar:/external_jars/https/repo1.maven.org/maven2/io/netty/netty-codec-http/4.1.113.Final/netty-codec-http-4.1.113.Final.jar:/external_jars/https/repo1.maven.org/maven2/io/opentelemetry/opentelemetry-sdk-trace/1.42.1/opentelemetry-sdk-trace-1.42.1.jar:/external_jars/https/repo1.maven.org/maven2/io/opentelemetry/opentelemetry-sdk-metrics/1.42.1/opentelemetry-sdk-metrics-1.42.1.jar:/external_jars/https/repo1.maven.org/maven2/io/opentelemetry/opentelemetry-sdk-logs/1.42.1/opentelemetry-sdk-logs-1.42.1.jar:/external_jars/https/repo1.maven.org/maven2/io/opentelemetry/opentelemetry-exporter-otlp-common/1.42.1/opentelemetry-exporter-otlp-common-1.42.1.jar:/external_jars/https/repo1.maven.org/maven2/io/opentelemetry/opentelemetry-exporter-sender-okhttp/1.42.1/opentelemetry-exporter-sender-okhttp-1.42.1.jar:/external_jars/https/repo1.maven.org/maven2/io/opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi/1.42.1/opentelemetry-sdk-extension-autoconfigure-spi-1.42.1.jar:/external_jars/https/repo1.maven.org/maven2/io/grpc/grpc-api/1.66.0/grpc-api-1.66.0.jar:/external_jars/https/repo1.maven.org/maven2/io/netty/netty-codec-http2/4.1.100.Final/netty-codec-http2-4.1.100.Final.jar:/external_jars/https/repo1.maven.org/maven2/io/grpc/grpc-core/1.66.0/grpc-core-1.66.0.jar:/external_jars/https/repo1.maven.org/maven2/io/netty/netty-handler-proxy/4.1.100.Final/netty-handler-proxy-4.1.100.Final.jar:/external_jars/https/repo1.maven.org/maven2/com/google/guava/guava/33.2.1-android/guava-33.2.1-android.jar:/external_jars/https/repo1.maven.org/maven2/com/google/errorprone/error_prone_annotations/2.28.0/error_prone_annotations-2.28.0.jar:/external_jars/https/repo1.maven.org/maven2/io/perfmark/perfmark-api/0.27.0/perfmark-api-0.27.0.jar:/external_jars/https/repo1.maven.org/maven2/io/netty/netty-transport-native-unix-common/4.1.113.Final/netty-transport-native-unix-common-4.1.113.Final.jar:/external_jars/https/repo1.maven.org/maven2/io/grpc/grpc-util/1.66.0/grpc-util-1.66.0.jar:/external_jars/https/repo1.maven.org/maven2/io/netty/netty-common/4.1.113.Final/netty-common-4.1.113.Final.jar:/external_jars/https/repo1.maven.org/maven2/io/netty/netty-buffer/4.1.113.Final/netty-buffer-4.1.113.Final.jar:/external_jars/https/repo1.maven.org/maven2/io/netty/netty-transport/4.1.113.Final/netty-transport-4.1.113.Final.jar:/external_jars/https/repo1.maven.org/maven2/io/netty/netty-codec/4.1.113.Final/netty-codec-4.1.113.Final.jar:/external_jars/https/repo1.maven.org/maven2/io/netty/netty-handler/4.1.113.Final/netty-handler-4.1.113.Final.jar:/external_jars/https/repo1.maven.org/maven2/io/opentelemetry/opentelemetry-api/1.42.1/opentelemetry-api-1.42.1.jar:/external_jars/https/repo1.maven.org/maven2/io/opentelemetry/opentelemetry-sdk-common/1.42.1/opentelemetry-sdk-common-1.42.1.jar:/external_jars/https/repo1.maven.org/maven2/io/opentelemetry/opentelemetry-api-incubator/1.42.1-alpha/opentelemetry-api-incubator-1.42.1-alpha.jar:/external_jars/https/repo1.maven.org/maven2/io/opentelemetry/opentelemetry-exporter-common/1.42.1/opentelemetry-exporter-common-1.42.1.jar:/external_jars/https/repo1.maven.org/maven2/com/squareup/okhttp3/okhttp/4.12.0/okhttp-4.12.0.jar:/external_jars/https/repo1.maven.org/maven2/io/opentelemetry/opentelemetry-sdk/1.42.1/opentelemetry-sdk-1.42.1.jar:/external_jars/https/repo1.maven.org/maven2/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar:/external_jars/https/repo1.maven.org/maven2/com/google/code/gson/gson/2.11.0/gson-2.11.0.jar:/external_jars/https/repo1.maven.org/maven2/com/google/android/annotations/4.1.1.4/annotations-4.1.1.4.jar:/external_jars/https/repo1.maven.org/maven2/org/codehaus/mojo/animal-sniffer-annotations/1.24/animal-sniffer-annotations-1.24.jar:/external_jars/https/repo1.maven.org/maven2/io/grpc/grpc-context/1.66.0/grpc-context-1.66.0.jar:/external_jars/https/repo1.maven.org/maven2/io/netty/netty-codec-socks/4.1.100.Final/netty-codec-socks-4.1.100.Final.jar:/external_jars/https/repo1.maven.org/maven2/com/google/guava/failureaccess/1.0.2/failureaccess-1.0.2.jar:/external_jars/https/repo1.maven.org/maven2/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:/external_jars/https/repo1.maven.org/maven2/org/checkerframework/checker-qual/3.42.0/checker-qual-3.42.0.jar:/external_jars/https/repo1.maven.org/maven2/com/google/j2objc/j2objc-annotations/3.0.0/j2objc-annotations-3.0.0.jar:/external_jars/https/repo1.maven.org/maven2/io/netty/netty-resolver/4.1.113.Final/netty-resolver-4.1.113.Final.jar:/external_jars/https/repo1.maven.org/maven2/io/opentelemetry/opentelemetry-context/1.42.1/opentelemetry-context-1.42.1.jar:/external_jars/https/repo1.maven.org/maven2/com/squareup/okio/okio/3.6.0/okio-3.6.0.jar:/external_jars/https/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.9.10/kotlin-stdlib-jdk8-1.9.10.jar:/external_jars/https/repo1.maven.org/maven2/com/squareup/okio/okio-jvm/3.6.0/okio-jvm-3.6.0.jar:/external_jars/https/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.10/kotlin-stdlib-1.9.10.jar:/external_jars/https/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.9.10/kotlin-stdlib-jdk7-1.9.10.jar:/external_jars/https/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.9.10/kotlin-stdlib-common-1.9.10.jar:/external_jars/https/repo1.maven.org/maven2/org/jetbrains/annotations/13.0/annotations-13.0.jar
List arguments for OpenTelemetry:  -Dotel.resource.attributes=service.name=selenium-standalone -Dotel.traces.exporter=otlp -Dotel.java.global-autoconfigure.enabled=true
Dec 17, 2024 3:00:21 PM org.openqa.selenium.grid.config.TomlConfig <init>
WARNING: Please use quotes to denote strings. Upcoming TOML parser will require this and unquoted strings will throw an error in the future
15:00:21.629 INFO [LoggingOptions.configureLogEncoding] - Using the system default encoding
15:00:21.632 INFO [OpenTelemetryTracer.createTracer] - Using OpenTelemetry for tracing
15:00:22.745 INFO [NodeOptions.getSessionFactories] - Detected 5 available processors
15:00:22.812 INFO [NodeOptions.report] - Adding chrome for {"browserName": "chrome","browserVersion": "130.0","goog:chromeOptions": {"binary": "\u002fusr\u002fbin\u002fchromium"},"platformName": "linux","se:containerName": "","se:noVncPort": 7900,"se:vncEnabled": true} 1 times
15:00:22.874 INFO [Node.<init>] - Binding additional locator mechanisms: relative
15:00:22.907 INFO [GridModel.setAvailability] - Switching Node 747d82ef-c32f-4fcc-8dca-a514f9967b27 (uri: http://172.17.0.3:4444) from DOWN to UP
15:00:22.908 INFO [LocalDistributor.add] - Added node 747d82ef-c32f-4fcc-8dca-a514f9967b27 at http://172.17.0.3:4444. Health check every 120s
15:00:23.167 INFO [Standalone.execute] - Started Selenium Standalone 4.25.0 (revision 030fcf7918): http://172.17.0.3:4444

Dec 17, 2024 8:30:23 PM org.openqa.selenium.remote.tracing.opentelemetry.OpenTelemetryTracer createTracer
INFO: Using OpenTelemetry for tracing
Dec 17, 2024 8:30:26 PM org.openqa.selenium.devtools.CdpVersionFinder findNearestMatch
WARNING: Unable to find an exact match for CDP version 130, returning the closest version; found: 129; Please update to a Selenium version that supports CDP version 130

org.openqa.selenium.remote.http.ConnectionFailedException: JdkWebSocket initial request execution error
Build info: version: '4.25.0', revision: '8a8aea2337'
System info: os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '14.6.1', java.version: '17.0.10'
Driver info: driver.version: unknown

	at org.openqa.selenium.remote.http.jdk.JdkHttpClient.openSocket(JdkHttpClient.java:248)
	at org.openqa.selenium.devtools.Connection.<init>(Connection.java:89)
	at org.openqa.selenium.devtools.SeleniumCdpConnection.<init>(SeleniumCdpConnection.java:36)
	at org.openqa.selenium.devtools.SeleniumCdpConnection.lambda$create$3(SeleniumCdpConnection.java:103)
	at java.base/java.util.Optional.map(Optional.java:260)
	at org.openqa.selenium.devtools.SeleniumCdpConnection.create(SeleniumCdpConnection.java:103)
	at org.openqa.selenium.devtools.SeleniumCdpConnection.create(SeleniumCdpConnection.java:49)
	at org.openqa.selenium.devtools.DevToolsProvider.getImplementation(DevToolsProvider.java:50)
	at org.openqa.selenium.devtools.DevToolsProvider.getImplementation(DevToolsProvider.java:29)
	at org.openqa.selenium.remote.Augmenter.augment(Augmenter.java:207)
	at org.openqa.selenium.remote.Augmenter.augment(Augmenter.java:178)
	at SeleniumTestWithWebSockets.testBiDiConnection(SeleniumTestWithWebSockets.java:55)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:141)
	at org.testng.internal.invokers.TestInvoker.invokeMethod(TestInvoker.java:686)
	at org.testng.internal.invokers.TestInvoker.invokeTestMethod(TestInvoker.java:230)
	at org.testng.internal.invokers.MethodRunner.runInSequence(MethodRunner.java:63)
	at org.testng.internal.invokers.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:992)
	at org.testng.internal.invokers.TestInvoker.invokeTestMethods(TestInvoker.java:203)
	at org.testng.internal.invokers.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:154)
	at org.testng.internal.invokers.TestMethodWorker.run(TestMethodWorker.java:134)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.testng.TestRunner.privateRun(TestRunner.java:739)
	at org.testng.TestRunner.run(TestRunner.java:614)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:421)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:413)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:373)
	at org.testng.SuiteRunner.run(SuiteRunner.java:312)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1274)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1208)
	at org.testng.TestNG.runSuites(TestNG.java:1112)
	at org.testng.TestNG.run(TestNG.java:1079)
	at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:65)
	at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:105)
Caused by: java.net.ConnectException
	at java.net.http/jdk.internal.net.http.common.Utils.toConnectException(Utils.java:1055)
	at java.net.http/jdk.internal.net.http.PlainHttpConnection.connectAsync(PlainHttpConnection.java:198)
	at java.net.http/jdk.internal.net.http.PlainHttpConnection.checkRetryConnect(PlainHttpConnection.java:230)
	at java.net.http/jdk.internal.net.http.PlainHttpConnection.lambda$connectAsync$1(PlainHttpConnection.java:206)
	at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:934)
	at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(CompletableFuture.java:911)
	at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
	at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1773)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: java.nio.channels.ClosedChannelException
	at java.base/sun.nio.ch.SocketChannelImpl.ensureOpen(SocketChannelImpl.java:195)
	at java.base/sun.nio.ch.SocketChannelImpl.beginConnect(SocketChannelImpl.java:760)
	at java.base/sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:848)
	at java.net.http/jdk.internal.net.http.PlainHttpConnection.lambda$connectAsync$0(PlainHttpConnection.java:183)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
	at java.net.http/jdk.internal.net.http.PlainHttpConnection.connectAsync(PlainHttpConnection.java:185)
	... 9 more

I tried with different versions so ignore this warning -
WARNING: Unable to find an exact match for CDP version 130, returning the closest version; found: 129; Please update to a Selenium version that supports CDP version 130
This can be reproduce with latest docker image selenium/standalone-chromium:latest or previous versions

Operating System

Mac

Selenium version

4.25 and later

What are the browser(s) and version(s) where you see this issue?

128,129,130,131

What are the browser driver(s) and version(s) where you see this issue?

128,129,130,131

Are you using Selenium Grid?

No

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-needs-triagingA Selenium member will evaluate this soon!I-defectSomething is not working as intended

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions