├── .dockerignore ├── .editorconfig ├── .gitattributes ├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE.md ├── .gitignore ├── .menv ├── .travis.yml ├── Analytics.md ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Dockerfile ├── Dockerfile.older.browser ├── GLOBAL_PATCH_LEVEL.txt ├── LATEST_RELEASE.md ├── LATEST_RELEASE_TEMPLATE.md ├── LICENSE.md ├── MAINTAINERS ├── Makefile ├── README.md ├── SECURITY.md ├── bin ├── DisplayDataProcessingAgreement ├── DisplaySponsorRequest ├── chrome_stable_version ├── chromedriver_commit_version ├── chromedriver_version ├── cleanup-container.sh ├── entry.sh ├── error ├── fail ├── firefox_version ├── fixperms.sh ├── functions.sh ├── geckodriver_version ├── get_chrome_stable.sh ├── get_unused_port ├── get_unused_port_from_range ├── java_build_version ├── java_vendor_version ├── log ├── notify ├── python_version ├── selenium_revision_version ├── selenium_version ├── stop ├── untrunc ├── versions ├── wait_pid └── warn ├── binaries ├── google-chrome-stable_43.0.2357.134_amd64.md5 ├── google-chrome-stable_43.0.2357.134_amd64.sha ├── google-chrome-stable_44.0.2403.157_amd64.md5 ├── google-chrome-stable_44.0.2403.157_amd64.sha ├── google-chrome-stable_45.0.2454.101_amd64.md5 ├── google-chrome-stable_45.0.2454.101_amd64.sha ├── google-chrome-stable_46.0.2490.86_amd64.md5 ├── google-chrome-stable_46.0.2490.86_amd64.sha ├── google-chrome-stable_47.0.2526.106_amd64.md5 ├── google-chrome-stable_47.0.2526.106_amd64.sha ├── google-chrome-stable_47.0.2526.111_amd64.md5 ├── google-chrome-stable_47.0.2526.111_amd64.sha ├── google-chrome-stable_48.0.2564.103_amd64.md5 ├── google-chrome-stable_48.0.2564.103_amd64.sha ├── google-chrome-stable_48.0.2564.109_amd64.md5 ├── google-chrome-stable_48.0.2564.109_amd64.sha ├── google-chrome-stable_48.0.2564.116_amd64.md5 ├── google-chrome-stable_48.0.2564.116_amd64.sha ├── google-chrome-stable_48.0.2564.82_amd64.md5 ├── google-chrome-stable_48.0.2564.82_amd64.sha ├── google-chrome-stable_48.0.2564.97_amd64.md5 ├── google-chrome-stable_48.0.2564.97_amd64.sha ├── google-chrome-stable_49.0.2623.108_amd64.md5 ├── google-chrome-stable_49.0.2623.108_amd64.sha ├── google-chrome-stable_49.0.2623.110_amd64.md5 ├── google-chrome-stable_49.0.2623.110_amd64.sha ├── google-chrome-stable_49.0.2623.111_amd64.md5 ├── google-chrome-stable_49.0.2623.111_amd64.sha ├── google-chrome-stable_49.0.2623.112_amd64.md5 ├── google-chrome-stable_49.0.2623.112_amd64.sha ├── google-chrome-stable_49.0.2623.75_amd64.md5 ├── google-chrome-stable_49.0.2623.75_amd64.sha ├── google-chrome-stable_49.0.2623.87_amd64.md5 ├── google-chrome-stable_49.0.2623.87_amd64.sha ├── google-chrome-stable_50.0.2661.102_amd64.md5 ├── google-chrome-stable_50.0.2661.102_amd64.sha ├── google-chrome-stable_50.0.2661.75_amd64.md5 ├── google-chrome-stable_50.0.2661.75_amd64.sha ├── google-chrome-stable_50.0.2661.86_amd64.md5 ├── google-chrome-stable_50.0.2661.86_amd64.sha ├── google-chrome-stable_50.0.2661.87_amd64.md5 ├── google-chrome-stable_50.0.2661.87_amd64.sha ├── google-chrome-stable_50.0.2661.94_amd64.md5 ├── google-chrome-stable_50.0.2661.94_amd64.sha ├── google-chrome-stable_51.0.2704.103_amd64.md5 ├── google-chrome-stable_51.0.2704.103_amd64.sha ├── google-chrome-stable_51.0.2704.106_amd64.md5 ├── google-chrome-stable_51.0.2704.106_amd64.sha ├── google-chrome-stable_51.0.2704.63_amd64.md5 ├── google-chrome-stable_51.0.2704.63_amd64.sha ├── google-chrome-stable_51.0.2704.79_amd64.md5 ├── google-chrome-stable_51.0.2704.79_amd64.sha ├── google-chrome-stable_51.0.2704.84_amd64.md5 └── google-chrome-stable_51.0.2704.84_amd64.sha ├── browsermobproxy ├── bin │ └── browsermob-proxy └── etc │ └── supervisor │ └── conf.d │ └── browsermobproxy.conf ├── capabilities.json ├── ci_cd └── deploy.sh ├── dns ├── bin │ └── improve_etc_hosts.sh └── etc │ └── hosts ├── docker-compose-host.yml ├── docker-compose-scales.yml ├── docker-compose-tests.yml ├── docker-compose.yml ├── docs ├── docker-compose.md ├── gource.md ├── hub_and_nodes.md ├── hub_and_nodes_alternatives.md ├── interview.md ├── jenkins.md ├── make.md ├── share-host.md └── videos.md ├── host-scripts ├── gen-scm-source.sh ├── get-host-scripts.sh ├── install_minishift.sh ├── install_vnc.sh ├── loop-wait-docker.sh ├── see.sh ├── wait-docker-selenium.sh └── wait.sh ├── images ├── Docker_Mac_CPUs_Memory.png ├── chrome_grid_console.png ├── completed.png ├── empty_grid_console.png ├── failure.png ├── firefox_grid_console.png ├── ga-datastudio-docker-selenium.png ├── gource.png ├── grid2_console.png ├── grid3_console.png ├── grid_4_nodes_diagram_host.png ├── grid_4_nodes_diagram_host.svg ├── grid_4_nodes_diagram_seleniums.png ├── grid_4_nodes_diagram_seleniums.svg ├── grid_4_nodes_random_ports.png ├── grid_4_nodes_random_ports_localhost.png ├── icons │ ├── BIG_NOODLE_TITLING.TTF │ ├── logo.png │ ├── logo_25px.png │ ├── logo_40px.png │ ├── logo_wide.jpg │ └── logo_wide_transp.png ├── message.png ├── success.png ├── timeout.png ├── wallpaper-dosel.png └── wallpaper-zalenium.png ├── java └── bin │ └── java-dynamic-memory-opts.sh ├── lib ├── libpolyfill.so └── libstderred.so ├── logo.png ├── misc └── misc.md ├── mk ├── gather_videos.sh ├── install_vnc.sh ├── install_wmctrl.sh ├── move.sh ├── see.sh ├── vnc_cask.rb └── wait.sh ├── novnc ├── bin │ ├── start-novnc.sh │ └── wait-novnc.sh └── etc │ └── supervisor │ └── conf.d │ └── novnc.conf ├── osx ├── dockertoolbox-pkg-rc.rb ├── dockertoolbox-pkg-rc3.rb ├── dockertoolbox-rc.rb └── vnc_cask.rb ├── scm-source.json ├── selenium-hub ├── bin │ ├── start-selenium-hub.sh │ └── wait-selenium-hub.sh └── etc │ └── supervisor │ └── conf.d │ └── selenium-hub.conf ├── selenium-multinode ├── bin │ ├── start-selenium-multinode.sh │ └── wait-selenium-multinode.sh └── etc │ └── supervisor │ └── conf.d │ └── selenium-multinode.conf ├── selenium-node-chrome ├── bin │ ├── start-selenium-node-chrome.sh │ └── wait-selenium-node-chrome.sh ├── etc │ └── supervisor │ │ └── conf.d │ │ └── selenium-node-chrome.conf └── opt │ └── google │ └── chrome │ └── google-chrome ├── selenium-node-firefox ├── bin │ ├── start-selenium-node-firefox.sh │ └── wait-selenium-node-firefox.sh └── etc │ └── supervisor │ └── conf.d │ └── selenium-node-firefox.conf ├── supervisor ├── bin │ └── run-supervisord.sh └── etc │ └── supervisor │ └── supervisord.conf ├── test ├── README.md ├── after_script ├── bef ├── before_install_build ├── before_install_docker_linux ├── before_install_docker_osx ├── before_install_pull ├── before_install_setup ├── compose-test.sh ├── docker-compose.yml ├── install_bats ├── install_hub_cli ├── parallel.sh ├── python_test.py ├── requirements.txt ├── run_locally.sh ├── run_test.sh ├── script_archive ├── script_bats ├── script_run_all_tests ├── script_scenario_arbitrary_uid ├── script_scenario_basic ├── script_scenario_compose_N_N ├── script_scenario_make ├── script_scenario_node_dies ├── script_scenario_restart ├── script_scenario_zalenium ├── selenium_test.sh ├── test-functions.sh ├── wait_videos_count └── x ├── utils └── bin │ ├── chrome_node_logs │ ├── docker_alongside_docker.sh │ ├── errors │ ├── generate_capabilities_json │ ├── genpassword.sh │ ├── please_update_scm-source_json │ ├── selenium-status.sh │ └── vncview.sh ├── video-rec ├── bin │ ├── fix_videos.sh │ ├── mp4box_retry.sh │ ├── rm_videos │ ├── start-video │ ├── start-video-rec.sh │ ├── stop-video │ ├── wait-stop-video-rec.sh │ └── wait-video-rec.sh └── etc │ └── supervisor │ └── conf.d │ └── video-rec.conf ├── vnc ├── bin │ ├── start-vnc.sh │ └── wait-vnc.sh └── etc │ └── supervisor │ └── conf.d │ └── vnc.conf ├── xmanager ├── bin │ ├── start-xmanager.sh │ └── wait-xmanager.sh └── etc │ └── supervisor │ └── conf.d │ └── xmanager.conf ├── xterm ├── bin │ ├── start-xterm.sh │ ├── wait-xterm.sh │ └── wait_all_done └── etc │ └── supervisor │ └── conf.d │ └── xterm.conf └── xvfb ├── bin ├── start-xvfb.sh └── wait-xvfb.sh └── etc └── supervisor └── conf.d └── xvfb.conf.old /.dockerignore: -------------------------------------------------------------------------------- 1 | tmp/ 2 | *_image/ 3 | binaries/ 4 | READMEBS.md 5 | READMEZala.sh 6 | .python-version 7 | videos/ 8 | android/ 9 | binaries 10 | README.md 11 | TODO.md 12 | CHANGELOG.md 13 | CONTRIBUTING.md 14 | LATEST_RELEASE_TEMPLATE.md 15 | LATEST_RELEASE.md 16 | bats/ 17 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | 11 | [*.json] 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [*.md] 16 | indent_style = space 17 | indent_size = 4 18 | 19 | [Makefile] 20 | indent_style = tab 21 | indent_size = 2 22 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sh eol=lf 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | github: [elgalu] 5 | 6 | patreon: # Replace with a single Patreon username 7 | open_collective: # Replace with a single Open Collective username 8 | ko_fi: # Replace with a single Ko-fi username 9 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 10 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 11 | liberapay: # Replace with a single Liberapay username 12 | issuehunt: # Replace with a single IssueHunt username 13 | otechie: # Replace with a single Otechie username 14 | 15 | # Bitcoin (BTC) 16 | custom: 17 | - "https://www.blockchain.com/btc/address/1PNfExdfu7Kc2n32swKGhqXzzpPd2iXhXB" 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Please make sure that the boxes below are checked before you submit your issue. Thank you! 2 | 3 | #### Operating System 4 | - [ ] I provided my operating system name and version, e.g. output of `uname -a` 5 | 6 | #### Image version 7 | - [ ] I have latest version of this image. Upgrade with `docker pull elgalu/selenium` 8 | 9 | - [ ] If I don't have latest version of this image and can't upgrade, I will specify which one I'm using. 10 | 11 | #### Docker version 12 | - [ ] I have latest version of docker and I will specify here the output of `docker --version` 13 | 14 | - [ ] If I don't have latest version of docker I will specify which version with `docker --version` output 15 | 16 | #### Docker-Compose 17 | _(if using docker-compose)_ 18 | 19 | - [ ] I have latest version of docker-compose and I will specify here the output of `docker-compose --version` 20 | 21 | - [ ] If I don't have latest version of docker-compose I will specify which version with `docker-compose --version` output 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | tmp/ 2 | tmp_make/ 3 | *_image/ 4 | binaries/* 5 | READMEBS.md 6 | READMEZala.sh 7 | .python-version 8 | videos 9 | tmp_videos 10 | android/ 11 | scm-source.json 12 | TODO.md 13 | docker_push.log 14 | bats/ 15 | compose_down.log 16 | docker-pull.log 17 | hub_1.log 18 | chrome*.log 19 | firefox*.log 20 | stop_video_chrome*.log 21 | stop_video_firefox*.log 22 | VNC-*-Linux-x64-DEB.tar.gz 23 | VNC-Viewer-*-Linux-x64.deb 24 | VNC-*-MacOSX-x86_64.pkg 25 | vnc_linux.md5 26 | vnc_osx.md5 27 | tmposx/ 28 | *.log 29 | NEXT_RELEASE.md 30 | temp.md 31 | git_shortlog.stdout 32 | .bitballoon 33 | .idea 34 | *.DS_Store 35 | *.iml 36 | -------------------------------------------------------------------------------- /.menv: -------------------------------------------------------------------------------- 1 | # Specify the path to a Compose file. If not provided, Compose looks for a 2 | # file named docker-compose-tests.yml in the current directory and then each 3 | # parent directory in succession until a file by that name is found. 4 | # https://docs.docker.com/compose/reference/envvars/#compose-file 5 | export COMPOSE_FILE ?= docker-compose-tests.yml 6 | export DOCKER_SELENIUM_TAG ?= latest 7 | 8 | # We prefer Real VNC client because it allows the 9 | # -Scaling % option 10 | export VNC_CLIENT_NAME ?= RealVNC 11 | export VNC_DOWNLOAD_BASE_URL = https://www.realvnc.com/download/file/vnc.files 12 | export VNC_CLIENT_VERSION = 5.3.2 13 | export VNC_CLIENT_ERROR_MSG="Required VNC viewer '${VNC_CLIENT_NAME}' is not installed" 14 | export VNC_FILE_OSX = VNC-${VNC_CLIENT_VERSION}-MacOSX-x86_64.pkg 15 | export VNC_FILE_LINUX = VNC-${VNC_CLIENT_VERSION}-Linux-x64-DEB.tar.gz 16 | export VNC_MD5SUM_OSX = a9b2ba07286f04dadc63db252a95b639 17 | export VNC_MD5SUM_LINUX = 5b0da4c2d3a8f1e3db5982b9e6be2cb6 18 | # The command we will use to check if proper VNC is installed 19 | export VNC_CHECK_CMD = \"${VNC_CLIENT}\" -h | grep -i '${VNC_CLIENT_NAME}' >/dev/null 20 | export WMCTRL_CHECK_CMD = wmctrl --version 21 | export WMCTRL_CLIENT_ERROR_MSG="Required wmctrl is not installed" 22 | 23 | # We need a fixed port range to expose VNC 24 | # due to a bug in Docker for Mac beta (1.12) 25 | # https://forums.docker.com/t/docker-for-mac-beta-not-forwarding-ports/8658/6 26 | export VNC_FROM_PORT ?= 40650 27 | export VNC_TO_PORT ?= 40700 28 | 29 | # Timeouts 30 | export WAIT_ALL_DONE ?= 80s 31 | 32 | # Number of nodes 33 | export chrome ?= 1 34 | export firefox ?= 1 35 | 36 | # To target a specific node number 37 | # for example to VNC into it via 38 | # make see browser=chrome node=1 39 | export browser ?= chrome 40 | export node ?= 1 41 | 42 | # If you project name is selenium and it includes two services 43 | # `hub` and `node` then compose starts containers named 44 | # grid_hub_1 and grid_node_1 respectively. 45 | # It will also 46 | # https://docs.docker.com/compose/reference/envvars/#compose-project-name 47 | export proj ?= grid 48 | export PROJ_NAME ?= ${proj} 49 | export COMPOSE_PROJ_NAME ?= ${PROJ_NAME} 50 | # VNC viewer relative size, vncviewer -Scaling 51 | export SIZE ?= 50% 52 | 53 | # Enable video recording 54 | export VIDEO ?= true 55 | 56 | # Enable audio recording 57 | export AUDIO ?= true 58 | 59 | # App name is the service name for the web app under test 60 | # export APP ?= zalando_uk 61 | export APP ?= mock 62 | export APP_NAME ?= ${APP} 63 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Even though we run everything inside docker, 2 | # Travis requires us to pick a language else it will pick Ruby by default. 3 | # Let's choose a lightweight base image then we provide our own build tools. 4 | # Note: `language: generic` was failing in OSX so in that case you can use language: c 5 | # UPDATE: Switching to python as we want to run Zalenium tests from the host 6 | language: python 7 | python: 8 | - "3.6" 9 | 10 | sudo: required 11 | 12 | os: linux 13 | dist: xenial 14 | 15 | services: 16 | - docker 17 | 18 | branches: 19 | except: 20 | - latest 21 | 22 | env: 23 | global: 24 | - TEST_SLEEPS="0.7" 25 | - ADDED_TEST_SLEEP="6.5" 26 | - DOCKER_VERSION="stable" 27 | 28 | jobs: 29 | allow_failures: 30 | - env: test=scenario_make 31 | 32 | include: 33 | - stage: Docker build (re-use in stages) 34 | env: step=build_push 35 | script: 36 | - travis_retry ./test/before_install_build 37 | 38 | - stage: Integration and Unit Tests 39 | env: test=scenario_basic__restart 40 | script: 41 | - travis_retry ./test/before_install_pull 42 | - travis_retry ./test/script_scenario_basic 43 | - travis_retry ./test/script_scenario_restart 44 | 45 | - env: test=scenario_arbitrary_uid 46 | script: 47 | - travis_retry ./test/before_install_pull 48 | - travis_retry ./test/script_scenario_arbitrary_uid 49 | 50 | - env: test=scenario_node_dies 51 | script: 52 | - travis_retry ./test/before_install_pull 53 | - travis_retry ./test/script_scenario_node_dies 54 | 55 | - env: test=scenario_compose_N_N 56 | script: 57 | - travis_retry ./test/before_install_pull 58 | - travis_retry ./test/script_scenario_compose_N_N 59 | 60 | - env: test=Zalenium_Latest 61 | script: 62 | - gem install bitballoon || true 63 | - travis_retry ./test/before_install_pull 64 | - travis_retry ./test/script_scenario_zalenium 65 | 66 | - stage: Bump versions 67 | if: branch = master AND sender != elgalubot AND tag IS blank AND type != pull_request 68 | script: 69 | - travis_retry ./test/install_hub_cli 70 | - travis_retry ./test/before_install_pull 71 | - ./ci_cd/deploy.sh bump 72 | 73 | - stage: Push Image & Release 74 | if: tag =~ ^\d+\.\d+\.\d+-p\d+$ AND type != pull_request 75 | script: 76 | - travis_retry ./test/install_hub_cli 77 | - travis_retry ./test/before_install_pull 78 | - ./ci_cd/deploy.sh release 79 | -------------------------------------------------------------------------------- /Analytics.md: -------------------------------------------------------------------------------- 1 | # Docker-selenium's Anonymous Aggregate User Behaviour Analytics 2 | Docker-selenium no longer gathers anonymous aggregate user behaviour analytics and reporting to Google Analytics. 3 | 4 | We are stopping GA tracking due to: 5 | https://www.allenovery.com/en-gb/global/news-and-insights/publications/werbe-cookies-erfordern-die-aktive-einwilligung-des-nutzers 6 | 7 | > a statement or clear affirmative action by the user is required 8 | > website operators can no longer rely on an opt-out procedure. 9 | 10 | ## Why? 11 | Docker-selenium is provided free of charge and we don't have direct communication with its users nor time resources to ask directly for their feedback. As a result, we now use anonymous aggregate user analytics to help us understand how Docker-selenium is being used, the most common used features based on how, where and when people use it. With this information we can prioritize some features over other ones, understand better which Selenium or Docker versions we should support depending on the usage, and get execution exceptions to identify bugs. 12 | 13 | ## What? 14 | Docker-selenium's analytics record some shared information for every event: 15 | 16 | - The Google Analytics version i.e. `1` (https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#v) 17 | - The Docker-selenium analytics tracking ID e.g. `UA-18144954-9` (https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#tid) 18 | - The Google Analytics anonymous IP setting is enabled i.e. `1` (https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#aip) 19 | - The Docker-selenium application name e.g. `dosel` (https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#an) 20 | - The Docker-selenium application version e.g. `3.0.1-p0` (https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#av) 21 | - The Docker-selenium analytics hit type e.g. `screenview` (https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#t) 22 | 23 | Docker-selenium's analytics records the following different events: 24 | 25 | - a `screenview` when you start Docker-selenium and the options you used to start it. Users and API keys for the cloud testing providers are never recorded. 26 | - an `event` hit type with the `test_start` event category from the capabilities as event label. 27 | - an `event` hit type with the `test_stop` event category from the capabilities as event label. 28 | - an `exception` hit type with the `exception` event category, exception description of the exception name and whether the exception was fatal e.g. `1` 29 | 30 | With the recorded information, it is not possible for us to match any particular real user. 31 | 32 | As far as we can tell it would be impossible for Google to match the randomly generated analytics user ID to any other Google Analytics user ID. If Google turned evil (by being hacked for example) the only thing they could do would be to lie about anonymising IP addresses and attempt to match users based on IP addresses. 33 | 34 | ## When/Where? 35 | Docker-selenium's analytics are sent throughout Docker-selenium's execution to Google Analytics over HTTPS. 36 | 37 | ## Who? 38 | Docker-selenium's analytics are accessible to Docker-selenium's current maintainers. Contact [@elgalu](https://github.com/elgalu) if you are a maintainer and need access. 39 | 40 | ## How? 41 | The code is viewable in: 42 | * [Docker-selenium start](./bin/entry.sh#300) 43 | * [Docker-selenium stop](./supervisor/bin/run-supervisord.sh#16) 44 | 45 | The code is implemented so it gets executed in a background process, without delaying normal execution. If it fails, it will do it immediately and silently. 46 | 47 | ## Opting out before starting Docker-selenium 48 | Docker-selenium analytics helps us maintainers and leaving it on is appreciated. However, if you want to opt out and not send any information, you can do this by using passing the following parameter at docker run time: 49 | 50 | ```sh 51 | -e SEND_ANONYMOUS_USAGE_INFO=false 52 | ``` 53 | 54 | ## Disclaimer 55 | This document and the implementation are based on the great idea implemented by [Homebrew](https://github.com/Homebrew/brew/blob/master/docs/Analytics.md) 56 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | Simply put your changes in a new branch and open a pull request. 3 | 4 | ## Build Locally 5 | ./test/before_install_build 6 | 7 | ## Local Testing 8 | To test your local changes: 9 | 10 | ./test/run_locally.sh 11 | 12 | Optionally, manually check if the png and videos were generated: 13 | 14 | open ./images/grid3_console.png && open ./videos/mobile_emulation/*.mp4 15 | 16 | Optionally, do a local cleanup 17 | 18 | ./test/after_script 19 | -------------------------------------------------------------------------------- /Dockerfile.older.browser: -------------------------------------------------------------------------------- 1 | # docker-selenium tags are pointer based, for instance: 2 | # latest now points to 3 that points to 3.5 that points to 3.5.0 that points to 3.5.0-p1 3 | # 3.3 points to 3.3.1 that points to 3.3.1-p27 4 | # and so on 5 | FROM elgalu/selenium:3.5 6 | 7 | USER root 8 | 9 | # In order to install an older chrome we need to: 10 | # 1. identify the git tag of the release that has that .deb version file 11 | # e.g. 3.3.1-p22 12 | # 2. grab the .deb download url 13 | # e.g. https://github.com/elgalu/....../google-chrome-stable_60.0.3112.101_amd64.deb 14 | RUN mkdir -p /home/seluser/chrome-deb \ 15 | && cd /home/seluser/chrome-deb \ 16 | && wget -O "older_chrome.deb" -nv \ 17 | "https://github.com/elgalu/docker-selenium/releases/download/3.3.1-p22/google-chrome-stable_60.0.3112.101_amd64.deb" 18 | 19 | # Installing the deb file will upgrade replace existing Chrome with the one we need 20 | RUN cd /home/seluser/chrome-deb \ 21 | && dpkg -i "older_chrome.deb" \ 22 | && rm "older_chrome.deb" \ 23 | && apt-get -qyy autoremove \ 24 | && rm -rf /var/lib/apt/lists/* \ 25 | && apt-get -qyy clean \ 26 | && export CH_STABLE_VER=$(/usr/bin/google-chrome-stable --version | grep -iEo "${GREP_ONLY_NUMS_VER}") \ 27 | && echo "${CH_STABLE_VER}" 28 | 29 | # Restore default user 30 | USER seluser 31 | -------------------------------------------------------------------------------- /GLOBAL_PATCH_LEVEL.txt: -------------------------------------------------------------------------------- 1 | 358 2 | -------------------------------------------------------------------------------- /LATEST_RELEASE.md: -------------------------------------------------------------------------------- 1 | ## 3.141.59-p59 2 | + **Changes:** https://github.com/elgalu/docker-selenium/compare/3.141.59-p58...3.141.59-p59 (2021-05-26) 3 | + **Image tag details:** 4 | + Selenium version: 3.141.59 (82b03c358b) 5 | + Chrome stable: 91.0.4472.77 6 | + Firefox stable: 88.0.1 7 | + Geckodriver: 0.29.1 8 | + Chromedriver: 91.0.4472.19 (1bf021f248676a0b2ab3ee0561d83a59e424c23e) 9 | + Java: OpenJDK Java 1.8.0_292-8u292-b10-0ubuntu1 10 | + Default Timezone: Europe/Berlin 11 | + FROM ubuntu:xenial-20190904 12 | + Python: 3.5.2 13 | + Tested on kernel CI host: 4.15.0-1077-gcp x86_64 14 | + Built at CI host with: Docker version 18.06.0, build 0ffa825 15 | + Built at CI host with: Docker Compose version 1.23.1, build b02f1306 16 | + Image version: 3.141.59-357 17 | + Image size: 1.62GB 18 | + Digest: sha256:8b83d2a3bc0cf26d0aed929c25dd09ecbc5949a852a8f01081ff14d175b4619d 19 | 20 | -------------------------------------------------------------------------------- /LATEST_RELEASE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## NEXT_RELEASE 2 | + **Changes:** https://github.com/elgalu/docker-selenium/compare/PREV_RELEASE...NEXT_RELEASE (TBD_DATE) 3 | + **Image tag details:** 4 | + Selenium version: TBD_SELENIUM_VERSION (TBD_SELENIUM_REVISION) 5 | + Chrome stable: TBD_CHROME_STABLE 6 | + Firefox stable: TBD_FIREFOX_VERSION 7 | + Geckodriver: TBD_GECKO_DRIVER 8 | + Chromedriver: TBD_CHROME_DRIVER (TBD_CHROMEDRIVER_COMMIT) 9 | + Java: TBD_JAVA_VENDOR Java TBD_JAVA_BUILD 10 | + Default Timezone: TBD_TIME_ZONE 11 | + FROM ubuntu:UBUNTU_FLAVOR-UBUNTU_DATE 12 | + Python: TBD_PYTHON_VERSION 13 | + Tested on kernel CI host: TBD_HOST_UNAME 14 | + Built at CI host with: Docker version TBD_DOCKER_VERS, build TBD_DOCKER_BUILD 15 | + Built at CI host with: Docker Compose version TBD_DOCKER_COMPOSE_VERS, build TBD_DOCKER_COMPOSE_BUILD 16 | + Image version: TBD_IMAGE_VERSION 17 | + Image size: TBD_IMAGE_SIZE 18 | + Digest: TBD_DIGEST 19 | 20 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | ## License Information 2 | 3 | This program is subject to the terms of the Apache License, Version 2.0 AND the following amendments on forks and data processing. Thus, this is a Custom Apache 2.0 License, NOT a dual-license model you may choose from. 4 | 5 | You can obtain a copy of the license at http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 8 | 9 | ## Forks 10 | Additionally to Apache-2.0, when you fork this repo you are required to either remove our Google Analytics tracking ID: UA-18144954-9 or stop usage gathering completely. 11 | 12 | ## Data processing agreement 13 | By using this software you agree that the following non-PII (non personally identifiable information) data will be collected, processed and used by Dosel for the purpose of improving our test infrastructure tools. Anonymisation with respect of the IP address means that only the first two octets of the IP address are collected. 14 | 15 | By using this software you also grant us a nonexclusive, irrevocable, world-wide, perpetual royalty-free permission to use, modify and publish these data for all purposes, internally or publicly, including the right to sub-license said permission rights. 16 | 17 | We collect, process and use the following data: 18 | * Docker-selenium version 19 | * Anonymized IP address (only first two octets) 20 | * Country and city 21 | * Selected screen resolution 22 | * Selected timezone 23 | * System language 24 | * Chrome nodes count 25 | * Firefox nodes count 26 | * Docker-selenium options set via environment variables 27 | * Date and time of certain events 28 | * Docker-selenium started 29 | * Docker-selenium stopped 30 | * Test duration 31 | * Test capabilities 32 | * Errors and stacktraces 33 | * Docker version 34 | * Docker info fields 35 | * Server Version 36 | * Kernel Version 37 | * Operating System 38 | * OSType 39 | * Architecture 40 | * CPUs 41 | * Total Memory 42 | * ID 43 | 44 | ## End of License Information 45 | 46 | More information about anonymized data collection can be seen [here](Analytics.md) 47 | -------------------------------------------------------------------------------- /MAINTAINERS: -------------------------------------------------------------------------------- 1 | Leo Gallucci 2 | Diego Molina 3 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security notes on Docker-Selenium 2 | 3 | The docker images are built and pushed from [TravisCI](https://travis-ci.org/elgalu/docker-selenium/builds/123103275) for full traceability. 4 | 5 | Using `VNC_PASSWORD=no` will make it VNC passwordless accessible, leave it empty to get a randomly generated one or if you don't use VNC simply deactivate it via `docker run ... -e VNC_START=false` but VNC is currently set to not use encryption. This should be irrelevant as the VNC should only be accessible within your Docker host machine, if you choose to expose VNC to the outside world 6 | 7 | ## Important 8 | 9 | Do **NOT** expose your selenium grid to the outside world (e.g. in AWS), because Selenium does not provide authentication. Therefore, if the ports are not firewalled malicious users will use [your selenium grid as a bot net](https://github.com/SeleniumHQ/docker-selenium/issues/147). 10 | 11 | There are also additional steps you can take to ensure you're using the correct image: 12 | 13 | ### Option 1 - Check the Full Image Id 14 | 15 | You can simply verify that image id is indeed the correct one. 16 | 17 | # e.g. full image id for some specific tag version 18 | export IMGID="<>" 19 | if docker inspect -f='{{.Id}}' elgalu/selenium:latest |grep ${IMGID} >/dev/null; then 20 | echo "Image ID tested ok" 21 | else 22 | echo "Image ID doesn't match" 23 | fi 24 | 25 | ### Option 2 - Use immutable image digests 26 | 27 | Given docker.io currently allows to push the same tag image twice this represent a security concern but since docker >= 1.6.2 is possible to fetch the digest sha256 instead of the tag so you can be sure you're using the exact same docker image every time: 28 | 29 | # e.g. sha256 for some specific tag 30 | export SHA=<> 31 | docker pull elgalu/selenium@sha256:${SHA} 32 | 33 | You can find all digests sha256 and image ids per tag in the [CHANGELOG](./CHANGELOG.md) so as of now you just need to trust the sha256 in the CHANGELOG. Bullet proof is to fork this project and build the images yourself if security is a big concern. 34 | -------------------------------------------------------------------------------- /bin/DisplayDataProcessingAgreement: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "***************** BEGIN: Data Processing Agreement *****************" 4 | echo -e "By using this software you agree that the following non-PII" 5 | echo -e "(non personally identifiable information) data will be collected," 6 | echo -e "processed and used by Docker-selenium for the purpose of improving" 7 | echo -e "our test infrastructure tools. Anonymisation with respect of the IP" 8 | echo -e "address means that only the first two octets of the IP address are" 9 | echo -e "collected. See the complete license at:" 10 | echo -e "https://github.com/elgalu/docker-selenium/blob/master/LICENSE.md" 11 | echo "****************** END: Data Processing Agreement ******************" 12 | -------------------------------------------------------------------------------- /bin/DisplaySponsorRequest: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "*********** CALL FOR SPONSORS ***********" 4 | echo -e "" 5 | echo -e " https://github.com/sponsors/elgalu " 6 | echo -e "" 7 | echo "*********** CALL FOR SPONSORS ***********" 8 | -------------------------------------------------------------------------------- /bin/chrome_stable_version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | # Example: 5 | # google-chrome-stable --version 2>&1 6 | #=> Google Chrome 50.0.2661.75 7 | 8 | # Example: 9 | #=> 50.0.2661.75 10 | if google-chrome-stable --version >/dev/null 2>&1; then 11 | google-chrome-stable --version 2>&1 | grep -Po '(?<=Google Chrome )([a-z0-9\.]+)' 12 | else 13 | google-chrome-stable --version #fail and show error 14 | fi 15 | -------------------------------------------------------------------------------- /bin/chromedriver_commit_version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | # Example: 5 | #=> 633e689b520b25f3e264a2ede6b74ccc23cb636a 6 | if chromedriver --version >/dev/null 2>&1; then 7 | chromedriver --version 2>&1 | grep -Po '(?<=\s\()([a-z0-9]+)' 8 | else 9 | chromedriver --version #fail and show error 10 | fi 11 | -------------------------------------------------------------------------------- /bin/chromedriver_version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | # Example: 5 | # chromedriver --version 2>&1 6 | #=> ChromeDriver 2.21.371461 (633e689b520b25f3e264a2ede6b74ccc23cb636a) 7 | 8 | # Example: 9 | #=> 2.21.371461 10 | if chromedriver --version >/dev/null 2>&1; then 11 | chromedriver --version 2>&1 | grep -Po '(?<=ChromeDriver )([a-z0-9\.]+)' 12 | else 13 | chromedriver --version #fail and show error 14 | fi 15 | -------------------------------------------------------------------------------- /bin/cleanup-container.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set +e 4 | 5 | # After transferring the logs: Kill unclosed browsers, if any 6 | killall --ignore-case --quiet --regexp "chrome.*" 7 | killall --ignore-case --quiet --regexp "geckodriver.*" 8 | killall --ignore-case --quiet --regexp "firefox.*" 9 | # Kill any open notifications so the next test does not see them 10 | killall --ignore-case --quiet --regexp "xfce4-notifyd.*" 11 | 12 | # After transferring the logs: reset them for the next test 13 | for filename in /var/log/cont/*.log; do 14 | truncate -s 0 ${filename} || echo "WARN: Failed to truncate ${filename}" 15 | done 16 | -------------------------------------------------------------------------------- /bin/error: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Prints debug info with precise time 4 | exec echo "--${SELENIUM_FIRST_NODE_PORT}ERROR $(date "+%H:%M:%S:%N") $@" >&2 5 | -------------------------------------------------------------------------------- /bin/fail: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Prints debug info with precise time 4 | echo "--${SELENIUM_FIRST_NODE_PORT}ERROR $(date "+%H:%M:%S:%N") $@" >&2 5 | exit 101 6 | -------------------------------------------------------------------------------- /bin/firefox_version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | # Example: 5 | # firefox -version 2>&1 6 | #=> Mozilla Firefox 45.0.2 7 | 8 | # Fix the DISPLAY env var if we saved it 9 | [ -f DISPLAY ] && export DISPLAY=$(cat DISPLAY) 10 | 11 | # Example: 12 | #=> 45.0.2 13 | if firefox -version >/dev/null 2>&1; then 14 | firefox -version 2>&1 | grep -Po '(?<=Firefox )([a-z0-9\.]+)' 15 | else 16 | firefox -version #fail and show error 17 | fi 18 | -------------------------------------------------------------------------------- /bin/fixperms.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set +e: don't exit if a command exits with a non-zero status 4 | set +e 5 | 6 | ###################################################################### 7 | # Relaxing permissions for OpenShift and other non-sudo environments # 8 | ###################################################################### 9 | 10 | # List of directories in which we need to fix perms: 11 | DIR_LIST="/var/lib/dbus /tmp /var/run /run /var/log/cont /etc/supervisor" 12 | DIR_LIST="${DIR_LIST} /videos ${VIDEOS_DIR} /test /home/seluser" 13 | 14 | # Relaxing permissions for OpenShift and other non-sudo environments 15 | chmod 777 /etc/passwd 16 | 17 | # Permissions related to the X system 18 | chmod 1777 /tmp/.X11-unix /tmp/.ICE-unix 19 | 20 | for d in ${DIR_LIST}; do 21 | 22 | chown -R seluser:seluser ${d} 23 | 24 | # Give full acess to everything (easier) 25 | # chmod -R 777 ${d} 26 | 27 | # Give 666 to files that were not executable 28 | find ${d} ! -executable -type f -exec chmod 666 "{}" \; 29 | 30 | # Give 777 to directories 31 | find ${d} -type d -exec chmod 777 "{}" \; 32 | 33 | # Give 777 to files that were already executable 34 | find ${d} -executable -type f -exec chmod 777 "{}" \; 35 | 36 | done 37 | -------------------------------------------------------------------------------- /bin/functions.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # https://github.com/SeleniumHQ/docker-selenium/issues/184 4 | function get_server_num() { 5 | echo $(echo $DISPLAY | sed -r -e 's/([^:]+)?:([0-9]+)(\.[0-9]+)?/\2/') 6 | } 7 | -------------------------------------------------------------------------------- /bin/geckodriver_version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | # Example: 5 | # geckodriver --version 2>&1 6 | #=> geckodriver 0.10.0 7 | #=> ...... The source is available at.... 8 | 9 | # Example: 10 | #=> 0.10.0 11 | CMD="geckodriver" 12 | if ${CMD} --version >/dev/null 2>&1; then 13 | ${CMD} --version 2>&1 | grep -Po '(?<=geckodriver )([0-9\.]+)' 14 | else 15 | ${CMD} --version #fail and show error 16 | fi 17 | -------------------------------------------------------------------------------- /bin/get_chrome_stable.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | # set -u: treat unset variables as an error and exit immediately 5 | # set -x: print each command right before it is executed 6 | set -eux 7 | 8 | mkdir -p ./chrome-deb && cd chrome-deb 9 | export CHROME_URL="https://dl.google.com/linux/direct" 10 | wget -nv --show-progress -O chrome_amd64.deb "${CHROME_URL}/google-chrome-stable_current_amd64.deb" 11 | 12 | set +e #do not fail from now on 13 | 14 | wget -O stable_updates.html "http://googlechromereleases.blogspot.de/search/label/Stable%20updates" 15 | VER=$(grep -Po '([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)' stable_updates.html | head -1) 16 | NAME="google-chrome-stable_${VER}_amd64" 17 | mv chrome_amd64.deb ${NAME}.deb 18 | 19 | md5sum ${NAME}.deb > ${NAME}.md5 20 | shasum ${NAME}.deb > ${NAME}.sha 21 | -------------------------------------------------------------------------------- /bin/get_unused_port: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import socket 5 | 6 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 7 | s.bind(('', 0)) 8 | addr = s.getsockname() 9 | print(addr[1]) 10 | s.close() 11 | -------------------------------------------------------------------------------- /bin/get_unused_port_from_range: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import sys 5 | import socket 6 | import random 7 | 8 | from_port = int(sys.argv[1]) 9 | to_port = int(sys.argv[2]) 10 | 11 | ports = list(range(from_port, to_port)) 12 | random.shuffle(ports) 13 | 14 | for port in ports: 15 | # print("Trying port %s" % port) 16 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 17 | try: 18 | s.bind(('', port)) 19 | except: 20 | # print("Port %s is used" % port) 21 | continue 22 | addr = s.getsockname() 23 | print(addr[1]) 24 | s.close() 25 | break 26 | 27 | if port == to_port: 28 | raise Exception("Port range %s - %s not available to bind" % (from_port, to_port)) 29 | -------------------------------------------------------------------------------- /bin/java_build_version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | # Example OpenJDK 8: 5 | # java -version 2>&1 6 | #=> openjdk version "1.8.0_66-internal" 7 | #=> OpenJDK Runtime Environment (build 1.8.0_66-internal-b17) 8 | #=> OpenJDK 64-Bit Server VM (build 25.66-b17, mixed mode) 9 | 10 | # Example Oracle 9: 11 | # java -version 2>&1 12 | #=> java version "9-ea" 13 | #=> Java(TM) SE Runtime Environment (build 9-ea+112) 14 | #=> Java HotSpot(TM) 64-Bit Server VM (build 9-ea+112, mixed mode) 15 | 16 | # Example OpenJDK 8: 17 | #=> 1.8.0_66-internal-b17 18 | # Example Oracle 9: 19 | #=> 9-ea+112 20 | if java -version >/dev/null 2>&1; then 21 | java -version 2>&1 | grep -Po '(?<=Environment \(build )([a-z0-9\._\-\+]+)' 22 | else 23 | java -version #fail and show error 24 | fi 25 | -------------------------------------------------------------------------------- /bin/java_vendor_version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | if java -version >/dev/null 2>&1; then 5 | if java -version 2>&1 | grep "OpenJ" >/dev/null; then 6 | JAVA_VENDOR="OpenJDK" 7 | else 8 | JAVA_VENDOR="Oracle" 9 | fi 10 | echo "${JAVA_VENDOR}" 11 | else 12 | java -version #fail and show error 13 | fi 14 | -------------------------------------------------------------------------------- /bin/log: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Prints debug info with precise time 4 | exec echo "--${SELENIUM_FIRST_NODE_PORT}LOG $(date "+%H:%M:%S:%N") $@" 5 | -------------------------------------------------------------------------------- /bin/notify: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | export DISPLAY=$(cat DISPLAY) 4 | 5 | exec notify-send "$@" 6 | -------------------------------------------------------------------------------- /bin/python_version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | # Example: 5 | # python --version 2>&1 6 | #=> Python 2.7.11+ 7 | 8 | # Example: 9 | #=> 2.7.11 10 | if python --version >/dev/null 2>&1; then 11 | python --version 2>&1 | grep -Po '(?<=Python )([a-z0-9\.]+)' 12 | else 13 | python --version #fail and show error 14 | fi 15 | -------------------------------------------------------------------------------- /bin/selenium_revision_version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | SELENIUM_JAR_PATH="/home/seluser/selenium-server-standalone-3.jar" 5 | 6 | # Selenium 3 - Example: 7 | #=> 5234b32 8 | java -jar ${SELENIUM_JAR_PATH} --version \ 9 | | grep revision \ 10 | | grep -Po '(?<=revision: )([a-z0-9\.]+)' 11 | -------------------------------------------------------------------------------- /bin/selenium_version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | SELENIUM_JAR_PATH="/home/seluser/selenium-server-standalone-3.jar" 5 | 6 | # Selenium 3 - Example: 7 | #=> 3.3.1 8 | java -jar ${SELENIUM_JAR_PATH} --version \ 9 | | grep version \ 10 | | grep -Po '(?<=version: )([a-z0-9\.]+)' \ 11 | | sed 's/\.$//' 12 | -------------------------------------------------------------------------------- /bin/stop: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # First stop video recording because it needs some time to flush it 4 | supervisorctl -c /etc/supervisor/supervisord.conf stop video-rec >/dev/null 2>&1 || true 5 | 6 | # Now stop the rest 7 | supervisorctl -c /etc/supervisor/supervisord.conf stop all >/dev/null 2>&1 8 | 9 | # Finally kill supervisor 10 | killall supervisord >/dev/null 2>&1 11 | -------------------------------------------------------------------------------- /bin/untrunc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/bin/untrunc -------------------------------------------------------------------------------- /bin/versions: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "selenium 3 version=$(selenium_version) revision=$(selenium_revision_version)" 4 | 5 | echo "chrome_stable_version=$(chrome_stable_version)" 6 | google-chrome-stable --version 7 | 8 | echo "firefox_version=$(firefox_version)" 9 | firefox --version 10 | 11 | echo "chromedriver_version=$(chromedriver_version)" 12 | chromedriver --version 13 | 14 | echo "geckodriver_version=$(geckodriver_version)" 15 | /opt/geckodriver --version 16 | 17 | echo "java_build_version=$(java_build_version)" 18 | java -version 19 | 20 | echo "python_version=$(python_version)" 21 | python --version 22 | -------------------------------------------------------------------------------- /bin/wait_pid: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # WAIT for “any process” to finish 4 | # http://stackoverflow.com/questions/1058047/wait-for-any-process-to-finish 5 | for pid in "$@"; do 6 | while kill -0 "$pid" 2>/dev/null; do 7 | sleep 0.5 8 | done 9 | done 10 | -------------------------------------------------------------------------------- /bin/warn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Prints debug info with precise time 4 | exec echo "--${SELENIUM_FIRST_NODE_PORT}WARN $(date "+%H:%M:%S:%N") $@" 5 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_43.0.2357.134_amd64.md5: -------------------------------------------------------------------------------- 1 | b26558f6be7834d36a58e70348082203 google-chrome-stable_43.0.2357.134_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_43.0.2357.134_amd64.sha: -------------------------------------------------------------------------------- 1 | 2edd6ac78f1d883201827977a6408cd83b43d67d google-chrome-stable_43.0.2357.134_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_44.0.2403.157_amd64.md5: -------------------------------------------------------------------------------- 1 | 24097e63c43976e9f9304edd5bcd4ac0 google-chrome-stable_44.0.2403.157_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_44.0.2403.157_amd64.sha: -------------------------------------------------------------------------------- 1 | 344267d343dff4f78205663cbeb0b87e2ec67ef8 google-chrome-stable_44.0.2403.157_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_45.0.2454.101_amd64.md5: -------------------------------------------------------------------------------- 1 | df54ff74c9c9228a5d0bb441f7465e14 google-chrome-stable_45.0.2454.101_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_45.0.2454.101_amd64.sha: -------------------------------------------------------------------------------- 1 | aa9fa8a5db542ef29d5aade14190bbca70bc6259 google-chrome-stable_45.0.2454.101_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_46.0.2490.86_amd64.md5: -------------------------------------------------------------------------------- 1 | 28dbecbd7cbc3db94d215a8a50a90b06 google-chrome-stable_46.0.2490.86_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_46.0.2490.86_amd64.sha: -------------------------------------------------------------------------------- 1 | ffabe2f7bde7aed83d207c6f31e701af9f1d2c6a google-chrome-stable_46.0.2490.86_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_47.0.2526.106_amd64.md5: -------------------------------------------------------------------------------- 1 | ac9a6f982fb0e64a96ca63229ae7b56e google-chrome-stable_47.0.2526.106_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_47.0.2526.106_amd64.sha: -------------------------------------------------------------------------------- 1 | 72f49f78f19d84db27862d11d41a1d6a1e042712 google-chrome-stable_47.0.2526.106_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_47.0.2526.111_amd64.md5: -------------------------------------------------------------------------------- 1 | 5aa55a8382b7614098c775d011249abb google-chrome-stable_47.0.2526.111_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_47.0.2526.111_amd64.sha: -------------------------------------------------------------------------------- 1 | 5f9524d1fa8d3be7da48c9fdd98573614d9df87b google-chrome-stable_47.0.2526.111_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_48.0.2564.103_amd64.md5: -------------------------------------------------------------------------------- 1 | d4157117c4c81e198b3c536707809f4a google-chrome-stable_48.0.2564.103_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_48.0.2564.103_amd64.sha: -------------------------------------------------------------------------------- 1 | a1a2e5d17e1e787c54f19e19b6e4e90885c08029 google-chrome-stable_48.0.2564.103_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_48.0.2564.109_amd64.md5: -------------------------------------------------------------------------------- 1 | 7d19dad1a4549610431533f4bc0ce04b google-chrome-stable_48.0.2564.109_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_48.0.2564.109_amd64.sha: -------------------------------------------------------------------------------- 1 | ce1603711b089cada2d836e964ab5186a5adbda6 google-chrome-stable_48.0.2564.109_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_48.0.2564.116_amd64.md5: -------------------------------------------------------------------------------- 1 | 4fc58c6da74c6fed6889b0e4c2eca35f google-chrome-stable_48.0.2564.116_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_48.0.2564.116_amd64.sha: -------------------------------------------------------------------------------- 1 | 9783604a86be8d98706789df66c344e00c6a8480 google-chrome-stable_48.0.2564.116_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_48.0.2564.82_amd64.md5: -------------------------------------------------------------------------------- 1 | 40f60779d04053b4aac829cc28af0ddf google-chrome-stable_48.0.2564.82_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_48.0.2564.82_amd64.sha: -------------------------------------------------------------------------------- 1 | aff32113a98f323439b84aa75dc9eb64844b0de9 google-chrome-stable_48.0.2564.82_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_48.0.2564.97_amd64.md5: -------------------------------------------------------------------------------- 1 | 0a5fecb92e1b51c207515769cb9b1d01 google-chrome-stable_48.0.2564.97_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_48.0.2564.97_amd64.sha: -------------------------------------------------------------------------------- 1 | 2edd1c5928105304bc1a757178d9a458bcdc271a google-chrome-stable_48.0.2564.97_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_49.0.2623.108_amd64.md5: -------------------------------------------------------------------------------- 1 | d87160b1af3e799170dd7a8633a8178e google-chrome-stable_49.0.2623.108_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_49.0.2623.108_amd64.sha: -------------------------------------------------------------------------------- 1 | 5f083feaa2dd7100740f53b384feb11232304e28 google-chrome-stable_49.0.2623.108_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_49.0.2623.110_amd64.md5: -------------------------------------------------------------------------------- 1 | e56d5a0fe4c039abc3df1434a228b460 google-chrome-stable_49.0.2623.110_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_49.0.2623.110_amd64.sha: -------------------------------------------------------------------------------- 1 | 0dc8c8b991a96474ee27b704d1feec5dcea2a308 google-chrome-stable_49.0.2623.110_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_49.0.2623.111_amd64.md5: -------------------------------------------------------------------------------- 1 | e56d5a0fe4c039abc3df1434a228b460 google-chrome-stable_49.0.2623.111_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_49.0.2623.111_amd64.sha: -------------------------------------------------------------------------------- 1 | 0dc8c8b991a96474ee27b704d1feec5dcea2a308 google-chrome-stable_49.0.2623.111_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_49.0.2623.112_amd64.md5: -------------------------------------------------------------------------------- 1 | 83fae8f1aa50ae19ed55f603d814c856 google-chrome-stable_49.0.2623.112_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_49.0.2623.112_amd64.sha: -------------------------------------------------------------------------------- 1 | 3d8e09777b9eb333ae5f7ff21e25a2cbd04ff52b google-chrome-stable_49.0.2623.112_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_49.0.2623.75_amd64.md5: -------------------------------------------------------------------------------- 1 | 149e09d5f8c64ca4eea0da757e142529 google-chrome-stable_49.0.2623.75_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_49.0.2623.75_amd64.sha: -------------------------------------------------------------------------------- 1 | 782d6fe6a94a636bfa4ad4100a7579ed94fe2448 google-chrome-stable_49.0.2623.75_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_49.0.2623.87_amd64.md5: -------------------------------------------------------------------------------- 1 | 27cb02203490413a766dfa7d1d7599e0 google-chrome-stable_49.0.2623.87_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_49.0.2623.87_amd64.sha: -------------------------------------------------------------------------------- 1 | a40275c34a4f7a5e4db7b9d3a1325c39fbf90eaf google-chrome-stable_49.0.2623.87_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_50.0.2661.102_amd64.md5: -------------------------------------------------------------------------------- 1 | 28ea63b729ef8b83bc783ab99cfe8f67 google-chrome-stable_50.0.2661.102_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_50.0.2661.102_amd64.sha: -------------------------------------------------------------------------------- 1 | b3ee9ccf07bb0a7646c75ee19f4342ada33a4eae google-chrome-stable_50.0.2661.102_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_50.0.2661.75_amd64.md5: -------------------------------------------------------------------------------- 1 | 51f58db79ee3b9937db5526077d2a9e4 google-chrome-stable_50.0.2661.75_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_50.0.2661.75_amd64.sha: -------------------------------------------------------------------------------- 1 | 0615a991e3af755eddba15c49af6aef66656944e google-chrome-stable_50.0.2661.75_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_50.0.2661.86_amd64.md5: -------------------------------------------------------------------------------- 1 | 43389ec63781028be9cb04b854d2ed0a google-chrome-stable_50.0.2661.86_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_50.0.2661.86_amd64.sha: -------------------------------------------------------------------------------- 1 | 72c9ac895ba433db68c02291090852b5943a49aa google-chrome-stable_50.0.2661.86_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_50.0.2661.87_amd64.md5: -------------------------------------------------------------------------------- 1 | 43389ec63781028be9cb04b854d2ed0a google-chrome-stable_50.0.2661.87_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_50.0.2661.87_amd64.sha: -------------------------------------------------------------------------------- 1 | 72c9ac895ba433db68c02291090852b5943a49aa google-chrome-stable_50.0.2661.87_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_50.0.2661.94_amd64.md5: -------------------------------------------------------------------------------- 1 | 160452ed091c30dbb2dd6c4fdaf9e345 google-chrome-stable_50.0.2661.94_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_50.0.2661.94_amd64.sha: -------------------------------------------------------------------------------- 1 | 1b9aa36ce094378bda1e20a1301edfaa5685f91f google-chrome-stable_50.0.2661.94_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_51.0.2704.103_amd64.md5: -------------------------------------------------------------------------------- 1 | e7cbfbba31cf8ff70d0f967bdbc7a225 google-chrome-stable_51.0.2704.103_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_51.0.2704.103_amd64.sha: -------------------------------------------------------------------------------- 1 | d91c0143a50d60b1d0a6decccf87a290ca7c34d0 google-chrome-stable_51.0.2704.103_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_51.0.2704.106_amd64.md5: -------------------------------------------------------------------------------- 1 | 14103d3e38d1cd1cafabe823967e2f32 google-chrome-stable_51.0.2704.106_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_51.0.2704.106_amd64.sha: -------------------------------------------------------------------------------- 1 | 2a9246cae2dbf03a42a716dd7118a8fc6c545c93 google-chrome-stable_51.0.2704.106_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_51.0.2704.63_amd64.md5: -------------------------------------------------------------------------------- 1 | dfe4241f97e74856f828fc454a28da47 google-chrome-stable_51.0.2704.63_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_51.0.2704.63_amd64.sha: -------------------------------------------------------------------------------- 1 | 08aa2ea1ac414ebd3bbac1825d51ab34b40c6c48 google-chrome-stable_51.0.2704.63_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_51.0.2704.79_amd64.md5: -------------------------------------------------------------------------------- 1 | 7b4837870786ac6649ce5f21a31db56b google-chrome-stable_51.0.2704.79_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_51.0.2704.79_amd64.sha: -------------------------------------------------------------------------------- 1 | 7f64d64ff267c9ec0271f58fa4aa0b60456e0006 google-chrome-stable_51.0.2704.79_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_51.0.2704.84_amd64.md5: -------------------------------------------------------------------------------- 1 | 627b0face2df4c77557e2c9e4ed14608 google-chrome-stable_51.0.2704.84_amd64.deb 2 | -------------------------------------------------------------------------------- /binaries/google-chrome-stable_51.0.2704.84_amd64.sha: -------------------------------------------------------------------------------- 1 | 12c4c6723ee12cc4c7f907895e7fec907eadb529 google-chrome-stable_51.0.2704.84_amd64.deb 2 | -------------------------------------------------------------------------------- /browsermobproxy/bin/browsermob-proxy: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | BASEDIR=`dirname $0`/.. 4 | BASEDIR=`(cd "$BASEDIR"; pwd)` 5 | 6 | # if user has not explicitly set a command to use to invoke java, use 'java' and assume it is on the path 7 | if [ -z "$JAVACMD" ] 8 | then 9 | JAVACMD="java" 10 | fi 11 | 12 | "$JAVACMD" $JAVA_OPTS \ 13 | -Dapp.name="browsermob-proxy" \ 14 | -Dbasedir="$BASEDIR" \ 15 | -jar "$BASEDIR/lib/browsermob-dist-2.1.4.jar" \ 16 | --port ${ENV_BROWSERMOBPROXY_PORT:-8080} 17 | "$@" 18 | 19 | # if we couldn't find java, print a helpful error message 20 | if [ $? -eq 127 ] 21 | then 22 | echo 23 | echo "Unable to run java using command: $JAVACMD" 24 | echo "Make sure java is installed and on the path, or set JAVACMD to the java executable before running this script." 25 | echo 26 | echo "Example:" 27 | echo 28 | echo " $ JAVACMD=/var/lib/jdk/bin/java ./browsermob-proxy" 29 | echo 30 | fi 31 | -------------------------------------------------------------------------------- /browsermobproxy/etc/supervisor/conf.d/browsermobproxy.conf: -------------------------------------------------------------------------------- 1 | [program:browsermobproxy] 2 | 3 | ;The relative priority of the program in the start and shutdown ordering. 4 | ;Lower priorities indicate programs that start first and shut down last. 5 | priority=95 6 | 7 | ;User to run-as, note environment expansion outside of `command` is only 8 | ;supported in supervisor >= 3.2 9 | ;user=seluser 10 | 11 | ;The command that will be run when this program is started. 12 | ;Controlled programs should themselves not be daemons, as supervisord 13 | ;assumes it is responsible for daemonizing its subprocesses 14 | directory=/home/seluser 15 | command=%(ENV_BIN_UTILS)s/browsermob-proxy 16 | 17 | ;If true, this program will start automatically when supervisord is started. 18 | ;default=true 19 | autostart=%(ENV_BROWSERMOBPROXY_START)s 20 | 21 | ;If false, the process will never be autorestarted. 22 | ;If true, the process will be unconditionally restarted when it exits, 23 | ;without regard to its exit code. default=unexpected 24 | ;If unexpected, the process will be restart when the program exits with an 25 | ;exit code that is not one of the exit codes associated with this process. 26 | autorestart=unexpected 27 | 28 | ;Set to 0 to indicate that the program needn’t stay running for any 29 | ;particular amount of time. 30 | ;So using custom wait-xxxx.sh scripts to perform a more efficient 31 | ;active waiting until https://github.com/Supervisor/supervisor/issues/584 32 | startsecs=2 33 | 34 | ;The number of serial failure attempts that supervisord will allow when 35 | ;attempting to start the program before giving up and puting the process 36 | ;into an FATAL state. 37 | startretries=3 38 | 39 | ;Logs 40 | redirect_stderr=false 41 | stdout_logfile=%(ENV_LOGS_DIR)s/browsermobproxy-stdout.log 42 | stderr_logfile=%(ENV_LOGS_DIR)s/browsermobproxy-stderr.log 43 | stdout_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 44 | stderr_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 45 | stdout_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 46 | stderr_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 47 | stdout_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 48 | stderr_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 49 | 50 | ;The signal used to kill the program when a stop is requested. This can be 51 | ;any of TERM, HUP, INT, QUIT, KILL, USR1, or USR2. default=TERM 52 | stopsignal=%(ENV_BROWSERMOBPROXY_STOP_SIGNAL)s 53 | -------------------------------------------------------------------------------- /capabilities.json: -------------------------------------------------------------------------------- 1 | { 2 | "caps": [ 3 | { 4 | "BROWSER_NAME": "chrome", 5 | "VERSION": "91.0.4472.77", 6 | "PLATFORM": "LINUX" 7 | }, 8 | { 9 | "BROWSER_NAME": "firefox", 10 | "VERSION": "88.0.1", 11 | "PLATFORM": "LINUX" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /dns/bin/improve_etc_hosts.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Note: In OSX use docker.for.mac.localhost 4 | 5 | cat /tmp/hosts >> /etc/hosts 6 | 7 | if [ "${DOCKER_HOST_IP}" != "" ]; then 8 | echo "${DOCKER_HOST_IP} docker.host" >> /etc/hosts 9 | echo "${DOCKER_HOST_IP} docker.host.dev" >> /etc/hosts 10 | echo "${DOCKER_HOST_IP} d.host.loc.dev" >> /etc/hosts 11 | echo "${DOCKER_HOST_IP} host.docker.local" >> /etc/hosts 12 | echo "${DOCKER_HOST_IP} host.docker" >> /etc/hosts 13 | fi 14 | 15 | if [ "${CONTAINER_IP}" != "" ]; then 16 | echo "${CONTAINER_IP} docker.guest" >> /etc/hosts 17 | echo "${CONTAINER_IP} docker.guest.dev" >> /etc/hosts 18 | echo "${CONTAINER_IP} guest.docker.local" >> /etc/hosts 19 | echo "${CONTAINER_IP} d.guest.loc.dev" >> /etc/hosts 20 | echo "${CONTAINER_IP} guest.docker" >> /etc/hosts 21 | fi 22 | -------------------------------------------------------------------------------- /dns/etc/hosts: -------------------------------------------------------------------------------- 1 | 10.0.2.2 my_internal_web_server.local 2 | -------------------------------------------------------------------------------- /docker-compose-host.yml: -------------------------------------------------------------------------------- 1 | version: '2.1' 2 | 3 | services: 4 | hub: 5 | image: elgalu/selenium 6 | network_mode: host 7 | volumes: 8 | - /dev/shm:/dev/shm 9 | privileged: true 10 | environment: 11 | - SELENIUM_HUB_PORT=${SELENIUM_HUB_PORT-4444} 12 | - PICK_ALL_RANDOM_PORTS=true 13 | - GRID=true 14 | - CHROME=false 15 | - FIREFOX=false 16 | 17 | chrome: 18 | image: elgalu/selenium 19 | network_mode: host 20 | volumes: 21 | - /dev/shm:/dev/shm 22 | privileged: true 23 | environment: 24 | - SELENIUM_HUB_PORT=${SELENIUM_HUB_PORT-4444} 25 | - PICK_ALL_RANDOM_PORTS=true 26 | - GRID=false 27 | - CHROME=true 28 | - FIREFOX=false 29 | 30 | firefox: 31 | image: elgalu/selenium 32 | network_mode: host 33 | volumes: 34 | - /dev/shm:/dev/shm 35 | privileged: true 36 | environment: 37 | - SELENIUM_HUB_PORT=${SELENIUM_HUB_PORT-4444} 38 | - PICK_ALL_RANDOM_PORTS=true 39 | - GRID=false 40 | - CHROME=false 41 | - FIREFOX=true 42 | 43 | mock: 44 | image: elgalu/google_adwords_mock 45 | network_mode: host 46 | tty: true 47 | environment: 48 | - MOCK_SERVER_PORT=8280 49 | -------------------------------------------------------------------------------- /docker-compose-scales.yml: -------------------------------------------------------------------------------- 1 | # The purpose of this -scales example is to run 1 hub, N chromes, N firefox 2 | # 3 | # Usage: 4 | # docker-compose -f docker-compose-scales.yml -p grid up --force-recreate 5 | # How to scale it: 6 | # docker-compose -f docker-compose-scales.yml -p grid scale hub=1 chrome=2 firefox=1 7 | version: '3' 8 | 9 | services: 10 | hub: 11 | image: elgalu/selenium 12 | ports: 13 | - 4444:4444 14 | volumes: 15 | - /dev/shm:/dev/shm 16 | privileged: true 17 | environment: 18 | - SELENIUM_HUB_HOST=hub 19 | - SELENIUM_HUB_PORT=4444 20 | - GRID=true 21 | - CHROME=false 22 | - FIREFOX=false 23 | 24 | chrome: 25 | image: elgalu/selenium 26 | depends_on: 27 | - hub 28 | volumes: 29 | - /dev/shm:/dev/shm 30 | privileged: true 31 | environment: 32 | - SELENIUM_HUB_HOST=hub 33 | - SELENIUM_HUB_PORT=4444 34 | - SELENIUM_NODE_HOST={{CONTAINER_IP}} 35 | - SCREEN_WIDTH=1300 36 | - SCREEN_HEIGHT=999 37 | - VIDEO=false 38 | - AUDIO=false 39 | - GRID=false 40 | - CHROME=true 41 | - FIREFOX=false 42 | 43 | firefox: 44 | image: elgalu/selenium 45 | depends_on: 46 | - hub 47 | volumes: 48 | - /dev/shm:/dev/shm 49 | privileged: true 50 | environment: 51 | - SELENIUM_HUB_HOST=hub 52 | - SELENIUM_HUB_PORT=4444 53 | - SELENIUM_NODE_HOST={{CONTAINER_IP}} 54 | - SCREEN_WIDTH=1300 55 | - SCREEN_HEIGHT=999 56 | - VIDEO=false 57 | - AUDIO=false 58 | - GRID=false 59 | - CHROME=false 60 | - FIREFOX=true 61 | -------------------------------------------------------------------------------- /docker-compose-tests.yml: -------------------------------------------------------------------------------- 1 | # The purpose of this -test example is for the e2e tests of this project 2 | # 3 | # Usage: 4 | # docker-compose -p grid up --force-recreate 5 | # docker-compose -p grid scale mock=1 hub=1 chrome=3 firefox=3 6 | version: '2.1' 7 | 8 | services: 9 | hub: 10 | image: elgalu/selenium 11 | ports: 12 | # Note 24444 is the default SELENIUM_HUB_PORT inside the container 13 | # and 4444 will be mapped into your host for easy access. 14 | - 4444:4444 15 | # We need a fixed port range to expose VNC 16 | # due to a bug in Docker for Mac beta (1.12) 17 | # https://forums.docker.com/t/docker-for-mac-beta-not-forwarding-ports/8658/6 18 | - ${VNC_FROM_PORT-40650}-${VNC_TO_PORT-40700}:${VNC_FROM_PORT-40650}-${VNC_TO_PORT-40700} 19 | # e.g. (hard-coded) 20 | # - 40650-40700:40650-40700 21 | volumes: 22 | - /dev/shm:/dev/shm 23 | privileged: true 24 | environment: 25 | - DEBUG=false 26 | - PICK_ALL_RANDOM_PORTS=true 27 | - SELENIUM_HUB_HOST=hub 28 | - SELENIUM_HUB_PORT=4444 29 | - GRID=true 30 | - CHROME=false 31 | - FIREFOX=false 32 | - MOCK_SERVER_HOST=mock 33 | 34 | chrome: 35 | image: elgalu/selenium 36 | depends_on: 37 | - hub 38 | volumes: 39 | - /dev/shm:/dev/shm 40 | privileged: true 41 | environment: 42 | - DEBUG=false 43 | - PICK_ALL_RANDOM_PORTS=true 44 | - SELENIUM_HUB_HOST=hub 45 | - SELENIUM_HUB_PORT=4444 46 | - SELENIUM_NODE_HOST={{CONTAINER_IP}} 47 | - VNC_FROM_PORT=${VNC_FROM_PORT-40650} 48 | - VNC_TO_PORT=${VNC_TO_PORT-40700} 49 | - SCREEN_WIDTH=1300 50 | - SCREEN_HEIGHT=999 51 | - VIDEO=${VIDEO-false} 52 | - AUDIO=${AUDIO-false} 53 | - GRID=false 54 | - CHROME=true 55 | - FIREFOX=false 56 | 57 | firefox: 58 | image: elgalu/selenium 59 | depends_on: 60 | - hub 61 | volumes: 62 | - /dev/shm:/dev/shm 63 | privileged: true 64 | environment: 65 | - DEBUG=false 66 | - PICK_ALL_RANDOM_PORTS=true 67 | - SELENIUM_HUB_HOST=hub 68 | - SELENIUM_HUB_PORT=4444 69 | - SELENIUM_NODE_HOST={{CONTAINER_IP}} 70 | - VNC_FROM_PORT=${VNC_FROM_PORT-40650} 71 | - VNC_TO_PORT=${VNC_TO_PORT-40700} 72 | - SCREEN_WIDTH=1300 73 | - SCREEN_HEIGHT=999 74 | - VIDEO=${VIDEO-false} 75 | - AUDIO=${AUDIO-false} 76 | - GRID=false 77 | - CHROME=false 78 | - FIREFOX=true 79 | 80 | mock: 81 | image: elgalu/google_adwords_mock 82 | depends_on: 83 | - hub 84 | tty: true 85 | environment: 86 | - MOCK_SERVER_PORT=8280 87 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | # The purpose of this `docker-compose.yml` example is to run 1 hub, 1 chrome, 1 firefox 2 | # i.e. this example doesn't scale, but there is another file for that: docker-compose-scales.yml 3 | # i.e. this example doesn't support `docker-compose scale` 4 | # 5 | # If you try to scale this one you will get `Bind for 0.0.0.0:6080 failed: port is already allocated` 6 | # 7 | # Usage: 8 | # docker-compose -p grid up --force-recreate 9 | version: '3' 10 | 11 | services: 12 | hub: 13 | image: elgalu/selenium 14 | ports: 15 | - 4444:4444 16 | volumes: 17 | - /dev/shm:/dev/shm 18 | privileged: true 19 | environment: 20 | - SELENIUM_HUB_HOST=hub 21 | - SELENIUM_HUB_PORT=4444 22 | - GRID=true 23 | - CHROME=false 24 | - FIREFOX=false 25 | 26 | chrome: 27 | image: elgalu/selenium 28 | depends_on: 29 | - hub 30 | ports: 31 | # VNC: See what's going on by connecting your VNC client to 0.0.0.0:5900 32 | - 5900:25900 33 | # noVNC: See what's going on by hitting http://0.0.0.0:6080 in your browser 34 | # Important: http://127.0.0.1:6080 works but http://localhost:6080 doesn't 35 | - 6080:26080 36 | volumes: 37 | - /dev/shm:/dev/shm 38 | privileged: true 39 | environment: 40 | - NOVNC=true 41 | - SELENIUM_HUB_HOST=hub 42 | - SELENIUM_HUB_PORT=4444 43 | - SELENIUM_NODE_HOST={{CONTAINER_IP}} 44 | - SCREEN_WIDTH=1300 45 | - SCREEN_HEIGHT=999 46 | - VIDEO=false 47 | - AUDIO=false 48 | - GRID=false 49 | - CHROME=true 50 | - FIREFOX=false 51 | 52 | firefox: 53 | image: elgalu/selenium 54 | depends_on: 55 | - hub 56 | ports: 57 | # VNC: See what's going on by connecting your VNC client to 0.0.0.0:5901 58 | - 5901:25900 59 | # noVNC: See what's going on by hitting http://0.0.0.0:6081 in your browser 60 | - 6081:26080 61 | volumes: 62 | - /dev/shm:/dev/shm 63 | privileged: true 64 | environment: 65 | - NOVNC=true 66 | - SELENIUM_HUB_HOST=hub 67 | - SELENIUM_HUB_PORT=4444 68 | - SELENIUM_NODE_HOST={{CONTAINER_IP}} 69 | - SCREEN_WIDTH=1300 70 | - SCREEN_HEIGHT=999 71 | - VIDEO=false 72 | - AUDIO=false 73 | - GRID=false 74 | - CHROME=false 75 | - FIREFOX=true 76 | -------------------------------------------------------------------------------- /docs/docker-compose.md: -------------------------------------------------------------------------------- 1 | # Compose 2 | Scale up and down the nodes by using [docker-compose](https://docs.docker.com/compose/). 3 | 4 | For using it by sharing the host (localhost) network interface see [share-host](./share-host.md) 5 | 6 | For requirements check [README#requisites](../README.md#requisites) 7 | 8 | ## Usage 9 | Either clone this repository or download the file [docker-compose-tests.yml][] using `wget` 10 | 11 | wget -nv "https://raw.githubusercontent.com/elgalu/docker-selenium/latest/docker-compose-tests.yml" 12 | mv -f docker-compose-tests.yml docker-compose.yml 13 | docker-compose -p grid down #ensure is not already running 14 | 15 | ### Run 16 | Start it with `docker-compose up` then **scale** it: 17 | You should replace `mock` with your web service under test within the [docker-compose-tests.yml][] file. 18 | 19 | export NODES=3 VIDEO=false 20 | docker-compose -p grid up --force-recreate 21 | docker-compose -p grid scale chrome=${NODES} firefox=${NODES} 22 | 23 | Wait until the grid starts properly before starting the tests _(Optional but recommended)_ 24 | 25 | docker exec grid_hub_1 wait_all_done 30s 26 | for ((i=1; i<=${NODES}; i++)); do 27 | docker-compose -p grid exec -T --index=$i chrome wait_all_done 30s 28 | docker-compose -p grid exec -T --index=$i firefox wait_all_done 30s 29 | done 30 | 31 | ### Test 32 | You can now run your tests by using the `--seleniumUrl="http://localhost:4444/wd/hub"`. 33 | 34 | However if your web application under test is running in localhost, e.g. `--appHost=localhost` or is publicly not accessible 35 | you should instead either dockerize your application as shown in the example [adwords_mock](https://github.com/elgalu/google_adwords_mock) within the [docker-compose-tests.yml][]. Its there shown as another [service](https://docs.docker.com/compose/compose-file/#/service-configuration-reference). Another option (if you don't want to dockerize your app yet) is to somehow replace `--appHost=localhost` with `--appHost=d.host.loc.dev` in the config file of your testing framework. The string `d.host.loc.dev` is a place holder inside the docker container that points to the IP of your localhost. 36 | 37 | ## Docker Swarm mode 38 | You might get the following error if you try to run a `SELENIUM_NODE` as part of a Swarm stack: 39 | ``` 40 | $ docker stack deploy selenium 41 | Updating service selenium_selenium-chrome (id: joru9fw8xej2imcrvgblcrc85) 42 | failed to create service selenium_selenium-chrome: Error response from daemon: rpc error: code = InvalidArgument desc = expanding env failed: expanding env "SELENIUM_NODE_HOST={{CONTAINER_IP}}": template: expansion:1: function "CONTAINER_IP" not defined 43 | ``` 44 | Thanks to https://github.com/elgalu/docker-selenium/issues/236 you just have to update your variable `SELENIUM_NODE_HOST` to `{{__CONTAINER_IP__}}`. 45 | Example in a `docker-compose file`: 46 | ``` 47 | selenium-firefox: 48 | image: elgalu/selenium 49 | depends_on: 50 | - hub 51 | volumes: 52 | - /dev/shm:/dev/shm 53 | deploy: 54 | replicas: 3 55 | environment: 56 | - DEBUG=true 57 | - PICK_ALL_RANDOM_PORTS=true 58 | - SELENIUM_HUB_HOST=hub 59 | - SELENIUM_HUB_PORT=4444 60 | - SELENIUM_NODE_HOST={{__CONTAINER_IP__}} 61 | - SCREEN_WIDTH=1300 62 | - SCREEN_HEIGHT=999 63 | - VIDEO=false 64 | - AUDIO=false 65 | - GRID=false 66 | - CHROME=false 67 | - FIREFOX=true 68 | - MAX_INSTANCES=1 69 | - MAX_SESSIONS=1 70 | ``` 71 | 72 | 73 | ### Cleanup 74 | Once your tests are done you can clean up: 75 | 76 | docker-compose -p grid down 77 | 78 | The `down` compose command stops and remove containers, networks, volumes, and images created by `up` or `scale` 79 | 80 | [docker-compose-tests.yml]: ../docker-compose-tests.yml 81 | -------------------------------------------------------------------------------- /docs/gource.md: -------------------------------------------------------------------------------- 1 | # Grouce.io 2 | From a git repository history to [video visualization](https://youtu.be/OU7IdCSB_0E). 3 | 4 | [![video visualization](../images/gource.md)](https://youtu.be/OU7IdCSB_0E) 5 | 6 | ## Requirements 7 | Tested on Ubuntu 15.10 8 | 9 | sudo apt-get -qyy install ffmpeg libsdl2-dev libsdl2-image-dev \ 10 | libpcre3-dev libfreetype6-dev libglew-dev libglm-dev \ 11 | libboost-filesystem-dev libpng12-dev libtinyxml-dev 12 | 13 | ## Prepare 14 | 15 | wget "https://github.com/acaudwell/Gource/releases/download/gource-0.43/gource-0.43.tar.gz" 16 | tar xvzf gource-0.43.tar.gz 17 | cd gource-0.43 18 | ./configure && make 19 | 20 | ## Install 21 | 22 | sudo make install 23 | 24 | ## Usage 25 | 26 | gource -s 1 -c 2.0 -1280x720 -o gource.ppm 27 | ffmpeg -y -r 60 -f image2pipe -vcodec ppm -i gource.ppm \ 28 | -vcodec libx264 -preset medium -pix_fmt yuv420p \ 29 | -crf 1 -threads 0 -bf 0 gource.mp4 30 | -------------------------------------------------------------------------------- /docs/hub_and_nodes.md: -------------------------------------------------------------------------------- 1 | ## Grid 2 | The preferred way now is to use [docker-compose](./docker-compose.md) or keep reading if you don't want to use docker-compose. 3 | 4 | For even morealternatives see [hub_and_nodes_alternatives](./hub_and_nodes_alternatives.md) 5 | 6 | ## Hub 7 | Let's setup a grid and all the nodes on the same IP address than the host machine. 8 | 9 | Flags `-e CHROME=false -e FIREFOX=false` turn the container into a grid-only one. 10 | 11 | docker run -d --name=hub --net=host \ 12 | -e GRID=true -e CHROME=false -e FIREFOX=false \ 13 | -e VNC_START=false -e PICK_ALL_RANDOM_PORTS=true \ 14 | -e SELENIUM_HUB_PORT=4444 \ 15 | elgalu/selenium 16 | 17 | docker exec hub wait_all_done 30s 18 | 19 | This is how it should look like so far: 20 | 21 | ![docker-empty-selenium-grid](../images/empty_grid_console.png) 22 | 23 | ## Nodes 24 | Let's add some nodes 25 | 26 | ### Chrome 27 | Chrome will also attach to the `host` network interface. 28 | 29 | docker run -d --name=node1_ch --net=host \ 30 | -e GRID=false -e CHROME=true -e FIREFOX=false \ 31 | -e VNC_START=false -e PICK_ALL_RANDOM_PORTS=true \ 32 | -e SELENIUM_HUB_PORT=4444 \ 33 | --shm-size=1g \ 34 | elgalu/selenium 35 | 36 | ![docker-selenium-chrome-node](../images/chrome_grid_console.png) 37 | 38 | docker run -d --name=node2_ch --net=host \ 39 | -e GRID=false -e CHROME=true -e FIREFOX=false \ 40 | -e VNC_START=false -e PICK_ALL_RANDOM_PORTS=true \ 41 | -e SELENIUM_HUB_PORT=4444 \ 42 | --shm-size=1g \ 43 | elgalu/selenium 44 | 45 | ### Firefox 46 | Firefox will also attach to the host machine network interface. 47 | 48 | docker run -d --name=node3_ff --net=host \ 49 | -e GRID=false -e CHROME=false -e FIREFOX=true \ 50 | -e VNC_START=false -e PICK_ALL_RANDOM_PORTS=true \ 51 | -e SELENIUM_HUB_PORT=4444 \ 52 | --shm-size=1g \ 53 | elgalu/selenium 54 | 55 | ![docker-selenium-firefox-node](../images/firefox_grid_console.png) 56 | 57 | docker run -d --name=node4_ff --net=host \ 58 | -e GRID=false -e CHROME=false -e FIREFOX=true \ 59 | -e VNC_START=false -e PICK_ALL_RANDOM_PORTS=true \ 60 | -e SELENIUM_HUB_PORT=4444 \ 61 | --shm-size=1g \ 62 | elgalu/selenium 63 | 64 | ### Wait 65 | Is convenient to wait for all the nodes to start correctly, also to catch errors before starting the tests in vane: 66 | 67 | docker exec node1_ch wait_all_done 30s 68 | docker exec node2_ch wait_all_done 30s 69 | docker exec node3_ff wait_all_done 30s 70 | docker exec node4_ff wait_all_done 30s 71 | 72 | ### Finally 73 | 74 | This is the final sample grid 75 | 76 | ![docker-selenium-hub-4-nodes](../images/grid_4_nodes_random_ports_localhost.png) 77 | 78 | #### Diagram 79 | This is the docker diagram of that grid 80 | 81 | ![diagram-selenium-hub-4-nodes](../images/grid_4_nodes_diagram_host.png) 82 | 83 | ### Cleanup 84 | 85 | docker rm -vf hub node1_ch node2_ch node3_ff node4_ff || true 86 | -------------------------------------------------------------------------------- /docs/jenkins.md: -------------------------------------------------------------------------------- 1 | # Jenkins 2 | Follow the same procedure as explained in [docker-compose](./docker-compose.md) 3 | -------------------------------------------------------------------------------- /docs/make.md: -------------------------------------------------------------------------------- 1 | # Make 2 | 3 | ## Setup 4 | This is only necessary the first time: 5 | 6 | wget -nv https://git.io/vKrBP -O Makefile 7 | make get setup 8 | 9 | If you want VNC helpers support _(optional)_ 10 | 11 | make install_vnc 12 | 13 | You should now replace the `mock` example service with your web service under test within the generated [docker-compose.yml][] file. 14 | 15 | ### OSX 16 | In OSX is convenient to increase the Docker service CPUs and Memory specially if you plan to run more than one Chrome and Firefox at the same time: 17 | 18 | 19 | 20 | ## Usage 21 | Make sure to [setup](#setup) first. 22 | 23 | ### Run 24 | Run specifying how many nodes you need to run your tests. 25 | 26 | make chrome=2 firefox=2 27 | 28 | The idea of having *N* Chrome nodes and *N* Firefox nodes is to be able to run tests in parallel. Note *N* is `2` in this arbitrary example. 29 | 30 | ### VNC 31 | This will open the VNC viewer. 32 | 33 | make see browser=chrome node=1 34 | make see browser=firefox node=1 35 | 36 | ### Test 37 | The best way is to run your tests inside your web application under test, in this case is called `mock` 38 | 39 | docker exec -t grid_mock_1 \ 40 | npm test --seleniumUrl="http://localhost:4444/wd/hub" 41 | 42 | ### Videos 43 | Gather the videos artifacts easily 44 | 45 | export chrome=2 firefox=2 46 | make videos 47 | 48 | ### Cleanup 49 | When done, is convenient to shutdown all the containers. 50 | 51 | make down 52 | 53 | ## Update 54 | To update latest version of this docker image either `docker pull elgalu/selenium` or simply: 55 | 56 | make pull 57 | 58 | Every now and then you will want to upgrade the script files [.menv](../.menv), [docker-compose.yml][], [mk/](../mk) and so on. 59 | But given the upgrades are destructive is better to git clone this repository and do `git pull` from time to time. 60 | If you make changes to these config files locally git will advise how to merge latest changes and you will be safe of losing your customizations. 61 | 62 | ### Git setup 63 | git clone https://github.com/elgalu/docker-selenium.git 64 | 65 | ### Git upgrades 66 | git pull 67 | make pull 68 | 69 | [docker-compose.yml]: ../docker-compose.yml 70 | -------------------------------------------------------------------------------- /docs/share-host.md: -------------------------------------------------------------------------------- 1 | # Share the host 2 | Scale up and down the nodes locally in Linux by using sharing the host (localhost) network interface [docker-compose](https://docs.docker.com/compose/). 3 | 4 | For using it non-Linux machines or, in general, by not sharing the host (localhost) network interface see [docker-compose](./docker-compose.md) 5 | 6 | For requirements check [README#requisites](../README.md#requisites) 7 | 8 | ## Usage 9 | Either clone this repository or download the file [docker-compose-host.yml][] using `wget` 10 | 11 | wget -nv "https://raw.githubusercontent.com/elgalu/docker-selenium/latest/docker-compose-host.yml" 12 | mv -f docker-compose-host.yml docker-compose.yml 13 | docker-compose -p grid down #ensure is not already running 14 | 15 | ### Run 16 | Either start with `docker-compose ... scale` as shown in below example or you can also use `docker-compose up` and scale after in a second command. 17 | You should replace `mock` with your web service under test within the [docker-compose-host.yml][] file.. 18 | 19 | export NODES=3 20 | docker-compose -p grid scale mock=1 hub=1 chrome=${NODES} firefox=${NODES} 21 | 22 | Wait until the grid starts properly before starting the tests _(Optional but recommended)_ 23 | 24 | docker exec grid_hub_1 wait_all_done 30s 25 | for ((i=1; i<=${NODES}; i++)); do 26 | docker-compose -p grid exec -T --index=$i chrome wait_all_done 30s 27 | docker-compose -p grid exec -T --index=$i firefox wait_all_done 30s 28 | done 29 | 30 | ### Test 31 | You can now run your tests by using the `--seleniumUrl="http://localhost:4444/wd/hub"`. 32 | Because we use the `network_mode: host` feature everything will run in `localhost` so is transparent to use at a networking level and you don't need to worry about it just run test web application under test in localhost, a.k.a. `127.0.0.1` 33 | 34 | ### Cleanup 35 | Once your tests are done you can clean up: 36 | 37 | docker-compose -p grid down 38 | 39 | The `down` compose command stops and remove containers, networks, volumes, and images created by `up` or `scale` 40 | 41 | [docker-compose-host.yml]: ../docker-compose-host.yml 42 | -------------------------------------------------------------------------------- /docs/videos.md: -------------------------------------------------------------------------------- 1 | # Video Recording 2 | 3 | ## Step by step 4 | 5 | ### Pull 6 | Pull image 7 | 8 | docker pull elgalu/selenium 9 | 10 | ### Run 11 | Run a new grid 12 | 13 | docker run --rm --name=grid -p 4444:24444 -p 5920:25900 \ 14 | --shm-size=2g -e VNC_PASSWORD=hola \ 15 | -e VIDEO=true elgalu/selenium 16 | 17 | ### Wait 18 | Wait for the grid to start 19 | 20 | docker exec grid wait_all_done 30s 21 | 22 | ## Check 23 | Check your grid has Chrome and Firefox. 24 | OSX: replace `localhost` with `boot2docker ip` or `docker-machine ip default`. 25 | 26 | open http://localhost:4444/grid/console 27 | 28 | ### Test 29 | Run your tests 30 | 31 | #at http://localhost:4444/wd/hub 32 | 33 | ### Stop 34 | Stopping the grid will also stop video recording and close the file properly. 35 | However is better to stop the video service first then copy the videos to the host machine. 36 | 37 | docker exec grid stop-video 38 | mkdir -p ./videos 39 | docker cp grid:/videos/. videos 40 | 41 | ### Finalize 42 | docker exec grid stop 43 | docker stop grid 44 | 45 | ### View 46 | Check your video, note it may be splitted in many files if is too long 47 | 48 | vlc videos/test.mp4 49 | 50 | ## Customizations 51 | 52 | ### Audio 53 | If you want to additionaly record audio with the video use this 54 | 55 | docker run --rm --name=grid -p 4444:24444 -p 5920:25900 \ 56 | --shm-size=2g -e VNC_PASSWORD=hola \ 57 | -e VIDEO=true \ 58 | -e AUDIO=true elgalu/selenium 59 | 60 | ### Start 61 | Start and stop on-demand 62 | 63 | docker exec grid start-video 64 | 65 | Now run your tests 66 | 67 | Then stop. Follow the steps in the [Stop](#stop) section 68 | -------------------------------------------------------------------------------- /host-scripts/gen-scm-source.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | GIT_AUTHOR=lgallucci 4 | GIT_URL="https://github.com/elgalu/docker-selenium" 5 | GIT_SHA1=$(git rev-parse HEAD) 6 | # Optional SCM working directory status information. Might contain git status output for example 7 | # GIT_STATUS=$(git describe --all) 8 | 9 | cat >scm-source.json < ${CURVERSION}.tar 36 | # fi 37 | -------------------------------------------------------------------------------- /host-scripts/install_minishift.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | # set -u: treat unset variables as an error and exit immediately 5 | # set -x: print each command right before it is executed 6 | set -ex 7 | 8 | echoerr() { printf "%s\n" "$*" >&2; } 9 | 10 | # print error and exit 11 | die () { 12 | echoerr "ERROR: $1" 13 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "3" 14 | errnum=${2-3} 15 | exit $errnum 16 | } 17 | 18 | # Required params 19 | [ -z "${USER}" ] && die "Need env var USER" 20 | 21 | # Add yourself to the libvirtd group 22 | sudo usermod -a -G libvirtd ${USER} 23 | # Update your current session to apply the group change 24 | # newgrp libvirtd 25 | 26 | ## Minishift binary 27 | mkdir -p /tmp/minishift 28 | cd /tmp/minishift 29 | wget -nv -O minishift.tgz \ 30 | "https://github.com/minishift/minishift/releases/download/v1.6.0/minishift-1.6.0-linux-amd64.tgz" 31 | tar xzf minishift.tgz 32 | ./minishift version 33 | 34 | sudo virt-manager 35 | 36 | # sudo service libvirtd start 37 | # sudo libvirtd 38 | 39 | ## docker-machine-driver-kvm 40 | wget -nv -O dmdkvm \ 41 | "https://github.com/dhiltgen/docker-machine-kvm/releases/download/v0.10.0/docker-machine-driver-kvm-ubuntu16.04" 42 | chmod +x dmdkvm 43 | # (./dmdkvm 2>&1 | grep "invoked directly") || ./dmdkvm || echo "WARN: dmdkvm won't work" 44 | (./dmdkvm 2>&1 | grep "invoked directly") || ./dmdkvm || true 45 | 46 | sudo mv minishift /usr/bin/ 47 | sudo mv dmdkvm /usr/local/bin/docker-machine-driver-kvm 48 | rm -rf /tmp/minishift/ 49 | 50 | # Start will also wget minishift-b2d.iso 51 | # (Memory: 2GB, vCPUs: 2, Disk size: 20 GB) 52 | sudo kvm-ok 53 | # TravisCI: INFO: Your CPU does not support KVM extensions 54 | 55 | # Starts a local OpenShift cluster 56 | minishift start 57 | minishift status | grep -i "Running" 58 | 59 | eval $(minishift oc-env) 60 | 61 | 62 | ## Zalenium 63 | oc login -u system:admin 64 | -------------------------------------------------------------------------------- /host-scripts/install_vnc.sh: -------------------------------------------------------------------------------- 1 | ../mk/install_vnc.sh -------------------------------------------------------------------------------- /host-scripts/loop-wait-docker.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | echoerr() { printf "%s\n" "$*" >&2; } 7 | 8 | # print error and exit 9 | die () { 10 | echoerr "ERROR: $1" 11 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "3" 12 | errnum=${2-3} 13 | exit $errnum 14 | } 15 | 16 | # Required params 17 | [ -z "$1" ] && die "Need 1st argument: CONTAINER_ID" 18 | CONTAINER_ID=${1} 19 | 20 | echo -n "Waiting for docker-selenium to be ready..." 21 | while ! docker exec ${CONTAINER_ID} \ 22 | grep 'Container docker internal IP' /var/log/cont/xterm-stdout.log \ 23 | > /dev/null 2>&1; do 24 | echo -n '.' 25 | sleep 0.2; 26 | done 27 | -------------------------------------------------------------------------------- /host-scripts/see.sh: -------------------------------------------------------------------------------- 1 | ../mk/see.sh -------------------------------------------------------------------------------- /host-scripts/wait-docker-selenium.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | echoerr() { printf "%s\n" "$*" >&2; } 7 | 8 | # print error and exit 9 | die () { 10 | echoerr "ERROR: $1" 11 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "3" 12 | errnum=${2-3} 13 | exit $errnum 14 | } 15 | 16 | # Required params 17 | [ -z "$1" ] && die "Need 1st argument: CONTAINER_ID" 18 | CONTAINER_ID=${1} 19 | 20 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "7s" 21 | WAIT_TIMEOUT=${2-7s} 22 | 23 | # default $TAIL_LOG_LINES when not provided 24 | TAIL_LOG_LINES=${TAIL_LOG_LINES-10} 25 | 26 | # Full directory name of the script no matter where it is being called from 27 | DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) 28 | LOOP_SCRIPT_PATH="${DIR}/loop-wait-docker.sh" 29 | 30 | if [ ! -f "${LOOP_SCRIPT_PATH}" ]; then 31 | die "Need '${LOOP_SCRIPT_PATH}' to exist!" 32 | fi 33 | 34 | # Avoid waiting forever using the `timeout` command 35 | if timeout --foreground ${WAIT_TIMEOUT} \ 36 | ${LOOP_SCRIPT_PATH} ${CONTAINER_ID}; then 37 | echo "" 38 | docker exec ${CONTAINER_ID} \ 39 | grep 'password' /var/log/cont/vnc-stdout.log || true 40 | docker exec ${CONTAINER_ID} \ 41 | grep 'IP:' /var/log/cont/xterm-stdout.log || die "Failed to grep IP:" 42 | else 43 | docker exec ${CONTAINER_ID} \ 44 | bash -c 'tail --lines=${TAIL_LOG_LINES} /var/log/cont/*' || true 45 | echo "" && echo "" && echo "==> errors <==" 46 | docker exec ${CONTAINER_ID} \ 47 | bash -c 'errors' || true 48 | 49 | die " 50 | Your docker-selenium didn't start properly. 51 | Start it next time with -e DISABLE_ROLLBACK=true 52 | " 53 | fi 54 | 55 | -------------------------------------------------------------------------------- /host-scripts/wait.sh: -------------------------------------------------------------------------------- 1 | ../mk/wait.sh -------------------------------------------------------------------------------- /images/Docker_Mac_CPUs_Memory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/Docker_Mac_CPUs_Memory.png -------------------------------------------------------------------------------- /images/chrome_grid_console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/chrome_grid_console.png -------------------------------------------------------------------------------- /images/completed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/completed.png -------------------------------------------------------------------------------- /images/empty_grid_console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/empty_grid_console.png -------------------------------------------------------------------------------- /images/failure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/failure.png -------------------------------------------------------------------------------- /images/firefox_grid_console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/firefox_grid_console.png -------------------------------------------------------------------------------- /images/ga-datastudio-docker-selenium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/ga-datastudio-docker-selenium.png -------------------------------------------------------------------------------- /images/gource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/gource.png -------------------------------------------------------------------------------- /images/grid2_console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/grid2_console.png -------------------------------------------------------------------------------- /images/grid3_console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/grid3_console.png -------------------------------------------------------------------------------- /images/grid_4_nodes_diagram_host.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/grid_4_nodes_diagram_host.png -------------------------------------------------------------------------------- /images/grid_4_nodes_diagram_seleniums.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/grid_4_nodes_diagram_seleniums.png -------------------------------------------------------------------------------- /images/grid_4_nodes_random_ports.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/grid_4_nodes_random_ports.png -------------------------------------------------------------------------------- /images/grid_4_nodes_random_ports_localhost.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/grid_4_nodes_random_ports_localhost.png -------------------------------------------------------------------------------- /images/icons/BIG_NOODLE_TITLING.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/icons/BIG_NOODLE_TITLING.TTF -------------------------------------------------------------------------------- /images/icons/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/icons/logo.png -------------------------------------------------------------------------------- /images/icons/logo_25px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/icons/logo_25px.png -------------------------------------------------------------------------------- /images/icons/logo_40px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/icons/logo_40px.png -------------------------------------------------------------------------------- /images/icons/logo_wide.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/icons/logo_wide.jpg -------------------------------------------------------------------------------- /images/icons/logo_wide_transp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/icons/logo_wide_transp.png -------------------------------------------------------------------------------- /images/message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/message.png -------------------------------------------------------------------------------- /images/success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/success.png -------------------------------------------------------------------------------- /images/timeout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/timeout.png -------------------------------------------------------------------------------- /images/wallpaper-dosel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/wallpaper-dosel.png -------------------------------------------------------------------------------- /images/wallpaper-zalenium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/images/wallpaper-zalenium.png -------------------------------------------------------------------------------- /java/bin/java-dynamic-memory-opts.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echoerr() { printf "%s\n" "$*" >&2; } 4 | 5 | # print error and exit 6 | die () { 7 | echoerr "ERROR: $1" 8 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "1" 9 | errnum=${2-1} 10 | exit $errnum 11 | } 12 | 13 | # Example usage: 14 | # exec java $(java-dynamic-memory-opts.sh) -jar myfatjar.jar 15 | 16 | # JVM uses only 1/4 of system memory by default 17 | # set at Dockerfile or via docker run: MEM_JAVA_PERCENT=80 18 | # Required env vars validations 19 | [ -z "${MEM_JAVA_PERCENT}" ] && die "Need to set env var MEM_JAVA_PERCENT" 20 | 21 | MEM_TOTAL_KB=0 22 | 23 | CGROUP_LIMIT=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes) 24 | if [ $CGROUP_LIMIT -ne 9223372036854771712 ] && [ $CGROUP_LIMIT -gt 0 ] ; then 25 | MEM_TOTAL_KB=$CGROUP_LIMIT/1000 26 | else 27 | MEM_TOTAL_KB=$(cat /proc/meminfo | grep MemTotal | awk '{print $2}') 28 | fi 29 | MEM_JAVA_KB=$((${MEM_TOTAL_KB} * ${MEM_JAVA_PERCENT} / 100)) 30 | [ -z "${MEM_JAVA}" ] && export MEM_JAVA="${MEM_JAVA_KB}k" 31 | 32 | echo "-Xmx${MEM_JAVA}" 33 | -------------------------------------------------------------------------------- /lib/libpolyfill.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/lib/libpolyfill.so -------------------------------------------------------------------------------- /lib/libstderred.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/lib/libstderred.so -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elgalu/docker-selenium/8bdbd06d2a288936e5d7142ac7956f6f67b4c70c/logo.png -------------------------------------------------------------------------------- /mk/gather_videos.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | # set -u: treat unset variables as an error and exit immediately 5 | set -e 6 | set -u 7 | 8 | echoerr() { printf "%s\n" "$*" >&2; } 9 | 10 | # print error and exit 11 | die () { 12 | echoerr "ERROR: $1" 13 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "3" 14 | errnum=${2-3} 15 | exit $errnum 16 | } 17 | 18 | [ -z "${COMPOSE_FILE}" ] && die "Need env var COMPOSE_FILE" 19 | [ -z "${proj}" ] && die "Need env var proj" 20 | [ -z "${browser}" ] && die "Need env var browser" 21 | [ -z "${node}" ] && die "Need env var node" 22 | [ -z "${tot_nodes}" ] && die "Need env var tot_nodes" 23 | 24 | # Gather actual container name as hard-coding it is unreliable 25 | CONT_NAME=$(docker ps --filter status=running --filter "name=${proj}_${browser}_${node}" --format "{{.Names}}" -q) 26 | 27 | # set -x: print each command right before it is executed 28 | set -x 29 | 30 | mkdir -p ./videos 31 | 32 | for node in $(seq -s ' ' 1 ${tot_nodes}); do 33 | docker-compose -f ${COMPOSE_FILE} -p ${proj} exec --index=${node} ${browser} stop-video \ 34 | >./mk/stop_video_${browser}_${node}.log || true 35 | docker cp "${CONT_NAME}:/videos/." videos 36 | docker-compose -f ${COMPOSE_FILE} -p ${proj} exec --index=${node} ${browser} rm_videos || true 37 | docker-compose -f ${COMPOSE_FILE} -p ${proj} exec --index=${node} ${browser} start-video 38 | done 39 | 40 | ls -la ./videos/ 41 | -------------------------------------------------------------------------------- /mk/install_vnc.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -x: print each command right before it is executed 4 | # set -e: exit asap if a command exits with a non-zero status 5 | set -e 6 | # set -u: treat unset variables as an error and exit immediately 7 | set -u 8 | 9 | echoerr() { printf "%s\n" "$*" >&2; } 10 | 11 | # print error and exit 12 | die () { 13 | echoerr "ERROR: $1" 14 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "3" 15 | errnum=${2-3} 16 | exit $errnum 17 | } 18 | 19 | # http://stackoverflow.com/a/8996924/511069 20 | md5_sum() { 21 | if builtin command -v md5 > /dev/null; then 22 | echo "md5" 23 | elif builtin command -v md5sum > /dev/null ; then 24 | echo "md5sum" 25 | else 26 | die "Neither md5 nor md5sum were found in the PATH" 27 | fi 28 | return 0 29 | } 30 | 31 | cd mk 32 | if [ "$(uname)" = 'Darwin' ]; then 33 | echo "Will install '${VNC_CLIENT_NAME}' for OSX" 34 | echo "${VNC_MD5SUM_OSX} ${VNC_FILE_OSX}" > vnc_osx.md5 35 | if [ ! -f "${VNC_FILE_OSX}" ]; then 36 | wget -nv "${VNC_DOWNLOAD_BASE_URL}/${VNC_FILE_OSX}" 37 | fi 38 | $(md5_sum) -r vnc_osx.md5 39 | # https://github.com/caskroom/homebrew-cask/blob/master/USAGE.md#other-ways-to-specify-a-cask 40 | brew cask install ./vnc_cask.rb --force 41 | else 42 | echo "Will install '${VNC_CLIENT_NAME}' for Linux" 43 | echo "${VNC_MD5SUM_LINUX} ${VNC_FILE_LINUX}" > vnc_linux.md5 44 | if [ ! -f "${VNC_FILE_LINUX}" ]; then 45 | wget -nv "${VNC_DOWNLOAD_BASE_URL}/${VNC_FILE_LINUX}" 46 | fi 47 | $(md5_sum) --check vnc_linux.md5 48 | tar xzf ${VNC_FILE_LINUX} 49 | rm -f "VNC-Server-${VNC_CLIENT_VERSION}-Linux-x64.deb" 50 | INST_CMD="sudo dpkg -i VNC-Viewer-${VNC_CLIENT_VERSION}-Linux-x64.deb" 51 | echo "About to: '${INST_CMD}'" 52 | if ! eval "${INST_CMD}"; then 53 | echoerr "Please install manually with sudo or open this deb file to install it:" 54 | echoerr "${INST_CMD}" 55 | fi 56 | # Uninstall with: 57 | # sudo apt-get -qyy remove realvnc-vnc-viewer 58 | fi 59 | cd .. 60 | -------------------------------------------------------------------------------- /mk/install_wmctrl.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | # set -x: print each command right before it is executed 5 | # set -u: treat unset variables as an error and exit immediately 6 | set -e 7 | set -u 8 | 9 | echoerr() { printf "%s\n" "$*" >&2; } 10 | 11 | # print error and exit 12 | die () { 13 | echoerr "ERROR: $1" 14 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "3" 15 | errnum=${2-3} 16 | exit $errnum 17 | } 18 | 19 | if [ "$(uname)" = 'Darwin' ]; then 20 | die "Sorry: moving windows with wmctrl in OSX is not properly supported." 21 | #----------------------------------------------------------------- 22 | echo "Will install wmctrl for OSX" 23 | set -x 24 | brew cask install xquartz 25 | # https://github.com/Homebrew/homebrew-x11/blob/master/wmctrl.rb 26 | brew install homebrew/x11/wmctrl 27 | else 28 | echo "Will install wmctrl for Linux" 29 | INST_CMD="sudo apt-get -qyy install wmctrl" 30 | echo "About to: '${INST_CMD}'" 31 | if ! eval "${INST_CMD}"; then 32 | echoerr "Please install wmctrl manually with sudo or open this deb file to install it:" 33 | echoerr "${INST_CMD}" 34 | fi 35 | # Uninstall with: 36 | # sudo apt-get -qyy remove wmctrl 37 | fi 38 | -------------------------------------------------------------------------------- /mk/move.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | # set -u: treat unset variables as an error and exit immediately 5 | set -e 6 | set -u 7 | 8 | echoerr() { printf "%s\n" "$*" >&2; } 9 | 10 | # print error and exit 11 | die () { 12 | echoerr "ERROR: $1" 13 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "3" 14 | errnum=${2-3} 15 | exit $errnum 16 | } 17 | 18 | if [ "$(uname)" = 'Darwin' ]; then 19 | die "Sorry: moving windows with wmctrl in OSX is not properly supported." 20 | fi 21 | 22 | DISP="$(docker exec ${COMPOSE_PROJ_NAME}_${browser}_${node} cat DISPLAY)" 23 | CONT_HOSTNAME=$(docker exec ${COMPOSE_PROJ_NAME}_${browser}_${node} hostname) 24 | WIN_TITLE="${CONT_HOSTNAME}${DISP} - VNC Viewer" 25 | 26 | if [ "${browser}" = "chrome" ] && [ "${node}" = "1" ]; then 27 | # NorthWest(1)0,0 28 | set -x && wmctrl -r "${WIN_TITLE}" -e 1,0,0,-1,-1 29 | elif [ "${browser}" = "firefox" ] && [ "${node}" = "1" ]; then 30 | # NorthEast(3)1920,0 31 | set -x && wmctrl -r "${WIN_TITLE}" -e 3,1920,0,-1,-1 32 | else 33 | # TODO: make it smarter 34 | echo "-- TODO: Sorry I still don't know where to move ${browser} node: ${node}" 35 | fi 36 | -------------------------------------------------------------------------------- /mk/see.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | # set -u: treat unset variables as an error and exit immediately 5 | set -e 6 | set -u 7 | 8 | echoerr() { printf "%s\n" "$*" >&2; } 9 | 10 | # print error and exit 11 | die () { 12 | echoerr "ERROR: $1" 13 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "3" 14 | errnum=${2-3} 15 | exit $errnum 16 | } 17 | 18 | [ -z "${VNC_CLIENT}" ] && die "Need env var VNC_CLIENT" 19 | [ -z "${COMPOSE_PROJ_NAME}" ] && die "Need env var COMPOSE_PROJ_NAME" 20 | [ -z "${browser}" ] && die "Need env var browser" 21 | [ -z "${node}" ] && die "Need env var node" 22 | 23 | # Gather actual container name as hard-coding it is unreliable 24 | CONT_NAME=$(docker ps --filter status=running --filter "name=${COMPOSE_PROJ_NAME}_${browser}_${node}" --format "{{.Names}}" -q) 25 | IP=`docker inspect -f='{{.NetworkSettings.IPAddress}}' ${CONT_NAME}` 26 | 27 | if [ "${IP}" == "" ]; then 28 | IP=`docker inspect -f='{{json .NetworkSettings.Networks.grid_default}}' ${CONT_NAME} | jq .IPAddress -r` 29 | fi 30 | 31 | if [ "${IP}" == "" ]; then 32 | die "Failed to grab IP for container ${CONT_NAME}" 33 | fi 34 | 35 | # We need a fixed port range to expose VNC 36 | PORT=$(docker exec ${CONT_NAME} cat VNC_PORT) 37 | # if [ "$(uname)" = 'Darwin' ]; then 38 | # # due to a bug in Docker for Mac beta (1.12) 39 | # # https://forums.docker.com/t/docker-for-mac-beta-not-forwarding-ports/8658/6 40 | # IP="localhost" 41 | # fi 42 | 43 | if [ "$(uname)" != 'Darwin' ]; then 44 | OPTS="-GrabKeyboard=0" 45 | else 46 | OPTS="" 47 | fi 48 | 49 | # set -x: print each command right before it is executed 50 | set -x 51 | 52 | "${VNC_CLIENT}" -WarnUnencrypted=0 -SendKeyEvents=0 SendPointerEvents=0 -Scaling=${SIZE} ${OPTS} ${IP}:${PORT} 53 | -------------------------------------------------------------------------------- /mk/vnc_cask.rb: -------------------------------------------------------------------------------- 1 | # Docs: 2 | # https://github.com/astorije/homebrew-cask/blob/master/CONTRIBUTING.md#cask-stanzas 3 | cask 'vnc_cask' do 4 | version '5.3.2' 5 | 6 | # shasum -a 256 VNC-5.3.2-MacOSX-x86_64.pkg 7 | sha256 'ed075ad1bec0d3d6ae9c446fbdec211798853d79f14c7a98520819f22fe991d3' 8 | url "https://www.realvnc.com/download/file/vnc.files/VNC-#{version}-MacOSX-x86_64.pkg" 9 | 10 | name 'RealVNC Viewer' 11 | homepage 'https://www.realvnc.com' 12 | 13 | pkg "VNC-#{version}-MacOSX-x86_64.pkg" 14 | end 15 | -------------------------------------------------------------------------------- /mk/wait.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | # set -u: treat unset variables as an error and exit immediately 5 | set -e 6 | set -u 7 | 8 | echoerr() { printf "%s\n" "$*" >&2; } 9 | 10 | # print error and exit 11 | die () { 12 | echoerr "ERROR: $1" 13 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "3" 14 | errnum=${2-3} 15 | exit $errnum 16 | } 17 | 18 | # set -x: print each command right before it is executed 19 | # set -x 20 | 21 | echo "Waiting for the Hub and all Nodes to be ready..." 22 | 23 | if ! docker-compose -f ${COMPOSE_FILE} -p ${COMPOSE_PROJ_NAME} \ 24 | exec --index 1 hub wait_all_done ${WAIT_ALL_DONE} \ 25 | >./mk/hub_1.log; then 26 | docker-compose -f ${COMPOSE_FILE} -p ${COMPOSE_PROJ_NAME} logs hub 27 | docker-compose -f ${COMPOSE_FILE} -p ${COMPOSE_PROJ_NAME} \ 28 | exec --index 1 hub errors || true 29 | cat ./mk/hub_1.log 1>&2 30 | die "Failed to start the Hub (a.k.a. Grid) 1" 31 | fi 32 | echo "Hub is ready..." 33 | 34 | for i in $(seq 1 ${chrome}); do 35 | if ! docker-compose -f ${COMPOSE_FILE} -p ${COMPOSE_PROJ_NAME} \ 36 | exec --index ${i} chrome wait_all_done ${WAIT_ALL_DONE} \ 37 | >./mk/chrome_${i}.log; then 38 | docker-compose -f ${COMPOSE_FILE} -p ${COMPOSE_PROJ_NAME} logs chrome 39 | docker-compose -f ${COMPOSE_FILE} -p ${COMPOSE_PROJ_NAME} \ 40 | exec --index ${i} chrome errors || true 41 | cat ./mk/chrome_${i}.log 1>&2 42 | die "Failed to start Node chrome ${i}" 43 | fi 44 | [ "${i}" = "1" ] && echo "Chrome is ready..." 45 | done 46 | 47 | for i in $(seq 1 ${firefox}); do 48 | if ! docker-compose -f ${COMPOSE_FILE} -p ${COMPOSE_PROJ_NAME} \ 49 | exec --index ${i} firefox wait_all_done ${WAIT_ALL_DONE} \ 50 | >./mk/firefox_${i}.log; then 51 | docker-compose -f ${COMPOSE_FILE} -p ${COMPOSE_PROJ_NAME} logs firefox 52 | docker-compose -f ${COMPOSE_FILE} -p ${COMPOSE_PROJ_NAME} \ 53 | exec --index ${i} firefox errors || true 54 | cat ./mk/firefox_${i}.log 1>&2 55 | die "Failed to start Node firefox ${i}" 56 | fi 57 | [ "${i}" = "1" ] && echo "Firefox is ready..." 58 | done 59 | 60 | echo "------------------------------------------------" 61 | echo "-------- SUCCESS: Hub and Nodes ready ----------" 62 | echo "------------------------------------------------" 63 | -------------------------------------------------------------------------------- /novnc/bin/start-novnc.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | export VNC_PORT=$(cat VNC_PORT) 7 | 8 | # Wait for this process dependencies 9 | timeout --foreground ${WAIT_TIMEOUT} wait-vnc.sh 10 | 11 | # Usage at https://github.com/kanaka/noVNC/blob/master/utils/launch.sh 12 | /home/seluser/noVNC/utils/launch.sh \ 13 | --listen ${NOVNC_PORT}\ 14 | --vnc localhost:${VNC_PORT} 15 | -------------------------------------------------------------------------------- /novnc/bin/wait-novnc.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | if [ "${NOVNC}" != "true" ]; then 7 | log "Won't start noVNC service due to NOVNC env var false" 8 | exit 0 9 | fi 10 | 11 | if [ ! -z "${XE_DISP_NUM}" ]; then 12 | log "Will not wait for noVNC because env var XE_DISP_NUM is set." 13 | exit 0 14 | fi 15 | 16 | log "Waiting for noVNC to be ready..." 17 | while ! curl -s "http://localhost:${NOVNC_PORT}/vnc.html" \ 18 | | grep "noVNC_screen"; do 19 | echo -n '.' 20 | sleep 0.1 21 | done 22 | log "Done wait-novnc.sh" 23 | -------------------------------------------------------------------------------- /novnc/etc/supervisor/conf.d/novnc.conf: -------------------------------------------------------------------------------- 1 | [program:novnc] 2 | 3 | ;The relative priority of the program in the start and shutdown ordering. 4 | ;Lower priorities indicate programs that start first and shut down last. 5 | priority=40 6 | 7 | ;User to run-as, note environment expansion outside of `command` is only 8 | ;supported in supervisor >= 3.2 9 | ;user=seluser 10 | 11 | ;The command that will be run when this program is started. 12 | ;Controlled programs should themselves not be daemons, as supervisord 13 | ;assumes it is responsible for daemonizing its subprocesses 14 | directory=/home/seluser 15 | command=%(ENV_BIN_UTILS)s/start-novnc.sh 16 | 17 | ;If true, this program will start automatically when supervisord is started. 18 | ;default=true 19 | autostart=%(ENV_NOVNC)s 20 | 21 | ;If false, the process will never be autorestarted. 22 | ;If true, the process will be unconditionally restarted when it exits, 23 | ;without regard to its exit code. default=unexpected 24 | ;If unexpected, the process will be restart when the program exits with an 25 | ;exit code that is not one of the exit codes associated with this process. 26 | autorestart=unexpected 27 | 28 | ;Set to 0 to indicate that the program needn’t stay running for any 29 | ;particular amount of time. 30 | ;So using custom wait-xxxx.sh scripts to perform a more efficient 31 | ;active waiting until https://github.com/Supervisor/supervisor/issues/584 32 | startsecs=2 33 | 34 | ;The number of serial failure attempts that supervisord will allow when 35 | ;attempting to start the program before giving up and puting the process 36 | ;into an FATAL state. 37 | startretries=3 38 | 39 | ;Logs 40 | redirect_stderr=false 41 | stdout_logfile=%(ENV_LOGS_DIR)s/novnc-stdout.log 42 | stderr_logfile=%(ENV_LOGS_DIR)s/novnc-stderr.log 43 | stdout_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 44 | stderr_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 45 | stdout_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 46 | stderr_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 47 | stdout_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 48 | stderr_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 49 | 50 | ;The signal used to kill the program when a stop is requested. This can be 51 | ;any of TERM, HUP, INT, QUIT, KILL, USR1, or USR2. default=TERM 52 | stopsignal=%(ENV_NOVNC_STOP_SIGNAL)s 53 | -------------------------------------------------------------------------------- /osx/dockertoolbox-pkg-rc.rb: -------------------------------------------------------------------------------- 1 | # Forked from: 2 | # https://github.com/caskroom/homebrew-cask/blob/master/Casks/dockertoolbox.rb 3 | # Docs: 4 | # https://github.com/astorije/homebrew-cask/blob/master/CONTRIBUTING.md#cask-stanzas 5 | cask 'dockertoolbox-rc' do 6 | version '1.12.0-rc4' 7 | 8 | # shasum -a 256 DockerToolbox-1.12.0-rc4.pkg 9 | sha256 '95ac6d6688c08443f9e42926f50c058083fc96fee8cd9ec124644572956d32a0' 10 | # github.com/docker/toolbox was verified as official when first introduced to the cask 11 | url "https://github.com/docker/toolbox/releases/download/v#{version}/DockerToolbox-#{version}.pkg" 12 | 13 | # appcast URL for an appcast which provides information on future updates 14 | # https://github.com/caskroom/homebrew-cask/blob/master/doc/cask_language_reference/stanzas/appcast.md 15 | # curl --compressed -L "https://github.com/docker/toolbox/releases.atom" | \ 16 | # sed 's|[^<]*||g' | shasum -a 256 17 | appcast 'https://github.com/docker/toolbox/releases.atom', 18 | checkpoint: '1099f331135a6e1178c057cdd6938dca3102d37cb245f574b33833f2d78e67a7' 19 | 20 | name 'Docker Toolbox' 21 | homepage 'https://www.docker.com/toolbox' 22 | license :apache 23 | 24 | pkg "DockerToolbox-#{version}.pkg" 25 | 26 | postflight do 27 | set_ownership '~/.docker' 28 | end 29 | 30 | uninstall pkgutil: [ 31 | 'io.boot2dockeriso.pkg.boot2dockeriso', 32 | 'io.docker.pkg.docker', 33 | 'io.docker.pkg.dockercompose', 34 | 'io.docker.pkg.dockermachine', 35 | 'io.docker.pkg.dockerquickstartterminalapp', 36 | 'io.docker.pkg.kitematicapp', 37 | ] 38 | end 39 | -------------------------------------------------------------------------------- /osx/dockertoolbox-pkg-rc3.rb: -------------------------------------------------------------------------------- 1 | # Forked from: 2 | # https://github.com/caskroom/homebrew-cask/blob/master/Casks/dockertoolbox.rb 3 | # Docs: 4 | # https://github.com/astorije/homebrew-cask/blob/master/CONTRIBUTING.md#cask-stanzas 5 | cask 'dockertoolbox-rc' do 6 | version '1.12.0-rc3' 7 | 8 | # shasum -a 256 DockerToolbox-1.12.0-rc3.pkg 9 | sha256 'e661176aa37223a081ed6bcb82ff94e6c8be15d48075badf4d32c4ddb2ac8cb9' 10 | # github.com/docker/toolbox was verified as official when first introduced to the cask 11 | url "https://github.com/docker/toolbox/releases/download/v#{version}/DockerToolbox-#{version}.pkg" 12 | 13 | # appcast URL for an appcast which provides information on future updates 14 | # https://github.com/caskroom/homebrew-cask/blob/master/doc/cask_language_reference/stanzas/appcast.md 15 | # curl --compressed -L "https://github.com/docker/toolbox/releases.atom" | \ 16 | # sed 's|[^<]*||g' | shasum -a 256 17 | appcast 'https://github.com/docker/toolbox/releases.atom', 18 | checkpoint: '634a681112d156cbcdc75e66508b2a759f70b7e8ce9ff8e8b794338705a8ead7' 19 | 20 | name 'Docker Toolbox' 21 | homepage 'https://www.docker.com/toolbox' 22 | license :apache 23 | 24 | pkg "DockerToolbox-#{version}.pkg" 25 | 26 | postflight do 27 | set_ownership '~/.docker' 28 | end 29 | 30 | uninstall pkgutil: [ 31 | 'io.boot2dockeriso.pkg.boot2dockeriso', 32 | 'io.docker.pkg.docker', 33 | 'io.docker.pkg.dockercompose', 34 | 'io.docker.pkg.dockermachine', 35 | 'io.docker.pkg.dockerquickstartterminalapp', 36 | 'io.docker.pkg.kitematicapp', 37 | ] 38 | end 39 | -------------------------------------------------------------------------------- /osx/dockertoolbox-rc.rb: -------------------------------------------------------------------------------- 1 | # Refs: 2 | # https://github.com/caskroom/homebrew-cask/blob/master/Casks/docker.rb 3 | # https://github.com/caskroom/homebrew-cask/issues/22281 4 | cask 'dockertoolbox-rc' do 5 | version 'beta' 6 | 7 | # rc3 8 | # sha256 '7ac7c061b135f821fac39e53f7b74233dcaf8f926e4c6d28031acc8717b85107' 9 | 10 | # rc4 11 | # shasum -a 256 Docker.dmg 12 | sha256 'ebb8b471045defd93b9f100d601b2d1dde4b69cb2465ee12e74976ee00b221d3' 13 | url "https://download.docker.com/mac/#{version}/Docker.dmg" 14 | 15 | name 'Docker for Mac' 16 | homepage 'http://www.docker.com/products/docker#/mac' 17 | license :mit 18 | 19 | auto_updates true 20 | 21 | app 'Docker.app' 22 | end 23 | -------------------------------------------------------------------------------- /osx/vnc_cask.rb: -------------------------------------------------------------------------------- 1 | # Docs: 2 | # https://github.com/astorije/homebrew-cask/blob/master/CONTRIBUTING.md#cask-stanzas 3 | cask 'vnc_cask' do 4 | version '5.3.2' 5 | 6 | # shasum -a 256 VNC-5.3.2-MacOSX-x86_64.pkg 7 | sha256 'ed075ad1bec0d3d6ae9c446fbdec211798853d79f14c7a98520819f22fe991d3' 8 | url "https://www.realvnc.com/download/file/vnc.files/VNC-#{version}-MacOSX-x86_64.pkg" 9 | 10 | name 'RealVNC Viewer' 11 | homepage 'https://www.realvnc.com' 12 | 13 | pkg "VNC-#{version}-MacOSX-x86_64.pkg" 14 | end 15 | -------------------------------------------------------------------------------- /scm-source.json: -------------------------------------------------------------------------------- 1 | { 2 | "url": "https://github.com/elgalu/docker-selenium", 3 | "revision": "dc5bbf5a3e15272c6b830c8a3257f5f74ae01bb3", 4 | "author": "lgallucci", 5 | "status": "" 6 | } 7 | -------------------------------------------------------------------------------- /selenium-hub/bin/start-selenium-hub.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | JAVA_OPTS="$(java-dynamic-memory-opts.sh) ${JAVA_OPTS}" 7 | echo "INFO: JAVA_OPTS are '${JAVA_OPTS}'" 8 | 9 | # See standalone params docs at 10 | # https://code.google.com/p/selenium/wiki/Grid2 11 | # https://github.com/pilwon/selenium-webdriver/blob/master/java/server/src/org/openqa/grid/common/defaults/GridParameters.properties 12 | # See hub defaults at 13 | # https://github.com/pilwon/selenium-webdriver/blob/master/java/server/src/org/openqa/grid/common/defaults/DefaultNode.json 14 | # Had to increase -cleanUpCycle and -nodePolling to avoid 15 | # UnknownError: Session [.*] was terminated due to TIMEOUT 16 | java ${JAVA_OPTS} \ 17 | -jar ${SELENIUM_JAR_PATH} \ 18 | -port ${SELENIUM_HUB_PORT} \ 19 | -role hub \ 20 | -maxSession ${MAX_SESSIONS} \ 21 | -timeout ${SEL_RELEASE_TIMEOUT_SECS} \ 22 | -browserTimeout ${SEL_BROWSER_TIMEOUT_SECS} \ 23 | -cleanUpCycle ${SEL_CLEANUPCYCLE_MS} \ 24 | ${SELENIUM_HUB_PARAMS} 25 | 26 | # Note to double pipe output and keep this process logs add at the end: 27 | # 2>&1 | tee ${SELENIUM_LOG} 28 | # But is no longer required because individual logs are maintained by 29 | # supervisord right now. 30 | -------------------------------------------------------------------------------- /selenium-hub/bin/wait-selenium-hub.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SEL_STATUS_URL="${SELENIUM_HUB_PROTO}://${SELENIUM_HUB_HOST}:${SELENIUM_HUB_PORT}/wd/hub/status" 4 | 5 | # set -e: exit asap if a command exits with a non-zero status 6 | set -e 7 | 8 | if [ "${GRID}" != "true" ]; then 9 | echo "Won't start selenium grid due to GRID env var false" 10 | exit 0 11 | fi 12 | 13 | echo "Waiting for Selenium Hub to be ready..." 14 | 15 | # Selenium <= 3.3.1 then: while ! curl -s "${SEL_STATUS_URL}" | jq '.status' | grep "13"; do 16 | # SUCESS_CMD="jq .status | grep 13" 17 | 18 | # Selenium >= 3.5.0 then: while ! curl -s "${SEL_STATUS_URL}" | jq '.status' | grep "0"; do 19 | SUCESS_CMD="jq .status | grep 0" 20 | 21 | while ! curl -s "${SEL_STATUS_URL}" | sh -c "${SUCESS_CMD}"; do 22 | echo -n '.' 23 | sleep 0.1 24 | done 25 | echo "Done wait-selenium-hub.sh" 26 | -------------------------------------------------------------------------------- /selenium-hub/etc/supervisor/conf.d/selenium-hub.conf: -------------------------------------------------------------------------------- 1 | [program:selenium-hub] 2 | 3 | ;The relative priority of the program in the start and shutdown ordering. 4 | ;Lower priorities indicate programs that start first and shut down last. 5 | priority=60 6 | 7 | ;User to run-as, note environment expansion outside of `command` is only 8 | ;supported in supervisor >= 3.2 9 | ;user=seluser 10 | 11 | ;The command that will be run when this program is started. 12 | ;Controlled programs should themselves not be daemons, as supervisord 13 | ;assumes it is responsible for daemonizing its subprocesses 14 | directory=/home/seluser 15 | command=%(ENV_BIN_UTILS)s/start-selenium-hub.sh 16 | 17 | ;If true, this program will start automatically when supervisord is started. 18 | ;default=true 19 | autostart=%(ENV_GRID)s 20 | 21 | ;If false, the process will never be autorestarted. 22 | ;If true, the process will be unconditionally restarted when it exits, 23 | ;without regard to its exit code. default=unexpected 24 | ;If unexpected, the process will be restart when the program exits with an 25 | ;exit code that is not one of the exit codes associated with this process. 26 | autorestart=false 27 | 28 | ;Set to 0 to indicate that the program needn’t stay running for any 29 | ;particular amount of time. 30 | ;So using custom wait-xxxx.sh scripts to perform a more efficient 31 | ;active waiting until https://github.com/Supervisor/supervisor/issues/584 32 | startsecs=0 33 | 34 | ;The number of serial failure attempts that supervisord will allow when 35 | ;attempting to start the program before giving up and puting the process 36 | ;into an FATAL state. 37 | startretries=0 38 | 39 | ;Logs 40 | redirect_stderr=false 41 | stdout_logfile=%(ENV_LOGS_DIR)s/selenium-hub-stdout.log 42 | stderr_logfile=%(ENV_LOGS_DIR)s/selenium-hub-stderr.log 43 | stdout_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 44 | stderr_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 45 | stdout_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 46 | stderr_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 47 | stdout_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 48 | stderr_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 49 | 50 | ;The signal used to kill the program when a stop is requested. This can be 51 | ;any of TERM, HUP, INT, QUIT, KILL, USR1, or USR2. default=TERM 52 | stopsignal=%(ENV_SELENIUM_HUB_STOP_SIGNAL)s 53 | -------------------------------------------------------------------------------- /selenium-multinode/bin/wait-selenium-multinode.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SEL_STATUS_URL="http://${SELENIUM_NODE_HOST}:${SELENIUM_MULTINODE_PORT}/wd/hub/status" 4 | 5 | # set -e: exit asap if a command exits with a non-zero status 6 | set -e 7 | 8 | if [ "${MULTINODE}" != "true" ]; then 9 | echo "Won't start selenium multi-node (Chrome & Firefox) due to MULTINODE env var false" 10 | exit 0 11 | fi 12 | 13 | echo "Waiting for Selenium multi-node (Chrome & Firefox) to be ready..." 14 | 15 | # Selenium <= 3.3.1 then: while ! curl -s "${SEL_STATUS_URL}" | jq '.state' | grep "success"; do 16 | # SUCESS_CMD="jq .state | grep success" 17 | 18 | # Selenium >= 3.5.0 then: while ! curl -s "${SEL_STATUS_URL}" | jq .value.ready | grep "true"; do 19 | SUCESS_CMD="jq .value.ready | grep true" 20 | 21 | while ! curl -s "${SEL_STATUS_URL}" | sh -c "${SUCESS_CMD}"; do 22 | if [ "${DEBUG}" != "false" ]; then 23 | if ! curl --verbose "${SEL_STATUS_URL}"; then 24 | sleep 0.2 25 | if ! wget --verbose --tries=1 "${SEL_STATUS_URL}"; then 26 | sleep 0.2 27 | netstat -tlnp 28 | if ! ps -A | grep -i java; then 29 | sleep 0.2 30 | ps -A 31 | fi 32 | fi 33 | fi 34 | else 35 | echo -n '.' 36 | sleep 0.1 37 | fi 38 | done 39 | 40 | echo "Done wait-selenium-multinode.sh" 41 | -------------------------------------------------------------------------------- /selenium-multinode/etc/supervisor/conf.d/selenium-multinode.conf: -------------------------------------------------------------------------------- 1 | [program:selenium-multinode] 2 | 3 | ;The relative priority of the program in the start and shutdown ordering. 4 | ;Lower priorities indicate programs that start first and shut down last. 5 | priority=63 6 | 7 | ;User to run-as, note environment expansion outside of `command` is only 8 | ;supported in supervisor >= 3.2 9 | ;user=seluser 10 | 11 | ;The command that will be run when this program is started. 12 | ;Controlled programs should themselves not be daemons, as supervisord 13 | ;assumes it is responsible for daemonizing its subprocesses 14 | directory=/home/seluser 15 | command=%(ENV_BIN_UTILS)s/start-selenium-multinode.sh 16 | 17 | ;If true, this program will start automatically when supervisord is started. 18 | ;default=true 19 | autostart=%(ENV_MULTINODE)s 20 | 21 | ;If false, the process will never be autorestarted. 22 | ;If true, the process will be unconditionally restarted when it exits, 23 | ;without regard to its exit code. default=unexpected 24 | ;If unexpected, the process will be restart when the program exits with an 25 | ;exit code that is not one of the exit codes associated with this process. 26 | autorestart=unexpected 27 | 28 | ;Set to 0 to indicate that the program needn’t stay running for any 29 | ;particular amount of time. 30 | ;So using custom wait-xxxx.sh scripts to perform a more efficient 31 | ;active waiting until https://github.com/Supervisor/supervisor/issues/584 32 | startsecs=3 33 | 34 | ;The number of serial failure attempts that supervisord will allow when 35 | ;attempting to start the program before giving up and puting the process 36 | ;into an FATAL state. 37 | startretries=2 38 | 39 | ;Logs 40 | redirect_stderr=false 41 | stdout_logfile=%(ENV_LOGS_DIR)s/selenium-multinode-stdout.log 42 | stderr_logfile=%(ENV_LOGS_DIR)s/selenium-multinode-stderr.log 43 | stdout_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 44 | stderr_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 45 | stdout_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 46 | stderr_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 47 | stdout_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 48 | stderr_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 49 | 50 | ;The signal used to kill the program when a stop is requested. This can be 51 | ;any of TERM, HUP, INT, QUIT, KILL, USR1, or USR2. default=TERM 52 | stopsignal=%(ENV_SELENIUM_MULTINODE_STOP_SIGNAL)s 53 | -------------------------------------------------------------------------------- /selenium-node-chrome/bin/start-selenium-node-chrome.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | echoerr() { printf "%s\n" "$*" >&2; } 7 | 8 | # print error and exit 9 | die () { 10 | echoerr "ERROR: $1" 11 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "150" 12 | errnum=${2-110} 13 | exit $errnum 14 | } 15 | 16 | # Required params (some) 17 | [ -z "${WAIT_TIMEOUT}" ] && die "Required env var WAIT_TIMEOUT" 18 | [ -z "${COMMON_CAPS}" ] && die "Required env var COMMON_CAPS" 19 | [ -z "${SELENIUM_JAR_PATH}" ] && die "Required env var SELENIUM_JAR_PATH" 20 | [ -z "${SELENIUM_NODE_HOST}" ] && die "Required env var SELENIUM_NODE_HOST" 21 | [ -z "${CHROME_VERSION}" ] && die "Required env var CHROME_VERSION" 22 | [ -z "${CHROME_PATH}" ] && die "Required env var CHROME_PATH" 23 | 24 | if [ "${ZALENIUM}" != "true" ]; then 25 | timeout --foreground ${WAIT_TIMEOUT} wait-selenium-hub.sh || \ 26 | shutdown "Failed while waiting for selenium hub to start!" 27 | fi 28 | 29 | JAVA_OPTS="$(java-dynamic-memory-opts.sh) ${JAVA_OPTS}" 30 | echo "INFO: JAVA_OPTS are '${JAVA_OPTS}'" 31 | 32 | # See standalone params docs at 33 | # https://code.google.com/p/selenium/wiki/Grid2 34 | # https://github.com/pilwon/selenium-webdriver/blob/master/java/server/src/org/openqa/grid/common/defaults/GridParameters.properties 35 | # See node defaults at 36 | # https://github.com/pilwon/selenium-webdriver/blob/master/java/server/src/org/openqa/grid/common/defaults/DefaultNode.json 37 | CHROME_BROWSER_CAPS="browserName=chrome,${COMMON_CAPS}" 38 | CHROME_BROWSER_CAPS="${CHROME_BROWSER_CAPS},version=${CHROME_VERSION}" 39 | 40 | java \ 41 | -Dwebdriver.chrome.driver="/home/seluser/chromedriver" \ 42 | -Dwebdriver.chrome.logfile="${LOGS_DIR}/chrome_driver.log" \ 43 | -Dwebdriver.chrome.verboseLogging="${CHROME_VERBOSELOGGING}" \ 44 | ${JAVA_OPTS} \ 45 | -jar ${SELENIUM_JAR_PATH} \ 46 | -port ${SELENIUM_NODE_CH_PORT} \ 47 | -host "${SELENIUM_NODE_HOST}" \ 48 | -role node \ 49 | -hub "${SELENIUM_HUB_PROTO}://${SELENIUM_HUB_HOST}:${SELENIUM_HUB_PORT}/grid/register" \ 50 | -browser "${CHROME_BROWSER_CAPS}" \ 51 | -maxSession ${MAX_SESSIONS} \ 52 | -timeout ${SEL_RELEASE_TIMEOUT_SECS} \ 53 | -browserTimeout ${SEL_BROWSER_TIMEOUT_SECS} \ 54 | -cleanUpCycle ${SEL_CLEANUPCYCLE_MS} \ 55 | -nodePolling ${SEL_NODEPOLLING_MS} \ 56 | -unregisterIfStillDownAfter ${SEL_UNREGISTER_IF_STILL_DOWN_AFTER} \ 57 | ${SELENIUM_NODE_PARAMS} \ 58 | ${CUSTOM_SELENIUM_NODE_PROXY_PARAMS} \ 59 | ${CUSTOM_SELENIUM_NODE_REGISTER_CYCLE} \ 60 | & 61 | NODE_PID=$! 62 | 63 | function shutdown { 64 | echo "-- INFO: Shutting down Chrome NODE gracefully..." 65 | kill -SIGINT ${NODE_PID} || true 66 | kill -SIGTERM ${NODE_PID} || true 67 | kill -SIGKILL ${NODE_PID} || true 68 | wait ${NODE_PID} 69 | echo "-- INFO: Chrome node shutdown complete." 70 | # First stop video recording because it needs some time to flush it 71 | supervisorctl -c /etc/supervisor/supervisord.conf stop video-rec || true 72 | exit 0 73 | } 74 | 75 | function trappedFn { 76 | echo "-- INFO: Trapped SIGTERM/SIGINT on Chrome NODE" 77 | shutdown 78 | } 79 | # Run function shutdown() when this process receives a killing signal 80 | trap trappedFn SIGTERM SIGINT SIGKILL 81 | 82 | # tells bash to wait until child processes have exited 83 | wait ${NODE_PID} 84 | echo "-- INFO: Passed after wait java Chrome node" 85 | 86 | # Always shutdown if the node dies 87 | shutdown 88 | 89 | # Note to double pipe output and keep this process logs add at the end: 90 | # 2>&1 | tee $SELENIUM_LOG 91 | # But is no longer required because individual logs are maintained by 92 | # supervisord right now. 93 | -------------------------------------------------------------------------------- /selenium-node-chrome/bin/wait-selenium-node-chrome.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SEL_STATUS_URL="http://${SELENIUM_NODE_HOST}:${SELENIUM_NODE_CH_PORT}/wd/hub/status" 4 | 5 | # set -e: exit asap if a command exits with a non-zero status 6 | set -e 7 | 8 | if [ "${CHROME}" != "true" ]; then 9 | echo "Won't start selenium node chrome due to CHROME env var false" 10 | exit 0 11 | fi 12 | 13 | echo "Waiting for Selenium Node Chrome ${CHROME_FLAVOR} to be ready..." 14 | 15 | # Selenium <= 3.3.1 then: while ! curl -s "${SEL_STATUS_URL}" | jq '.state' | grep "success"; do 16 | # SUCESS_CMD="jq .state | grep success" 17 | 18 | # Selenium >= 3.5.0 then: while ! curl -s "${SEL_STATUS_URL}" | jq .value.ready | grep "true"; do 19 | SUCESS_CMD="jq .value.ready | grep true" 20 | 21 | while ! curl -s "${SEL_STATUS_URL}" | sh -c "${SUCESS_CMD}"; do 22 | if [ "${DEBUG}" != "false" ]; then 23 | if ! curl --verbose "${SEL_STATUS_URL}"; then 24 | sleep 0.2 25 | if ! wget --verbose --tries=1 "${SEL_STATUS_URL}"; then 26 | sleep 0.2 27 | netstat -tlnp 28 | if ! ps -A | grep -i java; then 29 | sleep 0.2 30 | ps -A 31 | fi 32 | fi 33 | fi 34 | else 35 | echo -n '.' 36 | sleep 0.1 37 | fi 38 | done 39 | 40 | echo "Done wait-selenium-node-chrome-${CHROME_FLAVOR}.sh" 41 | -------------------------------------------------------------------------------- /selenium-node-chrome/etc/supervisor/conf.d/selenium-node-chrome.conf: -------------------------------------------------------------------------------- 1 | [program:selenium-node-chrome] 2 | 3 | ;The relative priority of the program in the start and shutdown ordering. 4 | ;Lower priorities indicate programs that start first and shut down last. 5 | priority=65 6 | 7 | ;User to run-as, note environment expansion outside of `command` is only 8 | ;supported in supervisor >= 3.2 9 | ;user=seluser 10 | 11 | ;The command that will be run when this program is started. 12 | ;Controlled programs should themselves not be daemons, as supervisord 13 | ;assumes it is responsible for daemonizing its subprocesses 14 | directory=/home/seluser 15 | command=%(ENV_BIN_UTILS)s/start-selenium-node-chrome.sh 16 | 17 | ;If true, this program will start automatically when supervisord is started. 18 | ;default=true 19 | autostart=%(ENV_CHROME)s 20 | 21 | ;If false, the process will never be autorestarted. 22 | ;If true, the process will be unconditionally restarted when it exits, 23 | ;without regard to its exit code. default=unexpected 24 | ;If unexpected, the process will be restart when the program exits with an 25 | ;exit code that is not one of the exit codes associated with this process. 26 | autorestart=unexpected 27 | 28 | ;Set to 0 to indicate that the program needn’t stay running for any 29 | ;particular amount of time. 30 | ;So using custom wait-xxxx.sh scripts to perform a more efficient 31 | ;active waiting until https://github.com/Supervisor/supervisor/issues/584 32 | startsecs=3 33 | 34 | ;The number of serial failure attempts that supervisord will allow when 35 | ;attempting to start the program before giving up and puting the process 36 | ;into an FATAL state. 37 | startretries=2 38 | 39 | ;Logs 40 | redirect_stderr=false 41 | stdout_logfile=%(ENV_LOGS_DIR)s/selenium-node-chrome-stdout.log 42 | stderr_logfile=%(ENV_LOGS_DIR)s/selenium-node-chrome-stderr.log 43 | stdout_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 44 | stderr_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 45 | stdout_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 46 | stderr_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 47 | stdout_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 48 | stderr_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 49 | 50 | ;The signal used to kill the program when a stop is requested. This can be 51 | ;any of TERM, HUP, INT, QUIT, KILL, USR1, or USR2. default=TERM 52 | stopsignal=%(ENV_SELENIUM_NODE_CHROME_STOP_SIGNAL)s 53 | -------------------------------------------------------------------------------- /selenium-node-chrome/opt/google/chrome/google-chrome: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Note: the output of this script is normally found at 4 | # /var/log/cont/selenium-node-chrome-stderr.log 5 | 6 | # Debian/Ubuntu seems to not respect --lang, it instead needs to be a LANGUAGE environment var 7 | # See: https://stackoverflow.com/a/41893197/359999 8 | for var in "$@"; do 9 | if [[ $var == --lang=* ]]; then 10 | export LANGUAGE=${var//--lang=} 11 | fi 12 | done 13 | 14 | exec /opt/google/chrome/google-chrome-base "$@" ${CHROME_ARGS} ${CHROME_ADDITIONAL_ARGS} 15 | 16 | # See: On How To Turn Chrome or Firefox Into A Single-Site Browser 17 | # Google Chrome users can make use of the --host-rules parameter to block all domain connections except the ones they whitelist. The general parameter looks like this: 18 | # 19 | # --host-rules="MAP * 127.0.0.1, EXCLUDE *.ghacks.net" 20 | # 21 | # This redirects all connection attempts to localhost, except for connections to the ghacks.net site or one of its subdomains. 22 | # You can also add multiple inclusions in the following way: 23 | # 24 | # --host-rules="MAP * 127.0.0.1, EXCLUDE *.ghacks.net","MAP * 127.0.0.1, EXCLUDE *.microsoft.com" 25 | # https://github.com/electron/electron/blob/master/docs/api/chrome-command-line-switches.md#--host-rulesrules 26 | # 27 | # @outerpasta idea: 28 | # 29 | # if [ "${THE_DOCKER_HOST_IP}" != "" ]; then 30 | # exec /opt/google/chrome/google-chrome-base "$@" ${CHROME_ARGS} --host-rules="MAP localhost ${THE_DOCKER_HOST_IP}" 31 | # else 32 | # exec /opt/google/chrome/google-chrome-base "$@" ${CHROME_ARGS} 33 | # fi 34 | -------------------------------------------------------------------------------- /selenium-node-firefox/bin/start-selenium-node-firefox.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | echoerr() { printf "%s\n" "$*" >&2; } 7 | 8 | # print error and exit 9 | die () { 10 | echoerr "ERROR: $1" 11 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "150" 12 | errnum=${2-110} 13 | exit $errnum 14 | } 15 | 16 | # Required params (some) 17 | [ -z "${WAIT_TIMEOUT}" ] && die "Required env var WAIT_TIMEOUT" 18 | [ -z "${COMMON_CAPS}" ] && die "Required env var COMMON_CAPS" 19 | [ -z "${SELENIUM_JAR_PATH}" ] && die "Required env var SELENIUM_JAR_PATH" 20 | [ -z "${SELENIUM_NODE_HOST}" ] && die "Required env var SELENIUM_NODE_HOST" 21 | [ -z "${FIREFOX_VERSION}" ] && die "Required env var FIREFOX_VERSION" 22 | [ -z "${FIREFOX_DEST_BIN}" ] && die "Required env var FIREFOX_DEST_BIN" 23 | 24 | if [ "${ZALENIUM}" != "true" ]; then 25 | timeout --foreground ${WAIT_TIMEOUT} wait-selenium-hub.sh || \ 26 | shutdown "Failed while waiting for selenium hub to start!" 27 | fi 28 | 29 | JAVA_OPTS="-Dwebdriver.gecko.driver=/usr/bin/geckodriver ${JAVA_OPTS}" 30 | JAVA_OPTS="$(java-dynamic-memory-opts.sh) ${JAVA_OPTS}" 31 | echo "INFO: JAVA_OPTS are '${JAVA_OPTS}'" 32 | 33 | # See standalone params docs at 34 | # https://code.google.com/p/selenium/wiki/Grid2 35 | # https://github.com/pilwon/selenium-webdriver/blob/master/java/server/src/org/openqa/grid/common/defaults/GridParameters.properties 36 | # See node defaults at 37 | # https://github.com/pilwon/selenium-webdriver/blob/master/java/server/src/org/openqa/grid/common/defaults/DefaultNode.json 38 | # TODO: how to set default firefox to latest? 39 | FIREFOX_BROWSER_CAPS="browserName=firefox,${COMMON_CAPS}" 40 | FIREFOX_BROWSER_CAPS="${FIREFOX_BROWSER_CAPS},version=${FIREFOX_VERSION}" 41 | 42 | # public static final String BROWSER_LOGFILE = "webdriver.firefox.logfile"; 43 | # System property that defines the location of the file where Firefox log should be stored. 44 | 45 | java \ 46 | -Dwebdriver.firefox.logfile="${LOGS_DIR}/firefox_driver.log" \ 47 | ${JAVA_OPTS} \ 48 | -jar ${SELENIUM_JAR_PATH} \ 49 | -port ${SELENIUM_NODE_FF_PORT} \ 50 | -host "${SELENIUM_NODE_HOST}" \ 51 | -role node \ 52 | -hub "${SELENIUM_HUB_PROTO}://${SELENIUM_HUB_HOST}:${SELENIUM_HUB_PORT}/grid/register" \ 53 | -browser "${FIREFOX_BROWSER_CAPS}" \ 54 | -maxSession ${MAX_SESSIONS} \ 55 | -timeout ${SEL_RELEASE_TIMEOUT_SECS} \ 56 | -browserTimeout ${SEL_BROWSER_TIMEOUT_SECS} \ 57 | -cleanUpCycle ${SEL_CLEANUPCYCLE_MS} \ 58 | -nodePolling ${SEL_NODEPOLLING_MS} \ 59 | -unregisterIfStillDownAfter ${SEL_UNREGISTER_IF_STILL_DOWN_AFTER} \ 60 | ${SELENIUM_NODE_PARAMS} \ 61 | ${CUSTOM_SELENIUM_NODE_PROXY_PARAMS} \ 62 | ${CUSTOM_SELENIUM_NODE_REGISTER_CYCLE} \ 63 | & 64 | NODE_PID=$! 65 | 66 | function shutdown { 67 | echo "-- INFO: Shutting down Firefox NODE gracefully..." 68 | kill -SIGINT ${NODE_PID} || true 69 | kill -SIGTERM ${NODE_PID} || true 70 | kill -SIGKILL ${NODE_PID} || true 71 | wait ${NODE_PID} 72 | echo "-- INFO: Firefox node shutdown complete." 73 | # First stop video recording because it needs some time to flush it 74 | supervisorctl -c /etc/supervisor/supervisord.conf stop video-rec || true 75 | exit 0 76 | } 77 | 78 | function trappedFn { 79 | echo "-- INFO: Trapped SIGTERM/SIGINT on Firefox NODE" 80 | shutdown 81 | } 82 | # Run function shutdown() when this process receives a killing signal 83 | trap trappedFn SIGTERM SIGINT SIGKILL 84 | 85 | # tells bash to wait until child processes have exited 86 | wait ${NODE_PID} 87 | echo "-- INFO: Passed after wait java Firefox node" 88 | 89 | # Always shutdown if the node dies 90 | shutdown 91 | -------------------------------------------------------------------------------- /selenium-node-firefox/bin/wait-selenium-node-firefox.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SEL_STATUS_URL="http://${SELENIUM_NODE_HOST}:${SELENIUM_NODE_FF_PORT}/wd/hub/status" 4 | 5 | # set -e: exit asap if a command exits with a non-zero status 6 | set -e 7 | 8 | if [ "${FIREFOX}" != "true" ]; then 9 | echo "Won't start selenium node firefox due to FIREFOX env var false" 10 | exit 0 11 | fi 12 | 13 | echo "Waiting for Selenium Node Firefox ${FIREFOX_VERSION} to be ready..." 14 | 15 | # Selenium <= 3.3.1 then: while ! curl -s "${SEL_STATUS_URL}" | jq '.state' | grep "success"; do 16 | # SUCESS_CMD="jq .state | grep success" 17 | 18 | # Selenium >= 3.5.0 then: while ! curl -s "${SEL_STATUS_URL}" | jq .value.ready | grep "true"; do 19 | SUCESS_CMD="jq .value.ready | grep true" 20 | 21 | while ! curl -s "${SEL_STATUS_URL}" | sh -c "${SUCESS_CMD}"; do 22 | if [ "${DEBUG}" != "false" ]; then 23 | if ! curl --verbose "${SEL_STATUS_URL}"; then 24 | sleep 0.2 25 | if ! wget --verbose --tries=1 "${SEL_STATUS_URL}"; then 26 | sleep 0.2 27 | netstat -tlnp 28 | if ! ps -A | grep -i java; then 29 | sleep 0.2 30 | ps -A 31 | fi 32 | fi 33 | fi 34 | else 35 | echo -n '.' 36 | sleep 0.1 37 | fi 38 | done 39 | 40 | echo "Done wait-selenium-node-firefox-${FIREFOX_VERSION}" 41 | -------------------------------------------------------------------------------- /selenium-node-firefox/etc/supervisor/conf.d/selenium-node-firefox.conf: -------------------------------------------------------------------------------- 1 | [program:selenium-node-firefox] 2 | 3 | ;The relative priority of the program in the start and shutdown ordering. 4 | ;Lower priorities indicate programs that start first and shut down last. 5 | priority=66 6 | 7 | ;User to run-as, note environment expansion outside of `command` is only 8 | ;supported in supervisor >= 3.2 9 | ;user=seluser 10 | 11 | ;The command that will be run when this program is started. 12 | ;Controlled programs should themselves not be daemons, as supervisord 13 | ;assumes it is responsible for daemonizing its subprocesses 14 | directory=/home/seluser 15 | command=%(ENV_BIN_UTILS)s/start-selenium-node-firefox.sh 16 | 17 | ;If true, this program will start automatically when supervisord is started. 18 | ;default=true 19 | autostart=%(ENV_FIREFOX)s 20 | 21 | ;If false, the process will never be autorestarted. 22 | ;If true, the process will be unconditionally restarted when it exits, 23 | ;without regard to its exit code. default=unexpected 24 | ;If unexpected, the process will be restart when the program exits with an 25 | ;exit code that is not one of the exit codes associated with this process. 26 | autorestart=unexpected 27 | 28 | ;Set to 0 to indicate that the program needn’t stay running for any 29 | ;particular amount of time. 30 | ;So using custom wait-xxxx.sh scripts to perform a more efficient 31 | ;active waiting until https://github.com/Supervisor/supervisor/issues/584 32 | startsecs=3 33 | 34 | ;The number of serial failure attempts that supervisord will allow when 35 | ;attempting to start the program before giving up and puting the process 36 | ;into an FATAL state. 37 | startretries=2 38 | 39 | ;Logs 40 | redirect_stderr=false 41 | stdout_logfile=%(ENV_LOGS_DIR)s/selenium-node-firefox-stdout.log 42 | stderr_logfile=%(ENV_LOGS_DIR)s/selenium-node-firefox-stderr.log 43 | stdout_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 44 | stderr_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 45 | stdout_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 46 | stderr_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 47 | stdout_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 48 | stderr_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 49 | 50 | ;The signal used to kill the program when a stop is requested. This can be 51 | ;any of TERM, HUP, INT, QUIT, KILL, USR1, or USR2. default=TERM 52 | stopsignal=%(ENV_SELENIUM_NODE_FIREFOX_STOP_SIGNAL)s 53 | -------------------------------------------------------------------------------- /supervisor/bin/run-supervisord.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echoerr() { printf "%s\n" "$*" >&2; } 4 | 5 | # print error and exit 6 | die () { 7 | echoerr "ERROR: $1" 8 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "13" 9 | errnum=${2-13} 10 | exit $errnum 11 | } 12 | 13 | # Required params 14 | [ -z "${TAIL_LOG_LINES}" ] && die "Required TAIL_LOG_LINES" 15 | 16 | ga_track_shutdown () { 17 | if [ "${SEND_ANONYMOUS_USAGE_INFO}" == "true" ]; then 18 | DisplayDataProcessingAgreement 19 | DisplaySponsorRequest 20 | 21 | local args=( 22 | --max-time 10 23 | --data v=${GA_API_VERSION} 24 | --data aip=1 25 | --data t="screenview" 26 | --data tid="${GA_TRACKING_ID}" 27 | --data cid="${RANDOM_USER_GA_ID}" 28 | --data an="dosel" 29 | --data av="${DOSEL_VERSION}" 30 | --data cd="shutdown" 31 | --data sc="end" 32 | --data ds="docker" 33 | ) 34 | 35 | curl ${GA_ENDPOINT} "${args[@]}" \ 36 | --silent --output /dev/null >/dev/null 2>&1 37 | fi 38 | } 39 | 40 | # Exit all child processes properly 41 | shutdown () { 42 | echo "Trapped SIGTERM/SIGINT/x so shutting down supervisord gracefully..." 43 | # no longer tracking due to German law 44 | # ga_track_shutdown 45 | stop 46 | wait 47 | 48 | # when DISABLE_ROLLBACK=true it will: 49 | # - output logs 50 | # - exec bash to permit troubleshooting 51 | if [ "$(cat ${DOCKER_SELENIUM_STATUS})" = "failed" ]; then 52 | tail --lines=${TAIL_LOG_LINES} /var/log/cont/* 53 | echo "" && echo "" && echo "==> errors <==" 54 | errors 55 | 56 | if [ "${DISABLE_ROLLBACK}" = "true" ]; then 57 | echo "" 58 | echo "DEBUGGING: to find out what happened please analyze logs or run" 59 | echo " errors" 60 | echo "" 61 | 62 | exec bash 63 | else 64 | exit 122 65 | fi 66 | else 67 | exit 0 68 | fi 69 | } 70 | 71 | # Run function shutdown() when this process receives a killing signal 72 | trap shutdown SIGHUP SIGTERM SIGINT 73 | 74 | echo -n "supervisord --version=" && supervisord --version 75 | 76 | # supervisord -c /etc/supervisor/supervisord.conf --user ${USER} --nodaemon & 77 | supervisord -c /etc/supervisor/supervisord.conf --nodaemon & 78 | SUPERVISOR_PID=$! 79 | 80 | if [ "${DEBUG}" != "false" ]; then 81 | # Make sure all logs files are there so we can tail them 82 | touch /var/log/cont/chrome_browser.log 83 | touch /var/log/cont/docker-selenium-status.log 84 | touch /var/log/cont/firefox_browser.log 85 | touch /var/log/cont/fluxbox-tryouts-stderr.log 86 | touch /var/log/cont/fluxbox-tryouts-stdout.log 87 | touch /var/log/cont/selenium-node-chrome-stderr.log 88 | touch /var/log/cont/selenium-node-chrome-stdout.log 89 | touch /var/log/cont/selenium-node-firefox-stderr.log 90 | touch /var/log/cont/selenium-node-firefox-stdout.log 91 | touch /var/log/cont/supervisord.log 92 | touch /var/log/cont/vnc-stderr.log 93 | touch /var/log/cont/vnc-stdout.log 94 | touch /var/log/cont/vnc-tryouts-stderr.40675.log 95 | touch /var/log/cont/vnc-tryouts-stdout.40675.log 96 | touch /var/log/cont/wait-xmanager-stdout.log 97 | touch /var/log/cont/wait-xvfb.1.log 98 | touch /var/log/cont/wait-xvfb.2.log 99 | touch /var/log/cont/wait-xvfb-stdout.log 100 | touch /var/log/cont/xmanager-stderr.log 101 | touch /var/log/cont/xmanager-stdout.log 102 | touch /var/log/cont/xterm-stderr.log 103 | touch /var/log/cont/xterm-stdout.log 104 | touch /var/log/cont/xvfb-tryouts-stderr.log 105 | touch /var/log/cont/xvfb-tryouts-stdout.log 106 | 107 | (find /var/log/cont -type f \( -name "*.log" \) -exec tail -f "$file" {} +) & 108 | fi 109 | 110 | # tells bash to wait until child processes have exited 111 | wait "${SUPERVISOR_PID}" 112 | -------------------------------------------------------------------------------- /supervisor/etc/supervisor/supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | ;nodaemon=true is useful when running supervisor in docker so we 3 | ;can immediately attach docker to supervisor stdout/stderr 4 | nodaemon=true 5 | 6 | ;main log file;default $CWD/supervisord.log 7 | logfile=%(ENV_LOGS_DIR)s/supervisord.log 8 | 9 | ;max main logfile bytes b4 rotation;default 50MB 10 | logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 11 | 12 | ;num of main logfile rotation backups;default 10 13 | logfile_backups=%(ENV_LOGFILE_BACKUPS)s 14 | 15 | ;log level; default=info; options: debug,warn,trace 16 | ;debug will log all monitored process outputs 17 | ;an alternative to debug would be to tail all logs 18 | ;and pipe `ts` to inject the timestamp: 19 | ; tail -f %(ENV_LOGS_DIR)s/*.log --pid.... | ts 20 | loglevel=%(ENV_LOG_LEVEL)s 21 | 22 | ;supervisord pidfile;default supervisord.pid 23 | pidfile=%(ENV_SUPERVISOR_PIDFILE)s 24 | 25 | ;'AUTO' child log dir, default $TEMP 26 | childlogdir=%(ENV_LOGS_DIR)s 27 | 28 | ;The number of seconds to wait for the OS to return a SIGCHILD to 29 | ;supervisord after the program has been sent a stopsignal. 30 | ;If this number of seconds elapses before supervisord receives a SIGCHILD 31 | ;from the process, supervisord will attempt to kill it with a final. 32 | ;default=10 33 | stopwaitsecs=%(ENV_SUPERVISOR_STOPWAITSECS)s 34 | 35 | ;The signal used to kill the program when a stop is requested. 36 | ;This can be any of TERM, HUP, INT, QUIT, KILL, USR1, or USR2. 37 | ;Default: TERM. Required: No. Introduced: 3.0 38 | stopsignal=%(ENV_SUPERVISOR_STOPSIGNAL)s 39 | 40 | ;If true, when resorting to send SIGKILL to the program to terminate it 41 | ;send it to its whole process group instead, taking care of its children 42 | ;as well, useful e.g with Python programs using multiprocessing. 43 | ;Default: false. Required: No. Introduced: 3.0a11 44 | killasgroup=%(ENV_SUPERVISOR_KILLASGROUP)s 45 | 46 | ;If true, the flag causes supervisor to send the stop signal to the 47 | ;whole process group and implies killasgroup is true. 48 | ;This is useful for programs, such as Flask in debug mode, 49 | ;that do not propagate stop signals to their children, 50 | ;leaving them orphaned. 51 | ;Default: false. Required: No. Introduced: 3.0b1 52 | stopasgroup=%(ENV_SUPERVISOR_STOPASGROUP)s 53 | 54 | [unix_http_server] 55 | file=%(ENV_RUN_DIR)s/supervisor.sock 56 | username=%(ENV_SUPERVISOR_HTTP_USERNAME)s 57 | password=%(ENV_SUPERVISOR_HTTP_PASSWORD)s 58 | ;sockef file mode (default 0700) 59 | chmod=0700 60 | 61 | ; the below section must remain in the config file for RPC 62 | ; (supervisorctl/web interface) to work, additional interfaces may be 63 | ; added by defining them in separate rpcinterface: sections 64 | [rpcinterface:supervisor] 65 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface 66 | 67 | [supervisorctl] 68 | ; use a unix:// URL for a unix socket 69 | serverurl=unix://%(ENV_RUN_DIR)s/supervisor.sock 70 | username=%(ENV_SUPERVISOR_HTTP_USERNAME)s 71 | password=%(ENV_SUPERVISOR_HTTP_PASSWORD)s 72 | 73 | ; The [include] section can just contain the "files" setting. This 74 | ; setting can list multiple files (separated by whitespace or 75 | ; newlines). It can also contain wildcards. The filenames are 76 | ; interpreted as relative to this file. Included files *cannot* 77 | ; include files themselves. 78 | 79 | ;making port, username and password configurable via shell environment vars 80 | ;if no inet_http_server section then the inet HTTP server won't be started 81 | [inet_http_server] 82 | ;Note to listen on all interfaces in the machine, use :9001 or *:9001 83 | ;Note to listen only on localhost interface use 127.0.0.1:9001 84 | port=127.0.0.1:%(ENV_SUPERVISOR_HTTP_PORT)s 85 | username=%(ENV_SUPERVISOR_HTTP_USERNAME)s 86 | password=%(ENV_SUPERVISOR_HTTP_PASSWORD)s 87 | ;WARNING: Seems broken in current master branch: 88 | ;getting: TypeError: 'bool' object is not callable 89 | 90 | [include] 91 | files = /etc/supervisor/conf.d/*.conf 92 | -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | # selenium-test [![Build Status](https://travis-ci.org/elgalu/selenium-test.svg?branch=master)](https://travis-ci.org/elgalu/selenium-test) 2 | 3 | Hello world selenium test. 4 | 5 | If you want to see this running inside a docker container visit [selenium-test-dockerized][] or scroll down to the *Docker* section. 6 | 7 | ## Requisistes 8 | Add `sudo` only if you get permission denied. 9 | 10 | pip install --upgrade -r requirements.txt 11 | 12 | It needs a selenium server, for example [docker-selenium][] 13 | 14 | docker run -d --name=myselenium elgalu/selenium:latest 15 | docker exec myselenium wait_all_done 30s 16 | export SELENIUM_HUB_HOST=$(docker inspect -f='{{.NetworkSettings.IPAddress}}' myselenium) 17 | export SELENIUM_HUB_PORT=24444 18 | 19 | ## Run 20 | 21 | python python_test.py 22 | 23 | Sample output 24 | 25 | Will connect to selenium at http://172.17.0.6:24444/wd/hub 26 | Opening page http://www.google.com/adwords 27 | Current title: Google AdWords | Pay-per-Click-Onlinewerbung auf Google (PPC) 28 | Asserting 'Google AdWords' in driver.title 29 | Opening page http://www.python.org 30 | Asserting 'Python' in driver.title 31 | Finding element by name: q 32 | Sending keys 'pycon' 33 | Sending RETURN key 34 | Ensure no results were found 35 | Close driver and clean up 36 | All done. SUCCESS! 37 | 38 | ## Docker 39 | ### Build 40 | 41 | docker build -t elgalu/selenium-test . 42 | 43 | ### Run 44 | 45 | export SELENIUM_HUB_HOST=$(docker inspect -f='{{.NetworkSettings.IPAddress}}' myselenium) 46 | docker run --rm --name=test1 -ti -e SELENIUM_HUB_HOST elgalu/selenium-test 47 | 48 | 49 | [selenium-test-dockerized]: https://github.com/elgalu/selenium-test-dockerized 50 | [docker-selenium]: https://github.com/elgalu/docker-selenium 51 | -------------------------------------------------------------------------------- /test/after_script: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # long wait 4 | docker exec grid versions || true 5 | docker exec grid stop || true 6 | docker stop grid || true 7 | docker rm grid || true 8 | # quick destroy 9 | docker rm -vf grid_mock || true 10 | 11 | docker stop grid_x_user || true 12 | docker rm grid_x_user || true 13 | -------------------------------------------------------------------------------- /test/bef: -------------------------------------------------------------------------------- 1 | before_install_build -------------------------------------------------------------------------------- /test/before_install_build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | # set -x: print each command right before it is executed 5 | set -xe 6 | 7 | docker --version 8 | docker-compose --version 9 | 10 | if [[ ${TRAVIS_PULL_REQUEST_SLUG} != "" && \ 11 | ${TRAVIS_PULL_REQUEST_SLUG} != ${TRAVIS_REPO_SLUG} && \ 12 | ${TRAVIS_PULL_REQUEST} != "false" ]]; then 13 | echo "WARN: External PRs are untrusted by default therefore we need can't reuse and push the image" 14 | exit 0 15 | fi 16 | 17 | pip install --upgrade -r test/requirements.txt 18 | 19 | # We always need to login to docker to avoid: toomanyrequests 20 | [ "${DOCKER_USERNAME}" == "" ] && die "Need env var DOCKER_USERNAME to pull/push to docker" 21 | [ "${DOCKER_PASSWORD}" == "" ] && die "Need env var DOCKER_PASSWORD to pull/push to docker" 22 | 23 | docker login -u="${DOCKER_USERNAME}" -p="${DOCKER_PASSWORD}" 24 | echo "Logged in to docker with user '${DOCKER_USERNAME}'" 25 | 26 | ./host-scripts/gen-scm-source.sh 27 | docker build -t selenium . 28 | docker tag selenium:latest elgalu/selenium:latest 29 | docker images selenium 30 | 31 | if [ "${TRAVIS_BUILD_NUMBER}" != "" ]; then 32 | # Let's push this image to re-use it in TravisCI stages 33 | # in order to speed up the build 34 | docker tag selenium:latest elgalu/build_selenium:${TRAVIS_BUILD_NUMBER} 35 | docker push elgalu/build_selenium:${TRAVIS_BUILD_NUMBER} 36 | fi 37 | -------------------------------------------------------------------------------- /test/before_install_docker_linux: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | # set -x: print each command right before it is executed 5 | set -xe 6 | 7 | # cleanup 8 | # sudo service docker stop || true 9 | # sudo rm -f /etc/apt/sources.list.d/docker.list 10 | # sudo rm -f /usr/lib/systemd/system/docker.service 11 | # sudo apt -qqy purge lxc-docker || true 12 | # sudo apt -qqy purge docker-engine || true 13 | # sudo /etc/init.d/apparmor stop || true 14 | # sudo rm -rf /var/lib/docker /dev/mapper/docker* /usr/bin/docker /run/docker /etc/docker || true 15 | # sudo rm -rf /etc/apt/sources.list.d/docker* /etc/default/docker /etc/init.d/docker /etc/apparmor.d/cache/docker || true 16 | # sudo rm -rf /etc/apparmor.d/docker /etc/bash_completion.d/docker /var/log/upstart/docker* || true 17 | # sudo rm -rf /var/lib/apt/lists/*docker* /var/lib/dpkg/info/*docker* /dev/disk/by-id/*docker* || true 18 | # sudo rm -rf /var/cache/apt/archives/docker* || true 19 | # sudo chown -R ${USER} /home/travis/.gnupg || true 20 | 21 | # GPG servers aren't too reliable (especially in out test builds) 22 | # so fallback servers are needed 23 | # ref: https://github.com/nodejs/docker-node/issues/340#issuecomment-321669029 24 | # ref: http://askubuntu.com/a/235911/134645 25 | # ref: https://github.com/moby/moby/issues/20022#issuecomment-182169732 26 | set -ex 27 | for key in \ 28 | 2EA8F35793D8809A \ 29 | 40976EAF437D05B5 \ 30 | 3B4FE6ACC0B21F32 \ 31 | A2F683C52980AECF \ 32 | F76221572C52609D \ 33 | 58118E89F3A912897C070ADBF76221572C52609D \ 34 | ; do \ 35 | gpg --keyserver keyserver.ubuntu.com --recv-keys "$key" || \ 36 | gpg --keyserver pgp.mit.edu --recv-keys "$key" || \ 37 | gpg --keyserver keyserver.pgp.com --recv-keys "$key" || \ 38 | gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$key" ; \ 39 | done 40 | 41 | export DEBCONF_NONINTERACTIVE_SEEN=true 42 | 43 | # install docker (<=2018) 44 | # CODE_NAME=$(lsb_release -sc) #e.g. trusty 45 | # [ "${CODE_NAME}" == "" ] && CODE_NAME=trusty 46 | # sudo sh -c "echo 'deb [arch=amd64] https://download.docker.com/linux/ubuntu ${CODE_NAME} stable' >> /etc/apt/sources.list.d/docker.list" 47 | # # sed -i.bak '/docker/d' /etc/apt/sources.list.d/docker.list 48 | # sudo apt -qqy update 49 | # sudo apt -qqy install apt-transport-https ca-certificates 50 | 51 | # sudo apt-cache policy docker-engine || true 52 | # sudo apt -qqy install linux-image-extra-$(uname -r) 53 | # sudo apt -qqy install apparmor 54 | # sudo /etc/init.d/apparmor start || true 55 | # sudo apt -qqy install docker-engine 56 | # sudo apt -qyy install docker-ce 57 | 58 | # install docker (2019) 59 | # https://docs.travis-ci.com/user/docker/#installing-a-newer-docker-version 60 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 61 | sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" 62 | sudo apt -qqy update 63 | sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce 64 | 65 | # if [ "${DOCKER_VERSION}" != "stable" ]; then 66 | # # wget -nv -O docker.tgz "https://github.com/docker/docker/archive/v${DOCKER_VERSION}.tar.gz" 67 | # # tar xvzf docker.tgz 68 | # # mv docker-${DOCKER_VERSION} docker_src 69 | # # mv docker_src/* /usr/bin/ 70 | # wget -nv -O docker.tgz "https://test.docker.com/builds/Linux/x86_64/docker-${DOCKER_VERSION}.tgz" 71 | # tar -xvzf docker.tgz 72 | # sudo mv docker/* /usr/bin/ 73 | # sudo service docker stop || true 74 | # fi 75 | 76 | sudo service docker start || true 77 | 78 | docker --version 79 | -------------------------------------------------------------------------------- /test/before_install_docker_osx: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | # set -x: print each command right before it is executed 5 | set -xe 6 | 7 | # ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 8 | brew update 9 | brew install wget || true 10 | 11 | # https://github.com/caskroom/homebrew-cask/blob/master/USAGE.md#other-ways-to-specify-a-cask 12 | # brew cask install ./osx/dockertoolbox-rc.rb --force 13 | brew install docker docker-compose docker-machine docker-machine-driver-xhyve boot2docker 14 | sudo chown root:wheel /usr/local/bin/docker-machine-driver-xhyve || true 15 | sudo chmod u+s /usr/local/bin/docker-machine-driver-xhyve || true 16 | 17 | # We don't want to use docker-machine 18 | # docker-machine stop default || true 19 | 20 | # Currently erroring: 21 | # https://travis-ci.org/elgalu/docker-selenium/jobs/143358317 22 | # com.docker.docker Incompatible CPU detected 23 | # Docker requires a processor with virtualization capabilities 24 | # /Applications/Docker.app/Contents/MacOS/Docker & 25 | # sleep 20 26 | brew services start docker-machine 27 | docker-machine create default --driver xhyve --xhyve-experimental-nfs-share || true 28 | docker-machine start 29 | #=> ERROR! vmx_init: processor not supported by Hypervisor.framework 30 | # Apparently due to Travis using old Mac machines 31 | # we will have to wait a couple of years 32 | 33 | # Below will fail with 34 | # Error with pre-create check: 35 | # This computer doesn't have VT-X/AMD-v enabled. 36 | # Enabling it in the BIOS is mandatory 37 | # for the time being, see 38 | # https://github.com/travis-ci/travis-ci/issues/5738#issuecomment-227167082 39 | # docker-machine --restart || true 40 | # docker-machine create --driver virtualbox default || true 41 | # docker-machine --version 42 | # docker-machine ls 43 | # eval "$(docker-machine env default)" 44 | docker --version 45 | docker-compose --version 46 | docker-machine version 47 | # docker-machine env default 48 | #=> Host does not exist: "default" 49 | # docker-machine create --driver virtualbox default 50 | #=> Error with pre-create check: 51 | #=> "VBoxManage not found. Make sure VirtualBox is installed 52 | #=> and VBoxManage is in the path" 53 | eval "$(docker-machine env default)" || true 54 | docker run --rm -t ubuntu uname -a 55 | docker build -t selenium . 56 | -------------------------------------------------------------------------------- /test/before_install_pull: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | # set -x: print each command right before it is executed 5 | set -xe 6 | 7 | echoerr() { printf "%s\n" "$*" >&2; } 8 | 9 | # print error and exit 10 | die () { 11 | echoerr "ERROR: $1" 12 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "150" 13 | errnum=${2-133} 14 | exit $errnum 15 | } 16 | 17 | docker --version || echo "WARN: No docker installed yet" 18 | docker-compose --version || echo "WARN: No docker-compose installed yet" 19 | 20 | [ "${TRAVIS_BUILD_NUMBER}" == "" ] && die "Need env var TRAVIS_BUILD_NUMBER to know where to pull from" 21 | 22 | # We always need to login to docker to avoid: toomanyrequests 23 | [ "${DOCKER_USERNAME}" == "" ] && die "Need env var DOCKER_USERNAME to pull from docker" 24 | [ "${DOCKER_PASSWORD}" == "" ] && die "Need env var DOCKER_PASSWORD to pull from docker" 25 | 26 | docker login -u="${DOCKER_USERNAME}" -p="${DOCKER_PASSWORD}" 27 | echo "Logged in to docker with user '${DOCKER_USERNAME}'" 28 | 29 | if [[ ${TRAVIS_PULL_REQUEST_SLUG} != "" && \ 30 | ${TRAVIS_PULL_REQUEST_SLUG} != ${TRAVIS_REPO_SLUG} && \ 31 | ${TRAVIS_PULL_REQUEST} != "false" ]]; then 32 | echo "WARN: External PRs are untrusted by default therefore we need can't reuse and pull the image so building it from scratch..." 33 | # ./test/before_install_setup 34 | ./host-scripts/gen-scm-source.sh 35 | docker build -t selenium . 36 | docker tag selenium:latest elgalu/selenium:latest 37 | else 38 | docker pull elgalu/build_selenium:${TRAVIS_BUILD_NUMBER} 39 | docker tag elgalu/build_selenium:${TRAVIS_BUILD_NUMBER} selenium:latest 40 | docker tag elgalu/build_selenium:${TRAVIS_BUILD_NUMBER} elgalu/selenium:latest 41 | fi 42 | 43 | docker images selenium 44 | docker images elgalu/selenium 45 | -------------------------------------------------------------------------------- /test/before_install_setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | # set -x: print each command right before it is executed 5 | set -xe 6 | 7 | # Docker 8 | docker --version || echo "INFO: No docker installed yet" 9 | if [ "${TRAVIS_OS_NAME}" = "osx" ]; then 10 | # # Let's wait until Travis provides Docker for OSX 11 | # docker --version || exit 0 12 | # docker --version && exit 1 #that's how I'll know 13 | ./test/before_install_docker_osx 14 | # https://github.com/github/hub#homebrew 15 | else 16 | ./test/before_install_docker_linux 17 | fi 18 | docker --version || (echo "FATAL: No docker installed" && exit 1) 19 | 20 | # Docker Compose 21 | docker-compose --version || (echo "FATAL: No docker compose installed" && exit 1) 22 | -------------------------------------------------------------------------------- /test/compose-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | # set -x: print each command right before it is executed 5 | set -xe 6 | 7 | echoerr() { printf "%s\n" "$*" >&2; } 8 | 9 | # print error and exit 10 | die () { 11 | echoerr "ERROR: $1" 12 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "160" 13 | errnum=${2-160} 14 | exit $errnum 15 | } 16 | 17 | # Required params or defaults 18 | [ -z "${NUM_NODES}" ] && die "Required env var NUM_NODES" 19 | [ -z "${PARAL_TESTS}" ] && die "Required env var PARAL_TESTS" 20 | [ -z "${WAIT_ALL_DONE}" ] && export WAIT_ALL_DONE="40s" 21 | [ -z "${PAUSE_SECS_BETWEEN_RUN_TEST}" ] && export PAUSE_SECS_BETWEEN_RUN_TEST="0" 22 | [ -z "${SLEEP_TIME}" ] && die "Required env var SLEEP_TIME" 23 | 24 | # Ensure clean 25 | docker-compose -f ${COMPOSE_FILE} -p grid down || true 26 | 27 | # Compose up! 28 | if [ "${DO_COMPOSE_UP}" = "true" ]; then 29 | docker-compose -f ${COMPOSE_FILE} -p grid up -d 30 | fi 31 | 32 | # Compose scale! 33 | docker-compose -f ${COMPOSE_FILE} -p grid scale mock=1 hub=1 chrome=${NUM_NODES} firefox=${NUM_NODES} 34 | 35 | # FIXME: We still need to wait a bit because the nodes registration is not 36 | # being waited on wait_all_done script :( 37 | # mabe related to issue #83 38 | sleep ${SLEEP_TIME} 39 | 40 | # Wait then show errors, if any 41 | if ! docker-compose -f ${COMPOSE_FILE} -p grid exec --index=1 hub wait_all_done ${WAIT_ALL_DONE}; then 42 | docker-compose -f ${COMPOSE_FILE} -p grid exec --index=1 hub errors || docker ps -a 43 | docker-compose -f ${COMPOSE_FILE} -p grid logs hub 44 | die "$0 Failed to start the Hub" 45 | fi 46 | 47 | for i in $(seq 1 ${NUM_NODES}); do 48 | if ! docker-compose -f ${COMPOSE_FILE} -p grid exec --index ${i} chrome wait_all_done ${WAIT_ALL_DONE}; then 49 | docker-compose -f ${COMPOSE_FILE} -p grid logs chrome 50 | docker-compose -f ${COMPOSE_FILE} -p grid exec --index ${i} chrome errors || true 51 | die "Failed to start Node chrome ${i}" 52 | fi 53 | if ! docker-compose -f ${COMPOSE_FILE} -p grid exec --index ${i} firefox wait_all_done ${WAIT_ALL_DONE}; then 54 | docker-compose -f ${COMPOSE_FILE} -p grid logs firefox 55 | docker-compose -f ${COMPOSE_FILE} -p grid exec --index ${i} firefox errors || true 56 | die "Failed to start Node firefox ${i}" 57 | fi 58 | done 59 | 60 | # FIXME: We still need to wait a bit because the nodes registration is not 61 | # being waited on wait_all_done script :( 62 | # mabe related to issue #83 63 | sleep ${SLEEP_TIME} 64 | 65 | # Tests can run anywere, in the hub, in the host, doesn't matter 66 | for i in $(seq 1 ${PARAL_TESTS}); do 67 | # Need to sleep a bit between tests to avoid 68 | # https://github.com/SeleniumHQ/selenium/issues/2442 69 | sleep ${PAUSE_SECS_BETWEEN_RUN_TEST} 70 | # Docker-ompose exec is giving me error: 71 | # in dockerpty/io.py", line 42, in set_blocking 72 | # ValueError: file descriptor cannot be a negative integer (-1) 73 | # docker-compose -f ${COMPOSE_FILE} -p grid exec --index 1 hub run_test & 74 | docker-compose -f ${COMPOSE_FILE} -p grid exec --index=1 hub selenium_test chrome & 75 | docker-compose -f ${COMPOSE_FILE} -p grid exec --index=1 hub selenium_test firefox & 76 | done 77 | 78 | # sleep a moment to let the UI tests start 79 | sleep ${SLEEP_TIME} 80 | 81 | # not so verbose from here 82 | set +x 83 | 84 | # http://jeremy.zawodny.com/blog/archives/010717.html 85 | FAIL_COUNT=0 86 | for job in `jobs -p`; do 87 | wait $job || let "FAIL_COUNT+=1" 88 | done 89 | 90 | # Show logs also 91 | docker-compose -f ${COMPOSE_FILE} -p grid logs hub 92 | docker-compose -f ${COMPOSE_FILE} -p grid logs chrome 93 | docker-compose -f ${COMPOSE_FILE} -p grid logs firefox 94 | # for i in $(seq 1 ${NUM_NODES}); do 95 | # docker logs grid_chrome_${i} 96 | # docker logs grid_firefox_${i} 97 | # done 98 | 99 | # Cleanup 100 | docker-compose -f ${COMPOSE_FILE} -p grid down 101 | 102 | # Results 103 | if [ "$FAIL_COUNT" == "0" ]; then 104 | echo "Awesome! $PARAL_TESTS tests succeeded and $FAIL_COUNT tests failed" 105 | else 106 | die "In total $FAIL_COUNT tests failed" 107 | fi 108 | -------------------------------------------------------------------------------- /test/docker-compose.yml: -------------------------------------------------------------------------------- 1 | ../docker-compose.yml -------------------------------------------------------------------------------- /test/install_bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set +e 5 | 6 | which bats >/dev/null 2>&1 7 | if [ $? -ne 0 ] ; then 8 | echo "Install bats for testing shell scripts." 9 | if [ "$(uname)" = 'Darwin' ]; then 10 | brew install bats 11 | else 12 | git clone https://github.com/sstephenson/bats.git 13 | cd bats 14 | sudo ./install.sh /usr/local 15 | fi 16 | fi 17 | -------------------------------------------------------------------------------- /test/install_hub_cli: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | # set -x: print each command right before it is executed 5 | set -xe 6 | 7 | if [ "${TRAVIS_OS_NAME}" = "osx" ]; then 8 | brew install hub 9 | else 10 | mkdir -p tmp_hub 11 | cd tmp_hub 12 | 13 | wget -nv -O hub.tgz "https://github.com/github/hub/releases/download/v2.3.0-pre10/hub-linux-amd64-2.3.0-pre10.tgz" 14 | tar -xvzf hub.tgz 15 | ./hub*/bin/hub --version 16 | sudo mv hub*/bin/hub /usr/bin/ 17 | 18 | cd .. 19 | rm -rf tmp_hub 20 | fi 21 | -------------------------------------------------------------------------------- /test/requirements.txt: -------------------------------------------------------------------------------- 1 | selenium==3.141.0 2 | retrying>=1.3.3 3 | -------------------------------------------------------------------------------- /test/run_locally.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | run_sequence() { 7 | ./test/bef 8 | ./test/script_run_all_tests 9 | ./test/script_archive 10 | } 11 | 12 | # Not all environments have the `time` command installed 13 | if which time >/dev/null 2>&1; then 14 | time (run_sequence) 15 | else 16 | run_sequence 17 | fi 18 | 19 | git checkout scm-source.json 20 | -------------------------------------------------------------------------------- /test/run_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | if [ "${VIDEO}" = "true" ]; then 7 | # backup 8 | stop-video || true 9 | mkdir -p /test/videos/bup/ 10 | mv /videos/* /test/videos/bup/ 11 | fi 12 | 13 | selenium_test chrome 14 | selenium_test firefox 15 | selenium_test mobile_emulation 16 | 17 | if [ "${VIDEO}" = "true" ]; then 18 | # restore backup 19 | mv /test/videos/bup/* /videos/ 20 | start-video 21 | fi 22 | -------------------------------------------------------------------------------- /test/script_archive: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | echo "#==================" 7 | echo "# Archive artifacts" 8 | echo "#==================" 9 | # pending to upload to S3 bucket 10 | docker cp grid:/test/console.png ./images/grid3_console.png 11 | ls -la ./images/ 12 | mkdir -p ./videos 13 | docker cp grid:/test/videos/chrome ./videos/ 14 | docker cp grid:/test/videos/firefox ./videos/ 15 | docker cp grid:/test/videos/mobile_emulation ./videos/ 16 | ls -la ./videos/chrome 17 | ls -la ./videos/firefox 18 | ls -la ./videos/mobile_emulation 19 | ls -la ./videos/ 20 | -------------------------------------------------------------------------------- /test/script_bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set +e 5 | 6 | echo "#=======================" 7 | echo "# Scenario 0: Unit tests" 8 | echo "#=======================" 9 | 10 | # Due to the dependency GNU sed, we're skipping this part when running 11 | # on Mac OS X. 12 | # https://github.com/SeleniumHQ/docker-selenium/blob/master/test.sh#L12 13 | if [ "$(uname)" != 'Darwin' ]; then 14 | echo 'Testing shell functions...' 15 | which bats >/dev/null 2>&1 16 | if [ $? -ne 0 ] ; then 17 | echo "Could not find 'bats'. Please install it first, e.g., following https://github.com/sstephenson/bats#installing-bats-from-source." 18 | exit 1 19 | fi 20 | ./test/test-functions.sh || exit 1 21 | else 22 | echo 'Skipping shell functions test on Mac OS X.' 23 | fi 24 | -------------------------------------------------------------------------------- /test/script_run_all_tests: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | # set -x: print each command right before it is executed 5 | set -xe 6 | 7 | rm -rf ./videos ./tmp_videos 8 | ./test/script_bats 9 | 10 | # In Travis these ones require travis_retry 11 | if [ "${CI}" != "true" ]; then 12 | ./test/script_scenario_basic 13 | ./test/script_scenario_arbitrary_uid 14 | ./test/script_scenario_restart 15 | ./test/script_scenario_node_dies 16 | ./test/script_scenario_compose_N_N 17 | ./test/script_scenario_zalenium 18 | fi 19 | -------------------------------------------------------------------------------- /test/script_scenario_arbitrary_uid: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | # set -x: print each command right before it is executed 5 | set -xe 6 | 7 | function get_mock_ip() { 8 | docker inspect -f='{{.NetworkSettings.IPAddress}}' grid_mock 9 | } 10 | 11 | set +x 12 | echo "#================================" 13 | echo "# Scenario 1e [basic]: Setup mock" 14 | echo "#================================" 15 | set -x 16 | 17 | docker rm -vf grid_mock || true 18 | 19 | export MOCK_SERVER_PORT=8280 20 | 21 | docker run -d -t --name=grid_mock -e MOCK_SERVER_PORT \ 22 | -p $MOCK_SERVER_PORT:$MOCK_SERVER_PORT \ 23 | elgalu/google_adwords_mock 24 | 25 | docker attach grid_mock & 26 | 27 | export MOCK_SERVER_HOST=$(get_mock_ip) 28 | 29 | while ! curl -s "http://localhost:${MOCK_SERVER_PORT}/adwords"; do 30 | echo -n '.' 31 | sleep 0.2 32 | done 33 | 34 | set +x 35 | echo "#=======================================================================" 36 | echo "# Scenario 1e [basic]: Make sure it can run with an arbitrary uid number" 37 | echo "#=======================================================================" 38 | set -x 39 | 40 | docker rm -vf grid_x_user || true 41 | 42 | docker run --name=grid_x_user -d -e VIDEO=true \ 43 | -e MOCK_SERVER_HOST \ 44 | -e MOCK_SERVER_PORT \ 45 | -e CI \ 46 | -v /dev/shm:/dev/shm \ 47 | -u 1000060000:1000060000 \ 48 | selenium 49 | 50 | docker logs grid_x_user 51 | docker attach grid_x_user & 52 | 53 | docker exec grid_x_user wait_all_done 70s 54 | docker exec grid_x_user versions 55 | docker exec grid_x_user errors || true 56 | docker logs grid_x_user 57 | 58 | if ! docker exec -t grid_x_user run_test; then 59 | docker logs grid_x_user 60 | docker exec grid_x_user errors || true 61 | exit 103 62 | fi 63 | 64 | # Test videos 65 | docker exec grid_x_user stop-video 66 | docker logs grid_x_user 67 | docker exec -t grid_x_user log "-- DEBUG: video-rec-stdout.log ----" 68 | docker exec -t grid_x_user tail -n 40 /var/log/cont/video-rec-stdout.log || true 69 | docker exec -t grid_x_user log "-- DEBUG: video-rec-stderr.log ----" 70 | docker exec -t grid_x_user tail -n 40 /var/log/cont/video-rec-stderr.log || true 71 | 72 | set +x 73 | echo "#=============================================================================" 74 | echo "# Scenario 1f [basic]: arbitrary uid + REMOVE_SELUSER_FROM_SUDOERS_FOR_TESTING" 75 | echo "#=============================================================================" 76 | set -x 77 | 78 | docker stop grid_x_user 79 | docker rm grid_x_user 80 | 81 | docker run --name=grid_x_user -d -e VIDEO=true \ 82 | -e MOCK_SERVER_HOST \ 83 | -e MOCK_SERVER_PORT \ 84 | -e REMOVE_SELUSER_FROM_SUDOERS_FOR_TESTING=true \ 85 | -e CI \ 86 | -v /dev/shm:/dev/shm \ 87 | -u 1000060000:1000060000 \ 88 | selenium 89 | 90 | docker logs grid_x_user 91 | docker attach grid_x_user & 92 | 93 | docker exec grid_x_user wait_all_done 70s 94 | docker exec grid_x_user versions 95 | docker exec grid_x_user errors || true 96 | docker logs grid_x_user 97 | 98 | if ! docker exec -t grid_x_user run_test; then 99 | docker logs grid_x_user 100 | docker exec grid_x_user errors || true 101 | exit 103 102 | fi 103 | 104 | # Test videos 105 | docker exec grid_x_user stop-video 106 | docker logs grid_x_user 107 | docker exec -t grid_x_user log "-- DEBUG: video-rec-stdout.log ----" 108 | docker exec -t grid_x_user tail -n 40 /var/log/cont/video-rec-stdout.log || true 109 | docker exec -t grid_x_user log "-- DEBUG: video-rec-stderr.log ----" 110 | docker exec -t grid_x_user tail -n 40 /var/log/cont/video-rec-stderr.log || true 111 | -------------------------------------------------------------------------------- /test/script_scenario_compose_N_N: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "#====================================================" 4 | echo "# Scenario 6a [compose_N_N]: Docker Compose many nodes" 5 | echo "#====================================================" 6 | 7 | # set -e: exit asap if a command exits with a non-zero status 8 | # set -x: print each command right before it is executed 9 | set -xe 10 | 11 | export VNC_FROM_PORT="43900" VNC_TO_PORT="43950" 12 | 13 | export NUM_NODES=2 PARAL_TESTS=2 WAIT_ALL_DONE="390s" SLEEP_TIME=10 PAUSE_SECS_BETWEEN_RUN_TEST="0" 14 | 15 | export COMPOSE_FILE="docker-compose-host.yml" \ 16 | DO_COMPOSE_UP="false" 17 | ./test/compose-test.sh 18 | 19 | set +x 20 | echo "#===================================================================" 21 | echo "# Scenario 6b [compose_N_N]: Docker Compose many nodes and no video" 22 | echo "#===================================================================" 23 | set -x 24 | 25 | export VIDEO="false" 26 | export AUDIO="false" 27 | export NUM_NODES=2 PARAL_TESTS=2 WAIT_ALL_DONE="390s" SLEEP_TIME=10 PAUSE_SECS_BETWEEN_RUN_TEST="0" 28 | 29 | export VNC_FROM_PORT="26950" VNC_TO_PORT="26999" 30 | export COMPOSE_FILE="docker-compose-tests.yml" \ 31 | DO_COMPOSE_UP="true" 32 | ./test/compose-test.sh 33 | -------------------------------------------------------------------------------- /test/script_scenario_make: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "#================================================" 4 | echo "# Scenario 4a [make]: Docker Compose many nodes" 5 | echo "#================================================" 6 | 7 | # set -e: exit asap if a command exits with a non-zero status 8 | # set -x: print each command right before it is executed 9 | set -xe 10 | 11 | export TESTING_MAKE="true" \ 12 | VNC_FROM_PORT="5010" VNC_TO_PORT="5030" 13 | 14 | if [ "${CI}" = "true" ]; then 15 | make setup compose chrome=2 firefox=1 16 | else 17 | make setup compose chrome=2 firefox=1 18 | make scale chrome=2 firefox=2 19 | # also has a real display so we can "see" 20 | make see browser=chrome node=1 21 | fi 22 | 23 | make wait 24 | make test 25 | rm -f videos/*.mp4 26 | make videos 27 | make cleanup 28 | make down 29 | docker rm -vf grid_hub_1 || true 30 | 31 | set +x 32 | echo "#===================================" 33 | echo "# Scenario 4b [make]: wget Makefile" 34 | echo "#===================================" 35 | set -x 36 | 37 | # Test clean directory 38 | if [ "${TRAVIS_PULL_REQUEST}" == "true" ]; then 39 | echo "This is a PR so will skip to test make clean dir" 40 | export GIT_TAG_OR_BRANCH="" 41 | elif [ "${TRAVIS_TAG}" != "" ]; then 42 | export GIT_TAG_OR_BRANCH="${TRAVIS_TAG}" 43 | elif [ "${TRAVIS_COMMIT}" != "" ]; then 44 | export GIT_TAG_OR_BRANCH="${TRAVIS_COMMIT}" 45 | else 46 | export GIT_TAG_OR_BRANCH="master" 47 | fi 48 | 49 | if [ "${GIT_TAG_OR_BRANCH}" != "" ]; then 50 | mkdir -p tmp_make 51 | cd tmp_make 52 | ln -s ../Makefile || true 53 | export VNC_FROM_PORT="5110" VNC_TO_PORT="5120" 54 | make get setup 55 | if [ "${CI}" = "true" ]; then 56 | make install_vnc install_wmctrl 57 | fi 58 | # Test default 1 chrome 1 firefox case 59 | make 60 | make wait 61 | make test 62 | # Test alias 63 | make down 64 | cd .. 65 | fi 66 | -------------------------------------------------------------------------------- /test/script_scenario_restart: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | # set -x: print each command right before it is executed 5 | set -xe 6 | 7 | SLEEP_RACE_COND_SECS=2 8 | WAIT_ALL_DONE="40s" 9 | 10 | if [ "${CI}" = "true" ]; then 11 | SLEEP_RACE_COND_SECS=7 #to avoid issue #83 12 | WAIT_ALL_DONE="200s" 13 | fi 14 | 15 | set +x 16 | echo "#======================================" 17 | echo "# Scenario 2a [restart]: Normal restart" 18 | echo "#======================================" 19 | set -x 20 | 21 | docker restart grid #normal restart 22 | # docker restart grid_mock #only needed when sharing the network interface 23 | sleep ${SLEEP_RACE_COND_SECS} 24 | docker exec grid wait_all_done ${WAIT_ALL_DONE} 25 | docker logs grid 26 | docker exec grid errors || true 27 | docker exec -t grid run_test 28 | 29 | set +x 30 | echo "#========================================================================" 31 | echo "# Scenario 2b [restart]: Forced quick container restart + run tests again" 32 | echo "#========================================================================" 33 | set -x 34 | 35 | docker restart --time=0 grid #forced quick restart 36 | # docker restart --time=0 grid_mock #only needed when sharing the network interface 37 | sleep ${SLEEP_RACE_COND_SECS} 38 | docker exec grid wait_all_done ${WAIT_ALL_DONE} 39 | docker logs grid 40 | docker exec grid errors || true 41 | docker exec -t grid run_test 42 | -------------------------------------------------------------------------------- /test/script_scenario_zalenium: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | # set -x: print each command right before it is executed 5 | set -xe 6 | 7 | echoerr() { printf "%s\n" "$*" >&2; } 8 | 9 | # print error and exit 10 | die () { 11 | echoerr "ERROR: $1" 12 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "150" 13 | errnum=${2-188} 14 | exit $errnum 15 | } 16 | 17 | set +x 18 | echo "#====================================================" 19 | echo "# Scenario 7a [zalenium]: Integration" 20 | echo "# with Zalenium and the one-liner should still work" 21 | echo "#====================================================" 22 | set -x 23 | 24 | function stop_zalenium() { 25 | curl -sSL https://raw.githubusercontent.com/dosel/t/i/p | \ 26 | PULL_DEPENDENCIES=false bash -s \ 27 | stop 28 | } 29 | 30 | # Cleanup 31 | stop_zalenium 32 | rm -rf $(pwd)/tmp_videos || true 33 | 34 | # Can take Zalenium docker tag as first argument 35 | _zalenium_tag=${1-latest} 36 | 37 | # Dependencies 38 | pip install --upgrade -r test/requirements.txt 39 | docker pull dosel/zalenium:${_zalenium_tag} 40 | docker tag dosel/zalenium:${_zalenium_tag} dosel/zalenium:latest 41 | 42 | # Use Zalenium one-liner but don't pull 43 | # TODO: --maxTestSessions 5 44 | curl -sSL https://raw.githubusercontent.com/dosel/t/i/p | \ 45 | PULL_DEPENDENCIES=false bash -s \ 46 | start --desiredContainers 0 \ 47 | --videos-dir $(pwd)/tmp_videos 48 | 49 | set +x 50 | 51 | docker logs zalenium 52 | 53 | # Usage 54 | # bash parallel.sh {browser} {threads} {test-per-thread=5} 55 | VIDEO=true bash test/parallel.sh hybrid 2 3 56 | 57 | # There should be a dashboard 58 | if ! ls -la tmp_videos/dashboard.html; then 59 | die "The dashboard.html file is missing but should be there" 110 60 | fi 61 | 62 | # There should be (2 * 3) videos 63 | if ! ls -la tmp_videos/zalenium_build/*.mp4; then 64 | ls -la tmp_videos/ || true 65 | die "Video files were not found in the expected folder" 120 66 | fi 67 | 68 | export VID_EXT="mp4" 69 | export EXPECTED_VID_COUNT="6" 70 | export VID_FOLDER="tmp_videos/zalenium_build" 71 | 72 | # Wait up to 40 seconds for the videos to be there 73 | if [ "$(uname)" = 'Darwin' ]; then 74 | ./test/wait_videos_count 75 | else 76 | if ! timeout --foreground 40s test/wait_videos_count; then 77 | ls -la tmp_videos/zalenium_build/ || true 78 | die "Waited a few seconds for '${EXPECTED_VID_COUNT}' '${VID_EXT}' videos to be at ${VID_FOLDER}" 79 | fi 80 | fi 81 | 82 | # Cleanup 83 | stop_zalenium 84 | 85 | # Upload videos to 86 | # http://zalenium.bitballoon.com/dashboard.html 87 | if [ "${BITBALLOON_ACCESS_TOKEN}" != "" ] && [ "${BITBALLOON_SITE_ID}" != "" ]; then 88 | # Only update the site upon releases 89 | if [ "${TRAVIS_TAG}" != "" ]; then 90 | echo "{\"access_token\":\"${BITBALLOON_ACCESS_TOKEN}\",\"site_id\":\"${BITBALLOON_SITE_ID}\"}" > .bitballoon 91 | if ls -la tmp_videos/; then 92 | bitballoon deploy tmp_videos/ || true 93 | #=> Site deployed: http://zalenium.bitballoon.com 94 | else 95 | echo "ERROR! We need tmp_videos/ to upload to bitballoon" 96 | fi 97 | fi 98 | fi 99 | -------------------------------------------------------------------------------- /test/selenium_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | echoerr() { printf "%s\n" "$*" >&2; } 7 | 8 | # print error and exit 9 | die () { 10 | echoerr "ERROR: $1" 11 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "3" 12 | errnum=${2-3} 13 | exit $errnum 14 | } 15 | 16 | # Required params 17 | [ -z "${1}" ] && die "Need first argument to be the browser name" 18 | browser_name=${1} 19 | 20 | echo "----------------------------------------" 21 | echo "- Self test on ${browser_name}" 22 | echo "----------------------------------------" 23 | 24 | if [ "${VIDEO}" = "true" ]; then 25 | stop-video >/dev/null 2>&1 || true 26 | rm -f /test/videos/${browser_name}/* 27 | start-video 28 | fi 29 | 30 | # Install the correct version of selenium binding 31 | # How to find old versions? 32 | # https://pypi.python.org/simple/selenium/ 33 | mkdir -p ${HOME}/.local 34 | # pip install --user --requirement /test/requirements.txt 35 | 36 | python_test ${browser_name} 37 | 38 | if [ "${VIDEO}" = "true" ]; then 39 | stop-video 40 | mkdir -p /test/videos/${browser_name} 41 | mv /videos/* /test/videos/${browser_name}/ 42 | 43 | for f in /test/videos/${browser_name}/*; do 44 | # Validate the videos are correctly encoded 45 | if MP4Box -isma -inter \ 46 | ${MP4_INTERLEAVES_MEDIA_DATA_CHUNKS_SECS} ${f} 2>&1 | \ 47 | grep "Error opening"; then 48 | die "MP4Box got errors meaning the mp4 video file is corrupted!" 49 | fi 50 | done 51 | fi 52 | 53 | # How to archive console.png and videos from the docker host: 54 | # docker cp grid:/test/console.png . 55 | # docker cp grid:/test/videos/chrome/test.mp4 chrome.mp4 56 | # docker cp grid:/test/videos/firefox/test.mp4 firefox.mp4 57 | -------------------------------------------------------------------------------- /test/test-functions.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | source ./bin/functions.sh 4 | 5 | # Tests for function get_server_num 6 | # 7 | # https://github.com/SeleniumHQ/docker-selenium/blob/master/NodeBase/test-functions.sh 8 | # Test data from http://askubuntu.com/questions/432255/what-is-display-environment-variable 9 | @test 'get_server_num of :99.1' { 10 | 11 | export DISPLAY=':99.1' 12 | expected_result='99' 13 | result="$(get_server_num)" 14 | echo "result: $result" 15 | [ "$result" == "$expected_result" ] 16 | } 17 | 18 | @test 'get_server_num of :0' { 19 | 20 | export DISPLAY=':0' 21 | expected_result='0' 22 | result="$(get_server_num)" 23 | echo "result: $result" 24 | [ "$result" == "$expected_result" ] 25 | } 26 | 27 | @test 'get_server_num of localhost:4' { 28 | 29 | export DISPLAY='localhost:4' 30 | expected_result='4' 31 | result="$(get_server_num)" 32 | echo "result: $result" 33 | [ "$result" == "$expected_result" ] 34 | } 35 | 36 | @test 'get_server_num of google.com:0' { 37 | 38 | export DISPLAY='google.com:0' 39 | expected_result='0' 40 | result="$(get_server_num)" 41 | echo "result: $result" 42 | [ "$result" == "$expected_result" ] 43 | } 44 | 45 | @test 'get_server_num of google.com:99.1' { 46 | 47 | export DISPLAY='google.com:99.1' 48 | expected_result='99' 49 | result="$(get_server_num)" 50 | echo "result: $result" 51 | [ "$result" == "$expected_result" ] 52 | } 53 | -------------------------------------------------------------------------------- /test/wait_videos_count: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | echoerr() { printf "%s\n" "$*" >&2; } 7 | 8 | # print error and exit 9 | die () { 10 | echoerr "ERROR: $1" 11 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "160" 12 | errnum=${2-160} 13 | exit $errnum 14 | } 15 | 16 | # Required params 17 | [ -z "${VID_EXT}" ] && die "Need env var VID_EXT" 18 | [ -z "${EXPECTED_VID_COUNT}" ] && die "Need env var EXPECTED_VID_COUNT" 19 | [ -z "${VID_FOLDER}" ] && die "Need env var VID_FOLDER" 20 | 21 | echo "Waiting for total ${VID_EXT} videos to be ${EXPECTED_VID_COUNT}" 22 | while [ $(ls -1q ${VID_FOLDER}/*.${VID_EXT} 2>/dev/null | wc -l) -lt ${EXPECTED_VID_COUNT} ]; do 23 | echo -n '.' 24 | sleep 0.2; 25 | done 26 | echo "SUCCESS: Videos count ${EXPECTED_VID_COUNT} was reached." 27 | -------------------------------------------------------------------------------- /utils/bin/chrome_node_logs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | grep -Ev 'webSocketsHandshake|visual|colormap|bits|DirectColor|TrueColor|depth:|masks:|screen' \ 4 | /var/log/cont/* | grep "selenium-node-chrome" 5 | -------------------------------------------------------------------------------- /utils/bin/docker_alongside_docker.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # If docker running with 4 | # -v /var/run/docker.sock:/var/run/docker.sock 5 | # -v $(which docker):$(which docker) 6 | # Fix perms to avoid sudo when the docker container can docker run 7 | # outside of itself. Useful for integration environments for ex. 8 | if [ -S "${DOCKER_SOCK}" ]; then 9 | TARGET_GID=$(stat -c "%g" ${DOCKER_SOCK}) 10 | EXISTS=$(cat /etc/group | grep $TARGET_GID | wc -l) 11 | # Create new group using target GID and add seluser 12 | if [ ${EXISTS} == "0" ]; then 13 | GROUP_NAME="dockersockgrphelper" 14 | # Create the group as it doesn't exist yet 15 | sudo groupadd -g ${TARGET_GID} seluser 16 | else 17 | # GID exists, find the group name 18 | GROUP_NAME=$(getent group ${TARGET_GID} | cut -d: -f1) 19 | fi 20 | sudo gpasswd -a seluser seluser 21 | newgrp seluser 22 | fi 23 | -------------------------------------------------------------------------------- /utils/bin/errors: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | grep -v "webSocketsHandshake" /var/log/cont/* | \ 4 | grep -v "errors, etc) it may be disabled" | \ 5 | grep -i "error" -B 7 -A 7 || true 6 | 7 | grep -v "Failed to read: session" /var/log/cont/* | \ 8 | grep -v "Failed to read theme item:" | \ 9 | grep -i "failed" -B 7 -A 7 || true 10 | 11 | grep -i "fatal" /var/log/cont/* || true 12 | -------------------------------------------------------------------------------- /utils/bin/generate_capabilities_json: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # docker exec grid cat caps 4 | 5 | gen_caps_json() { 6 | CHROME_STABLE=$(chrome_stable_version) 7 | FIREFOX_STABLE=$(firefox_version) 8 | 9 | cat << EOF 10 | { 11 | "caps": [ 12 | { 13 | "BROWSER_NAME": "chrome", 14 | "VERSION": "${CHROME_STABLE}", 15 | "PLATFORM": "LINUX" 16 | }, 17 | { 18 | "BROWSER_NAME": "firefox", 19 | "VERSION": "${FIREFOX_STABLE}", 20 | "PLATFORM": "LINUX" 21 | } 22 | ] 23 | } 24 | EOF 25 | } 26 | 27 | gen_caps_json 28 | -------------------------------------------------------------------------------- /utils/bin/genpassword.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Generate a random password between 5 and 15 characters long 4 | # returns the value as echo to stdout due to bash limitation 5 | # that only integers are allowed: http://stackoverflow.com/a/3236940/511069 6 | # function genpassword { } 7 | 8 | # Switched to a better password generator `pwgen` but let's keep the old fn here 9 | # echo $(cat /dev/urandom | tr -dc 'a-zA-Z0-9-!@#$%&*_+~' | fold -w $(shuf -i 5-15 -n 1) | head -n 1) 10 | 11 | # pwget generates random password; pwgen [ OPTIONS ] [ pw_length ] [ num_pw ] 12 | pwgen -c -n -1 $(echo $[ 7 + $[ RANDOM % 17 ]]) 1 13 | -------------------------------------------------------------------------------- /utils/bin/please_update_scm-source_json: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "" 4 | echo "Please update scm-source.json by running" 5 | echo " ./host-scripts/gen-scm-source.sh" 6 | echo "" 7 | 8 | exit 100 -------------------------------------------------------------------------------- /utils/bin/selenium-status.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | supervisorctl -c /etc/supervisor/supervisord.conf status 4 | -------------------------------------------------------------------------------- /utils/bin/vncview.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo You need RealVNC client to use this script 4 | echo 5 | 6 | vnc -WarnUnencrypted=0 -SendKeyEvents=0 -GrabKeyboard=0 SendPointerEvents=0 "$@" 7 | -------------------------------------------------------------------------------- /video-rec/bin/fix_videos.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | echoerr() { printf "%s\n" "$*" >&2; } 7 | 8 | # print error and exit 9 | die () { 10 | echoerr "ERROR: $1" 11 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "150" 12 | errnum=${2-115} 13 | exit $errnum 14 | } 15 | 16 | # Required params 17 | [ -z "${tmp_video_path}" ] && die "Need env var set \$tmp_video_path" 18 | [ -z "${final_video_path}" ] && die "Need env var set \$final_video_path" 19 | 20 | # May need to fix perms when mounting volumes 21 | # Issue: http://stackoverflow.com/questions/23544282/ 22 | # Solution: http://stackoverflow.com/a/28596874/511069 23 | if [ -z "${HOST_GID}" ] && [ -z "${HOST_UID}" ]; then 24 | [ -z "${VIDEOS_DIR}" ] && die "Need env var set \$VIDEOS_DIR" 25 | export HOST_GID=$(stat -c "%g" ${VIDEOS_DIR}) 26 | export HOST_UID=$(stat -c "%u" ${VIDEOS_DIR}) 27 | elif [ "${USE_KUBERNETES}" == "true" ]; then 28 | log "No sudo support in K8s so will skip setting up sudo groupadd -g ${HOST_GID} tempgroup" 29 | else 30 | GROUP_EXISTS=$(cat /etc/group | grep ${HOST_GID} | wc -l) 31 | # Create new group using target GID and add seluser user 32 | if [ ${GROUP_EXISTS} == "0" ]; then 33 | sudo groupadd -g ${HOST_GID} tempgroup 34 | sudo gpasswd -a seluser tempgroup 35 | else 36 | # GID exists, find group name and add 37 | EXISTING_GROUP=$(getent group ${HOST_GID} | cut -d: -f1) 38 | sudo gpasswd -a seluser ${EXISTING_GROUP} 39 | fi 40 | fi 41 | 42 | # Portable defaults 43 | # [ -z "${VIDEO_BASE_PATH}" ] && export \ 44 | # VIDEO_BASE_PATH="${VIDEOS_DIR}/${VIDEO_FILE_NAME}" 45 | 46 | log "Fixing perms for "${tmp_video_path}"*" 47 | sudo chown ${HOST_UID}:${HOST_GID} "${tmp_video_path}"* || true 48 | 49 | if [ "${VIDEO_TMP_FILE_EXTENSION}" != "${VIDEO_FILE_EXTENSION}" ]; then 50 | log "Changing video encoding from ${VIDEO_TMP_FILE_EXTENSION} to ${VIDEO_FILE_EXTENSION}..." 51 | 52 | # TODO: Move this mkv to mp4 conversion to a post-processing Zalenium thread 53 | # ffmpeg -i ${tmp_video_path} ${final_video_path} 54 | if timeout --foreground "${VIDEO_CONVERSION_MAX_WAIT}" \ 55 | ffmpeg -i ${tmp_video_path} -vcodec libx264 ${FFMPEG_CODEC_ARGS} ${final_video_path}; \ 56 | then 57 | log "Conversion from ${VIDEO_TMP_FILE_EXTENSION} to ${VIDEO_FILE_EXTENSION} succeeded!" 58 | log "Cleaning up ${tmp_video_path} ..." 59 | rm -f "${tmp_video_path}" 60 | else 61 | log "Conversion from ${VIDEO_TMP_FILE_EXTENSION} to ${VIDEO_FILE_EXTENSION} FAILED! in within the ${VIDEO_CONVERSION_MAX_WAIT}" 62 | rm -f "${final_video_path}" 63 | mv "${tmp_video_path}" "${final_video_path}" 64 | fi 65 | 66 | fi 67 | 68 | if [ "${VIDEO_FILE_EXTENSION}" == "mp4" ]; then 69 | log "Optimizing ${final_video_path} for HTTP streaming..." 70 | 71 | # Portable defaults 72 | [ -z "${VIDEO_MP4_FIX_MAX_WAIT}" ] && export \ 73 | VIDEO_MP4_FIX_MAX_WAIT="8s" 74 | 75 | if timeout --foreground "${VIDEO_MP4_FIX_MAX_WAIT}" mp4box_retry.sh; then 76 | log "Succeeded to mp4box_retry.sh within ${VIDEO_MP4_FIX_MAX_WAIT}" 77 | else 78 | log "Failed! to mp4box_retry.sh within ${VIDEO_MP4_FIX_MAX_WAIT}" 79 | fi 80 | fi 81 | -------------------------------------------------------------------------------- /video-rec/bin/mp4box_retry.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | echoerr() { printf "%s\n" "$*" >&2; } 7 | 8 | # print error and exit 9 | die () { 10 | echoerr "ERROR: $1" 11 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "150" 12 | errnum=${2-115} 13 | exit $errnum 14 | } 15 | 16 | # Required params 17 | [ -z "${MP4_INTERLEAVES_MEDIA_DATA_CHUNKS_SECS}" ] && die "Need env var set \$MP4_INTERLEAVES_MEDIA_DATA_CHUNKS_SECS" 18 | [ -z "${final_video_path}" ] && die "Need env var set \$final_video_path" 19 | 20 | # -inter Duration : interleaves media data in chunks of desired 21 | # duration (in seconds). This is useful to optimize the file for 22 | # HTTP/FTP streaming or reducing disk access. 23 | # https://gpac.wp.imt.fr/mp4box/mp4box-documentation/ 24 | # Credits to @taskworld @dtinth https://goo.gl/JhJRI8 25 | 26 | # Catch e.g.: 27 | # Error opening file /home/seluser/videos/vid_firefox_40004.mp4: IsoMedia File is truncated 28 | while MP4Box -isma -inter ${MP4_INTERLEAVES_MEDIA_DATA_CHUNKS_SECS} ${final_video_path} 2>&1 | \ 29 | grep "Error opening"; do 30 | log "MP4Box got errors meaning the mp4 video file is corrupted, trying again..." 31 | sleep 1 32 | done 33 | 34 | # Also interesting: 35 | # ponchio/untrunc is used to restore a damaged (truncated) video 36 | # untrunc /home/seluser/working_video.mp4 ${f} 37 | -------------------------------------------------------------------------------- /video-rec/bin/rm_videos: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | rm -rf /videos/* 4 | -------------------------------------------------------------------------------- /video-rec/bin/start-video: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echoerr() { printf "%s\n" "$*" >&2; } 4 | 5 | # print error and exit 6 | die () { 7 | echoerr "ERROR: $1" 8 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "150" 9 | errnum=${2-150} 10 | exit $errnum 11 | } 12 | 13 | [ -z "${VIDEO_REC_STOP_SIGNAL}" ] && export VIDEO_REC_STOP_SIGNAL="INT" 14 | [ -z "${LOGFILE_MAXBYTES}" ] && export LOGFILE_MAXBYTES="10MB" 15 | [ -z "${LOGFILE_BACKUPS}" ] && export LOGFILE_BACKUPS=5 16 | [ -z "${LOGS_DIR}" ] && export LOGS_DIR="/var/log/cont" 17 | 18 | export VIDEO_LOG_FILE="$(cat VIDEO_LOG_FILE)" 19 | export VIDEO_PIDFILE="$(cat VIDEO_PIDFILE)" 20 | export VIDEO_FILE_NAME="$(cat VIDEO_FILE_NAME)" 21 | export VIDEO_PATH="$(cat VIDEO_PATH)" 22 | 23 | # Test: supervisorctl -c /etc/supervisor/supervisord.conf status 24 | export VIDEO=true 25 | supervisorctl -c /etc/supervisor/supervisord.conf start video-rec 26 | 27 | timeout --foreground ${WAIT_TIMEOUT} wait-video-rec.sh || \ 28 | die "Failed while waiting for video recording to start!" 29 | -------------------------------------------------------------------------------- /video-rec/bin/stop-video: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | echoerr() { printf "%s\n" "$*" >&2; } 7 | 8 | # print error and exit 9 | die () { 10 | echoerr "ERROR: $1" 11 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "15" 12 | errnum=${2-15} 13 | exit $errnum 14 | } 15 | 16 | # if $1 is defined AND NOT EMPTY, use $1; otherwise, set to "20s" 17 | WAIT_TIME_OUT_VIDEO_STOP=${1-20s} 18 | LOOP_SCRIPT_PATH="${BIN_UTILS}/wait-stop-video-rec.sh" 19 | 20 | if [ ! -f "${LOOP_SCRIPT_PATH}" ]; then 21 | die "Need '${LOOP_SCRIPT_PATH}' to exist!" 22 | fi 23 | 24 | #---------------------- 25 | # Stop video recording 26 | #---------------------- 27 | export VIDEO=false 28 | supervisorctl -c /etc/supervisor/supervisord.conf stop video-rec 29 | 30 | # Avoid waiting forever using the `timeout` command 31 | if timeout --foreground ${WAIT_TIME_OUT_VIDEO_STOP} \ 32 | ${LOOP_SCRIPT_PATH}; then 33 | echo "Video recording stopped" 34 | else 35 | bash -c 'tail --lines=${TAIL_LOG_LINES} /var/log/cont/video-rec/*' || true 36 | echo "" && echo "" && echo "==> errors <==" 37 | bash -c 'errors' || true 38 | 39 | die "Were unable to stop video recording within '${WAIT_TIME_OUT_VIDEO_STOP}'" 40 | fi 41 | 42 | sed -i -e "s/\r/\n/g" ${LOGS_DIR}/video-rec-stderr.log || true 43 | sed -i -e "s/\r/\n/g" ${LOGS_DIR}/video-rec-stdout.log || true 44 | 45 | # Include videos log in the output 46 | log "-- DEBUG: video-rec-stdout.log ----" 47 | tail -n 40 ${LOGS_DIR}/video-rec-stdout.log || true 48 | 49 | log "-- DEBUG: video-rec-stderr.log ----" 50 | tail -n 40 ${LOGS_DIR}/video-rec-stderr.log || true 51 | -------------------------------------------------------------------------------- /video-rec/bin/wait-stop-video-rec.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | echoerr() { printf "%s\n" "$*" >&2; } 7 | 8 | # print error and exit 9 | die () { 10 | echoerr "ERROR: $1" 11 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "160" 12 | errnum=${2-160} 13 | exit $errnum 14 | } 15 | 16 | echo "Waiting for video to stop recording..." 17 | while ! supervisorctl -c /etc/supervisor/supervisord.conf \ 18 | status video-rec 2>&1 \ 19 | | grep -E "STOPPED|EXITED|FATAL|UNKNOWN"; do 20 | echo -n '.' 21 | sleep 0.1; 22 | done 23 | echo "Done waiting for video recording to stop." 24 | -------------------------------------------------------------------------------- /video-rec/bin/wait-video-rec.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | echoerr() { printf "%s\n" "$*" >&2; } 7 | 8 | # print error and exit 9 | die () { 10 | echoerr "ERROR: $1" 11 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "160" 12 | errnum=${2-160} 13 | exit $errnum 14 | } 15 | 16 | export DONE_MSG="Stream mapping:" 17 | 18 | if [ "${VIDEO}" != "true" ]; then 19 | echo "Won't start video recording due to VIDEO env var false" 20 | exit 0 21 | fi 22 | 23 | echo "Waiting for ffmpeg video recording to start..." 24 | # Required params 25 | [ -z "${VIDEO_LOG_FILE}" ] && die "Required env var VIDEO_LOG_FILE" 26 | while ! grep "${DONE_MSG}" ${VIDEO_LOG_FILE} >/dev/null; do 27 | echo -n '.' 28 | sleep 0.2; 29 | done 30 | echo "Videos at ${VIDEO_PATH}* started to be recorded! (wait-video-rec.sh)" 31 | -------------------------------------------------------------------------------- /video-rec/etc/supervisor/conf.d/video-rec.conf: -------------------------------------------------------------------------------- 1 | [program:video-rec] 2 | 3 | ;The relative priority of the program in the start and shutdown ordering. 4 | ;Lower priorities indicate programs that start first and shut down last. 5 | priority=85 6 | 7 | ;User to run-as, note environment expansion outside of `command` is only 8 | ;supported in supervisor >= 3.2 9 | ;user=seluser 10 | 11 | ;The command that will be run when this program is started. 12 | ;Controlled programs should themselves not be daemons, as supervisord 13 | ;assumes it is responsible for daemonizing its subprocesses 14 | directory=/home/seluser 15 | command=%(ENV_BIN_UTILS)s/start-video-rec.sh 16 | 17 | ;If true, this program will start automatically when supervisord is started. 18 | ;default=true 19 | ;autostart=%(ENV_VIDEO)s 20 | autostart=false 21 | 22 | ;If false, the process will never be autorestarted. 23 | ;If true, the process will be unconditionally restarted when it exits, 24 | ;without regard to its exit code. default=unexpected 25 | ;If unexpected, the process will be restart when the program exits with an 26 | ;exit code that is not one of the exit codes associated with this process. 27 | autorestart=false 28 | 29 | ;Set to 0 to indicate that the program needn’t stay running for any 30 | ;particular amount of time. 31 | ;So using custom wait-xxxx.sh scripts to perform a more efficient 32 | ;active waiting until https://github.com/Supervisor/supervisor/issues/584 33 | startsecs=0 34 | 35 | ;The number of serial failure attempts that supervisord will allow when 36 | ;attempting to start the program before giving up and puting the process 37 | ;into an FATAL state. 38 | startretries=0 39 | 40 | ;Logs 41 | redirect_stderr=false 42 | stdout_logfile=%(ENV_LOGS_DIR)s/video-rec-stdout.log 43 | stderr_logfile=%(ENV_LOGS_DIR)s/video-rec-stderr.log 44 | stdout_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 45 | stderr_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 46 | stdout_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 47 | stderr_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 48 | stdout_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 49 | stderr_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 50 | 51 | ;The signal used to kill the program when a stop is requested. This can be 52 | ;any of TERM, HUP, INT, QUIT, KILL, USR1, or USR2. default=TERM 53 | stopsignal=%(ENV_VIDEO_REC_STOP_SIGNAL)s 54 | 55 | ;The number of seconds to wait for the OS to return a SIGCHILD to 56 | ;supervisord after the program has been sent a stopsignal. 57 | ;If this number of seconds elapses before supervisord receives a SIGCHILD 58 | ;from the process, supervisord will attempt to kill it with a final. 59 | ;default=10 60 | stopwaitsecs=%(ENV_VIDEO_STOPWAITSECS)s 61 | 62 | ;If true, the flag causes supervisor to send the stop signal to 63 | ;the whole process group and implies killasgroup is true. 64 | ;This is useful for programs, such as Flask in debug mode, 65 | ;that do not propagate stop signals to their children, 66 | ;leaving them orphaned. 67 | ;default=false 68 | stopasgroup=true 69 | -------------------------------------------------------------------------------- /vnc/bin/wait-vnc.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | echoerr() { printf "%s\n" "$*" >&2; } 7 | 8 | # print error and exit 9 | die () { 10 | echoerr "ERROR: $1" 11 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "150" 12 | errnum=${2-133} 13 | exit $errnum 14 | } 15 | 16 | export VNC_PORT=$(cat VNC_PORT) 17 | LOGSDTOUT="${VNC_TRYOUT_OUT_LOG}.${VNC_PORT}.log" 18 | LOGERR="${VNC_TRYOUT_ERR_LOG}.${VNC_PORT}.log" 19 | 20 | if [ "${VNC_START}" != "true" ]; then 21 | log "Won't start VNC service due to VNC_START env var false" 22 | exit 0 23 | fi 24 | 25 | # Note this active wait provokes below error, so ignore it 26 | # "webSocketsHandshake: unknown connection error" 27 | 28 | if [ -z "${XE_DISP_NUM}" ]; then 29 | log "Waiting for VNC to be ready via process, nc or netstat on VNC_PORT=${VNC_PORT}..." 30 | 31 | #-----------------# 32 | log 'By_process?' 33 | #-----------------# 34 | while ! pidof x11vnc >/dev/null 2>&1; do 35 | echo -n '.' 36 | sleep 0.1 37 | if grep "ListenOnTCPPort: Address already in use" ${LOGERR}; then 38 | die "wait-vnc: By_process: ListenOnTCPPort: Address already in use" 39 | elif grep "could not obtain listening port" ${LOGERR}; then 40 | die "wait-vnc: By_process: could not obtain listening port" 41 | elif grep "bind: Permission denied" ${LOGERR}; then 42 | die "wait-vnc: By_process: bind: Permission denied" 43 | fi 44 | done 45 | log 'By_process:OK' 46 | 47 | #-----------------# 48 | log 'By_nc?' 49 | #-----------------# 50 | while ! nc -z localhost ${VNC_PORT}; do 51 | echo -n '.' 52 | sleep 0.1 53 | if grep "ListenOnTCPPort: Address already in use" ${LOGERR}; then 54 | die "wait-vnc: By_nc: ListenOnTCPPort: Address already in use" 55 | elif grep "could not obtain listening port" ${LOGERR}; then 56 | die "wait-vnc: By_nc: could not obtain listening port" 57 | elif grep "bind: Permission denied" ${LOGERR}; then 58 | die "wait-vnc: By_nc: bind: Permission denied" 59 | fi 60 | done 61 | log 'By_nc:OK' 62 | 63 | #-----------------# 64 | log 'By_log_stderr?' 65 | #-----------------# 66 | while ! grep "Got connection from client" ${LOGERR}; do 67 | echo -n '.' 68 | sleep 0.1 69 | if grep "ListenOnTCPPort: Address already in use" ${LOGERR}; then 70 | die "wait-vnc: By_log_stderr: ListenOnTCPPort: Address already in use" 71 | elif grep "could not obtain listening port" ${LOGERR}; then 72 | die "wait-vnc: By_log_stderr: could not obtain listening port" 73 | elif grep "bind: Permission denied" ${LOGERR}; then 74 | die "wait-vnc: By_log_stderr: bind: Permission denied" 75 | fi 76 | nc -z localhost ${VNC_PORT} 77 | done 78 | log 'By_log_stderr:OK' 79 | 80 | #-----------------# 81 | log 'By_log_stdout?' 82 | #-----------------# 83 | while ! grep "PORT=${VNC_PORT}" ${LOGSDTOUT}; do 84 | echo -n '.' 85 | sleep 0.1 86 | done 87 | log 'By_log_stdout:OK' 88 | else 89 | log "Will not wait for VNC because env var XE_DISP_NUM is set." 90 | fi 91 | 92 | log "Done wait-vnc.sh" 93 | -------------------------------------------------------------------------------- /vnc/etc/supervisor/conf.d/vnc.conf: -------------------------------------------------------------------------------- 1 | [program:vnc] 2 | 3 | ;The relative priority of the program in the start and shutdown ordering. 4 | ;Lower priorities indicate programs that start first and shut down last. 5 | priority=30 6 | 7 | ;User to run-as, note environment expansion outside of `command` is only 8 | ;supported in supervisor >= 3.2 9 | ;user=seluser 10 | 11 | ;The command that will be run when this program is started. 12 | ;Controlled programs should themselves not be daemons, as supervisord 13 | ;assumes it is responsible for daemonizing its subprocesses 14 | directory=/home/seluser 15 | command=%(ENV_BIN_UTILS)s/start-vnc.sh 16 | 17 | ;If true, this program will start automatically when supervisord is started. 18 | ;default=true 19 | autostart=%(ENV_VNC_START)s 20 | 21 | ;If false, the process will never be autorestarted. 22 | ;If true, the process will be unconditionally restarted when it exits, 23 | ;without regard to its exit code. default=unexpected 24 | ;If unexpected, the process will be restart when the program exits with an 25 | ;exit code that is not one of the exit codes associated with this process. 26 | autorestart=unexpected 27 | 28 | ;Set to 0 to indicate that the program needn’t stay running for any 29 | ;particular amount of time. 30 | ;So using custom wait-xxxx.sh scripts to perform a more efficient 31 | ;active waiting until https://github.com/Supervisor/supervisor/issues/584 32 | startsecs=2 33 | 34 | ;The number of serial failure attempts that supervisord will allow when 35 | ;attempting to start the program before giving up and puting the process 36 | ;into an FATAL state. 37 | startretries=3 38 | 39 | ;Logs 40 | redirect_stderr=false 41 | stdout_logfile=%(ENV_LOGS_DIR)s/vnc-stdout.log 42 | stderr_logfile=%(ENV_LOGS_DIR)s/vnc-stderr.log 43 | stdout_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 44 | stderr_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 45 | stdout_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 46 | stderr_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 47 | stdout_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 48 | stderr_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 49 | 50 | ;The signal used to kill the program when a stop is requested. This can be 51 | ;any of TERM, HUP, INT, QUIT, KILL, USR1, or USR2. default=TERM 52 | stopsignal=%(ENV_VNC_STOP_SIGNAL)s 53 | -------------------------------------------------------------------------------- /xmanager/bin/start-xmanager.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | echoerr() { printf "%s\n" "$*" >&2; } 7 | 8 | # print error and exit 9 | die () { 10 | echoerr "ERROR: $1" 11 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "150" 12 | errnum=${2-110} 13 | exit $errnum 14 | } 15 | 16 | function shutdown { 17 | echo "Trapped SIGTERM/SIGINT so shutting down $0 gracefully..." 18 | exit 0 19 | } 20 | 21 | # Run function shutdown() when this process receives a killing signal 22 | trap shutdown SIGTERM SIGINT SIGKILL 23 | 24 | function start_fluxbox() { 25 | # http://stackoverflow.com/a/21028200/511069 26 | fluxbox -display "${DISPLAY}.0" -verbose \ 27 | 1> "${LOGS_DIR}/fluxbox-tryouts-stdout.log" \ 28 | 2> "${LOGS_DIR}/fluxbox-tryouts-stderr.log" & 29 | } 30 | 31 | if [ "${XMANAGER}" = "openbox" ]; then 32 | # Openbox is a lightweight window manager using freedesktop standards 33 | exec openbox-session 34 | elif [ "${XMANAGER}" = "fluxbox" ]; then 35 | # Fluxbox is a fast, lightweight and responsive window manager 36 | 37 | # Race conditions are possible for the port range lookup 38 | # so try again 39 | i=0 40 | stat_failed=true 41 | while true ; do 42 | while true ; do 43 | let i=${i}+1 44 | if ! start_fluxbox; then 45 | echo "-- WARN: start_fluxbox() failed!" 46 | fi 47 | if timeout --foreground "${WAIT_FOREGROUND_RETRY}" wait-xmanager.sh &> "${LOGS_DIR}/wait-xmanager-stdout.log"; then 48 | stat_failed=false 49 | break 50 | else 51 | echoerr "wait-xmanager.sh failed! for DISPLAY=${DISPLAY} during attempt ${i}" 52 | killall xsetroot || true 53 | killall fluxbox || true 54 | if [ ${i} -gt 3 ]; then 55 | echoerr "wait-xmanager.sh already failed ${i} times for DISPLAY=${DISPLAY}. Will kill Xvfb and find a new DISPLAY" 56 | killall Xvfb || true 57 | start-xvfb.sh 58 | export DISPLAY="$(cat DISPLAY)" 59 | export DISP_N="$(cat DISP_N)" 60 | fi 61 | fi 62 | if [ ${i} -gt ${FLUXBOX_START_MAX_RETRIES} ]; then 63 | echoerr "-- ERROR: Failed to start Fluxbox at $0 after many retries." 64 | break 65 | fi 66 | sleep 0.2 67 | done 68 | if [ "${stat_failed}" != "true" ]; then 69 | wait 70 | else 71 | stat_failed=true 72 | fi 73 | sleep 0.2 74 | done 75 | else 76 | die "The chosen X manager is not supported: '${XMANAGER}'" 77 | fi 78 | 79 | #---------------- 80 | # Alternative 3. 81 | # GNOME Shell provides core interface functions like switching windows, 82 | # launching applications or see your notifications 83 | # gnome-shell -display ${DISPLAY} 84 | 85 | #---------------- 86 | # Alternative 4. 87 | # GNOME ubuntu desktop; The fat and full featured windows manager 88 | # /etc/X11/Xsession & 89 | # gnome-session & 90 | 91 | #---------------- 92 | # Alternative 5. 93 | # Not working: LXDE is a Lightweight X11 Desktop Environment 94 | # lxde -display ${DISPLAY} 95 | 96 | #---------------- 97 | # Alternative 6. 98 | # lightdm is a fat and full featured windows manager 99 | # lightdm-session 100 | -------------------------------------------------------------------------------- /xmanager/bin/wait-xmanager.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | echoerr() { printf "%s\n" "$*" >&2; } 7 | 8 | # print error and exit 9 | die () { 10 | echoerr "ERROR: $1" 11 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "150" 12 | errnum=${2-115} 13 | exit $errnum 14 | } 15 | 16 | # Required params 17 | [ -z "${XMANAGER}" ] && die "Need env var set \$XMANAGER" 18 | 19 | # It happens that the process name of the X manager is the same as 20 | # the $XMANAGER variable so this just works `ps -A | grep "${XMANAGER}"` 21 | echo "Waiting for X Manager '${XMANAGER}' to be ready..." 22 | while ! ps -A | grep "${XMANAGER}" >/dev/null 2>&1; do 23 | echo -n '.' 24 | sleep 0.1 25 | done 26 | 27 | # Found a way to wait for an X Manager 28 | while ! xsetroot -cursor_name left_ptr -fg white -bg black > /dev/null 2>&1; do 29 | echo -n '.' 30 | sleep 0.1 31 | done 32 | 33 | echo "Done wait-xmanager.sh" 34 | -------------------------------------------------------------------------------- /xmanager/etc/supervisor/conf.d/xmanager.conf: -------------------------------------------------------------------------------- 1 | [program:xmanager] 2 | 3 | ;The relative priority of the program in the start and shutdown ordering. 4 | ;Lower priorities indicate programs that start first and shut down last. 5 | priority=20 6 | 7 | ;User to run-as, note environment expansion outside of `command` is only 8 | ;supported in supervisor >= 3.2 9 | ;user=seluser 10 | 11 | ;The command that will be run when this program is started. 12 | ;Controlled programs should themselves not be daemons, as supervisord 13 | ;assumes it is responsible for daemonizing its subprocesses 14 | directory=/home/seluser 15 | command=%(ENV_BIN_UTILS)s/start-xmanager.sh 16 | 17 | ;If true, this program will start automatically when supervisord is started. 18 | ;default=true 19 | autostart=true 20 | 21 | ;If false, the process will never be autorestarted. 22 | ;If true, the process will be unconditionally restarted when it exits, 23 | ;without regard to its exit code. default=unexpected 24 | ;If unexpected, the process will be restart when the program exits with an 25 | ;exit code that is not one of the exit codes associated with this process. 26 | autorestart=unexpected 27 | 28 | ;Set to 0 to indicate that the program needn’t stay running for any 29 | ;particular amount of time. 30 | ;So using custom wait-xxxx.sh scripts to perform a more efficient 31 | ;active waiting until https://github.com/Supervisor/supervisor/issues/584 32 | startsecs=%(ENV_XMANAGER_STARTSECS)s 33 | 34 | ;The number of serial failure attempts that supervisord will allow when 35 | ;attempting to start the program before giving up and puting the process 36 | ;into an FATAL state. 37 | startretries=%(ENV_XMANAGER_STARTRETRIES)s 38 | 39 | ;Logs 40 | redirect_stderr=false 41 | stdout_logfile=%(ENV_LOGS_DIR)s/xmanager-stdout.log 42 | stderr_logfile=%(ENV_LOGS_DIR)s/xmanager-stderr.log 43 | stdout_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 44 | stderr_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 45 | stdout_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 46 | stderr_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 47 | stdout_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 48 | stderr_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 49 | 50 | ;The signal used to kill the program when a stop is requested. This can be 51 | ;any of TERM, HUP, INT, QUIT, KILL, USR1, or USR2. default=TERM 52 | stopsignal=%(ENV_XMANAGER_STOP_SIGNAL)s 53 | -------------------------------------------------------------------------------- /xterm/bin/wait-xterm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | echo "Waiting for docker-selenium to be ready..." 7 | while ! grep 'Container docker internal IP' \ 8 | /var/log/cont/xterm-stdout.log > /dev/null 2>&1; do 9 | echo -n '.' 10 | sleep 0.2; 11 | done 12 | -------------------------------------------------------------------------------- /xterm/bin/wait_all_done: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | echoerr() { printf "%s\n" "$*" >&2; } 7 | 8 | # print error and exit 9 | die () { 10 | echoerr "ERROR: $1" 11 | # if $2 is defined AND NOT EMPTY, use $2; otherwise, set to "22" 12 | errnum=${2-22} 13 | exit $errnum 14 | } 15 | 16 | # if $1 is defined AND NOT EMPTY, use $1; otherwise, set to "7s" 17 | WAIT_TIMEOUT=${1-9s} 18 | LOOP_SCRIPT_PATH="${BIN_UTILS}/wait-xterm.sh" 19 | 20 | # default $TAIL_LOG_LINES when not provided 21 | TAIL_LOG_LINES=${TAIL_LOG_LINES-50} 22 | 23 | if [ ! -f "${LOOP_SCRIPT_PATH}" ]; then 24 | die "Need '${LOOP_SCRIPT_PATH}' to exist!" 25 | fi 26 | 27 | # Avoid waiting forever using the `timeout` command 28 | if timeout --foreground ${WAIT_TIMEOUT} ${LOOP_SCRIPT_PATH}; then 29 | echo "" 30 | if [ -f /var/log/cont/vnc-stdout.log ]; then 31 | grep 'password' /var/log/cont/vnc-stdout.log || true 32 | fi 33 | grep 'IP:' /var/log/cont/xterm-stdout.log || die "Failed to grep IP:" 34 | echo -e "Selenium all done and ready for testing!" 35 | else 36 | echo "" && echo "" && echo "==> logs tailed by +- ${TAIL_LOG_LINES} <==" 37 | bash -c 'tail --lines=${TAIL_LOG_LINES} /var/log/cont/*' || true 38 | echo "" && echo "" && echo "==> ls -la /var/log/cont/* <==" 39 | bash -c 'ls -la /var/log/cont/*' || true 40 | echo "" && echo "" && echo "==> errors <==" 41 | bash -c 'errors' || true 42 | 43 | die " 44 | Your docker-selenium didn't start properly. 45 | " 46 | fi 47 | -------------------------------------------------------------------------------- /xterm/etc/supervisor/conf.d/xterm.conf: -------------------------------------------------------------------------------- 1 | [program:xterm] 2 | 3 | ;The relative priority of the program in the start and shutdown ordering. 4 | ;Lower priorities indicate programs that start first and shut down last. 5 | priority=99 6 | 7 | ;User to run-as, note environment expansion outside of `command` is only 8 | ;supported in supervisor >= 3.2 9 | ;user=seluser 10 | 11 | ;The command that will be run when this program is started. 12 | ;Controlled programs should themselves not be daemons, as supervisord 13 | ;assumes it is responsible for daemonizing its subprocesses 14 | directory=/home/seluser 15 | command=%(ENV_BIN_UTILS)s/start-xterm.sh 16 | 17 | ;If true, this program will start automatically when supervisord is started. 18 | ;default=true 19 | autostart=true 20 | 21 | ;If false, the process will never be autorestarted. 22 | ;If true, the process will be unconditionally restarted when it exits, 23 | ;without regard to its exit code. default=unexpected 24 | ;If unexpected, the process will be restart when the program exits with an 25 | ;exit code that is not one of the exit codes associated with this process. 26 | autorestart=false 27 | 28 | ;Set to 0 to indicate that the program needn’t stay running for any 29 | ;particular amount of time. 30 | ;So using custom wait-xxxx.sh scripts to perform a more efficient 31 | ;active waiting until https://github.com/Supervisor/supervisor/issues/584 32 | startsecs=0 33 | 34 | ;The number of serial failure attempts that supervisord will allow when 35 | ;attempting to start the program before giving up and puting the process 36 | ;into an FATAL state. 37 | startretries=0 38 | 39 | ;Logs 40 | redirect_stderr=false 41 | stdout_logfile=%(ENV_LOGS_DIR)s/xterm-stdout.log 42 | stderr_logfile=%(ENV_LOGS_DIR)s/xterm-stderr.log 43 | stdout_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 44 | stderr_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 45 | stdout_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 46 | stderr_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 47 | stdout_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 48 | stderr_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 49 | 50 | ;The signal used to kill the program when a stop is requested. This can be 51 | ;any of TERM, HUP, INT, QUIT, KILL, USR1, or USR2. default=TERM 52 | stopsignal=%(ENV_XTERM_STOP_SIGNAL)s 53 | -------------------------------------------------------------------------------- /xvfb/bin/wait-xvfb.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # set -e: exit asap if a command exits with a non-zero status 4 | set -e 5 | 6 | echo "Waiting for Xvfb to be ready..." 7 | while ! xdpyinfo -display ${DISPLAY}; do 8 | echo -n '' 9 | sleep 0.1 10 | done 11 | 12 | echo "Done wait-xvfb.sh" 13 | -------------------------------------------------------------------------------- /xvfb/etc/supervisor/conf.d/xvfb.conf.old: -------------------------------------------------------------------------------- 1 | [program:xvfb] 2 | 3 | ;DISABLED! since we always need Xvfb this file will be deprecated 4 | 5 | ;The relative priority of the program in the start and shutdown ordering. 6 | ;Lower priorities indicate programs that start first and shut down last. 7 | priority=10 8 | 9 | ;User to run-as, note environment expansion outside of `command` is only 10 | ;supported in supervisor >= 3.2 11 | ;user=seluser 12 | 13 | ;The command that will be run when this program is started. 14 | ;Controlled programs should themselves not be daemons, as supervisord 15 | ;assumes it is responsible for daemonizing its subprocesses 16 | directory=/home/seluser 17 | command=%(ENV_BIN_UTILS)s/start-xvfb.sh 18 | 19 | ;If true, this program will start automatically when supervisord is started. 20 | ;default=true 21 | ;DISABLED! since we always need Xvfb this file will be deprecated 22 | autostart=false 23 | 24 | ;If false, the process will never be autorestarted. 25 | ;If true, the process will be unconditionally restarted when it exits, 26 | ;without regard to its exit code. default=unexpected 27 | ;If unexpected, the process will be restart when the program exits with an 28 | ;exit code that is not one of the exit codes associated with this process. 29 | autorestart=false 30 | 31 | ;Set to 0 to indicate that the program needn’t stay running for any 32 | ;particular amount of time. 33 | ;So using custom wait-xxxx.sh scripts to perform a more efficient 34 | ;active waiting until https://github.com/Supervisor/supervisor/issues/584 35 | startsecs=0 36 | 37 | ;The number of serial failure attempts that supervisord will allow when 38 | ;attempting to start the program before giving up and puting the process 39 | ;into an FATAL state. 40 | startretries=%(ENV_XVFB_STARTRETRIES)s 41 | 42 | ;Logs 43 | redirect_stderr=false 44 | stdout_logfile=%(ENV_LOGS_DIR)s/xvfb-stdout.log 45 | stderr_logfile=%(ENV_LOGS_DIR)s/xvfb-stderr.log 46 | stdout_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 47 | stderr_logfile_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 48 | stdout_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 49 | stderr_logfile_backups=%(ENV_LOGFILE_BACKUPS)s 50 | stdout_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 51 | stderr_capture_maxbytes=%(ENV_LOGFILE_MAXBYTES)s 52 | 53 | ;The signal used to kill the program when a stop is requested. This can be 54 | ;any of TERM, HUP, INT, QUIT, KILL, USR1, or USR2. default=TERM 55 | stopsignal=%(ENV_XVFB_STOP_SIGNAL)s 56 | --------------------------------------------------------------------------------