testcontainers-java icon indicating copy to clipboard operation
testcontainers-java copied to clipboard

[Bug]: Timeout exception when getting webdriver of BrowserWebDriverContainer

Open alexsuter opened this issue 1 year ago • 15 comments

Module

Selenium

Testcontainers version

1.17.3

Using the latest Testcontainers version?

Yes

Host OS

Linux

Host Arch

x86

Docker version

Client:
 Version:           20.10.12
 API version:       1.41
 Go version:        go1.17.3
 Git commit:        20.10.12-0ubuntu4
 Built:             Mon Mar  7 17:10:06 2022
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server:
 Engine:
  Version:          20.10.12
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.17.3
  Git commit:       20.10.12-0ubuntu4
  Built:            Mon Mar  7 15:57:50 2022
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.5.9-0ubuntu3
  GitCommit:        
 runc:
  Version:          1.1.0-0ubuntu1
  GitCommit:        
 docker-init:
  Version:          0.19.0
  GitCommit:

What happened?

In 8 of 10 cases I get a TimeoutException when calling org.testcontainers.containers.BrowserWebDriverContainer.getWebDriver() but only with Selenium 4. This does not happen with Selenium 3. There is a timeout and retry implemented when getting the webdriver. I think everything is just slower with Seleinum 4, we just need more time. If these timeouts would be configurable I could test it easily.

Note: In Selenium there is tracing when you create a new RemoteWebdriver. Maybe this just takes more time?

This is my setup:

  @Container
  BrowserWebDriverContainer<?> firefox = new BrowserWebDriverContainer<>()
          .withNetwork(network)
          .withCapabilities(new FirefoxOptions());

  @Container
  AxonIvyEngine ivy = new AxonIvyEngine()
          .withIvyYaml(new File("src/test/resources/azure/ivy.yaml").getAbsolutePath())
          .withNetwork(network)
          .withNetworkAliases("ivy");

  @BeforeEach
  void beforeEach() {
    RemoteWebDriver webDriver = firefox.getWebDriver(); // it is failing here.
    WebDriverRunner.setWebDriver(webDriver);
    Configuration.baseUrl = "https://ivy:8443";
  }

Relevant log output

[ERROR] com.axonivy.test.docker.integration.TestAzureOAuth2Login2.login  Time elapsed: 70.413 s  <<< ERROR!
org.rnorth.ducttape.TimeoutException: Timeout waiting for result with exception
	at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:54)
	at org.testcontainers.containers.BrowserWebDriverContainer.getWebDriver(BrowserWebDriverContainer.java:327)
	at com.axonivy.test.docker.integration.TestAzureOAuth2Login2.beforeEach(TestAzureOAuth2Login2.java:46)
	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.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptLifecycleMethod(TimeoutExtension.java:128)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptBeforeEachMethod(TimeoutExtension.java:78)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeMethodInExtensionContext(ClassBasedTestDescriptor.java:520)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$synthesizeBeforeEachMethodAdapter$23(ClassBasedTestDescriptor.java:505)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeEachMethods$3(TestMethodTestDescriptor.java:174)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeMethodsOrCallbacksUntilExceptionOccurs$6(TestMethodTestDescriptor.java:202)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeMethodsOrCallbacksUntilExceptionOccurs(TestMethodTestDescriptor.java:202)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeEachMethods(TestMethodTestDescriptor.java:171)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:134)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
	at org.apache.maven.surefire.junitplatform.LazyLauncher.execute(LazyLauncher.java:55)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:223)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:175)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:139)
	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:456)
	at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:169)
	at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:595)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:581)
Caused by: org.rnorth.ducttape.TimeoutException: java.util.concurrent.TimeoutException
	at org.rnorth.ducttape.timeouts.Timeouts.callFuture(Timeouts.java:70)
	at org.rnorth.ducttape.timeouts.Timeouts.getWithTimeout(Timeouts.java:43)
	at org.testcontainers.containers.BrowserWebDriverContainer.lambda$getWebDriver$1(BrowserWebDriverContainer.java:331)
	at org.rnorth.ducttape.unreliables.Unreliables.lambda$retryUntilSuccess$0(Unreliables.java:43)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	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:833)
Caused by: java.util.concurrent.TimeoutException
	at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:204)
	at org.rnorth.ducttape.timeouts.Timeouts.callFuture(Timeouts.java:65)
	... 7 more

Additional Information

No response

alexsuter avatar Sep 12 '22 06:09 alexsuter

Same problem here. It works mostly fine for Selenium 4.2.2 but with selenium 4.4.0 >60% of our tests suffer from above problem.

It looks like sometimes the part of Selenium inside Docker needs more than 10s to respond to the initial request:

