├── .gitignore ├── Hub ├── Dockerfile ├── docker-compose.yml ├── entry_point.sh ├── hub_4444.json ├── log4j.properties └── selenium_grid_extras_config.json ├── Makefile ├── NodeBase ├── Dockerfile ├── bg.jpg ├── docker-compose.yml ├── entry_point.sh ├── init_fluxbox └── log4j.properties ├── NodeChrome ├── Dockerfile ├── chrome_launcher.sh ├── docker-compose.yml ├── node_chrome.json └── selenium_grid_extras_config_chrome.json ├── NodeFirefox ├── Dockerfile ├── docker-compose.yml ├── node_firefox.json └── selenium_grid_extras_config_firefox.json ├── README.md ├── hub-chrome-firefox.yml └── tests ├── SeleniumTest ├── bin │ └── test.class ├── pom.xml └── src │ └── test │ └── SeleniumTest.java └── test.py /.gitignore: -------------------------------------------------------------------------------- 1 | /experimental 2 | .settings 3 | .project 4 | .classpath 5 | target 6 | *.iml 7 | .idea 8 | tests/SeleniumTest/bin 9 | -------------------------------------------------------------------------------- /Hub/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.7 2 | MAINTAINER Minium Team 3 | 4 | ARG SELENIUM_GRID_EXTRAS_VERSION=2.0.4 5 | ENV PATH_TO_SELENIUM /opt/selenium 6 | 7 | RUN apk add --no-cache \ 8 | bash \ 9 | wget \ 10 | ca-certificates \ 11 | openjdk8-jre \ 12 | && sed -i 's/securerandom\.source=file:\/dev\/random/securerandom\.source=file:\/dev\/urandom/' /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/java.security 13 | 14 | #============================ 15 | # Selenium Grid Extras 16 | #============================ 17 | RUN mkdir -p $PATH_TO_SELENIUM \ 18 | && wget https://github.com/groupon/Selenium-Grid-Extras/releases/download/v$SELENIUM_GRID_EXTRAS_VERSION/SeleniumGridExtras-$SELENIUM_GRID_EXTRAS_VERSION-SNAPSHOT-jar-with-dependencies.jar -O $PATH_TO_SELENIUM/selenium-grid-extras.jar 19 | 20 | #==================================== 21 | # Scripts to run Selenium Grid Extras 22 | #==================================== 23 | COPY entry_point.sh /opt/bin/ 24 | COPY log4j.properties $PATH_TO_SELENIUM/log4j.properties 25 | RUN chmod +x /opt/bin/entry_point.sh 26 | ADD hub_4444.json $PATH_TO_SELENIUM/hub_4444.json 27 | ADD selenium_grid_extras_config.json $PATH_TO_SELENIUM/selenium_grid_extras_config.json 28 | 29 | EXPOSE 4444 3000 30 | 31 | WORKDIR "$PATH_TO_SELENIUM" 32 | CMD "/opt/bin/entry_point.sh" -------------------------------------------------------------------------------- /Hub/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | seleniumhub: 4 | image: minium/selenium-grid-extras-hub:2.0.4 5 | build: 6 | context: . 7 | args: 8 | - SELENIUM_GRID_EXTRAS_VERSION 9 | container_name: selenium-grid-extras-hub 10 | restart: unless-stopped 11 | ports: 12 | - "4444:4444" 13 | - "3000:3000" 14 | environment: 15 | - JAVA_OPTS=-Xms512m -Xmx512m 16 | - SCREEN_DEPTH=24 -------------------------------------------------------------------------------- /Hub/entry_point.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function shutdown { 4 | kill -s SIGTERM $NODE_PID 5 | wait $NODE_PID 6 | } 7 | 8 | if [ ! -z "$SE_OPTS" ]; then 9 | echo "appending selenium options: ${SE_OPTS}" 10 | fi 11 | 12 | 13 | cd $PATH_TO_SELENIUM 14 | 15 | 16 | java ${JAVA_OPTS} -jar $PATH_TO_SELENIUM/selenium-grid-extras.jar ${SE_OPTS} & 17 | NODE_PID=$! 18 | 19 | trap shutdown SIGTERM SIGINT 20 | wait $NODE_PID 21 | -------------------------------------------------------------------------------- /Hub/hub_4444.json: -------------------------------------------------------------------------------- 1 | { 2 | "port": 4444, 3 | "newSessionWaitTimeout": 25000, 4 | "servlets": [ 5 | "com.groupon.seleniumgridextras.grid.servlets.ListNodesServlet" 6 | ], 7 | "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher", 8 | "throwOnCapabilityNotPresent": true, 9 | "nodePolling": 5000, 10 | "cleanUpCycle": 5000, 11 | "browserTimeout": 3600, 12 | "timeout": 1800, 13 | "maxSession": 5, 14 | "debug": false 15 | } -------------------------------------------------------------------------------- /Hub/log4j.properties: -------------------------------------------------------------------------------- 1 | # Define the root logger with appender file 2 | log = log/ 3 | log4j.rootLogger = ERROR, FILE 4 | 5 | # Define the file appender 6 | log4j.appender.FILE=org.apache.log4j.rolling.RollingFileAppender 7 | log4j.appender.FILE.rollingPolicy=org.apache.log4j.rolling.TimeBasedRollingPolicy 8 | log4j.appender.FILE.rollingPolicy.FileNamePattern=${log}/grid_extras.%d{yyyy-MM-dd}.log 9 | 10 | # Define the layout for file appender 11 | log4j.appender.FILE.layout=org.apache.log4j.PatternLayout 12 | log4j.appender.FILE.layout.ConversionPattern=%d{dd MMM yyyy HH:mm:ss} [%t] %-5p %c{2} %x - %m%n -------------------------------------------------------------------------------- /Hub/selenium_grid_extras_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "theConfigMap": { 3 | "auto_update_browser_versions": "1", 4 | "hub_config_files": [ 5 | "hub_4444.json" 6 | ], 7 | "auto_start_hub": "1", 8 | "default_role": "hub", 9 | "auto_update_drivers": "0", 10 | "hub_config": {}, 11 | "log_maximum_age_ms": 864000000, 12 | "reboot_after_sessions": "0", 13 | "grid_extras_port": "3000", 14 | "grid_jvm_x_options": "-Xmx512m", 15 | "grid_jvm_options": { 16 | "selenium.LOGGER.level": "SEVERE" 17 | }, 18 | "webdriver": { 19 | "version": "3.8.1", 20 | "directory": "/opt/selenium/webdrivers/webdriver" 21 | }, 22 | "node_config_files": [] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | NAME := minium/selenium-grid-extras 2 | SELENIUM_VERSION := $(SELENIUM_VERSION) 3 | SELENIUM_GRID_EXTRAS_VERSION := $(SELENIUM_GRID_EXTRAS_VERSION) 4 | CHROME_VERSION := $(CHROME_VERSION) 5 | FIREFOX_VERSION := $(FIREFOX_VERSION) 6 | 7 | all: hub chrome firefox 8 | 9 | build: all 10 | 11 | hub: 12 | cd ./Hub && SELENIUM_GRID_EXTRAS_VERSION=$(SELENIUM_GRID_EXTRAS_VERSION) docker-compose build --no-cache 13 | 14 | nodebase: 15 | cd ./NodeBase && SELENIUM_GRID_EXTRAS_VERSION=$(SELENIUM_GRID_EXTRAS_VERSION) docker-compose build --no-cache 16 | 17 | chrome: 18 | cd ./NodeChrome && docker-compose build --no-cache 19 | 20 | firefox: 21 | cd ./NodeFirefox && FIREFOX_VERSION=$(FIREFOX_VERSION) docker-compose build --no-cache 22 | 23 | release: 24 | docker push $(NAME)-hub:$(SELENIUM_GRID_EXTRAS_VERSION) 25 | docker push $(NAME)-base:$(SELENIUM_GRID_EXTRAS_VERSION) 26 | docker push $(NAME)-chrome:$(SELENIUM_VERSION)-$(SELENIUM_GRID_EXTRAS_VERSION)-$(CHROME_VERSION) 27 | docker push $(NAME)-firefox:$(SELENIUM_VERSION)-$(SELENIUM_GRID_EXTRAS_VERSION)-$(FIREFOX_VERSION) -------------------------------------------------------------------------------- /NodeBase/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:16.04 2 | LABEL maintainer="Minium Team " 3 | 4 | ARG SELENIUM_GRID_EXTRAS_VERSION=2.0.4 5 | ENV PATH_TO_SELENIUM /opt/selenium 6 | 7 | ENV DEBIAN_FRONTEND noninteractive 8 | ENV DEBCONF_NONINTERACTIVE_SEEN true 9 | ENV SCREEN_WIDTH 1440 10 | ENV SCREEN_HEIGHT 900 11 | ENV SCREEN_DEPTH 24 12 | ENV DISPLAY :99 13 | # Fixes https://github.com/SeleniumHQ/docker-selenium/issues/87 14 | ENV DBUS_SESSION_BUS_ADDRESS=/dev/null 15 | 16 | 17 | RUN echo "deb http://archive.ubuntu.com/ubuntu xenial main universe\n" > /etc/apt/sources.list \ 18 | && echo "deb http://archive.ubuntu.com/ubuntu xenial-updates main universe\n" >> /etc/apt/sources.list \ 19 | && echo "deb http://security.ubuntu.com/ubuntu xenial-security main universe\n" >> /etc/apt/sources.list 20 | 21 | 22 | RUN apt-get update -qqy 23 | RUN apt-get -qqy --no-install-recommends install lsof feh tzdata ca-certificates openjdk-8-jdk-headless unzip dbus-x11 wget xvfb fluxbox 24 | RUN rm -rf /var/lib/apt/lists/* /var/cache/apt/* \ 25 | && sed -i 's/securerandom\.source=file:\/dev\/random/securerandom\.source=file:\/dev\/urandom/' ./usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/java.security 26 | 27 | 28 | #=================== 29 | # Timezone settings 30 | # Possible alternative: https://github.com/docker/docker/issues/3359#issuecomment-32150214 31 | #=================== 32 | ENV TZ "UTC" 33 | RUN echo "${TZ}" > /etc/timezone \ 34 | && dpkg-reconfigure --frontend noninteractive tzdata 35 | 36 | #============================ 37 | # Selenium Grid Extras 38 | #============================ 39 | RUN mkdir -p $PATH_TO_SELENIUM \ 40 | && wget https://github.com/groupon/Selenium-Grid-Extras/releases/download/v$SELENIUM_GRID_EXTRAS_VERSION/SeleniumGridExtras-$SELENIUM_GRID_EXTRAS_VERSION-SNAPSHOT-jar-with-dependencies.jar -O $PATH_TO_SELENIUM/selenium-grid-extras.jar 41 | 42 | #==================================== 43 | # Scripts to run Selenium Grid Extras 44 | #==================================== 45 | COPY entry_point.sh /opt/bin/ 46 | COPY log4j.properties $PATH_TO_SELENIUM/log4j.properties 47 | COPY init_fluxbox /root/.fluxbox/init 48 | COPY bg.jpg /usr/share/images/fluxbox/ubuntu-light.png 49 | RUN chmod +x /opt/bin/entry_point.sh 50 | 51 | EXPOSE 5555 3000 52 | 53 | WORKDIR "$PATH_TO_SELENIUM" 54 | CMD "/opt/bin/entry_point.sh" 55 | -------------------------------------------------------------------------------- /NodeBase/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viltgroup/docker-selenium-grid-extras/61837abaa703b8c1bcdbeddd783d5132511ad46c/NodeBase/bg.jpg -------------------------------------------------------------------------------- /NodeBase/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | seleniumhub: 4 | image: minium/selenium-grid-extras-base:2.0.4 5 | build: 6 | context: . 7 | args: 8 | - SELENIUM_GRID_EXTRAS_VERSION -------------------------------------------------------------------------------- /NodeBase/entry_point.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export GEOMETRY="$SCREEN_WIDTH""x""$SCREEN_HEIGHT""x""$SCREEN_DEPTH" 4 | 5 | function shutdown { 6 | kill -s SIGTERM $NODE_PID 7 | wait $NODE_PID 8 | } 9 | 10 | if [ ! -z "$REMOTE_HOST" ]; then 11 | >&2 echo "REMOTE_HOST variable is *DEPRECATED* in these docker containers. Please use SE_OPTS=\"-host -port \" instead!" 12 | exit 1 13 | fi 14 | 15 | if [ ! -z "$SE_OPTS" ]; then 16 | echo "appending selenium options: ${SE_OPTS}" 17 | fi 18 | 19 | rm -f /tmp/.X*lock 20 | cd $PATH_TO_SELENIUM 21 | 22 | Xvfb $DISPLAY -screen 0 $GEOMETRY -ac +extension RANDR & fluxbox & 23 | java ${JAVA_OPTS} -jar $PATH_TO_SELENIUM/selenium-grid-extras.jar ${SE_OPTS} & 24 | NODE_PID=$! 25 | 26 | trap shutdown SIGTERM SIGINT 27 | wait $NODE_PID 28 | -------------------------------------------------------------------------------- /NodeBase/init_fluxbox: -------------------------------------------------------------------------------- 1 | ! If you're looking for settings to configure, they won't be saved here until 2 | ! you change something in the fluxbox configuration menu. 3 | 4 | session.menuFile: ~/.fluxbox/menu 5 | session.keyFile: ~/.fluxbox/keys 6 | session.styleFile: /usr/share/fluxbox/styles//ubuntu-light 7 | session.configVersion: 13 8 | session.screen0.toolbar.widthPercent: 0 9 | session.screen0.strftimeFormat: %d %b, %a %02k:%M:%S 10 | session.screen0.toolbar.tools: 11 | -------------------------------------------------------------------------------- /NodeBase/log4j.properties: -------------------------------------------------------------------------------- 1 | # Define the root logger with appender file 2 | log = log/ 3 | log4j.rootLogger = ERROR, FILE 4 | 5 | # Define the file appender 6 | log4j.appender.FILE=org.apache.log4j.rolling.RollingFileAppender 7 | log4j.appender.FILE.rollingPolicy=org.apache.log4j.rolling.TimeBasedRollingPolicy 8 | log4j.appender.FILE.rollingPolicy.FileNamePattern=${log}/grid_extras.%d{yyyy-MM-dd}.log 9 | 10 | # Define the layout for file appender 11 | log4j.appender.FILE.layout=org.apache.log4j.PatternLayout 12 | log4j.appender.FILE.layout.ConversionPattern=%d{dd MMM yyyy HH:mm:ss} [%t] %-5p %c{2} %x - %m%n -------------------------------------------------------------------------------- /NodeChrome/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM minium/selenium-grid-extras-base:2.0.4 2 | LABEL maintainer="Minium Team " 3 | 4 | #============================================ 5 | # Google Chrome 6 | #============================================ 7 | ARG CHROME_VERSION="google-chrome-stable" 8 | RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \ 9 | && echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list \ 10 | && apt-get update -qqy \ 11 | && apt-get -qqy install ${CHROME_VERSION:-google-chrome-stable} \ 12 | && rm /etc/apt/sources.list.d/google-chrome.list \ 13 | && rm -rf /var/lib/apt/lists/* /var/cache/apt/* 14 | 15 | #================================= 16 | # Google Chrome Launch Script 17 | #================================= 18 | COPY chrome_launcher.sh /opt/google/chrome/google-chrome 19 | RUN chmod +x /opt/google/chrome/google-chrome 20 | 21 | #Add Node Configuration 22 | ADD node_chrome.json $PATH_TO_SELENIUM/node_5555.json 23 | ADD selenium_grid_extras_config_chrome.json $PATH_TO_SELENIUM/selenium_grid_extras_config.json 24 | 25 | EXPOSE 5555 3000 -------------------------------------------------------------------------------- /NodeChrome/chrome_launcher.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2011 The Chromium Authors. All rights reserved. 4 | # Use of this source code is governed by a BSD-style license that can be 5 | # found in the LICENSE file. 6 | 7 | # Let the wrapped binary know that it has been run through the wrapper. 8 | export CHROME_WRAPPER="`readlink -f "$0"`" 9 | 10 | HERE="`dirname "$CHROME_WRAPPER"`" 11 | 12 | # Check if the CPU supports SSE2. If not, try to pop up a dialog to explain the 13 | # problem and exit. Otherwise the browser will just crash with a SIGILL. 14 | # http://crbug.com/348761 15 | grep ^flags /proc/cpuinfo|grep -qs sse2 16 | if [ $? != 0 ]; then 17 | SSE2_DEPRECATION_MSG="This computer can no longer run Google Chrome because \ 18 | its hardware is no longer supported." 19 | if which zenity &> /dev/null; then 20 | zenity --warning --text="$SSE2_DEPRECATION_MSG" 21 | elif which gmessage &> /dev/null; then 22 | gmessage "$SSE2_DEPRECATION_MSG" 23 | elif which xmessage &> /dev/null; then 24 | xmessage "$SSE2_DEPRECATION_MSG" 25 | else 26 | echo "$SSE2_DEPRECATION_MSG" 1>&2 27 | fi 28 | exit 1 29 | fi 30 | 31 | # We include some xdg utilities next to the binary, and we want to prefer them 32 | # over the system versions when we know the system versions are very old. We 33 | # detect whether the system xdg utilities are sufficiently new to be likely to 34 | # work for us by looking for xdg-settings. If we find it, we leave $PATH alone, 35 | # so that the system xdg utilities (including any distro patches) will be used. 36 | if ! which xdg-settings &> /dev/null; then 37 | # Old xdg utilities. Prepend $HERE to $PATH to use ours instead. 38 | export PATH="$HERE:$PATH" 39 | else 40 | # Use system xdg utilities. But first create mimeapps.list if it doesn't 41 | # exist; some systems have bugs in xdg-mime that make it fail without it. 42 | xdg_app_dir="${XDG_DATA_HOME:-$HOME/.local/share/applications}" 43 | mkdir -p "$xdg_app_dir" 44 | [ -f "$xdg_app_dir/mimeapps.list" ] || touch "$xdg_app_dir/mimeapps.list" 45 | fi 46 | 47 | # Always use our versions of ffmpeg libs. 48 | # This also makes RPMs find the compatibly-named library symlinks. 49 | if [[ -n "$LD_LIBRARY_PATH" ]]; then 50 | LD_LIBRARY_PATH="$HERE:$HERE/lib:$LD_LIBRARY_PATH" 51 | else 52 | LD_LIBRARY_PATH="$HERE:$HERE/lib" 53 | fi 54 | export LD_LIBRARY_PATH 55 | 56 | export CHROME_VERSION_EXTRA="stable" 57 | 58 | # We don't want bug-buddy intercepting our crashes. http://crbug.com/24120 59 | export GNOME_DISABLE_CRASH_DIALOG=SET_BY_GOOGLE_CHROME 60 | 61 | # Automagically migrate user data directory. 62 | # TODO(phajdan.jr): Remove along with migration code in the browser for M33. 63 | if [[ -n "" ]]; then 64 | if [[ ! -d "" ]]; then 65 | "$HERE/chrome" "--migrate-data-dir-for-sxs=" \ 66 | --enable-logging=stderr --log-level=0 67 | fi 68 | fi 69 | 70 | # Make sure that the profile directory specified in the environment, if any, 71 | # overrides the default. 72 | if [[ -n "$CHROME_USER_DATA_DIR" ]]; then 73 | PROFILE_DIRECTORY_FLAG="--user-data-dir=$CHROME_USER_DATA_DIR" 74 | fi 75 | 76 | # Sanitize std{in,out,err} because they'll be shared with untrusted child 77 | # processes (http://crbug.com/376567). 78 | exec < /dev/null 79 | exec > >(exec cat) 80 | exec 2> >(exec cat >&2) 81 | 82 | # Note: exec -a below is a bashism. 83 | # DOCKER SELENIUM NOTE: Strait copy of script installed by Chrome with the exception of adding 84 | # the --no-sandbox flag here. 85 | exec -a "$0" "$HERE/chrome" --no-sandbox "$PROFILE_DIRECTORY_FLAG" \ 86 | "$@" 87 | exec -a "$0" /etc/alternatives/google-chrome --no-sandbox "$@" -------------------------------------------------------------------------------- /NodeChrome/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | seleniumChrome: 4 | image: minium/selenium-grid-extras-chrome:3.8.1-2.0.4-70.0 5 | build: . 6 | container_name: selenium-grid-extras-chrome 7 | restart: unless-stopped 8 | shm_size: 2g 9 | ports: 10 | - "5555:5555" 11 | - "3100:3000" 12 | depends_on: 13 | - seleniumHub 14 | environment: 15 | - JAVA_OPTS=-Xms512m -Xmx512m 16 | - DBUS_SESSION_BUS_ADDRESS=/dev/null 17 | volumes: 18 | - /dev/shm:/dev/shm 19 | seleniumHub: 20 | image: minium/selenium-grid-extras-hub:2.0.4 21 | container_name: selenium-grid-extras-hub 22 | restart: unless-stopped 23 | ports: 24 | - "4444:4444" 25 | - "3000:3000" 26 | -------------------------------------------------------------------------------- /NodeChrome/node_chrome.json: -------------------------------------------------------------------------------- 1 | { 2 | "capabilities": [ 3 | { 4 | "seleniumProtocol": "WebDriver", 5 | "browserName": "chrome", 6 | "maxInstances": 3, 7 | "version": "", 8 | "platform": "LINUX" 9 | } 10 | ], 11 | "loadedFromFile": "node_5555.json", 12 | "proxy": "com.groupon.seleniumgridextras.grid.proxies.SetupTeardownProxy", 13 | "servlets": [], 14 | "maxSession": 3, 15 | "port": 5555, 16 | "register": true, 17 | "unregisterIfStillDownAfter": 10000, 18 | "hubPort": 4444, 19 | "hubHost": "seleniumHub", 20 | "registerCycle": 5000, 21 | "nodeStatusCheckTimeout": 10000, 22 | "custom": {}, 23 | "downPollingLimit": 0 24 | } -------------------------------------------------------------------------------- /NodeChrome/selenium_grid_extras_config_chrome.json: -------------------------------------------------------------------------------- 1 | { 2 | "theConfigMap": { 3 | "auto_update_browser_versions": "1", 4 | "hub_config_files": [], 5 | "auto_start_hub": "0", 6 | "default_role": "node", 7 | "unregisterNodeDuringReboot": "true", 8 | "auto_update_drivers": "0", 9 | "video_recording_options": { 10 | "videos_to_keep": "40", 11 | "lower_third_background_color": "0,0,0,0", 12 | "title_frame_font_color": "0,0,0,0", 13 | "lower_third_font_color": "0,0,0,0" 14 | }, 15 | "auto_start_node": "1", 16 | "hub_config": {}, 17 | "log_maximum_age_ms": 864000000, 18 | "reboot_after_sessions": "0", 19 | "grid_extras_port": "3000", 20 | "grid_jvm_x_options": "-Xms512m -Xmx512m", 21 | "grid_jvm_options": { 22 | "selenium.LOGGER.level": "SEVERE" 23 | }, 24 | "chromedriver": { 25 | "bit": "64", 26 | "version": "2.43" 27 | }, 28 | "webdriver": { 29 | "version": "3.8.1" 30 | }, 31 | "node_config_files": [ 32 | "node_5555.json" 33 | ] 34 | } 35 | } -------------------------------------------------------------------------------- /NodeFirefox/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM minium/selenium-grid-extras-base:2.0.4 2 | LABEL maintainer="Minium Team " 3 | 4 | #============================================ 5 | # Firefox 6 | #============================================ 7 | ARG FIREFOX_VERSION=63.0 8 | RUN apt-get update -qqy \ 9 | && apt-get -qqy --no-install-recommends install bzip2 firefox \ 10 | && rm -rf /var/lib/apt/lists/* /var/cache/apt/* \ 11 | && 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 \ 12 | && apt-get -y purge firefox \ 13 | && rm -rf /opt/firefox \ 14 | && tar -C /opt -xjf /tmp/firefox.tar.bz2 \ 15 | && rm /tmp/firefox.tar.bz2 \ 16 | && mv /opt/firefox /opt/firefox-$FIREFOX_VERSION \ 17 | && ln -fs /opt/firefox-$FIREFOX_VERSION/firefox /usr/bin/firefox 18 | 19 | #Add Node Configuration 20 | ADD node_firefox.json $PATH_TO_SELENIUM/node_5555.json 21 | ADD selenium_grid_extras_config_firefox.json $PATH_TO_SELENIUM/selenium_grid_extras_config.json 22 | 23 | EXPOSE 5555 3000 -------------------------------------------------------------------------------- /NodeFirefox/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | seleniumFirefox: 4 | image: minium/selenium-grid-extras-firefox:3.8.1-2.0.4-63.0 5 | build: 6 | context: . 7 | args: 8 | - FIREFOX_VERSION 9 | container_name: selenium-grid-extras-firefox 10 | restart: unless-stopped 11 | shm_size: 2g 12 | ports: 13 | - "5555:5555" 14 | - "3200:3000" 15 | depends_on: 16 | - seleniumHub 17 | environment: 18 | - JAVA_OPTS=-Xms512m -Xmx512m 19 | - SCREEN_DEPTH=24 20 | seleniumHub: 21 | image: minium/selenium-grid-extras-hub:2.0.4 22 | container_name: selenium-grid-extras-hub 23 | restart: unless-stopped 24 | ports: 25 | - "4444:4444" 26 | - "3000:3000" 27 | -------------------------------------------------------------------------------- /NodeFirefox/node_firefox.json: -------------------------------------------------------------------------------- 1 | { 2 | "capabilities": [ 3 | { 4 | "seleniumProtocol": "WebDriver", 5 | "browserName": "firefox", 6 | "maxInstances": 3, 7 | "version": "", 8 | "platform": "LINUX" 9 | } 10 | ], 11 | "loadedFromFile": "node_5555.json", 12 | "proxy": "com.groupon.seleniumgridextras.grid.proxies.SetupTeardownProxy", 13 | "servlets": [], 14 | "maxSession": 3, 15 | "port": 5555, 16 | "register": true, 17 | "unregisterIfStillDownAfter": 10000, 18 | "hubPort": 4444, 19 | "hubHost": "seleniumHub", 20 | "registerCycle": 5000, 21 | "nodeStatusCheckTimeout": 10000, 22 | "custom": {}, 23 | "downPollingLimit": 0 24 | } -------------------------------------------------------------------------------- /NodeFirefox/selenium_grid_extras_config_firefox.json: -------------------------------------------------------------------------------- 1 | { 2 | "theConfigMap": { 3 | "auto_update_browser_versions": "1", 4 | "hub_config_files": [], 5 | "auto_start_hub": "0", 6 | "default_role": "node", 7 | "unregisterNodeDuringReboot": "true", 8 | "auto_update_drivers": "0", 9 | "video_recording_options": { 10 | "videos_to_keep": "40", 11 | "lower_third_background_color": "0,0,0,0", 12 | "title_frame_font_color": "0,0,0,0", 13 | "lower_third_font_color": "0,0,0,0" 14 | }, 15 | "auto_start_node": "1", 16 | "hub_config": {}, 17 | "log_maximum_age_ms": 864000000, 18 | "reboot_after_sessions": "0", 19 | "grid_extras_port": "3000", 20 | "grid_jvm_x_options": "-Xms512m -Xmx512m", 21 | "grid_jvm_options": { 22 | "selenium.LOGGER.level": "SEVERE" 23 | }, 24 | "geckodriver": { 25 | "bit": "64", 26 | "version": "0.23.0", 27 | "directory": "/opt/selenium/webdrivers/webdriver" 28 | }, 29 | "webdriver": { 30 | "version": "3.8.1", 31 | "directory": "/opt/selenium/webdrivers/webdriver" 32 | }, 33 | "node_config_files": [ 34 | "node_5555.json" 35 | ] 36 | } 37 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker images for selenium grid extras Hub and Node with Chrome and Firefox 2 | 3 | Images included: 4 | 5 | - __minium/selenium-grid-extras-hub__: Image for running grid extras hub. Based on Alpine 6 | - __minium/selenium-grid-extras-base__: Base images for selenium nodes. Based on Ubuntu LTS 7 | - __minium/selenium-grid-extras-chrome__: Selenium Grid Extras Node with Chrome Latest 8 | - __minium/selenium-grid-extras-firefox__: Selenium Grid Extras Node with Firefox Latest (x86_64) 9 | 10 | All images are versioned after the [Selenium-Grid-Extras](https://github.com/groupon/Selenium-Grid-Extras) release number. 11 | 12 | The images can be found in the [Docker Hub](https://hub.docker.com/u/minium/) 13 | 14 | ## Running the images 15 | 16 | The easiest way is to run with docker-compose. There is at the root of the project a compose file (`hub-chrome-firefox.yml`) for running a Hub with 2 connected Nodes running Chrome and Firefox as an example: 17 | 18 | ``` bash 19 | docker-compose -f hub-chrome-firefox.yml up 20 | ``` 21 | 22 | Obviously you can also use the same configuration with just plain docker command line. 23 | 24 | ### Node tag explanation 25 | 26 | The tag of the selenium nodes are composed by \-\-\ (e.g. **minium/selenium-grid-extras-chrome:3.8.1-2.0.4-70.0**) 27 | 28 | 29 | ## Configuring the containers 30 | 31 | ### JAVA_OPTS Java Environment Options 32 | 33 | You can pass `JAVA_OPTS` environment variable to java process in the docker command line, or by editing your docker-compose: 34 | 35 | ``` bash 36 | environment: 37 | - JAVA_OPTS=-Xms512m -Xmx512m 38 | ``` 39 | 40 | ### SE_OPTS Selenium Configuration Options 41 | 42 | You can pass `SE_OPTS` variable with additional commandline parameters for starting a hub or a node. 43 | 44 | ``` bash 45 | environment: 46 | - SE_OPTS=-debug true 47 | ``` 48 | 49 | ## Building the images 50 | 51 | Clone the repo and from inside of each directoy you can build using docker-compose: 52 | 53 | ``` bash 54 | docker-compose build 55 | ``` 56 | 57 | Keep in mind the `NodeBase` needs to be built before `NodeChrome` and `NodeFirefox` 58 | 59 | Using Makefile to build all: 60 | 61 | ``` bash 62 | SELENIUM_VERSION=3.8.1 SELENIUM_GRID_EXTRAS_VERSION=2.0.4 CHROME_VERSION=70.0 FIREFOX_VERSION=63.0 make build 63 | ``` 64 | 65 | ## Troubleshooting 66 | 67 | In case you need to troubleshoot you can change LOG levels of different components, by changing your docker enviornments or providing a `log4j.properties` 68 | 69 | ``` 70 | environment: 71 | - SE_OPTS=-debug true 72 | volumes: 73 | - ./log4j.properties:/opt/selenium/log4j.properties 74 | ``` 75 | 76 | For more information see: https://github.com/groupon/Selenium-Grid-Extras#changing-the-logging-on-the-grid-hub-nodes-or-selenium-grid-extras 77 | 78 | ## Known Issues: 79 | 80 | - ~~Fullscreen doesn't work with Xvfb on Google Chrome~~ (https://github.com/seleniumhq/selenium-google-code-issue-archive/issues/6775) (Fixed by using fluxbox) -------------------------------------------------------------------------------- /hub-chrome-firefox.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | seleniumChrome: 4 | image: minium/selenium-grid-extras-chrome:2.0.4 5 | container_name: selenium-grid-extras-chrome 6 | restart: unless-stopped 7 | shm_size: 2g 8 | ports: 9 | - "5555:5555" 10 | - "3100:3000" 11 | depends_on: 12 | - seleniumHub 13 | environment: 14 | - JAVA_OPTS=-Xms512m -Xmx512m 15 | - DBUS_SESSION_BUS_ADDRESS=/dev/null 16 | volumes: 17 | - /dev/shm:/dev/shm 18 | # - ./custom_grid_config.json:/opt/selenium/selenium_grid_extras_config.json 19 | # - ./custom_node_config.json:/opt/selenium/node_5555.json 20 | seleniumFirefox: 21 | image: minium/selenium-grid-extras-firefox:2.0.4 22 | container_name: selenium-grid-extras-firefox 23 | restart: unless-stopped 24 | shm_size: 2g 25 | ports: 26 | - "5556:5555" 27 | - "3200:3000" 28 | depends_on: 29 | - seleniumHub 30 | environment: 31 | - JAVA_OPTS=-Xms512m -Xmx512m 32 | # volumes: 33 | # - ./custom_grid_config.json:/opt/selenium/selenium_grid_extras_config.json 34 | # - ./custom_node_config.json:/opt/selenium/node_5555.json 35 | seleniumHub: 36 | image: minium/selenium-grid-extras-hub:2.0.4 37 | container_name: selenium-grid-extras-hub 38 | restart: unless-stopped 39 | ports: 40 | - "4444:4444" 41 | - "3000:3000" 42 | environment: 43 | - JAVA_OPTS=-Xms512m -Xmx512m 44 | # - SE_OPTS=-debug true 45 | # volumes: 46 | # - ./custom_grid_config.json:/opt/selenium/selenium_grid_extras_config.json 47 | # - ./custom_hub_config.json:/opt/selenium/hub_4444.json 48 | # - ./log4j.properties:/opt/selenium/log4j.properties -------------------------------------------------------------------------------- /tests/SeleniumTest/bin/test.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viltgroup/docker-selenium-grid-extras/61837abaa703b8c1bcdbeddd783d5132511ad46c/tests/SeleniumTest/bin/test.class -------------------------------------------------------------------------------- /tests/SeleniumTest/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | SeleniumTest 5 | SeleniumTest 6 | 0.0.1-SNAPSHOT 7 | 8 | 9 | 10 | org.seleniumhq.selenium 11 | selenium-remote-driver 12 | 3.8.1 13 | 14 | 15 | 16 | src 17 | 18 | 19 | maven-compiler-plugin 20 | 3.6.1 21 | 22 | 1.3 23 | 1.1 24 | 25 | 26 | 27 | org.apache.maven.plugins 28 | maven-dependency-plugin 29 | 30 | 31 | copy-dependencies 32 | prepare-package 33 | 34 | copy-dependencies 35 | 36 | 37 | 38 | ${project.build.directory}/libs 39 | 40 | 41 | 42 | 43 | 44 | 45 | org.apache.maven.plugins 46 | maven-jar-plugin 47 | 48 | 49 | 50 | true 51 | libs/ 52 | test.SeleniumTest 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /tests/SeleniumTest/src/test/SeleniumTest.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import org.openqa.selenium.*; 4 | import org.openqa.selenium.remote.*; 5 | import java.net.URL; 6 | import java.util.concurrent.TimeUnit; 7 | 8 | public class SeleniumTest { 9 | private WebDriver driver; 10 | 11 | public void setUp() throws Exception { 12 | DesiredCapabilities capabilities = DesiredCapabilities.chrome(); 13 | driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capabilities); 14 | driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); 15 | // driver.driver.manage().window().maximize(); 16 | // driver.manage().window().maximize(); 17 | // driver.manage().window().maximize(); 18 | driver.manage().window().setPosition(new Point(0, 0)); 19 | driver.manage().window().setSize(new Dimension(1440, 900)); 20 | } 21 | 22 | public void testSimple() throws Exception { 23 | this.driver.get("http://www.google.com"); 24 | System.out.println("Title: "+ this.driver.getTitle()); 25 | } 26 | 27 | public void tearDown() throws Exception { 28 | this.driver.quit(); 29 | } 30 | 31 | public static void main(String[] args) { 32 | SeleniumTest test = new SeleniumTest(); 33 | try { 34 | System.out.println("Setup"); 35 | test.setUp(); 36 | System.out.println("Testing"); 37 | test.testSimple(); 38 | System.out.println("Done"); 39 | test.tearDown(); 40 | } catch (Exception e) { 41 | // TODO Auto-generated catch block 42 | e.printStackTrace(); 43 | } 44 | 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /tests/test.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from selenium import webdriver 3 | from selenium.webdriver.common.keys import Keys 4 | from selenium.webdriver.support.ui import Select 5 | from selenium.webdriver.chrome.options import Options 6 | 7 | 8 | class PythonOrgSearch(unittest.TestCase): 9 | 10 | def setUp(self): 11 | self.driver = webdriver.Remote( 12 | command_executor = 'http://127.0.0.1:4444/wd/hub', 13 | desired_capabilities = { 14 | 'browserName': 'chrome', 15 | }) 16 | 17 | def sign_in_to_github(self): 18 | driver = self.driver 19 | driver.get('http://codepad.org') 20 | 21 | # Select the Python language option 22 | python_link = driver.find_elements_by_xpath("//input[@name='lang' and @value='Python']")[0] 23 | python_link.click() 24 | 25 | # Enter some text! 26 | text_area = driver.find_element_by_id('textarea') 27 | text_area.send_keys("print 'Hello,' + ' World!'") 28 | 29 | # Submit the form! 30 | submit_button = driver.find_element_by_name('submit') 31 | submit_button.click() 32 | 33 | # Make this an actual test. Isn't Python beautiful? 34 | assert 1 35 | 36 | 37 | def test_create_delete_repository(self): 38 | self.sign_in_to_github() 39 | 40 | 41 | def tearDown(self): 42 | self.driver.close() 43 | 44 | if __name__ == "__main__": 45 | unittest.main() 46 | --------------------------------------------------------------------------------