Skip to main content

Running Gwen in Docker

Sometimes it may be useful to run Gwen in Docker. For example, if you want to run Gwen in a Jenkins pipeline on a build server or node agent. Setting up Gwen to run in a Selenoid container in Docker is describe here.

Get started

Start a new Gwen project or use an existing one.

Docker Setup

Since v3.16.0, the init --docker command was introduced to generate Docker and Selenoid files in your project. You will need to create the files manually if you are using an older version.

Run the following command in the root of your project to generate all the necessary Docker and Selenoid files

yarn gwen init --docker

Dockerfile

./project                    # Your project root
└── /gwen
└──Dockerfile # Docker image file

The init --docker commad will create a gwen/DockerFile with the following content to build an Alpine Linux node and Yarn based image with bash and Open JDK 11 JRE installed.

# base alpine image with node
FROM node:21-alpine

# install bash and java
RUN apk update \
&& apk add bash \
&& apk add openjdk11-jre

# Run as a non root user
RUN addgroup -S gwen && adduser -S gwen -G gwen -u 4936
USER gwen

Should you prefer a Red Hat Linux and Open JDK 11 based image with node and Yarn installed instead, you can change the content to this:

# base Red Hat image with open JDK 11
FROM adoptopenjdk/openjdk11:ubi

# install node & yarn
RUN dnf module install nodejs:16 -y
RUN npm install --global yarn

# Run as a non root user
RUN useradd -u 4936 gwen
USER gwen

Docker compose file

./project                        # Your project root
└── /gwen
├── .env # Docker env file
├── Dockerfile # Docker image file
└── docker-compose.yml # Docker compose YAML file

The init --docker commad will create a gwen/docker-compose.yml file with the following content to create containers for Gwen, Chrome, Firefox, and Edge web browsers, a video recorder, and a Selenoid hub that Gwen will connect to.

services:
chrome:
image: selenoid/chrome:latest
networks:
- gwen-net
edge:
image: browsers/edge:latest
networks:
- gwen-net
firefox:
image: selenoid/firefox:latest
networks:
- gwen-net
video-recorder:
image: selenoid/video-recorder:latest-release
networks:
- gwen-net
selenoid:
image: aerokube/selenoid:latest-release
networks:
- gwen-net
ports:
- "4444:4444"
volumes:
- "$PWD/gwen/browsers:/etc/selenoid/:ro"
- "/var/run/docker.sock:/var/run/docker.sock"
- "$PWD/gwen/output/.video:/opt/selenoid/video"
environment:
- OVERRIDE_VIDEO_OUTPUT_DIR=$PWD/gwen/output/.video
command: ["-container-network", "gwen-net", "-video-output-dir", "/opt/selenoid/video"]
selenoid-ui:
depends_on:
- selenoid
- $GWEN_BROWSER
image: aerokube/selenoid-ui:latest
environment:
- GWEN_BROWSER
networks:
- gwen-net
ports:
- "8999:8999"
command: ["--selenoid-uri", "http://selenoid:4444", "--listen", ":8999"]
gwen:
depends_on:
- selenoid
- video-recorder
- $GWEN_BROWSER
build:
context: .
dockerfile: Dockerfile
environment:
- SELENIUM_HUB
- NO_COLOR
- GWEN_ENV
- GWEN_PROFILE
- GWEN_BROWSER
- GWEN_DRY_RUN
- GWEN_PARALLEL
- GWEN_THREADS
- GWEN_HEADLESS
- GWEN_VIDEO
- GWEN_WEB_VERSION
volumes:
- "$PWD:/project"
working_dir: /project
command: bash -c "yarn install && yarn gwen -b -c gwen/conf/browsers/selenoid.conf gwen/features"
networks:
- gwen-net
gwen-dry-run:
build:
context: .
dockerfile: Dockerfile
environment:
- NO_COLOR
- GWEN_WEB_VERSION
volumes:
- "$PWD:/project"
working_dir: /project
command: bash -c "yarn install && yarn gwen -bn --parallel gwen/features"
networks:
- gwen-net
networks:
gwen-net:
name: gwen-net

Docker env file

Since v3.35.0

A gwen/.env file containing the following environment variable defaults will also be generated by init --docker.

SELENIUM_HUB=selenoid
NO_COLOR=1
GWEN_BROWSER=chrome

Selenoid browsers file

./project                    # Your project root
└── /gwen
└── /browsers
└──browsers.json # Selenoid browsers file

The init --docker commad will create a gwen/conf/browsers/browsers.json file with the following content that will be used by Selenoid to stand up the browsers in Docker.

{
"chrome": {
"default": "latest",
"versions": {
"latest": {
"image": "selenoid/chrome:latest",
"port": "4444",
"path": "/"
}
}
},
"MicrosoftEdge": {
"default": "latest",
"versions": {
"latest": {
"image": "browsers/edge:latest",
"port": "4444",
"path": "/"
}
}
},
"firefox": {
"default": "latest",
"versions": {
"latest": {
"image": "selenoid/firefox:latest",
"port": "4444",
"path": "/wd/hub"
}
}
}
}