Log
11:06:28 DEBUG [main] [e.testcases.TestPageShown] Getting WebDriver... 
11:06:28 INFO  [ducttape-1] [metry.OpenTelemetryTracer] Using OpenTelemetry for tracing 
11:06:28 DEBUG [ducttape-1] [ing.InternalLoggerFactory] Using SLF4J as the default logging framework 
11:06:28 DEBUG [ducttape-1] [util.ResourceLeakDetector] -Dio.netty.leakDetection.level: simple 
11:06:28 DEBUG [ducttape-1] [util.ResourceLeakDetector] -Dio.netty.leakDetection.targetRecords: 4 
11:06:28 DEBUG [ducttape-1] [sourceLeakDetectorFactory] Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@b353cf9 
11:06:28 DEBUG [ducttape-1] [ternal.PlatformDependent0] -Dio.netty.noUnsafe: false 
11:06:28 DEBUG [ducttape-1] [ternal.PlatformDependent0] Java version: 17 
11:06:28 DEBUG [ducttape-1] [ternal.PlatformDependent0] sun.misc.Unsafe.theUnsafe: available 
...
11:06:28 DEBUG [ducttape-1] [.netty.buffer.ByteBufUtil] -Dio.netty.maxThreadLocalCharBufferSize: 16384 
11:06:29 DEBUG [Forwarding newSession on session null to remote] [.channel.DefaultChannelId] -Dio.netty.processId: 42544 (auto-detected) 
11:06:29 DEBUG [Forwarding newSession on session null to remote] [io.netty.util.NetUtil    ] -Djava.net.preferIPv4Stack: false 
11:06:29 DEBUG [Forwarding newSession on session null to remote] [io.netty.util.NetUtil    ] -Djava.net.preferIPv6Addresses: false 
11:06:29 DEBUG [Forwarding newSession on session null to remote] [il.NetUtilInitializations] Loopback interface: lo (Software Loopback Interface 1, 127.0.0.1) 
11:06:29 DEBUG [Forwarding newSession on session null to remote] [io.netty.util.NetUtil    ] Failed to get SOMAXCONN from sysctl and file \proc\sys\net\core\somaxconn. Default: 200 
11:06:29 DEBUG [Forwarding newSession on session null to remote] [.channel.DefaultChannelId] -Dio.netty.machineId: 00:d8:61:ff:fe:d4:70:fb (auto-detected) 
11:06:29 DEBUG [AsyncHttpClient-1-2] [ty.buffer.AbstractByteBuf] -Dio.netty.buffer.checkAccessible: true 
11:06:29 DEBUG [AsyncHttpClient-1-2] [ty.buffer.AbstractByteBuf] -Dio.netty.buffer.checkBounds: true 
11:06:29 DEBUG [AsyncHttpClient-1-2] [sourceLeakDetectorFactory] Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@462ed7c7 
11:06:29 TRACE [AsyncHttpClient-1-2] [er.logging.LoggingHandler] [id: 0xafb917bd] REGISTERED 
11:06:29 TRACE [AsyncHttpClient-1-2] [er.logging.LoggingHandler] [id: 0xafb917bd] CONNECT: localhost/127.0.0.1:55480 
11:06:29 DEBUG [AsyncHttpClient-1-2] [nnel.NettyConnectListener] Using new Channel '[id: 0xafb917bd, L:/127.0.0.1:55484 - R:localhost/127.0.0.1:55480]' for 'POST' to '/wd/hub/session' 
11:06:29 DEBUG [AsyncHttpClient-1-2] [io.netty.util.Recycler   ] -Dio.netty.recycler.maxCapacityPerThread: 4096 
11:06:29 DEBUG [AsyncHttpClient-1-2] [io.netty.util.Recycler   ] -Dio.netty.recycler.ratio: 8 
11:06:29 DEBUG [AsyncHttpClient-1-2] [io.netty.util.Recycler   ] -Dio.netty.recycler.chunkSize: 32 
11:06:29 DEBUG [AsyncHttpClient-1-2] [io.netty.util.Recycler   ] -Dio.netty.recycler.blocking: false 
11:06:29 TRACE [AsyncHttpClient-1-2] [er.logging.LoggingHandler] [id: 0xafb917bd, L:/127.0.0.1:55484 - R:localhost/127.0.0.1:55480] WRITE: 250B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 50 4f 53 54 20 2f 77 64 2f 68 75 62 2f 73 65 73 |POST /wd/hub/ses|
|00000010| 73 69 6f 6e 20 48 54 54 50 2f 31 2e 31 0d 0a 55 |sion HTTP/1.1..U|
|00000020| 73 65 72 2d 41 67 65 6e 74 3a 20 73 65 6c 65 6e |ser-Agent: selen|
|00000030| 69 75 6d 2f 34 2e 34 2e 30 20 28 6a 61 76 61 20 |ium/4.4.0 (java |
|00000040| 77 69 6e 64 6f 77 73 29 0d 0a 74 72 61 63 65 70 |windows)..tracep|
|00000050| 61 72 65 6e 74 3a 20 30 30 2d 36 32 37 64 31 39 |arent: 00-627d19|
|00000060| 63 64 37 31 36 37 34 36 63 33 33 30 62 34 65 39 |cd716746c330b4e9|
|00000070| 63 32 35 31 64 37 32 61 37 33 2d 30 65 35 65 64 |c251d72a73-0e5ed|
|00000080| 30 36 37 66 35 66 36 39 65 62 61 2d 30 31 0d 0a |067f5f69eba-01..|
|00000090| 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 |Content-Length: |
|000000a0| 33 38 31 0d 0a 43 6f 6e 74 65 6e 74 2d 54 79 70 |381..Content-Typ|
|000000b0| 65 3a 20 61 70 70 6c 69 63 61 74 69 6f 6e 2f 6a |e: application/j|
|000000c0| 73 6f 6e 3b 20 63 68 61 72 73 65 74 3d 75 74 66 |son; charset=utf|
|000000d0| 2d 38 0d 0a 68 6f 73 74 3a 20 6c 6f 63 61 6c 68 |-8..host: localh|
|000000e0| 6f 73 74 3a 35 35 34 38 30 0d 0a 61 63 63 65 70 |ost:55480..accep|
|000000f0| 74 3a 20 2a 2f 2a 0d 0a 0d 0a                   |t: */*....      |
+--------+-------------------------------------------------+----------------+ 
11:06:29 TRACE [AsyncHttpClient-1-2] [er.logging.LoggingHandler] [id: 0xafb917bd, L:/127.0.0.1:55484 - R:localhost/127.0.0.1:55480] WRITE: 381B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 7b 0a 20 20 22 64 65 73 69 72 65 64 43 61 70 61 |{.  "desiredCapa|
|00000010| 62 69 6c 69 74 69 65 73 22 3a 20 7b 0a 20 20 20 |bilities": {.   |
|00000020| 20 22 62 72 6f 77 73 65 72 4e 61 6d 65 22 3a 20 | "browserName": |
|00000030| 22 66 69 72 65 66 6f 78 22 2c 0a 20 20 20 20 22 |"firefox",.    "|
|00000040| 6d 6f 7a 3a 64 65 62 75 67 67 65 72 41 64 64 72 |moz:debuggerAddr|
|00000050| 65 73 73 22 3a 20 74 72 75 65 2c 0a 20 20 20 20 |ess": true,.    |
|00000060| 22 6d 6f 7a 3a 66 69 72 65 66 6f 78 4f 70 74 69 |"moz:firefoxOpti|
|00000070| 6f 6e 73 22 3a 20 7b 0a 20 20 20 20 7d 2c 0a 20 |ons": {.    },. |
|00000080| 20 20 20 22 61 63 63 65 70 74 49 6e 73 65 63 75 |   "acceptInsecu|
|00000090| 72 65 43 65 72 74 73 22 3a 20 74 72 75 65 0a 20 |reCerts": true. |
|000000a0| 20 7d 2c 0a 20 20 22 63 61 70 61 62 69 6c 69 74 | },.  "capabilit|
|000000b0| 69 65 73 22 3a 20 7b 0a 20 20 20 20 22 66 69 72 |ies": {.    "fir|
|000000c0| 73 74 4d 61 74 63 68 22 3a 20 5b 0a 20 20 20 20 |stMatch": [.    |
|000000d0| 20 20 7b 0a 20 20 20 20 20 20 20 20 22 61 63 63 |  {.        "acc|
|000000e0| 65 70 74 49 6e 73 65 63 75 72 65 43 65 72 74 73 |eptInsecureCerts|
|000000f0| 22 3a 20 74 72 75 65 2c 0a 20 20 20 20 20 20 20 |": true,.       |
|00000100| 20 22 62 72 6f 77 73 65 72 4e 61 6d 65 22 3a 20 | "browserName": |
|00000110| 22 66 69 72 65 66 6f 78 22 2c 0a 20 20 20 20 20 |"firefox",.     |
|00000120| 20 20 20 22 6d 6f 7a 3a 64 65 62 75 67 67 65 72 |   "moz:debugger|
|00000130| 41 64 64 72 65 73 73 22 3a 20 74 72 75 65 2c 0a |Address": true,.|
|00000140| 20 20 20 20 20 20 20 20 22 6d 6f 7a 3a 66 69 72 |        "moz:fir|
|00000150| 65 66 6f 78 4f 70 74 69 6f 6e 73 22 3a 20 7b 0a |efoxOptions": {.|
|00000160| 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 |        }.      |
|00000170| 7d 0a 20 20 20 20 5d 0a 20 20 7d 0a 7d          |}.    ].  }.}   |
+--------+-------------------------------------------------+----------------+ 
11:06:29 TRACE [AsyncHttpClient-1-2] [er.logging.LoggingHandler] [id: 0xafb917bd, L:/127.0.0.1:55484 - R:localhost/127.0.0.1:55480] FLUSH 
11:06:29 TRACE [AsyncHttpClient-1-2] [er.logging.LoggingHandler] [id: 0xafb917bd, L:/127.0.0.1:55484 - R:localhost/127.0.0.1:55480] WRITE: 0B 
11:06:29 TRACE [AsyncHttpClient-1-2] [er.logging.LoggingHandler] [id: 0xafb917bd, L:/127.0.0.1:55484 - R:localhost/127.0.0.1:55480] FLUSH 
11:06:29 TRACE [AsyncHttpClient-1-2] [er.logging.LoggingHandler] [id: 0xafb917bd, L:/127.0.0.1:55484 - R:localhost/127.0.0.1:55480] ACTIVE 
11:06:38 TRACE [ducttape-0] [e.unreliables.Unreliables] Retrying lambda call on attempt 0 
11:06:38 TRACE [AsyncHttpClient-1-3] [er.logging.LoggingHandler] [id: 0x228976cf] REGISTERED 
11:06:38 TRACE [AsyncHttpClient-1-3] [er.logging.LoggingHandler] [id: 0x228976cf] CONNECT: localhost/127.0.0.1:55480 
11:06:38 DEBUG [AsyncHttpClient-1-3] [nnel.NettyConnectListener] Using new Channel '[id: 0x228976cf, L:/127.0.0.1:55486 - R:localhost/127.0.0.1:55480]' for 'POST' to '/wd/hub/session' 
11:06:38 TRACE [AsyncHttpClient-1-3] [er.logging.LoggingHandler] [id: 0x228976cf, L:/127.0.0.1:55486 - R:localhost/127.0.0.1:55480] WRITE: 250B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 50 4f 53 54 20 2f 77 64 2f 68 75 62 2f 73 65 73 |POST /wd/hub/ses|
|00000010| 73 69 6f 6e 20 48 54 54 50 2f 31 2e 31 0d 0a 55 |sion HTTP/1.1..U|
|00000020| 73 65 72 2d 41 67 65 6e 74 3a 20 73 65 6c 65 6e |ser-Agent: selen|
|00000030| 69 75 6d 2f 34 2e 34 2e 30 20 28 6a 61 76 61 20 |ium/4.4.0 (java |
|00000040| 77 69 6e 64 6f 77 73 29 0d 0a 74 72 61 63 65 70 |windows)..tracep|
|00000050| 61 72 65 6e 74 3a 20 30 30 2d 38 35 65 32 61 33 |arent: 00-85e2a3|
|00000060| 39 61 63 35 37 32 35 65 37 38 61 64 33 35 32 61 |9ac5725e78ad352a|
|00000070| 33 34 31 34 38 31 37 61 64 66 2d 61 31 39 38 39 |3414817adf-a1989|
|00000080| 34 61 62 62 35 62 34 38 36 64 61 2d 30 31 0d 0a |4abb5b486da-01..|
|00000090| 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 |Content-Length: |
|000000a0| 33 38 31 0d 0a 43 6f 6e 74 65 6e 74 2d 54 79 70 |381..Content-Typ|
|000000b0| 65 3a 20 61 70 70 6c 69 63 61 74 69 6f 6e 2f 6a |e: application/j|
|000000c0| 73 6f 6e 3b 20 63 68 61 72 73 65 74 3d 75 74 66 |son; charset=utf|
|000000d0| 2d 38 0d 0a 68 6f 73 74 3a 20 6c 6f 63 61 6c 68 |-8..host: localh|
|000000e0| 6f 73 74 3a 35 35 34 38 30 0d 0a 61 63 63 65 70 |ost:55480..accep|
|000000f0| 74 3a 20 2a 2f 2a 0d 0a 0d 0a                   |t: */*....      |
+--------+-------------------------------------------------+----------------+ 
11:06:38 TRACE [AsyncHttpClient-1-3] [er.logging.LoggingHandler] [id: 0x228976cf, L:/127.0.0.1:55486 - R:localhost/127.0.0.1:55480] WRITE: 381B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 7b 0a 20 20 22 64 65 73 69 72 65 64 43 61 70 61 |{.  "desiredCapa|
|00000010| 62 69 6c 69 74 69 65 73 22 3a 20 7b 0a 20 20 20 |bilities": {.   |
|00000020| 20 22 62 72 6f 77 73 65 72 4e 61 6d 65 22 3a 20 | "browserName": |
|00000030| 22 66 69 72 65 66 6f 78 22 2c 0a 20 20 20 20 22 |"firefox",.    "|
|00000040| 6d 6f 7a 3a 64 65 62 75 67 67 65 72 41 64 64 72 |moz:debuggerAddr|
|00000050| 65 73 73 22 3a 20 74 72 75 65 2c 0a 20 20 20 20 |ess": true,.    |
|00000060| 22 6d 6f 7a 3a 66 69 72 65 66 6f 78 4f 70 74 69 |"moz:firefoxOpti|
|00000070| 6f 6e 73 22 3a 20 7b 0a 20 20 20 20 7d 2c 0a 20 |ons": {.    },. |
|00000080| 20 20 20 22 61 63 63 65 70 74 49 6e 73 65 63 75 |   "acceptInsecu|
|00000090| 72 65 43 65 72 74 73 22 3a 20 74 72 75 65 0a 20 |reCerts": true. |
|000000a0| 20 7d 2c 0a 20 20 22 63 61 70 61 62 69 6c 69 74 | },.  "capabilit|
|000000b0| 69 65 73 22 3a 20 7b 0a 20 20 20 20 22 66 69 72 |ies": {.    "fir|
|000000c0| 73 74 4d 61 74 63 68 22 3a 20 5b 0a 20 20 20 20 |stMatch": [.    |
|000000d0| 20 20 7b 0a 20 20 20 20 20 20 20 20 22 61 63 63 |  {.        "acc|
|000000e0| 65 70 74 49 6e 73 65 63 75 72 65 43 65 72 74 73 |eptInsecureCerts|
|000000f0| 22 3a 20 74 72 75 65 2c 0a 20 20 20 20 20 20 20 |": true,.       |
|00000100| 20 22 62 72 6f 77 73 65 72 4e 61 6d 65 22 3a 20 | "browserName": |
|00000110| 22 66 69 72 65 66 6f 78 22 2c 0a 20 20 20 20 20 |"firefox",.     |
|00000120| 20 20 20 22 6d 6f 7a 3a 64 65 62 75 67 67 65 72 |   "moz:debugger|
|00000130| 41 64 64 72 65 73 73 22 3a 20 74 72 75 65 2c 0a |Address": true,.|
|00000140| 20 20 20 20 20 20 20 20 22 6d 6f 7a 3a 66 69 72 |        "moz:fir|
|00000150| 65 66 6f 78 4f 70 74 69 6f 6e 73 22 3a 20 7b 0a |efoxOptions": {.|
|00000160| 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 |        }.      |
|00000170| 7d 0a 20 20 20 20 5d 0a 20 20 7d 0a 7d          |}.    ].  }.}   |
+--------+-------------------------------------------------+----------------+ 
11:06:38 TRACE [AsyncHttpClient-1-3] [er.logging.LoggingHandler] [id: 0x228976cf, L:/127.0.0.1:55486 - R:localhost/127.0.0.1:55480] FLUSH 
11:06:38 TRACE [AsyncHttpClient-1-3] [er.logging.LoggingHandler] [id: 0x228976cf, L:/127.0.0.1:55486 - R:localhost/127.0.0.1:55480] WRITE: 0B 
11:06:38 TRACE [AsyncHttpClient-1-3] [er.logging.LoggingHandler] [id: 0x228976cf, L:/127.0.0.1:55486 - R:localhost/127.0.0.1:55480] FLUSH 
11:06:38 TRACE [AsyncHttpClient-1-3] [er.logging.LoggingHandler] [id: 0x228976cf, L:/127.0.0.1:55486 - R:localhost/127.0.0.1:55480] ACTIVE 
11:06:41 DEBUG [docker-java-stream-1229649897] [ache.hc.client5.http.wire] http-outgoing-4 << "e5[\r][\n]" 
11:06:41 DEBUG [docker-java-stream-1229649897] [ache.hc.client5.http.wire] http-outgoing-4 << "[0x1][0x0][0x0][0x0][0x0][0x0][0x0]`11:06:41.894 INFO [LocalDistributor.newSession] - Session request received by the Distributor: [\n]" 
11:06:41 DEBUG [docker-java-stream-1229649897] [ache.hc.client5.http.wire] http-outgoing-4 << "[0x1][0x0][0x0][0x0][0x0][0x0][0x0]u [Capabilities {acceptInsecureCerts: true, browserName: firefox, moz:debuggerAddress: true, moz:firefoxOptions: {}}][\n]" 
11:06:41 DEBUG [docker-java-stream-1229649897] [ache.hc.client5.http.wire] http-outgoing-4 << "[\r][\n]" 
11:06:41 INFO  [docker-java-stream-1229649897] [ontainer.browserwebdriver] STDOUT: 11:06:41.894 INFO [LocalDistributor.newSession] - Session request received by the Distributor:  
11:06:41 INFO  [docker-java-stream-1229649897] [ontainer.browserwebdriver] STDOUT:  [Capabilities {acceptInsecureCerts: true, browserName: firefox, moz:debuggerAddress: true, moz:firefoxOptions: {}}] 
11:06:41 DEBUG [docker-java-stream-1229649897] [ache.hc.client5.http.wire] http-outgoing-4 << "e5[\r][\n]" 

