Building your own docker images for different browser versions

When any application is deployed the software needs to be tested across multiple platforms and different versions of browsers. It’s tough to maintain environments with different versions of browsers. One approach is to use cloud solutions like Sauce Labs or BrowserStack which provides multi-version-browser support. But in case if you want to build your own environment which is easy to control and maintain, you can create your own docker images/containers for different browser versions as and when you need.


Overview

This post assumes you already know a little about Docker and Dockerfile. In the following sections we will be talking about below items:

    1. Third party sources for getting archived versions of browsers
    2. Why we chose to create Docker images/containers for different versions of browsers?
    3. Creating a Dockerfile
    4. Building your own images using this Dockerfile
    5. Creating a container and running Selenium tests

1.Third party sources for getting archived versions of browsers

We started exploring, where to get the official downloads of older stable browser(Chrome/Firefox) versions for Windows, Linux and Mac. Unlike Mozilla, Google seems to keep very quiet about versions, it does not keep an archive version so the old versions are gone forever as soon as a newer version becomes available. There is no official way to download Google Chrome older versions. So, we will have to rely on third-party sources for getting archived versions. There are some decent third party sites providing old versions. One such site is Slimjet. You can get older versions of Chrome using Slimjet. They have cached old versions of Chrome for Windows, Linux and Mac. Just run the executable and extract the files to any folder on your hard drive.


2. Why we chose to create Docker images/containers for different versions of browsers?

We can’t (easily) maintain multiple versions of the same browser in a single system. So the best way to tackle this to create different Docker images/containers for different browser versions and run your scripts in each container. In the following sections, we will be briefing you about how we created different containers for different browser versions and how we ran our Python-Selenium tests. We have created a Dockerfile and build different images using this Dockerfile for different versions of Chrome and Firefox. A Dockerfile is a text document that contains all the commands a user could execute on the command line to assemble an image. Whoever wants to test their application on for eg., Chrome version 57 can simply pull this image from DockerHub and create a container and run their scripts.


3. Creating a Dockerfile

