Does anyone know why I sometimes get exception when I use Selenium together with Testcontainers. See below:
Exception has occurred: CLR/OpenQA.Selenium.WebDriverException
An exception of type ‘OpenQA.Selenium.WebDriverException’ occurred in WebDriver.dll but was not handled in user code: ‘An unknown exception was encountered sending an HTTP request to the remote WebDriver server for URL http://localhost:4444/session. The exception message was: An error occurred while sending the request.’
Inner exceptions found, see $exception in variables window for more details.
Innermost exception System.IO.IOException : The response ended prematurely.
at System.Net.Http.HttpConnection.d__61.MoveNext()
This happens half the time when i run the following test constructor (C# / xUnit.net):
public DockerShould()
{
var gridNetwork = new NetworkBuilder()
.WithName("gridNetwork")
.Build();
const int SessionPort = 4444;
var containerHub = new ContainerBuilder()
.WithImage("selenium/hub:4.8")
.WithName("selenium-hub")
.WithPortBinding(4442, 4442)
.WithPortBinding(4443, 4443)
.WithPortBinding(SessionPort, SessionPort)
.WithNetwork(gridNetwork)
.Build();
var firefoxEnvironment = new Dictionary<string, string>()
{
{"SE_EVENT_BUS_HOST", "selenium-hub"},
{"SE_EVENT_BUS_PUBLISH_PORT", "4442"},
{"SE_EVENT_BUS_SUBSCRIBE_PORT", "4443"}
};
var containerFirefox = new ContainerBuilder()
.WithImage("selenium/node-firefox:4.8")
.WithEnvironment(firefoxEnvironment)
.WithNetwork(gridNetwork)
.Build();
var firefoxVideoEnvironment = new Dictionary<string, string>()
{
{"DISPLAY_CONTAINER_NAME", "firefox"},
{"FILE_NAME", "firefox.mp4"}
};
var containerFirefoxVideo = new ContainerBuilder()
.WithImage("selenium/video:ffmpeg-4.3.1-20230210")
.WithNetwork(gridNetwork)
.WithEnvironment(firefoxVideoEnvironment)
// .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(SessionPort))
.Build();
gridNetwork.CreateAsync().Wait();
containerHub.StartAsync().Wait();
containerFirefox.StartAsync().Wait();
containerFirefoxVideo.StartAsync().Wait();
Thread.Sleep(5000);
_remoteWebDriver = new RemoteWebDriver(new Uri("http://localhost:4444"), new FirefoxOptions());
}
The exception occurs when creating the new RemoteWebDriver. I’ve added a thread.sleep to give a bit of a delay before the variable is created. I’m not sure it’s really helping much. Is there a more elegant way to ensure all containers are started up before attempting to create the web driver (which i’m assuming is the problem)?
2
Answers
Your configuration has a few shortcomings. I am uncertain as to which one is ultimately causing the issue, but I have provided a working example below. The crucial parts have been commented. Please note that the example does not incorporate a wait strategy to determine the readiness of the container or the service inside it. That is an aspect that you will still need to address. But first lets take a look at some basics.
WithPortBinding(4444, 4444)
. To prevent port conflicts, assign a random host port by usingWithPortBinding(4444, true)
and retrieve it from the container instance usingGetMappedPublicPort(4444)
.WithNetworkAliases(string)
instead.localhost
to access services running inside containers. The endpoint varies according to the Docker environment. Use theHostname
property instead.I will like to ask you please: What do you use hub and node selenium mode?
I recommended using in this case standalone mode – and why?
Because the webDriver testcoaniner in my opinion works like a dynamic grid in s: docker-selenium github
I am also asking because I just working on that: Feature- WebDriver container
So I would like your opinion and how I can map between the testcotanienr and the RemoteWebDriver capabilities