AB-xdev avatar Sep 12 '22 07:09 AB-xdev

Thank you @alexsuter for the issue and @AB-xdev for the additional info. I've been able to reproduce this on my end (out of 10, I got 6 TimeoutExceptions). Let me look into this.

aidando73 avatar Sep 12 '22 08:09 aidando73

Ok I've submitted a fix for this issue.

In the meantime, the workaround would be to use a library like awaitily (or roll your own timeout mechanism) in order to instantiate the RemoteWebDriver yourself:

  private static FirefoxOptions firefoxOptions = new FirefoxOptions();

  @Container
  BrowserWebDriverContainer<?> firefox = new BrowserWebDriverContainer<>()
          .withNetwork(network)
          .withCapabilities(firefoxOptions);

  @BeforeEach
  void beforeEach() {
    RemoteWebDriver remoteWebDriver = await().atMost(20, TimeUnit.SECONDS).until(() -> {
      return new RemoteWebDriver(firefox.getSeleniumAddress(), firefoxOptions);
    }, Objects::nonNull);
    ...
  }

Which will let your specify your own timeout.

aidando73 avatar Sep 13 '22 12:09 aidando73

Yes. Seems to work! Thank you!

alexsuter avatar Sep 13 '22 12:09 alexsuter

Unfortunately, the workaround doesn't work for me. I get:

