Reputation: 48
I am trying to set up a .NET Core Console Application that uses Selenium Webdriver with Firefox in Docker, but I am having difficulty understanding how to actually use the official Selenium docker images.
For now the console app is just an app that tries to go to Google.com and report back successfully.
I am consistently getting the following error message when trying to create a new FirefoxDriver:
Expected browser binary location, but unable to find binary in default location, no 'moz:firefoxOptions.binary' capability provided, and no binary flag set on the command line (SessionNotCreated)
Here is the Dockerfile (generated by VSCode Docker extension + one line added by me, commented out now):
FROM microsoft/dotnet:2.1-runtime AS base
WORKDIR /app
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY ["MyAppName.csproj", "./"]
RUN dotnet restore "./MyAppName.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "MyAppName.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "MyAppName.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
# FROM selenium/standalone-firefox-debug ## where does this go?
ENTRYPOINT ["dotnet", "MyAppName.dll"]
I've tried to insert the selenium standalone image at various points, attempted to start with '/bin/bash/' entrypoint to try and find if firefox is actually in the image (which it didn't seem to be, not on the regular locations). It still throws the exception.
Really all I want is to have firefox installed in my container so that I can run my .NET Core console app, but according to some google searches the simplest way to do this should be through the selenium images.
How do I properly use the selenium docker image?
Upvotes: 1
Views: 1147
Reputation: 48
Answering my own question just in case someone else new to Docker has the same problem and ends up here.
I figured it out.
The better way to do this is with docker-compose to run 3 different services: my C# script, a selenium hub service and a selenium firefox node. (you might be able to do it with just a script and a selenium firefox standalone image, but I'm just posting the first thing that worked for me. Will try other stuff later)
I removed the FROM selenium/standalone-firefox-debug
statement from my .NET Core Console App Dockerfile and then put the following docker-compose.yml
file in the same folder as my Dockerfile (most of it taken from this stackoverflow answer):
version: '2'
services:
seltest:
build:
context: .
volumes:
- ./temp:/usr/src/app/target
environment:
- HUB_PORT_4444_TCP_ADDR=seleniumhub
- HUB_PORT_4444_TCP_PORT=4444
depends_on:
- seleniumhub
seleniumhub:
image: selenium/hub
ports:
- 4444:4444
firefoxnode:
image: selenium/node-firefox-debug
ports:
- 5900
environment:
- HUB_PORT_4444_TCP_ADDR=seleniumhub
- HUB_PORT_4444_TCP_PORT=4444
In my C# script I now had to make some changes. I had to connect my remote webdriver to the correct URI:
IWebDriver driver = new RemoteWebDriver(new Uri("http://seleniumhub:4444/wd/hub"), firefoxOptions);
(seleniumhub:4444 because the name of the service I create in the docker-compose.yml is seleniumhub and 4444 is the port opened for this service)
And because depends_on
in docker-compose only waits for the services to start and not until they're 'ready', I resorted to a hacky way of ensuring the selenium hub and firefox service are ready before I try to use them and just did a:
Thread.Sleep(10000);
before invoking the remote webdriver. If I don't do this then I get the following error trying to invoke the webdriver:
Unhandled Exception: OpenQA.Selenium.WebDriverException: A exception with a null response was thrown sending an HTTP request to the remote WebDriver server for URL http://seleniumhub:4444/wd/hub/session. The status of the exception was UnknownError, and the message was: Connection refused Connection refused ---> System.Net.WebException: Connection refused Connection refused ---> System.Net.Http.HttpRequestException: Connection refused ---> System.Net.Sockets.SocketException: Connection refused
Then I just run docker compose up
from the command line to start the service and I can verify that my C# script made it to https://www.google.com successfully.
Seems like the whole it could be optimized in many ways, but for me the proof of concept is done!
Upvotes: 1