Gwen settings file

./project                    # Your project root
└── /gwen
└── /conf
└── /browsers
├──browsers.json # Selenoid browsers file
└──selenoid.conf # Selenoid Gwen settings

The init --docker commad will create a gwen/conf/browsers/selenoid.conf file with the following content that will be used by Gwen to connect to Selenoid.

gwen {
web {
capabilities {
"selenoid:options" {
enableVNC = true
enableVideo = true
}
}
remote {
url = "http://${env.SELENIUM_HUB}:4444/wd/hub"
}
}
}

Run Gwen in docker

Start your docker desktop engine (see getting started with Docker for more info).

Create the Gwen output directory if it does not already exist.

mkdir -p gwen/output

Run the following command to build your docker image

docker-compose -f gwen/docker-compose.yml build

Run the following command in your project directory to launch Gwen in docker and run your features

docker-compose -f gwen/docker-compose.yml run gwen

To execute features in parallel (you can pass any number of environment varaibles in this manner)

GWEN_PARALLEL=true docker-compose -f gwen/docker-compose.yml run gwen

To execute dry run instead (Since v3.35.0)

docker-compose -f gwen/docker-compose.yml run gwen-dry-run

Tear it all down when done

docker-compose -f gwen/docker-compose.yml down

Run Gwen locally with Selenoid UI

Make sure enableVNC = true in your selenoid settings. Then run the following command to launch the Selenoid UI service in Docker

docker-compose -f gwen/docker-compose.yml run -d --service-ports selenoid-ui

Open http://localhost:8999 in a browser to check that the Selenoid UI is running and avaialable

Run the following command to launch Gwen against your Selenoid instance in Docker. You will see browser session(s) appear in the Selenoid UI.

SELENIUM_HUB=localhost yarn gwen -b -c gwen/conf/browsers/selenoid.conf gwen/features

Tear it all down when done

docker-compose -f gwen/docker-compose.yml down

Video capture

See also: Video recordings

If you set the GWEN_VIDEO environment variable or the selenoid:options.enableVideo capability setting to true in your selenoid.conf file, MP4 video recordings of each session will be attached to the feature level HTML reports. Set this to false if you do not wish to capture video.

File: gwen/conf/browsers/selenoid.conf

gwen {
web {
capabilities {
"selenoid:options" {
enableVNC = true
enableVideo = true
}
}
..
}
}
video settings
  • gwen-video.dir
    • Should match host directory mounted to /opt/selenoid/video in Selenoid video-recorder
  • gwen-video.timeoutSecs
    • Time to wait for asyncronous video writes to complete (override only if default does not suffice)
Limitation

Videos will not be recorded when parallel execution, headless browser, or interactive (non --batch/-b) modes are enabled.

Downloading Files in Chrome

Configure the following in your conf/browsers/selenoid.conf file to enable automatic file downloads for Chrome in the Selenoid/Docker container.

gwen {
web {
capabilities {
"selenoid:options" {
enableVNC = true
enableVideo = false
}
"goog:chromeOptions" {
prefs {
download {
prompt_for_download = false
directory_upgrade = true
default_directory = "/home/selenium/Downloads"
}
profile {
default_content_settings {
popups = 0
}
default_content_setting_values {
automatic_downloads = 1
}
}
safebrowsing {
enabled = false
}
plugins: {
plugins_disabled = false
}
}
}
}
remote {
url = "http://${env.SELENIUM_HUB}:4444/wd/hub"
}
}
}

To access the download files, you can use the Selenoid download API through a URL as follows:

   http://${env.SELENIUM_HUB}/download/${gwen.web.sessionId}/<filename>

Where <filename> is the name of the downloaded file.

Mac ARM notes

Chrome or Edge crashes

If you're running Chrome or Edge in a Selenoid docker container on a Mac ARM processor and encounter the following error

(unknown error: DevToolsActivePort file doesn't exist)

Make the following changes to the following files to use the experimanal Seleniarm images instead and try again.

File: gwen/docker-compose.yml

services:
chrome:
image: seleniarm/standalone-chromium:latest
networks:
- gwen-net
edge:
image: seleniarm/standalone-chromium:latest
networks:
- gwen-net

File: gwen/conf/browsers.json

  {
"chrome": {
"default": "latest",
"versions": {
"latest": {
"image": "seleniarm/standalone-chromium:latest",
"port": "4444",
"path": "/"
}
}
},
"MicrosoftEdge": {
"default": "latest",
"versions": {
"latest": {
"image": "seleniarm/standalone-chromium:latest",
"port": "4444",
"path": "/"
}
}
}
}

The Selenoid video recorder won't work with the experimental Seleniarm images, so you should disable video

File: gwen/conf/browsers/selenoid.conf

gwen {
web {
capabilities {
"selenoid:options" {
enableVNC = true
enableVideo = false
}
}
remote {
url = "http://${env.SELENIUM_HUB}:4444/wd/hub"
}
}
}