java.lang.IllegalStateException: Mapped port can only be obtained after the container is started

This is happening on this line:

return new RemoteWebDriver(chrome.getSeleniumAddress(), chromeOptions);

Presumably, it's the getSeleniumAddress call that's failing. My example looks exactly like yours, except I'm using Chrome. Using Junit 5 w/ @TestContainers annotation at the top of my test.

joeltine avatar Sep 28 '22 13:09 joeltine

@joeltine This happens because your container is not started when you call getSeleniumAddress(). Please share a reproducer on GitHub.

kiview avatar Sep 28 '22 15:09 kiview

The same bug also persists in Selenium 4.5.0.

I created an issue at https://github.com/SeleniumHQ/selenium/issues/11082 so that the underlying problem gets fixed.

AB-xdev avatar Oct 04 '22 10:10 AB-xdev

I think I found the problem or at least a workaround: https://github.com/SeleniumHQ/selenium/issues/10984#issuecomment-1268011440

Using .withEnv("SE_OPTS", "--session-retry-interval 1") (in Selenium 4.4+) fixed the timeouts for me

AB-xdev avatar Oct 05 '22 06:10 AB-xdev

@AB-xdev Thanks for sharing the workaround and your debugging findings with us, might be helpful for others as well.

As I read the upstream issues, this is a regression/change in the web driver regarding timing behavior, correct? Let's wait for how this proceeds in the upstream, but it's very good we have some workarounds handy by now.

