WebdriverIO 6.0 + Docker + Create your own docker image
Tags: docker, webdriverio, dockerfile, containers
Published: 2020-12-27 00:03:34

At the end of this article, you will be able to create your own image and execute your automation scripts in a docker container.

## Table Of Contents
* [Objective](#Objective)
* [Approach](#Approach)
* [Dockerfile](#Dockerfile)
* [Execution](#Execution)
* [Mounting Volumes](#Mounting Volumes)

<Youtube video>
{% youtube Yjg476fg1l0 %}

### Objective <a name="Objective"></a>
Below are a few points which summarizes what we are trying to do: 
- I need to run my automation scripts in a docker container
- I don't have to create multiple images every time I make a change
- use the memory available efficiently

### Approach<a name="Approach"></a>
In the previous article {% link https://dev.to/17thsep1/webdriverio-6-0-docker-selenium-hub-4-0-l4m %} we discussed how we can leverage docker images by docker selenium. Here, we will explain how we can create an image and run it
- mount a volume from local machine to container
- make changes locally and run it in a container

### Dockerfile <a name="Dockerfile"></a>
The first step is to have your automation scripts ready. Once the script is ready ensure we have the configuration to run it in headless mode. You can do so by adding the below in your wdio config file

![Screenshot 2020-12-26 at 23.15.03](https://dev-to-uploads.s3.amazonaws.com/i/m63xwuwzaild63zq49do.png)

This is because the chromium-browser in Debian primarily runs in headless mode, moreover, it's the headless browser that we have used in the docker image.

ok, that's done. Let's crack on.

If you take a look at the Dockerfile, with the node image as the base, we have installed a few libraries and fonts followed by the chrome browser. 

Once we have the base, we then set the working directory and copy all the files, and do an npm install to get the os specific node modules.

An important point to consider here is that the chrome driver for mac or windows will not work for the Debian version. So whatever node modules we have should not be carried over to the image, one way to prevent that from happening is to create a .dockerignore file and add node_modules to it. 
Again if you have any queries refer to the git hub URL provided below and search for the .dockerignore file.

The final step is to mention the ENTRY POINT. Since the scripts get triggered as soon as we run the image to get the container it's a necessity for us to give the npm test command or npm run <your tag> which points to the wdio config file.

This completes the docker file creation. You can refer to that docker file from the below link

https://github.com/17thSep/WDIO6_Docker_Custom_Image/blob/master/Dockerfile

Or refer to the screenshot below

![Screenshot 2020-12-22 at 17.28.18](https://dev-to-uploads.s3.amazonaws.com/i/b7lwozctio6ptin0hdtg.png)

![Screenshot 2020-12-22 at 17.29.49](https://dev-to-uploads.s3.amazonaws.com/i/xk74fii50w0w2v3s4cpg.png)

### Execution <a name="Execution"></a>
Now that we have created the Dockerfile, to build and image

#### docker build -t {image name} .

This will create an image for us to execute.

Once we create the image, we should run the image to create a container. We can run the image by using the below command

#### docker run -it {image name}

This will trigger the scripts right away and once the execution is complete, the container will be exited.

This is how we use docker to run automation scripts created using webdriverio.

### Mounting Volumes <a name="Mounting Volumes"></a>

Now comes the interesting topic, how can we ensure we don't create multiple images for every change that we make yet test all those changes in docker. This is where Volumes comes in.

Docker Volumes is a means of sharing a directory from the local machine with the container. So how do we achieve this?
It's quite simple actually. You don't have to do anything while creating the image, only when you run the image add -v tag as shown below

#### docker run -v <your local path>:<working directory in Docker file> {image name}

That's it!

But the question comes up again what do you want to share as sharing the node modules again will create a problem. So while sharing the directory ensure you only share the files you want to. For example, if you have all your spec files inside the folder "tests" then the below command will only share the files under this directory.

#### docker run -v <your local path>/tests/:<working directory in Docker file>/tests/ {image name}

Then comes the question of priority, one can assume that local files always takes precedence over the files in an image when we mount the volumes. Hurray!

Make as many changes as you want and run all of those changes in a docker container. 

Please refer to the video above in case you need a demo. 

Clone the repo from
{% github https://github.com/17thSep/WDIO6_Docker_Custom_Image %}


Below are some useful links to ponder upon.

buildpack-deps Image
https://github.com/docker-library/buildpack-deps

Node Image
https://github.com/nodejs/docker-node/blob/master/12/buster/Dockerfile

If you have any questions please add a comment, if you find this useful make sure you let me know. it is the biggest source of motivation!

Cheers!
Ap.