├── docker-compose.yml ├── hub └── Dockerfile ├── node-chrome ├── Dockerfile └── entry_point.sh ├── node-firefox ├── Dockerfile └── entry_point.sh └── test ├── Dockerfile ├── test_baidu.py └── test_yunqi.py /docker-compose.yml: -------------------------------------------------------------------------------- 1 | hub: 2 | image: registry.aliyuncs.com/denverdino/selenium-hub 3 | ports: 4 | - 4444:4444 5 | labels: 6 | aliyun.routing.port_4444: http://selenium/ 7 | firefox: 8 | image: registry.aliyuncs.com/denverdino/selenium-node-firefox 9 | links: 10 | - hub 11 | labels: 12 | aliyun.scale: "3" 13 | chrome: 14 | image: registry.aliyuncs.com/denverdino/selenium-node-chrome 15 | links: 16 | - hub 17 | labels: 18 | aliyun.scale: "3" 19 | test: 20 | image: registry.aliyuncs.com/denverdino/selenium-test 21 | links: 22 | - hub 23 | - firefox 24 | - chrome 25 | -------------------------------------------------------------------------------- /hub/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM selenium/hub 2 | -------------------------------------------------------------------------------- /node-chrome/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM selenium/node-chrome 2 | COPY entry_point.sh /opt/bin/entry_point.sh -------------------------------------------------------------------------------- /node-chrome/entry_point.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | file="/tmp/.X??-lock" 4 | 5 | echo "Looking for lock file: $file" 6 | if [ -f $file ] ; then 7 | echo "Lock file: $file FOUND" 8 | rm $file 9 | echo "Lock file: $file REMOVED" 10 | fi 11 | 12 | export GEOMETRY="$SCREEN_WIDTH""x""$SCREEN_HEIGHT""x""$SCREEN_DEPTH" 13 | 14 | if [ ! -e /opt/selenium/config.json ]; then 15 | echo No Selenium Node configuration file, the node-base image is not intended to be run directly. 1>&2 16 | exit 1 17 | fi 18 | 19 | if [ -z "$HUB_PORT_4444_TCP_ADDR" ]; then 20 | echo Not linked with a running Hub container 1>&2 21 | exit 1 22 | fi 23 | 24 | function shutdown { 25 | kill -s SIGTERM $NODE_PID 26 | wait $NODE_PID 27 | } 28 | 29 | REMOTE_HOST_PARAM="" 30 | if [ ! -z "$REMOTE_HOST" ]; then 31 | echo "REMOTE_HOST variable is set, appending -remoteHost" 32 | REMOTE_HOST_PARAM="-remoteHost $REMOTE_HOST" 33 | fi 34 | 35 | if [ ! -z "$SE_OPTS" ]; then 36 | echo "appending selenium options: ${SE_OPTS}" 37 | fi 38 | 39 | NODE_IP=$(hostname -i | awk '{ print $1}') 40 | 41 | # TODO: Look into http://www.seleniumhq.org/docs/05_selenium_rc.jsp#browser-side-logs 42 | 43 | xvfb-run --server-args="$DISPLAY -screen 0 $GEOMETRY -ac +extension RANDR" \ 44 | java ${JAVA_OPTS} -jar /opt/selenium/selenium-server-standalone.jar \ 45 | -role node -host $NODE_IP \ 46 | -hub http://hub:$HUB_PORT_4444_TCP_PORT/grid/register \ 47 | ${REMOTE_HOST_PARAM} \ 48 | -nodeConfig /opt/selenium/config.json \ 49 | ${SE_OPTS} & 50 | NODE_PID=$! 51 | 52 | trap shutdown SIGTERM SIGINT 53 | wait $NODE_PID -------------------------------------------------------------------------------- /node-firefox/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM selenium/node-firefox 2 | COPY entry_point.sh /opt/bin/entry_point.sh -------------------------------------------------------------------------------- /node-firefox/entry_point.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | file="/tmp/.X??-lock" 4 | 5 | echo "Looking for lock file: $file" 6 | if [ -f $file ] ; then 7 | echo "Lock file: $file FOUND" 8 | rm $file 9 | echo "Lock file: $file REMOVED" 10 | fi 11 | 12 | export GEOMETRY="$SCREEN_WIDTH""x""$SCREEN_HEIGHT""x""$SCREEN_DEPTH" 13 | 14 | if [ ! -e /opt/selenium/config.json ]; then 15 | echo No Selenium Node configuration file, the node-base image is not intended to be run directly. 1>&2 16 | exit 1 17 | fi 18 | 19 | if [ -z "$HUB_PORT_4444_TCP_ADDR" ]; then 20 | echo Not linked with a running Hub container 1>&2 21 | exit 1 22 | fi 23 | 24 | function shutdown { 25 | kill -s SIGTERM $NODE_PID 26 | wait $NODE_PID 27 | } 28 | 29 | REMOTE_HOST_PARAM="" 30 | if [ ! -z "$REMOTE_HOST" ]; then 31 | echo "REMOTE_HOST variable is set, appending -remoteHost" 32 | REMOTE_HOST_PARAM="-remoteHost $REMOTE_HOST" 33 | fi 34 | 35 | if [ ! -z "$SE_OPTS" ]; then 36 | echo "appending selenium options: ${SE_OPTS}" 37 | fi 38 | 39 | NODE_IP=$(hostname -i | awk '{ print $1}') 40 | 41 | # TODO: Look into http://www.seleniumhq.org/docs/05_selenium_rc.jsp#browser-side-logs 42 | 43 | xvfb-run --server-args="$DISPLAY -screen 0 $GEOMETRY -ac +extension RANDR" \ 44 | java ${JAVA_OPTS} -jar /opt/selenium/selenium-server-standalone.jar \ 45 | -role node -host $NODE_IP \ 46 | -hub http://hub:$HUB_PORT_4444_TCP_PORT/grid/register \ 47 | ${REMOTE_HOST_PARAM} \ 48 | -nodeConfig /opt/selenium/config.json \ 49 | ${SE_OPTS} & 50 | NODE_PID=$! 51 | 52 | trap shutdown SIGTERM SIGINT 53 | wait $NODE_PID -------------------------------------------------------------------------------- /test/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM registry.aliyuncs.com/acs-sample/python:2.7 2 | RUN pip install selenium nose 3 | COPY test_baidu.py . 4 | COPY test_yunqi.py . 5 | CMD ["sh", "-c", "sleep 15 && nosetests"] -------------------------------------------------------------------------------- /test/test_baidu.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | from selenium import webdriver 3 | from selenium.webdriver.common.desired_capabilities import DesiredCapabilities 4 | from selenium.webdriver.support.ui import WebDriverWait 5 | import time, unittest, nose, os 6 | 7 | class OnFirefox (unittest.TestCase): 8 | def setUp(self): 9 | self.driver = webdriver.Remote( 10 | command_executor='http://hub:4444/wd/hub', 11 | desired_capabilities=DesiredCapabilities.FIREFOX) 12 | 13 | def test_Baidu_Search_FF(self): 14 | driver = self.driver 15 | driver.get("http://www.baidu.com") 16 | inputElement = driver.find_element_by_name("wd") 17 | inputElement.send_keys("docker") 18 | inputElement.submit() 19 | WebDriverWait(driver, 20).until(lambda driver: driver.title.startswith("docker")) 20 | print driver.title 21 | 22 | def tearDown(self): 23 | self.driver.quit() 24 | 25 | if __name__ == "__main__": 26 | nose.main(verbosity=2) -------------------------------------------------------------------------------- /test/test_yunqi.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | from selenium import webdriver 3 | from selenium.webdriver.common.desired_capabilities import DesiredCapabilities 4 | from selenium.webdriver.support.ui import WebDriverWait 5 | import time, unittest, nose, os 6 | 7 | class OnChrome (unittest.TestCase): 8 | def setUp(self): 9 | self.driver = webdriver.Remote( 10 | command_executor='http://hub:4444/wd/hub', 11 | desired_capabilities=DesiredCapabilities.CHROME) 12 | 13 | def test_Yunqi_Search_Chrome(self): 14 | driver = self.driver 15 | driver.get("https://yq.aliyun.com/") 16 | inputElement = driver.find_element_by_name("q") 17 | inputElement.send_keys("docker") 18 | inputElement.submit() 19 | WebDriverWait(driver, 20).until(lambda driver: driver.title == u"搜索-云栖社区") 20 | 21 | def tearDown(self): 22 | self.driver.quit() 23 | 24 | if __name__ == "__main__": 25 | nose.main(verbosity=2) --------------------------------------------------------------------------------