kiview avatar Oct 05 '22 08:10 kiview

I believe that this issue is now fixed in selenium 4.5.1

https://github.com/SeleniumHQ/selenium/issues/10984

Could someone give 4.5.1/4.5.2 a try and see if this is still an issue?

aidando73 avatar Oct 25 '22 11:10 aidando73

@REslim30 It's still an issue. I've tested it with selenium 4.5.3 and test-containers 1.17.5 and got the same exception:

15:54:51  Caused by: org.rnorth.ducttape.TimeoutException: java.util.concurrent.TimeoutException
15:54:51  	at org.rnorth.ducttape.timeouts.Timeouts.callFuture(Timeouts.java:70)
15:54:51  	at org.rnorth.ducttape.timeouts.Timeouts.getWithTimeout(Timeouts.java:43)
15:54:51  	at org.testcontainers.containers.BrowserWebDriverContainer.lambda$getWebDriver$1(BrowserWebDriverContainer.java:331)
15:54:51  	at org.rnorth.ducttape.unreliables.Unreliables.lambda$retryUntilSuccess$0(Unreliables.java:43)
15:54:51  	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
15:54:51  	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
15:54:51  	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
15:54:51  	at java.base/java.lang.Thread.run(Thread.java:834)

czerwinm avatar Oct 28 '22 14:10 czerwinm

Same issue with Selenium 4.6.0 and Testcontainers 1.17.5.

Maybe it is a new bug, because the reason for the TimeoutException is a little bit different.

org.rnorth.ducttape.TimeoutException: Timeout waiting for result with exception

	at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:54)
	at org.testcontainers.containers.BrowserWebDriverContainer.getWebDriver(BrowserWebDriverContainer.java:327)
	at com.github.sparsick.testcontainerspringboot.hero.universum.HeroStartPageIT.searchForHero(HeroStartPageIT.java:63)
	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.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
	at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
	at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
	at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: java.lang.RuntimeException: java.lang.NoClassDefFoundError: org/openqa/selenium/AcceptedW3CCapabilityKeys
	at org.rnorth.ducttape.timeouts.Timeouts.callFuture(Timeouts.java:68)
	at org.rnorth.ducttape.timeouts.Timeouts.getWithTimeout(Timeouts.java:43)
	at org.testcontainers.containers.BrowserWebDriverContainer.lambda$getWebDriver$1(BrowserWebDriverContainer.java:331)
	at org.rnorth.ducttape.unreliables.Unreliables.lambda$retryUntilSuccess$0(Unreliables.java:43)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	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:833)
Caused by: java.lang.NoClassDefFoundError: org/openqa/selenium/AcceptedW3CCapabilityKeys
	at org.openqa.selenium.remote.RemoteWebDriver.lambda$checkNonW3CCapabilities$0(RemoteWebDriver.java:679)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:178)
	at java.base/java.util.TreeMap$KeySpliterator.forEachRemaining(TreeMap.java:3064)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
	at org.openqa.selenium.remote.RemoteWebDriver.checkNonW3CCapabilities(RemoteWebDriver.java:680)
	at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:239)
	at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:157)
	at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:139)
	at org.testcontainers.containers.BrowserWebDriverContainer.lambda$null$0(BrowserWebDriverContainer.java:335)
	... 4 more
Caused by: java.lang.ClassNotFoundException: org.openqa.selenium.AcceptedW3CCapabilityKeys
	... 17 more

With Selenium 4.1.4 the test runs successfully.

Test can be found here (Selenium Version has to be increased in the project POM to reproduce the failure)

sparsick avatar Nov 15 '22 08:11 sparsick

See original comment

getDriver() is being deprecated because it relies on the selenium driver classes. getSeleniumAddress() should be used instead. See #6204

Recommended usage:

RemoteWebDriver driver = new RemoteWebDriver(rule.getSeleniumAddress(), capabilities);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
...
driver.quit();

This way the timeout is handled without any dependency on BrowserWebDriverContainer class

eddumelendez avatar Nov 17 '22 19:11 eddumelendez

Thanks, @eddumelendez, for your hint.

In my case, the root cause was that I also have to add selenium-api to my dependency. Sorry for the noise.

A little improvement: In Selenium 4.6.0 implicitlyWait(30, TimeUnit.SECONDS) is deprecated. It is better to use implicitlyWait(Duration.ofSeconds(30))

sparsick avatar Nov 18 '22 14:11 sparsick

