Dockerize Selenium Java Project and run Selenium Scripts within Docker Container
There are a ton of materials available online to run our Selenium scripts in browser containers like standalone-firefox, standalone-chrome. In all those cases, the person need to clone the repository locally and then use Docker containers like standalone-chrome to run the scripts.
What if, we want to give testing service in such a way that, anybody can run the scripts anywhere and see the report without cloning our repository.
This is what we have done here. Here, we are dockerizing our entire Selenium Project and running our scripts inside Docker Container.
First, let us see the advantages of this approach:
- Once our Selenium Java Project is dockerized, anybody can run our script anywhere. They don’t need to clone our repository, don’t need to include those dependencies, etc. They just need to get the Docker Image and run it. Its inevitable when we are about to make “Testing as a Service”.
- Test can be run in any browser version. We don’t need to install that particular browser version in that system.
- Test can be performed in different screen resolution. Be it, 1366x768, 1920x1080 or anything.
- Parallel execution at ease. No configuration is required.
The benefits come with trade-offs too. Here are the disadvantages:
- Supports only headless execution. We cannot see the execution in real time. VNC Servers can be configured but that’s bit complex.
Let us create a sample project. I have a project with 2 test cases. One runs in Chrome and another in Firefox. The whole project is available in Github
Lets install Docker in our system and keep it running.
Now, lets create a DockerFile (case sensitive) in our project root folder.
We need to do the following things in Docker image.
0. Choose Base
- Install the pre-requisites.
- Download & Install Chrome browser
- Download Chrome driver
- Download & Install Firefox browser
- Download Firefox driver (Geckodriver)
- Download & Install Maven. Also set the env variables.
- Copy our project to Docker.
The whole DockerFile looks like this:
#Step 0: Choose base
FROM kshivaprasad/java:1.8#Step 1 : Install the pre-requisite
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y p7zip \
p7zip-full \
unace \
zip \
unzip \
bzip2
#Version numbers
ARG FIREFOX_VERSION=78.0.2
ARG CHROME_VERSION=83.0.4103.116
ARG CHROMDRIVER_VERSION=83.0.4103.39
ARG FIREFOXDRIVER_VERSION=0.26.0
#Step 2: Install Chrome
RUN curl http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_$CHROME_VERSION-1_amd64.deb -o /chrome.deb
RUN dpkg -i /chrome.deb
RUN rm /chrome.deb#Step 3: Install chromedriver for Selenium
RUN mkdir -p /app/bin
RUN curl https://chromedriver.storage.googleapis.com/$CHROMDRIVER_VERSION/chromedriver_linux64.zip -o /tmp/chromedriver.zip \
&& unzip /tmp/chromedriver.zip -d /app/bin/ \
&& rm /tmp/chromedriver.zip
RUN chmod +x /app/bin/chromedriver#Step 4 : Install firefox
RUN wget --no-verbose -O /tmp/firefox.tar.bz2 https://download-installer.cdn.mozilla.net/pub/firefox/releases/$FIREFOX_VERSION/linux-x86_64/en-US/firefox-$FIREFOX_VERSION.tar.bz2 \
&& bunzip2 /tmp/firefox.tar.bz2 \
&& tar xvf /tmp/firefox.tar \
&& mv /firefox /opt/firefox-$FIREFOX_VERSION \
&& ln -s /opt/firefox-$FIREFOX_VERSION/firefox /usr/bin/firefox#Step 5: Install Geckodriver
RUN wget https://github.com/mozilla/geckodriver/releases/download/v$FIREFOXDRIVER_VERSION/geckodriver-v$FIREFOXDRIVER_VERSION-linux64.tar.gz \
&& tar -xf geckodriver-v0.26.0-linux64.tar.gz \
&& cp geckodriver /app/bin/geckodriver
RUN chmod +x /app/bin/geckodriver#Step 6: Install Maven
# 1- Define Maven version
ARG MAVEN_VERSION=3.6.3
# 2- Define a constant with the working directory
ARG USER_HOME_DIR="/root"
# 3- Define the SHA key to validate the maven download
ARG SHA=c35a1803a6e70a126e80b2b3ae33eed961f83ed74d18fcd16909b2d44d7dada3203f1ffe726c17ef8dcca2dcaa9fca676987befeadc9b9f759967a8cb77181c0
# 4- Define the URL where maven can be downloaded from
ARG BASE_URL=http://apachemirror.wuchna.com/maven/maven-3/${MAVEN_VERSION}/binaries
# 5- Create the directories, download maven, validate the download, install it, remove downloaded file and set links
RUN mkdir -p /usr/share/maven /usr/share/maven/ref \
&& echo "Downlaoding maven" \
&& curl -fsSL -o /tmp/apache-maven.tar.gz ${BASE_URL}/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
\
&& echo "Checking download hash" \
&& echo "${SHA} /tmp/apache-maven.tar.gz" | sha512sum -c - \
\
&& echo "Unziping maven" \
&& tar -xzf /tmp/apache-maven.tar.gz -C /usr/share/maven --strip-components=1 \
\
&& echo "Cleaning and setting links" \
&& rm -f /tmp/apache-maven.tar.gz \
&& ln -s /usr/share/maven/bin/mvn /usr/bin/mvn
# 6- Define environmental variables required by Maven, like Maven_Home directory and where the maven repo is located
ENV MAVEN_HOME /usr/share/maven
ENV MAVEN_CONFIG "$USER_HOME_DIR/.m2"#Step 7: Copy our project
COPY . /app#Making our working directory as /app
WORKDIR /app
Lets see each steps in brief:
Step 0 : Choose Base
Choose any existing docker image here. I have chosen the Java image created by kshivaprasad as he has already build a Ubuntu container with Java. So, I don’t need to install Java again. If you don’t want to use it, you just need to take any other OS image and write code to install Java.
Step 1 : Install Pre-requisite:
curl, bzip2, unzip are some of the commands which we use in our project. So, installing them on the first hand. Installation is just
apt-get install curl
More than one installation can be clubbed using backslash (\).
Step 2 : Download & install Chrome browser
We need to know the URL that downloads the Chrome browser directly.
In order to download something in Docker (which is based on Linux), we need to use either wget or curl. We used curl here. (Remember, we have already installed these commands in Step 1):
curl http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_$CHROME_VERSION-1_amd64.deb -o /chrome.deb
For installation, we shall use either “dpkg” or “apt-get install”
dpkg -i /chrome.deb
Step 3 : Download Chromedriver:
Pretty straight forward, just take the link and download it. It would be a zip file, for unzipping it, we need to use unzip command. Then, we are removing the zip file.
Step 4: Install Firefox:
Installing firefox is quite different.
- We need to download the firefox file. It would be .tar.bz2 format.
- For extracting bz2, use “bunzip2". For extracting tar, use “tar xvf”.
- Then, we are moving the firefox folder to some path (here, /opt/Firefox-version).
- Then we need to soft link this file to /usr/bin/firefox. Soft linking is just like placing shorcut file. We have placed the shortcut file of /opt/Firefox-version/firefox in /usr/bin/firefox. So, whenever we call Firefox, this Firefox version gets called.
Step 5: Download Firefox driver (Geckodriver):
Same as Step 3.
Step 6 : Install Maven:
Set argument for Maven version, User Home directory, SHA key (optional), maven URL. Then install the maven and set the MAVEN_HOME, MAVEN_CONFIG.
Step 7 : Copy project:
Its to copy the whole project to docker container under /app folder.
Now that, the DockerFile is done.
We need to do some changes to our Selenium project as well:
For Chrome:
System.setProperty("webdriver.chrome.driver","/app/bin/chromedriver");
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless");
options.addArguments("--no-sandbox");
System.setProperty("webdriver.chrome.args", "--disable-logging");
System.setProperty("webdriver.chrome.silentOutput", "true");
options.addArguments("--disable-dev-shm-usage"); // overcome limited resource problems
options.addArguments("disable-infobars"); // disabling infobars
options.addArguments("--disable-extensions"); // disabling extensions
options.addArguments("--disable-gpu"); // applicable to windows os only
options.addArguments("window-size=1024,768"); // Bypass OS security model
ChromeDriver driver = new ChromeDriver(options);
For Firefox:
FirefoxOptions firefoxDockerOptions = new FirefoxOptions();
System.setProperty("webdriver.gecko.driver","/app/bin/geckodriver");
firefoxDockerOptions.addArguments("--headless");
firefoxDockerOptions.addArguments("--no-sandbox");
System.setProperty("webdriver.gecko.args", "--disable-logging");
System.setProperty("webdriver.gecko.silentOutput", "true");
firefoxDockerOptions.addArguments("--disable-dev-shm-usage"); // overcome limited resource problems
firefoxDockerOptions.addArguments("disable-infobars"); // disabling infobars
firefoxDockerOptions.addArguments("--disable-extensions"); // disabling extensions
firefoxDockerOptions.addArguments("--disable-gpu"); // applicable to windows os only
firefoxDockerOptions.addArguments("--width=1920"); // Bypass OS security model
firefoxDockerOptions.addArguments("--height=1080");
FirefoxDriver driver = new FirefoxDriver(firefoxDockerOptions);
The steps are self describing. Here, we can describe the width and height of the screen.
That’s it, we are done. Now, we need to build the docker image and run it.
To build the docker image (dot at the end is mandatory):
docker build -t selenium_docker_sample .
Once the build is done, it would look something like this:
To run the docker image:
docker run -it selenium_docker_sample
Now, we have entered into the docker container. We shall run our scripts. We run our scripts via maven surefire plugin:
mvn clean test -DsuiteXmlFile=testng/testng.xml
Once the execution is completed, the reports would have got created withing the Docker Container. To copy the file from Docker Container to our local system, we need to use “docker cp”. Before that, we need to exit from the Docker Container. Just use ‘exit’ command. Then, run the following command:
docker cp c345621:/app/test-output test-output
where, c345621 is the docker container id which we can see using ‘docker ps’ command.
This docker image can be uploaded to Docker hub. From there, anybody can just download the image and run it.
The whole project is available in Github in this link —
Happy Seldockering…. :)