Skip to content

Make headless browser automation easier #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jan 20, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions Docker_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,41 +6,41 @@

docker-machine create --driver virtualbox seleniumbase

#### 3. If your Docker environment ever goes down for any reason, you can bring it back up with a restart:
##### (If your Docker environment ever goes down for any reason, you can bring it back up with a restart.)

docker-machine restart seleniumbase

#### 4. Configure your shell:
#### 3. Configure your shell:

eval "$(docker-machine env seleniumbase)"

#### 5. Go to the SeleniumBase home directory. (That's where "Dockerfile" is located)
#### 4. Go to the SeleniumBase home directory. (That's where "Dockerfile" is located)

#### 6. Create your Docker image from your Dockerfile: (Get ready to wait awhile)
#### 5. Create your Docker image from your Dockerfile: (Get ready to wait awhile)

docker build -t seleniumbase .

#### 7. Run a test inside your Docker: (Once the test completes after a few seconds, you'll automatically exit the Docker shell)
#### 6. Run a test inside your Docker: (Once the test completes after a few seconds, you'll automatically exit the Docker shell)

docker run seleniumbase ./run_docker_test_in_firefox.sh

#### 8. Now run the same test with Chrome inside your Docker:
#### 7. Now run the same test with Chrome inside your Docker:

docker run seleniumbase ./run_docker_test_in_chrome.sh

#### 9. You can also enter Docker and stay inside the shell:
#### 8. You can also enter Docker and stay inside the shell:

docker run -i -t seleniumbase

#### 10. Now you can run the example test from inside the Docker shell: (This time with PhantomJS)
#### 9. Now you can run the example test from inside the Docker shell:

./run_docker_test_in_phantomjs.sh
./run_docker_test_in_chrome.sh

#### 11. When you're satisfied, you may exit the Docker shell:
#### 10. When you're satisfied, you may exit the Docker shell:

exit

#### 12. (Optional) Since Docker images and containers take up a lot of space, you may want to clean up your machine from time to time when they’re not being used:
#### 11. (Optional) Since Docker images and containers take up a lot of space, you may want to clean up your machine from time to time when they’re not being used:
http://stackoverflow.com/questions/17236796/how-to-remove-old-docker-containers
Here are a few of those cleanup commands:

Expand All @@ -57,7 +57,7 @@ Finally, if you want to wipe out your SeleniumBase Docker virtualbox, use these
docker-machine kill seleniumbase
docker-machine rm seleniumbase

#### 13. (Optional) More reading on Docker can be found here:
#### 12. (Optional) More reading on Docker can be found here:
* https://docs.docker.com
* https://docs.docker.com/mac/started/
* https://docs.docker.com/installation/mac/
111 changes: 54 additions & 57 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,40 +1,29 @@
# SeleniumBase Docker Image
FROM ubuntu:14.04

#=======================================
# Install Python and Basic Python Tools
#=======================================
RUN apt-get update && apt-get install -y python python-pip python-setuptools python-dev python-distribute

#========================
# Miscellaneous packages
# Includes minimal runtime used for executing selenium with firefox
#========================
ENV BUILD_DEPS '\
build-essential \
libmysqlclient-dev \
libpython-dev \
libyaml-dev \
libxml2-dev \
libxslt1-dev \
libxslt-dev \
zlib1g-dev \
'