A little improvement: In Selenium 4.6.0 implicitlyWait(30, TimeUnit.SECONDS) is deprecated. It is better to use implicitlyWait(Duration.ofSeconds(30))

thank you! I miss IntelliJ strikethrough instead of highlighting 😁

I am updating code via this PR

eddumelendez avatar Nov 18 '22 14:11 eddumelendez

I think I found the problem or at least a workaround: SeleniumHQ/selenium#10984 (comment)

Using .withEnv("SE_OPTS", "--session-retry-interval 1") (in Selenium 4.4+) fixed the timeouts for me

I don't know why exactly, but when upgrading selenium from 4.17 to 4.18.x, I needed to remove the line above again, to make everything work. (In the commit, I'm upgrading from 4.5 to 4.18 which failed, but while working on the fix, I realized that 4.17 was still working as before)

See: https://github.com/scrum-for-developers/worblehat/commit/e5b6d62d81390cf4ae00f551a006221d24942de2

2024-02-26 12:00:56.969  INFO 85683 --- [           main] tc.selenium/standalone-chrome:4.18.0     : Creating container for image: selenium/standalone-chrome:4.18.0
2024-02-26 12:00:57.020  INFO 85683 --- [           main] tc.selenium/standalone-chrome:4.18.0     : Container selenium/standalone-chrome:4.18.0 is starting: 105c12f1a50dd0c7732414e9ffd30b59ae33e5045014f2922e480cf1195e49b9
2024-02-26 12:01:57.372 ERROR 85683 --- [           main] tc.selenium/standalone-chrome:4.18.0     : Could not start container

java.lang.IllegalStateException: Wait strategy failed. Container exited with code 0
        at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:533)
        at org.testcontainers.containers.GenericContainer.lambda$doStart$0(GenericContainer.java:354)
        at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:81)
        at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:344)
        at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:330)
        at de.codecentric.psd.worblehat.acceptancetests.adapter.SeleniumAdapter.setup(SeleniumAdapter.java:77)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at io.cucumber.java.Invoker.doInvoke(Invoker.java:66)
        at io.cucumber.java.Invoker.invoke(Invoker.java:24)
        at io.cucumber.java.AbstractGlueDefinition.invokeMethod(AbstractGlueDefinition.java:47)
        at io.cucumber.java.JavaHookDefinition.execute(JavaHookDefinition.java:64)
        at io.cucumber.core.runner.CoreHookDefinition.execute(CoreHookDefinition.java:46)
        at io.cucumber.core.runner.HookDefinitionMatch.runStep(HookDefinitionMatch.java:21)
        at io.cucumber.core.runner.ExecutionMode$1.execute(ExecutionMode.java:10)
        at io.cucumber.core.runner.TestStep.executeStep(TestStep.java:84)
        at io.cucumber.core.runner.TestStep.run(TestStep.java:56)
        at io.cucumber.core.runner.TestCase.run(TestCase.java:78)
        at io.cucumber.core.runner.Runner.runPickle(Runner.java:75)
        at io.cucumber.junit.PickleRunners$WithStepDescriptions.lambda$run$1(PickleRunners.java:109)
        at io.cucumber.core.runtime.CucumberExecutionContext.lambda$runTestCase$5(CucumberExecutionContext.java:137)
        at io.cucumber.core.runtime.RethrowingThrowableCollector.executeAndThrow(RethrowingThrowableCollector.java:23)
        at io.cucumber.core.runtime.CucumberExecutionContext.runTestCase(CucumberExecutionContext.java:137)
        at io.cucumber.junit.PickleRunners$WithStepDescriptions.run(PickleRunners.java:106)
        at io.cucumber.junit.FeatureRunner.runChild(FeatureRunner.java:144)
        at io.cucumber.junit.FeatureRunner.runChild(FeatureRunner.java:28)
        at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
        at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
        at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
        at io.cucumber.junit.FeatureRunner.run(FeatureRunner.java:137)
        at io.cucumber.junit.Cucumber.runChild(Cucumber.java:196)
        at io.cucumber.junit.Cucumber.runChild(Cucumber.java:89)
        at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
        at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
        at io.cucumber.core.runtime.CucumberExecutionContext.lambda$runFeatures$6(CucumberExecutionContext.java:148)
        at io.cucumber.core.runtime.CucumberExecutionContext.execute(CucumberExecutionContext.java:163)
        at io.cucumber.core.runtime.CucumberExecutionContext.runFeatures(CucumberExecutionContext.java:146)
        at io.cucumber.junit.Cucumber$StartAndFinishTestRun.evaluate(Cucumber.java:226)
        at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
        at org.junit.runners.Suite.runChild(Suite.java:128)
        at org.junit.runners.Suite.runChild(Suite.java:27)
        at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
        at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
        at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
        at org.apache.maven.surefire.junitcore.JUnitCore.run(JUnitCore.java:49)
        at org.apache.maven.surefire.junitcore.JUnitCoreWrapper.createRequestAndRun(JUnitCoreWrapper.java:120)
        at org.apache.maven.surefire.junitcore.JUnitCoreWrapper.executeEager(JUnitCoreWrapper.java:95)
        at org.apache.maven.surefire.junitcore.JUnitCoreWrapper.execute(JUnitCoreWrapper.java:75)
        at org.apache.maven.surefire.junitcore.JUnitCoreWrapper.execute(JUnitCoreWrapper.java:69)
        at org.apache.maven.surefire.junitcore.JUnitCoreProvider.invoke(JUnitCoreProvider.java:146)
        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:385)
        at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
        at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:507)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:495)
Caused by: org.rnorth.ducttape.TimeoutException: java.util.concurrent.TimeoutException
        at org.rnorth.ducttape.timeouts.Timeouts.callFuture(Timeouts.java:70)
        at org.rnorth.ducttape.timeouts.Timeouts.doWithTimeout(Timeouts.java:60)
        at org.testcontainers.containers.wait.strategy.WaitAllStrategy.waitUntilReady(WaitAllStrategy.java:54)
        at org.testcontainers.containers.GenericContainer.waitUntilContainerStarted(GenericContainer.java:909)
        at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:500)
        ... 67 common frames omitted
Caused by: java.util.concurrent.TimeoutException: null
        at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:204)
        at org.rnorth.ducttape.timeouts.Timeouts.callFuture(Timeouts.java:65)
        ... 71 common frames omitted

