22

tl;dr

How can I install all the components to run Selenium in a docker container?


Question

I'm starting with this image:

FROM microsoft/aspnetcore-build:2 AS builder
WORKDIR /source

COPY . .
RUN dotnet restore
RUN dotnet build
ENTRYPOINT ["dotnet", "run"]

How can I make it so that I can start and use an headless Chrome Driver with this:

ChromeOptions options = new ChromeOptions();
options.AddArgument("--headless");
options.AddArgument("--disable-gpu");
var driverPath = Path.GetFullPath(Path.Combine(environment.ContentRootPath, "bin/Debug/netcoreapp2.0"));
return new ChromeDriver(driverPath, options, TimeSpan.FromSeconds(60));

within a docker container?


What have I tried

Installing the Chrome driver

The chromedriver is distributed via the Selenium.WebDriver.ChromeDriver NuGet package.

Installing Chrome

On my Mac OS X with Google Chrome installed the current setup works just fine.

I've tried to add these lines:

RUN apt-get update && apt-get -y install libglib2.0-dev libxi6 libnss3-dev
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
RUN apt-get update && apt-get -y install google-chrome-stable

The above installs this version of Chrome:

google-chrome-stable:
  Installed: 64.0.3282.119-1
  Candidate: 64.0.3282.119-1
  Version table:
 *** 64.0.3282.119-1 500
        500 http://dl.google.com/linux/chrome/deb stable/main amd64 Packages
        100 /var/lib/dpkg/status

which is compatible with the version of the Chrome Driver.

which come from trying to solve each error that came out by trying to run Selenium with the docker container.

If I run this setup I get:

Starting ChromeDriver 2.35.528139 (47ead77cb35ad2a9a83248b292151462a66cd881) on port 57889 Only local connections are allowed. An error occurred while sending the request. Couldn't connect to

when running the container.

Debugging in the container

If I enter the container manually and try to run the chrome driver manually I get:

Starting ChromeDriver 2.35.528139 (47ead77cb35ad2a9a83248b292151462a66cd881) on port 9515 Only local connections are allowed.

and running curl -i http://localhost:9515/status I get:

HTTP/1.1 200 OK
Content-Length:136
Content-Type:application/json; charset=utf-8
Connection:close

{"sessionId":"","status":0,"value":{"build":{"version":"alpha"},"os":{"arch":"x86_64","name":"Linux","version":"4.9.60-linuxkit-aufs"}}}

so it seems that the driver works just fine.

If I run chrome headless instead via google-chrome-stable --headless --disable-cpu --no-sandbox I get:

[0125/210641.877388:WARNING:discardable_shared_memory_manager.cc(178)] Less than 64MB of free space in temporary directory for shared memory files: 63
[0125/210641.902689:ERROR:instance.cc(49)] Unable to locate service manifest for metrics
[0125/210641.902756:ERROR:service_manager.cc(890)] Failed to resolve service name: metrics
[0125/210642.031088:ERROR:instance.cc(49)] Unable to locate service manifest for metrics
[0125/210642.031119:ERROR:service_manager.cc(890)] Failed to resolve service name: metrics
[0125/210642.032934:ERROR:gpu_process_transport_factory.cc(1009)] Lost UI shared context.

The first warning can be solved via setting a docker volume in /dev/shm:/dev/shm or by setting -shm-size to something large (higher than 64MB).

The rest of the errors, if google, lead to me many bug reports from Google Chrome repositories.

Shoe
  • 74,840
  • 36
  • 166
  • 272

4 Answers4

4

I used the Selenium image, installed dotnet runtime there and got it working.
Here is my Dockerfile:

FROM selenium/standalone-chrome:latest AS base
WORKDIR /app

# build and copy dotnet project
FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
WORKDIR /src
COPY ["TestBot/TestBot.csproj", "TestBot/"]
RUN dotnet restore "TestBot/TestBot.csproj"
COPY . .
WORKDIR "/src/TestBot"
RUN dotnet build "TestBot.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "TestBot.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .

# install dotnet
RUN sudo wget https://packages.microsoft.com/config/debian/10/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
RUN sudo dpkg -i packages-microsoft-prod.deb
RUN sudo apt-get update
RUN sudo apt-get install -y dotnet-runtime-5.0

ENTRYPOINT ["dotnet", "TestBot.dll"]

My C# code looks similar to yours:

using OpenQA.Selenium.Remote;
using OpenQA.Selenium;
using System;
using OpenQA.Selenium.Chrome;
using System.Drawing;
using OpenQA.Selenium.Firefox;
using System.Threading;

namespace TestBot
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            ChromeOptions Options = new ChromeOptions();

            if (OperatingSystem.IsWindows())
            {
                Options.AddAdditionalCapability("platform", "WIN10", true); // Supported values: "VISTA" (Windows 7), "WIN8" (Windows 8), "WIN8_1" (windows 8.1), "WIN10" (Windows 10), "LINUX" (Linux)
            }
            else
            {
                Options.AddAdditionalCapability("platform", "LINUX", true); // Supported values: "VISTA" (Windows 7), "WIN8" (Windows 8), "WIN8_1" (windows 8.1), "WIN10" (Windows 10), "LINUX" (Linux)
            }
            Options.AddArgument("--headless");

            ChromeDriver driver = new ChromeDriver(Options);
            try
            {
                // driver.Manage().Window.Size = new Size(1920, 1080);
                driver.Navigate().GoToUrl("https://google.com/");
                var test = driver.FindElementByTagName("html").Text;
                Console.WriteLine(test);
            }
            finally
            {
                driver.Quit();
            }
            Console.ReadLine();
        }
    }
}

I used the following Libraries: enter image description here

Michael Santos
  • 466
  • 7
  • 15
3

The most popular options are "docker selenium" or "selenoid". The implementation is different but both solutions take advantage of docker to create test environment similar to selenium grid.

I recommend "selenoid" and to configure it properly you could start with the following guide: https://www.swtestacademy.com/selenoid-tutorial/

If you choose "docker selenium" this could be your starting point: https://www.swtestacademy.com/docker-selenium-tutorial/

eroteev
  • 620
  • 1
  • 7
  • 17
0

There's a pretty neat framework built around Docker containers being used as Remote Driver locations.

http://aerokube.com/selenoid/latest/

I haven't fully implemented it yet, but I managed to effortlessly create docker containers with appropriate chrome and firefox drivers inside.

0

Here are the Dockerfile RUN commands to install Chrome and (a matching!) Chrome Driver into an image.

# install essential tools
RUN apt-get update && apt-get install unzip

# install Chrome
RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb \
    && apt-get install ./google-chrome-stable_current_amd64.deb -y

# download matching Chrome Driver
# https://stackoverflow.com/a/61928952/167920
RUN chromeVersion=$(google-chrome --product-version) \
    && chromeMajorVersion=${chromeVersion%%.*} \
    && latestDriverReleaseURL=https://chromedriver.storage.googleapis.com/LATEST_RELEASE_$chromeMajorVersion \
    && wget $latestDriverReleaseURL \
    && latestDriverVersionFileName="LATEST_RELEASE_"$chromeMajorVersion \
    && latestFullDriverVersion=$(cat $latestDriverVersionFileName) \
    && rm $latestDriverVersionFileName \
    && finalURL="http://chromedriver.storage.googleapis.com/"$latestFullDriverVersion"/chromedriver_linux64.zip" \
    && wget $finalURL \
    && unzip chromedriver_linux64.zip \
    && rm chromedriver_linux64.zip
    
# Copy chromedriver to the desired folder
# mkdir --parents /source/tests/MyProject.Tests/bin/Debug/net6.0 \
# && mv chromedriver /source/tests/MyProject.Tests/bin/Debug/net6.0/
Wallace Kelly
  • 15,565
  • 8
  • 50
  • 71