UI automation framework on Docker

Selenium Grid is a powerful tool for web applications testing across various browsers. This tool integrated with continuous integration tool like Jenkins Server for quick execution of any test case on any build makes a life of a tester very simple.

So, having this setup(Jenkins+Selenium Grid) is a life line for any tester.

That’s not it.

If you are on Docker or planning to move over to docker setup, having the above setup in a docker makes life easier.

That’s what we will be providing here.

Docker setup diagram:

As you can see the diagram I am running 4 docker containers on docker host.

  1. jenkinsserver –> To git pull the automation test cases, run test cases , show reports , show trend report, maintain history of test runs.This sends trigger to seleniumhub to  execute test cases.
  2. Seleniumhub –> Acts as a selenium hub runs Ui automation test cases on the registered nodes.
  3. selenium-chrome-node –> Acts as a node with headless chrome browser running
  4. selenium-firefox-node –> Acts as a node with headless firefox browser running

 

How to do setup and run a sample test case

Below steps in brief does, downloads jenkins,seleniumhub,senium-firefox-node and selenium-chrome-node docker images, does Jenkins initial setup and runs one Ui automation test case on firefox browser.

  1. Install docker on ubuntu server (or any linux server of your choice).Refer https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/ for installing Docker server.
  2. Verify Docker has installed correctly
  3. Install Docker Compose and verify. (Compose is a tool for defining and running complex applications with Docker. With Compose, you define a multi-container application in a single file, then spin your application up in a single command which does everything that needs to be done to get it running).
root@dockerserver:#curl -L https://github.com/docker/compose/releases/download/1.14.0-rc2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
root@dockerserver:#chmod +x /usr/local/bin/docker-compose
root@dockerserver:#docker-compose --version
   docker-compose version 1.14.0-rc2, build 24dae73

4. Download the docker-compose.yml here docker-compose.yml .  Look carefully the compose file it says for jenkinsserver container to have a persistent data volume and exposes port 8080 –> 8888 to access the jenkins server UI . For

version: "3"
services:
   jenkinsserver:
     image: raghumbalgi84/jenkinsserver:latest
     ports:
       - 8888:8080
     container_name: jenkinsserver
     networks:
       - myseleniumnet
     volumes:
        - /var/lib/docker/volumes/jenkins_home:/var/jenkins_home

   seleniumhub:
      image: raghumbalgi84/seleniumhub:latest
      ports:
        - 4444:4444
      expose:
        - "22"
      container_name: hub
      networks:
        - myseleniumnet

   firefoxnode:
      image: raghumbalgi84/selenium-firefox-node:latest
      container_name: firefox_node
      networks:
        - myseleniumnet

   chromenode:
     image: raghumbalgi84/selenium-chrome-node:latest
     container_name: chrome_node
     networks:
      - myseleniumnet

networks:
  myseleniumnet:
     driver: bridge

 

5. Run the “docker compose” command on downloaded docker-compose.yml file and verify the containers are running using “Docker ps ” command.