2024-02-26 12:01:57.401 ERROR 85683 --- [           main] tc.selenium/standalone-chrome:4.18.0     : Log output from the failed container:
2024-02-26 12:00:57,585 INFO Included extra file "/etc/supervisor/conf.d/selenium.conf" during parsing
2024-02-26 12:00:57,588 INFO RPC interface 'supervisor' initialized
2024-02-26 12:00:57,588 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2024-02-26 12:00:57,588 INFO supervisord started with pid 8
2024-02-26 12:00:58,592 INFO spawned: 'xvfb' with pid 9
2024-02-26 12:00:58,594 INFO spawned: 'vnc' with pid 10
2024-02-26 12:00:58,597 INFO spawned: 'novnc' with pid 11
2024-02-26 12:00:58,600 INFO spawned: 'selenium-standalone' with pid 12
Appending Selenium options: --session-retry-interval 1
2024-02-26 12:00:58,613 INFO success: xvfb entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
2024-02-26 12:00:58,613 INFO success: vnc entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
2024-02-26 12:00:58,613 INFO success: novnc entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
2024-02-26 12:00:58,613 INFO success: selenium-standalone entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
Appending Selenium options: --heartbeat-period 30
Appending Selenium options: --reject-unsupported-caps false
Setting up SE_NODE_GRID_URL...
Selenium Grid Standalone configuration: 
[network]
relax-checks = true

[node]
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": "121.0", "platformName": "Linux", "goog:chromeOptions": {"binary": "/usr/bin/google-chrome"}}'
max-sessions = 1