To give an overview of our Dockerfile, we created two different Dockerfiles for Chrome and Firefox respectively. It contains below steps. You may also refer to our other post on Preparing a docker image on Docker file creation and running selenium tests.

  • Step 1 is basic step where we pull the base image Ubuntu(We used Ubuntu 16.04.)
  • Step 2 is installation of Xvfb display and other essentials
  • Step 3 is setup browser version and driver using ARG parameters. The ARG instruction defines a variable that users can pass at build-time with the docker build command. You can specify versions by using CHROME_VERSION and FIREFOX_VERSION in –build-arg variables. Since we decided to use the old versions of Chrome/Firefox this step is critical. To know more about using ARG variables refer here
  • Step 4 is installing Python 2.7 and Python Pip
  • Dockerfile for Chrome browser

    #Step 1
    #Dockerfile to build an image for different versions of chrome
    #Pull ubuntu 16.04 base image
    FROM ubuntu
    MAINTAINER Qxf2 Services
     
    #Step 2
    #Essential tools and xvfb
    RUN apt-get update && apt-get install -y \
        software-properties-common \
        unzip \
        curl \
        wget \
        xvfb
     
    #Step 3
    #Chrome browser to run the tests
    ARG CHROME_VERSION=65.0.3325.181
    RUN curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add \
          && wget https://www.slimjet.com/chrome/download-chrome.php?file=lnx%2Fchrome64_$CHROME_VERSION.deb \
          && dpkg -i download-chrome*.deb || true
    RUN apt-get install -y -f \
          && rm -rf /var/lib/apt/lists/*
     
    #Disable the SUID sandbox so that chrome can launch without being in a privileged container
    RUN dpkg-divert --add --rename --divert /opt/google/chrome/google-chrome.real /opt/google/chrome/google-chrome \
            && echo "#! /bin/bash\nexec /opt/google/chrome/google-chrome.real --no-sandbox --disable-setuid-sandbox \"\$@\"" > /opt/google/chrome/google-chrome \
            && chmod 755 /opt/google/chrome/google-chrome
     
    #Chrome Driver
    ARG CHROME_DRIVER_VERSION=2.37
    RUN mkdir -p /opt/selenium \
            && curl http://chromedriver.storage.googleapis.com/$CHROME_DRIVER_VERSION/chromedriver_linux64.zip -o /opt/selenium/chromedriver_linux64.zip \
            && cd /opt/selenium; unzip /opt/selenium/chromedriver_linux64.zip; rm -rf chromedriver_linux64.zip; ln -fs /opt/selenium/chromedriver /usr/local/bin/chromedriver;
     
    #Firefox browser to run the tests
    RUN apt-get update && apt-get install -y firefox
     
    #Geckodriver
    ENV GECKODRIVER_VERSION 0.16.0
    RUN wget --no-verbose -O /tmp/geckodriver.tar.gz https://github.com/mozilla/geckodriver/releases/download/v$GECKODRIVER_VERSION/geckodriver-v$GECKODRIVER_VERSION-linux64.tar.gz \
      && rm -rf /opt/geckodriver \
      && tar -C /opt -zxf /tmp/geckodriver.tar.gz \
      && rm /tmp/geckodriver.tar.gz \
      && mv /opt/geckodriver /opt/geckodriver-$GECKODRIVER_VERSION \
      && chmod 755 /opt/geckodriver-$GECKODRIVER_VERSION \
      && ln -fs /opt/geckodriver-$GECKODRIVER_VERSION /usr/bin/geckodriver \
      && ln -fs /opt/geckodriver-$GECKODRIVER_VERSION /usr/bin/wires
     
    #Step 4
    #Python 2.7 and Python Pip
    RUN apt-get update
    RUN apt-get install -y \
        python \
        python-setuptools \
        python-pip

    In the above Dockerfile, if you look at Step 3 we are downloading and installing the .deb file for the specified chrome version and chrome driver version from Slimjet website using ARG variables.

    #Dockerfile for Firefox browser

    #Step 1
    #Dockerfile to build an image for different versions of firefox
    #Pull ubuntu 16.04 base image
    FROM ubuntu
    MAINTAINER Qxf2 Services
     
    #Step 2
    #Essential tools and xvfb
    RUN apt-get update && apt-get install -y \
        software-properties-common \
        unzip \
        curl \
        wget \
        bzip2\
        xvfb
     
    #Step 3
    #Firefox
    ARG FIREFOX_VERSION=59.0.2
    RUN apt-get update -qqy \
      && apt-get -qqy --no-install-recommends install firefox \
      && rm -rf /var/lib/apt/lists/* /var/cache/apt/* \
      && 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 \
      && apt-get -y purge firefox \
      && rm -rf /opt/firefox \
      && tar -C /opt -xjf /tmp/firefox.tar.bz2 \
      && rm /tmp/firefox.tar.bz2 \
      && mv /opt/firefox /opt/firefox-$FIREFOX_VERSION \
      && ln -fs /opt/firefox-$FIREFOX_VERSION/firefox /usr/bin/firefox\
     
    #GeckoDriver
    ARG GECKODRIVER_VERSION=0.20.1
    RUN wget --no-verbose -O /tmp/geckodriver.tar.gz https://github.com/mozilla/geckodriver/releases/download/v$GECKODRIVER_VERSION/geckodriver-v$GECKODRIVER_VERSION-linux64.tar.gz \
      && rm -rf /opt/geckodriver \
      && tar -C /opt -zxf /tmp/geckodriver.tar.gz \
      && rm /tmp/geckodriver.tar.gz \
      && mv /opt/geckodriver /opt/geckodriver-$GECKODRIVER_VERSION \
      && chmod 755 /opt/geckodriver-$GECKODRIVER_VERSION \
      && ln -fs /opt/geckodriver-$GECKODRIVER_VERSION /usr/bin/geckodriver
     
    #Step 4
    #Python 2.7 and Python Pip
    RUN apt-get update
    RUN apt-get install -y \
        python \
        python-setuptools \
        python-pip

    Since Mozilla maintains archived versions, for installing older firefox version we simply defined the ARG variables for FIREFOX_VERSION and GECKODRIVER_VERSION in the Dockerfile and downloaded the Firefox binaries.


    4. Building your own images using these Dockerfiles

    You can either build your own image using above Dockerfiles or you can directly download the image from our Docker Hub repository. If you want more finely tuned specification you can build your own images by using –build-args arguments when building the Docker image. The build uses the Dockerfile which needs to be saved in any directory in your system. We have a created few images python-selenium-chrome(for Chrome) and python-selenium-firefox(for Firefox) with different tags(Tag name specifies the version number) for different versions and pushed into our Dockerhub link

    Here is the sample command we used to build an image for chrome 57 version with compatible driver 2.28

    #build the python-selenium-chrome with a specific chrome driver and chrome version.

    $ docker build -t python-selenium-chrome:chrome57 --build-arg CHROME_DRIVER_VERSION=2.28 --build-arg CHROME_VERSION=57.0.2987.133 -f Dockerfile .

    #build the python-selenium-firefox with specific firefox version

    $ docker build -t python-selenium-firefox:firefox52 --build-arg FIREFOX_VERSION=52.0.1 -f Dockerfile .

    NOTE: Sometimes you may run into situations where the ChromeDriver version you are using is NOT compatible with the Chrome version you are using. If you run into these issues, please cross check and specify the correct driver version.


    5. Creating a container and running Selenium tests

    The images that we created are capable of running any Python-based Selenium tests. To run the Selenium tests using this image, you need to go through following steps:

    i) Create a Docker container out of this image and enter into the container using the following commands:

    docker run -it qxf2rohand/python-selenium-chrome:chrome57 "/bin/bash"

    Export display and enable Xvfb using following 2 commands:

    export DISPLAY=:20
    Xvfb :20 -screen 0 1366x768x16 &

    Install Selenium using pip

    pip install selenium

    ii) Use any Linux editor you like and add your test inside the container. You can also use the sample Selenium code (selenium_sample.py) given below. This selenium test visits Qxf2 Services website and prints the title.

    # contents of selenium_sample.py
    from selenium import webdriver
     
    driver = webdriver.Chrome()
    driver.get("http://www.qxf2.com")
    print driver.title
    driver.quit()

    iii) Run the selenium test using the following command:

    python selenium_sample.py

    The output will be similar to the screenshot shown below.

    Output of selenium_sample.py

    We hope this post is helpful to get started with building your own images with specific versions and finely tuned configurations and run your scripts on any version of browsers you want.

    This article was produced by Qxf2 Services. Learn more about Qxf2 Services.


    References

    1) Create docker image to run selenium tests on different browser versions

    2) dpkg command and installation

    3) Building your own images


    Indira Nellutla

    I am an engineer with about 10 years of experience in software development and testing. Prior to joining Qxf2, I worked with reputed companies like Dell and Infosys. They helped me gain good experience in the manufacturing and healthcare domains. My QA career started at Dell. I got exposure to various testing tools, processes and methodologies, got an opportunity to work on various platforms like JMS Hermes, SOAP UI, data integration, queues, etc. I chose Qxf2 because it allowed remote working. My interests are vegetable gardening using organic methods, listening to music and reading books.

    Be First to Comment

    Leave a Reply

    Your email address will not be published.