In summary what this command does is , it pulls 4 images specified from the dockerhub repo, assigns a name for the container, creates a persistent data volume for jenkinsserver container(this is to save the state(test cases,plugin info,reports,build info) of jenkins server , creates a bridge network (myseleniumnet) for seamless communication between 4 containers using their container name.

root@dockerserver:~# docker-compose -f /root/docker-compose.yml up -d
Creating firefox_node ...
Creating hub ...
Creating chrome_node ...
Creating jenkinsserver ...
Creating firefox_node
Creating chrome_node
Creating jenkinsserver
Creating jenkinsserver ... done


root@dockerserver:~# docker ps
CONTAINER ID   IMAGE                                      COMMAND                 CREATED        STATUS         PORTS                                NAMES
59b8add4cb45   raghumbalgi84/jenkinsserver:latest         "/bin/tini -- /usr..."  5 seconds ago  Up 3 seconds   50000/tcp, 0.0.0.0:8888->8080/tcp    jenkinsserver
3fec26c25798   raghumbalgi84/seleniumhub:latest           "/bin/sh -c '(serv..."  5 seconds ago  Up 4 seconds   22/tcp, 0.0.0.0:4444->4444/tcp       hub
eef9be2c2d37   raghumbalgi84/selenium-chrome-node:latest  "/bin/sh -c '(Xvfb..."  5 seconds ago  Up 4 seconds                                        chrome_node
f693e3e648c4   raghumbalgi84/selenium-firefox-node:latest "/bin/sh -c '(Xvfb..."  5 seconds ago  Up 4 seconds                                        firefox_node

 

6. Lauch Jenkins server UI by navigating to http://<ipaddressOfDockerHost>:8888/  . Jenkins will ask you for initial setup configuration , provide relevant details to complete the initial configuration. All you configuration will be saved in the persistent data volume and not lost even if you restart jenkinsserver container.

Get the administrator password by running following “docker exec” command shown below.

root@dockerserver:~# docker exec jenkinsserver cat /var/jenkins_home/secrets/initialAdminPassword
094f9d6b7f384666a7a7182f53143a56

 

7. To run the automation test script/case  I have created a sample test case which opens the google.com page and checks for the title=google. I have used robot framework test case format.You can install and use any framework of your choice.

Observe carefully the open browser function’s remote_url parameter , in this I am specifying the container name(firefox_node) the same name specified in the docker-compose.yml file. I am not using ipaddress for remote_url parameter because at the time of node creation through docker-compose command the ip address get assigned to container randomly so reaching the node with container name is a better option

Download the test cases file test.txt here

*** Settings ***
Library     Selenium2Library
Library     XvfbRobot

*** Test Cases ***
Create Headless Browser
 Start Virtual Display     1920   1080
 Open Browser      url=http://google.com     browser=firefox       remote_url=http://firefox_node:5555/wd/hub
 Set Window Size      1920     1080
 ${title}=     Get Title
 Should Be Equal      Google      ${title}
 [Teardown]      Run Keyword If Test Failed       Capture Page Screenshot

 

8. Copy the test case you downloaded/or you created to Jenkinsserver docker container from where you run the test case using “docker cp” command. This is a crude way of running test case, an elegant way is to have a git account/repository from which you should pull your latest test cases directly into Jenkinsserver (jenkins server comes with git installed).

root@dockerserver:~# docker cp test.txt jenkinsserver:/root/test.txt

9. Now login to Jenkins(http://<ipaddressOfDockerHost>:8888/) using user name and password you configured during the jenkins initial setup . Create a new item (freestyle project) and for example enter below details .

under build >>execute shell>>

#create a directory to store robot results
mkdir -p /root/robotresults/${BUILD_NUMBER}/

#copy test cases from jenkins to selenium hub 
sshpass -p password scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null /root/test.txt root@hub:/root/test.txt

#Run the selenium test case on selenium hub using pybot command
sshpass -p password ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@hub pybot -d /root/robotresults/ /root/test.txt || true

#Copy the robotresults back to jenkins server which shows up on the Ui
sshpass -p password scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@hub:/root/robotresults/* /root/robotresults/${BUILD_NUMBER}/

Configure Post build action>> select Publish robot framework test results and enter details as required or as shown in the screenshot.

 

10. Save and run the test case by clicking on “Build Now” . Once the Build is completed you can view the robot results by clicking on Open report.html link of that run.

 

That is it, you have successfully setup and ran UI automation test case purely using Docker with the additional capability of CI tool Jenkins. If you are aware of the power Jenkins bring on the table , you can come up with lot more use cases that suits your testing requirement.

Happy testing

 

Continue reading if you are interested in knowing Docker file used to create these 4 docker image

1. seleniumhub : Here for demo purpose I have given instruction to install robotframework and python you can install any other framework package or scripting language

FROM selenium/hub:latest
USER root
RUN echo root:password | /usr/sbin/chpasswd
RUN apt-get update
RUN apt-get install -y openssh-client openssh-server sshpass
RUN apt-get install -y xvfb python-pip
RUN pip install robotframework
RUN pip install robotframework-selenium2library
RUN pip install robotframework-xvfb
RUN mkdir -p /root/robotresults
RUN sed -i '/PermitRootLogin no/c\PermitRootLogin yes' /etc/ssh/sshd_config
RUN sed -i '/PermitRootLogin prohibit-password/c\PermitRootLogin yes' /etc/ssh/sshd_config
CMD (service ssh restart; java -jar /opt/selenium/selenium-server-standalone.jar -role hub & NODE_PID=$!; wait $NODE_PID)

 

2. For selenium-firefox-node  and  selenium-chrome-node refer http://testnblog.com/selenium-grid-on-docker/ (section: Continue reading if you are interested in knowing Docker file used to create selenium grid images)

3. Jenkinsserver: I have used jenkins:lts as base image , created a plugin.txt file which will have list of plugin to be preinstalled which this image gets created(example: this includes Robot Framework plugin this is required to publish test report in robot format)

Download the plugin list here plugin.txt

FROM jenkinsci/jenkins:lts
USER root
RUN echo jenkins:password | /usr/sbin/chpasswd
RUN apt-get update
RUN apt-get install -y openssh-client openssh-server sshpass
COPY plugins.txt /usr/share/jenkins/ref/plugins.txt
RUN xargs /usr/local/bin/install-plugins.sh < /usr/share/jenkins/ref/plugins.txt
CMD (service ssh start; java -Dhudson.model.DirectoryBrowserSupport.CSP= -jar /usr/share/jenkins/jenkins.war & JENKINS_PID=$!; wait $JENKINS_PID)

 

Enjoy

 

Like to come up with simple solutions to complex issues encountered during testing security products/applications and to share my knowledge thru blogs. Working as Technical leader in network security domain.

Leave a Reply