Starting Selenium Grid Standalone...
Tracing is disabled
Can only specify option --session-retry-interval once.
Usage: standalone [options]
  Options:
    --allow-cors
      Whether the Selenium server should allow web browser connections from 
      any host
      Default: false
    --bind-host
      Whether the server should bind to the host address/name, or only use it 
      to report its reachable url. Helpful in complex network topologies where 
      the server cannot report itself with the current IP/hostname but rather 
      an external IP or hostname (e.g. inside a Docker container).
      Default: true
    --config
      Config file to read from (may be specified more than once)
    --config-help
      Output detailed information about config options
      Default: false
    --detect-drivers
      Autodetect which drivers are available on the current system, and add 
      them to the Node.
      Default: true
    --disable-ui
      Disable the Grid UI
      Default: false
    -d, --distributor
      Url of the distributor.
    --distributor-host
      Host on which the distributor is listening.
    --distributor-implementation
      Full classname of non-default distributor implementation
      Default: org.openqa.selenium.grid.distributor.local.LocalDistributor
    --distributor-port
      Port on which the distributor is listening.
    --docker, -D
      Docker configs which map image name to stereotype capabilities (example: 
      -D selenium/standalone-firefox:latest '{"browserName": "firefox"}')
    --docker-assets-path
      Absolute path where assets will be stored
    --docker-devices
      Exposes devices to a container. Each device mapping declaration must 
      have  at least the path of the device in both host and container 
      separated by a colon like in this example: 
      /device/path/in/host:/device/path/in/container 
    --docker-host
      Host name where the docker daemon is running
    --docker-port
      Port where the docker daemon is running
    --docker-url
      URL for connecting to the docker daemon
    --docker-video-image
      Docker image to be used when video recording is enabled
      Default: selenium/video:latest
    --drain-after-session-count
      Drain and shutdown the Node after X sessions have been executed. Useful 
      for environments like Kubernetes. A value higher than zero enables this 
      feature. 
      Default: 0
    --driver-configuration
      List of configured drivers a Node supports. It is recommended to provide 
      this type of configuration through a toml config file to improve 
      readability. Command line example: --driver-configuration 
      display-name="Firefox Nightly" max-sessions=2 
      webdriver-path="/usr/local/bin/geckodriver" 
      stereotype="{\"browserName\": \"firefox\", \"browserVersion\": \"86\", 
      \"moz:firefoxOptions\": {\"binary":"/Applications/Firefox 
      Nightly.app/Contents/MacOS/firefox\"}}" 
    --driver-factory
      Mapping of fully qualified class name to a browser configuration that 
      this matches against. --driver-factory 
      org.openqa.selenium.example.LynxDriverFactory '{"browserName": "lynx"}'
    -I, --driver-implementation
      Drivers that should be checked. If specified, will skip 
      autoconfiguration. Example: -I "firefox" -I "chrome"
      Default: []
    --enable-bidi
      Enable BiDi proxying in Grid. A Grid admin can disable BiDi if the 
      network does not allow websockets. True by default
      Default: true
    --enable-cdp
      Enable CDP proxying in Grid. A Grid admin can disable CDP if the network 
      does not allow websockets. True by default
      Default: true
    --enable-managed-downloads
      When enabled, the Grid node will automatically do the following: 1. 
      Creates a temporary directory which will now represent the directory 
      into which files downloaded by Chrome/Firefox/Edge browser will be 
      under. 2. For every new session, a sub-directory will be created/deleted 
      so that all files that were downloaded for a given session are stored 
      in. 
    --external-url
      External URL where component is generally available. Useful on complex 
      network topologies when components are on different networks and proxy 
      servers are involved.
    --grid-url
      Public URL of the Grid as a whole (typically the address of the Hub or 
      the Router)
    --healthcheck-interval
      How often, in seconds, will the health check run for all Nodes.This 
      ensures the server can ping all the Nodes successfully.
      Default: 120
    --heartbeat-period
      How often, in seconds, will the Node send heartbeat events to the 
      Distributor to inform it that the Node is up.
      Default: 60
    --host
      Server IP or hostname: usually determined automatically.
    --http-logs
      Enable http logging. Tracing should be enabled to log http logs.
      Default: false
    --https-certificate
      Server certificate for https. Get more detailed information by running 
      "java -jar selenium-server.jar info security"
    --https-private-key
      Private key for https. Get more detailed information by running "java 
      -jar selenium-server.jar info security"
    --hub
      The address of the Hub in a Hub-and-Node configuration. This can be a 
      plain hostname or IP address (`hostname`), in which case the Hub will be 
      assumed to be `http://hostname:4444`, the `--grid-url` will be the same, 
      `--publish-events` will be `tcp://hostname:4442` and 
      `--subscribe-events` will be `tcp://hostname:4443`. If `hostname` 
      contains a port number, that will be used for `--grid-url` but the URIs 
      for the event bus will remain the same. Any of these default values may 
      be overridden but setting the correct flags. If the hostname has  a 
      protocol (such as `https`) that will be used too.
    --log
      File to write out logs. Ensure the file path is compatible with the 
      operating system's file path. Windows path example: 
      \\path\to\file\gridlog.log OR C:\path\path\to\file\gridlog.log 
      Linux/Unix/MacOS path example: /path/to/file/gridlog.log
    --log-encoding
      Log encoding
    --log-level
      Log level. Default logging level is INFO. Log levels are described here 
      https://docs.oracle.com/javase/7/docs/api/java/util/logging/Level.html 
      Default: INFO
    --log-timestamp-format
      Format of the timestamp in log output
    --max-sessions
      Maximum number of concurrent sessions. Default value is the number of 
      available processors.
      Default: 2
    --max-threads
      Maximum number of listener threads. Default value is: (available 
      processors) * 3.
      Default: 0
    --newsession-threadpool-size
      The Distributor uses a fixed-sized thread pool to create new sessions as 
      it consumes new session requests from the queue.This allows configuring 
      the size of the thread pool. The default value is no. of available 
      processors * 3. Note: If the no. of threads is way greater than the 
      available processors it will not always increase the performance. A high 
      number of threads causes more context switching which is an expensive 
      operation. 
      Default: 6
    --no-vnc-port
      If VNC is available, sets the port where the local noVNC stream can be 
      obtained 
      Default: 7900
    --node-implementation
      Full classname of non-default Node implementation. This is used to 
      manage a session's lifecycle.
      Default: org.openqa.selenium.grid.node.local.LocalNodeFactory
    --override-max-sessions
      The # of available processors is the recommended max sessions value (1 
      browser session per processor). Setting this flag to true allows the 
      recommended max value to be overwritten. Session stability and 
      reliability might suffer as the host could run out of resources.
      Default: false
    --password
      Password clients must use to connect to the server. Both this and the 
      username need to be set in order to be used.
    --plain-logs
      Use plain log lines
      Default: true
    -p, --port
      Port to listen on. There is no default as this parameter is used by 
      different components, for example Router/Hub/Standalone will use 4444 
      and Node will use 5555.
    --register-cycle
      How often, in seconds, the Node will try to register itself for the 
      first time to the Distributor.
      Default: 10
    --register-period
      How long, in seconds, will the Node try to register to the Distributor 
      for the first time. After this period is completed, the Node will not 
      attempt to register again.
      Default: 120
    --registration-secret
      Node registration secret
    --reject-unsupported-caps
      Allow the Distributor to reject a request immediately if the Grid does 
      not support the requested capability.Rejecting requests immediately is 
      suitable for Grid set up that does not spin up Nodes on demand.
      Default: false
    --relax-checks
      Relax checks on origin header and content type of incoming requests, in 
      contravention of strict W3C spec compliance.
      Default: false
    --selenium-manager
      When drivers are not available on the current system, use, Selenium 
      Manager. 
      Default: false
    --service-configuration
      Configuration for the service where calls will be relayed to. It is 
      recommended to provide this type of configuration through a toml config 
      file to improve readability. Command line example: 
      --service-configuration max-sessions=2 stereotype='{"browserName": 
      "safari", "platformName": "iOS", "appium:platformVersion": "14.5"}}'
    --service-host
      Host name where the service that supports WebDriver commands is running
    --service-port
      Port where the service that supports WebDriver commands is running
    --service-status-endpoint
      Endpoint to query the WebDriver service status, an HTTP 200 response is 
      expected 
    --service-url
      URL for connecting to the service that supports WebDriver commands, like 
      an Appium server or a cloud service.
    --session-request-timeout
      Timeout in seconds. New incoming session request is added to the queue. 
      Requests sitting in the queue for longer than the configured time will 
      timeout. 
      Default: 300
    --session-request-timeout-period
      In seconds, how often the timeout for new session requests is checked.
      Default: 10
    --session-retry-interval
      Session creation interval in milliseconds. If all slots are busy, new 
      session request will be retried after the given interval.
      Default: 15
    --session-timeout
      Let X be the session-timeout in seconds. The Node will automatically 
      kill a session that has not had any activity in the last X seconds. This 
      will release the slot for other tests.
      Default: 300
    --sq, --sessionqueue
      Address of the session queue server.
    --sessionqueue-batch-size
      Maximum batch size that can consumed from queue based on the available 
      slots. 
      Default: 6
    --sessionqueue-host
      Host on which the session queue server is listening.
    --sessionqueue-port
      Port on which the session queue server is listening.
    --slot-matcher
      Full classname of non-default slot matcher to use. This is used to 
      determine whether a Node can support a particular session.
      Default: org.openqa.selenium.grid.data.DefaultSlotMatcher
    --slot-selector
      Full classname of non-default slot selector. This is used to select a 
      slot in a Node once the Node has been matched.
      Default: org.openqa.selenium.grid.distributor.selector.DefaultSlotSelector
    --structured-logs
      Use structured logs
      Default: false
    --sub-path
      A sub-path that should be considered for all user facing routes on the 
      Hub/Router/Standalone 
    --tracing
      Enable trace collection
      Default: true
    --username
      User name clients must use to connect to the server. Both this and 
      password need to be set in order to be used.
    --version
      Displays the version and exits.
      Default: false
    --vnc-env-var
      Environment variable to check in order to determine if a vnc stream is 
      available or not.
      Default: SE_START_XVFB

2024-02-26 12:00:59,117 INFO exited: selenium-standalone (exit status 0; expected)
2024-02-26 12:00:59,118 WARN received SIGINT indicating exit request
2024-02-26 12:00:59,118 INFO waiting for xvfb, vnc, novnc to die
2024-02-26 12:00:59,660 INFO stopped: novnc (terminated by SIGTERM)
2024-02-26 12:00:59,661 INFO stopped: vnc (terminated by SIGTERM)
2024-02-26 12:01:00,666 INFO stopped: xvfb (terminated by SIGTERM)

AndreasEK avatar Feb 26 '24 11:02 AndreasEK