RUN apt-get update -qqy \
&& apt-get -qy --no-install-recommends install \
locales \
language-pack-en \
#=================================
# Install Bash Command Line Tools
#=================================
RUN apt-get -qy --no-install-recommends install \
sudo \
unzip \
wget \
curl \
vim \
xvfb \
libaio1 \
libxml2 \
libxslt1.1 \
mysql-client \
${BUILD_DEPS} \
&& rm -rf /var/lib/apt/lists/*
&& rm -rf /var/lib/apt/lists/*

#========================================
# Add normal user with passwordless sudo
#========================================
RUN sudo useradd seluser --shell /bin/bash --create-home \
&& sudo usermod -a -G sudo seluser \
&& echo 'ALL ALL = (ALL) NOPASSWD: ALL' >> /etc/sudoers

#==============================
# Locale and encoding settings
Expand All @@ -44,19 +33,16 @@ ENV LANG ${LANGUAGE}
RUN locale-gen ${LANGUAGE} \
&& dpkg-reconfigure --frontend noninteractive locales

#====================
# Firefox Latest ESR
#====================
RUN apt-get update -qqy \
&& apt-get -qy --no-install-recommends install \
$(apt-cache depends firefox | grep Depends | sed "s/.*ends:\ //" | tr '\n' ' ') \
&& rm -rf /var/lib/apt/lists/* \
&& cd /tmp \
&& wget --no-check-certificate -O firefox-esr.tar.bz2 \
'https://download.mozilla.org/?product=firefox-esr-latest&os=linux64&lang=en-US' \
&& tar -xjf firefox-esr.tar.bz2 -C /opt/ \
&& ln -s /opt/firefox/firefox /usr/bin/firefox \
&& rm -f /tmp/firefox-esr.tar.bz2
#======================
# Install Chromedriver
#======================
RUN CHROMEDRIVER_VERSION=`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE` && \
mkdir -p /opt/chromedriver-$CHROMEDRIVER_VERSION && \
curl -sS -o /tmp/chromedriver_linux64.zip http://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip && \
unzip -qq /tmp/chromedriver_linux64.zip -d /opt/chromedriver-$CHROMEDRIVER_VERSION && \
rm /tmp/chromedriver_linux64.zip && \
chmod +x /opt/chromedriver-$CHROMEDRIVER_VERSION/chromedriver && \
ln -fs /opt/chromedriver-$CHROMEDRIVER_VERSION/chromedriver /usr/local/bin/chromedriver

#================
# Install Chrome
Expand All @@ -67,22 +53,25 @@ RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key
&& apt-get install -y google-chrome-stable \
&& rm -rf /var/lib/apt/lists/*

#===================
# Timezone settings
#===================
# Full list at http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# e.g. "US/Pacific" for Los Angeles, California, USA
ENV TZ "America/New_York"
# Apply TimeZone
RUN echo $TZ | tee /etc/timezone \
&& dpkg-reconfigure --frontend noninteractive tzdata
#==================
# Configure Chrome
#==================
RUN dpkg-divert --add --rename --divert /opt/google/chrome/google-chrome.real /opt/google/chrome/google-chrome && \
echo "#!/bin/bash\nexec /opt/google/chrome/google-chrome.real --disable-setuid-sandbox \"\$@\"" > /opt/google/chrome/google-chrome && \
chmod 755 /opt/google/chrome/google-chrome

#========================================
# Add normal user with passwordless sudo
#========================================
RUN sudo useradd seluser --shell /bin/bash --create-home \
&& sudo usermod -a -G sudo seluser \
&& echo 'ALL ALL = (ALL) NOPASSWD: ALL' >> /etc/sudoers
#=================
# Install Firefox
#=================
RUN apt-get -qy --no-install-recommends install \
$(apt-cache depends firefox | grep Depends | sed "s/.*ends:\ //" | tr '\n' ' ') \
&& rm -rf /var/lib/apt/lists/* \
&& cd /tmp \
&& wget --no-check-certificate -O firefox-esr.tar.bz2 \
'https://download.mozilla.org/?product=firefox-esr-latest&os=linux64&lang=en-US' \
&& tar -xjf firefox-esr.tar.bz2 -C /opt/ \
&& ln -s /opt/firefox/firefox /usr/bin/firefox \
&& rm -f /tmp/firefox-esr.tar.bz2

#===================
# Install PhantomJS
Expand All @@ -93,6 +82,15 @@ RUN ln -s /usr/local/share/phantomjs-1.9.7-linux-x86_64/bin/phantomjs /usr/local
RUN ln -s /usr/local/share/phantomjs-1.9.7-linux-x86_64/bin/phantomjs /usr/local/bin/phantomjs
RUN ln -s /usr/local/share/phantomjs-1.9.7-linux-x86_64/bin/phantomjs /usr/bin/phantomjs

#===========================
# Configure Virtual Display
#===========================
RUN set -e
RUN echo "Starting X virtual framebuffer (Xvfb) in background..."
RUN Xvfb -ac :99 -screen 0 1280x1024x16 > /dev/null 2>&1 &
RUN export DISPLAY=:99
RUN exec "$@"

#=====================
# Set up SeleniumBase
#=====================
Expand All @@ -103,13 +101,12 @@ COPY examples /SeleniumBase/examples/
RUN cd /SeleniumBase && ls && sudo pip install -r docker_requirements.txt
RUN cd /SeleniumBase && ls && sudo python docker_setup.py install

#=========================================
# Create entrypoint and grab example test
#=========================================
#==========================================
# Create entrypoint and grab example tests
#==========================================
COPY docker/docker-entrypoint.sh /
COPY docker/run_docker_test_in_firefox.sh /
COPY docker/run_docker_test_in_chrome.sh /
COPY docker/run_docker_test_in_phantomjs.sh /
COPY docker/docker_config.cfg /SeleniumBase/examples/
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["/bin/bash"]
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,9 @@ If you're planning on using the full power of this test framework, there are a f

* Setup your Selenium Grid and update your *.cfg file to point there. An example config file called selenium_server_config_example.cfg has been provided for you in the grid folder. The start-selenium-node.bat and start-selenium-server.sh files are for running your grid. In an example situation, your Selenium Grid server might live on a unix box and your Selenium Grid nodes might live on EC2 Windows virtual machines. When your build server runs a Selenium test, it would connect to your Selenium Grid to find out which Grid browser nodes are available to run that test. To simplify things, you can use [Browser Stack](https://www.browserstack.com/automate) as your entire Selenium Grid (and let them do all the fun work of maintaining the grid for you).

* There are ways of running your tests from Jenkins without having to utilize a remote machine. One way is by using PhantomJS as your browser (it runs headlessly). Another way is by using Xvfb (another headless system). [There's a plugin for Xvfb in Jenkins](https://wiki.jenkins-ci.org/display/JENKINS/Xvfb+Plugin). Here are some more helpful resources I found regarding the use of Xvfb:
* There are ways of running your tests from Jenkins without having to utilize a remote machine. One way is by using PhantomJS as your browser (it runs headlessly). Another way is by using Xvfb (another headless system). [There's a plugin for Xvfb in Jenkins](https://wiki.jenkins-ci.org/display/JENKINS/Xvfb+Plugin).
If you have Xvfb running in the background, you can add ``--headless`` to your run command in order to utilize it.
Here are some more helpful resources I found regarding the use of Xvfb:
1. http://stackoverflow.com/questions/6183276/how-do-i-run-selenium-in-xvfb
2. http://qxf2.com/blog/xvfb-plugin-for-jenkins-selenium/
3. http://stackoverflow.com/questions/27202131/firefox-started-by-selenium-ignores-the-display-created-by-pyvirtualdisplay
Expand Down
7 changes: 7 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ def pytest_addoption(parser):
parser.addoption('--log_path', dest='log_path',
default='logs/',
help='Where the log files are saved.')
parser.addoption('--headless', action="store_true",
dest='headless',
default=False,
help="""Using this makes Webdriver run headlessly,
which is useful inside a Linux Docker.""")
parser.addoption('--demo_mode', action="store_true",
dest='demo_mode',
default=False,
Expand All @@ -50,6 +55,7 @@ def pytest_configure(config):
with_testing_base = config.getoption('with_testing_base')
browser = config.getoption('browser')
log_path = config.getoption('log_path')
headless = config.getoption('headless')
demo_mode = config.getoption('demo_mode')
demo_sleep = ''
data = ''
Expand All @@ -65,6 +71,7 @@ def pytest_configure(config):
config_file.write("data:::%s\n" % data)
config_file.write("with_testing_base:::%s\n" % with_testing_base)
config_file.write("log_path:::%s\n" % log_path)
config_file.write("headless:::%s\n" % headless)
config_file.write("demo_mode:::%s\n" % demo_mode)
config_file.write("demo_sleep:::%s\n" % demo_sleep)
config_file.close()
Expand Down
24 changes: 12 additions & 12 deletions docker/ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,41 +6,41 @@

docker-machine create --driver virtualbox seleniumbase

#### 3. If your Docker environment ever goes down for any reason, you can bring it back up with a restart:
##### (If your Docker environment ever goes down for any reason, you can bring it back up with a restart.)

docker-machine restart seleniumbase

#### 4. Configure your shell:
#### 3. Configure your shell:

eval "$(docker-machine env seleniumbase)"

#### 5. Go to the SeleniumBase home directory. (That's where "Dockerfile" is located)
#### 4. Go to the SeleniumBase home directory. (That's where "Dockerfile" is located)

#### 6. Create your Docker image from your Dockerfile: (Get ready to wait awhile)
#### 5. Create your Docker image from your Dockerfile: (Get ready to wait awhile)

docker build -t seleniumbase .

#### 7. Run a test inside your Docker: (Once the test completes after a few seconds, you'll automatically exit the Docker shell)
#### 6. Run a test inside your Docker: (Once the test completes after a few seconds, you'll automatically exit the Docker shell)

docker run seleniumbase ./run_docker_test_in_firefox.sh

#### 8. Now run the same test with Chrome inside your Docker:
#### 7. Now run the same test with Chrome inside your Docker:

docker run seleniumbase ./run_docker_test_in_chrome.sh

#### 9. You can also enter Docker and stay inside the shell:
#### 8. You can also enter Docker and stay inside the shell:

docker run -i -t seleniumbase

#### 10. Now you can run the example test from inside the Docker shell: (This time with PhantomJS)
#### 9. Now you can run the example test from inside the Docker shell:

./run_docker_test_in_phantomjs.sh
./run_docker_test_in_chrome.sh

#### 11. When you're satisfied, you may exit the Docker shell:
#### 10. When you're satisfied, you may exit the Docker shell:

exit

#### 12. (Optional) Since Docker images and containers take up a lot of space, you may want to clean up your machine from time to time when they’re not being used:
#### 11. (Optional) Since Docker images and containers take up a lot of space, you may want to clean up your machine from time to time when they’re not being used:
http://stackoverflow.com/questions/17236796/how-to-remove-old-docker-containers
Here are a few of those cleanup commands:

Expand All @@ -57,7 +57,7 @@ Finally, if you want to wipe out your SeleniumBase Docker virtualbox, use these
docker-machine kill seleniumbase
docker-machine rm seleniumbase

#### 13. (Optional) More reading on Docker can be found here:
#### 12. (Optional) More reading on Docker can be found here:
* https://docs.docker.com
* https://docs.docker.com/mac/started/
* https://docs.docker.com/installation/mac/
2 changes: 1 addition & 1 deletion docker/docker_config.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[nosetests]
with-selenium_docker=1
with-selenium=1
with-testing_base=1
with-basic_test_info=1
nocapture=1
Expand Down
5 changes: 2 additions & 3 deletions docker/docker_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

setup(
name='seleniumbase',
version='1.1.17',
version='1.1.18',
author='Michael Mintz',
author_email='@mintzworld',
maintainer='Michael Mintz',
Expand All @@ -24,8 +24,7 @@
entry_points={
'nose.plugins': [
'base_plugin = seleniumbase.plugins.base_plugin:Base',
'selenium_docker = '
'seleniumbase.plugins.docker_selenium_plugin:SeleniumBrowser',
'selenium = seleniumbase.plugins.selenium_plugin:SeleniumBrowser',
'page_source = seleniumbase.plugins.page_source:PageSource',
'screen_shots = seleniumbase.plugins.screen_shots:ScreenShots',
'test_info = seleniumbase.plugins.basic_test_info:BasicTestInfo',
Expand Down
2 changes: 1 addition & 1 deletion docker/run_docker_test_in_chrome.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
set -e
# Run example test from inside Docker image
echo "Running example SeleniumBase test from Docker with headless Chrome..."
cd /SeleniumBase/examples/ && nosetests my_first_test.py --config=docker_config.cfg --browser=chrome
cd /SeleniumBase/examples/ && nosetests my_first_test.py --config=docker_config.cfg --browser=chrome --headless
exec "$@"
2 changes: 1 addition & 1 deletion docker/run_docker_test_in_firefox.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
set -e
# Run example test from inside Docker image
echo "Running example SeleniumBase test from Docker with headless Firefox..."
cd /SeleniumBase/examples/ && nosetests my_first_test.py --config=docker_config.cfg --browser=firefox
cd /SeleniumBase/examples/ && nosetests my_first_test.py --config=docker_config.cfg --browser=firefox --headless
exec "$@"
6 changes: 0 additions & 6 deletions docker/run_docker_test_in_phantomjs.sh

This file was deleted.

1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ simplejson==3.8.1
boto==2.38.0
pdb==0.1
ipdb==0.8.1
pyvirtualdisplay==0.1.5
-e .
Loading