From 835e44e883e3e49da24cb35d6683e03dc9b7e8bc Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 9 Mar 2017 23:29:44 -0500 Subject: [PATCH 01/35] Upgrade to Selenium 3 and update the requirements --- requirements.txt | 22 +++++++++++----------- server_requirements.txt | 22 +++++++++++----------- setup.py | 22 +++++++++++----------- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/requirements.txt b/requirements.txt index 80e1ca1c364..76584b4727b 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,17 +1,17 @@ -pip>=8.1.2 -setuptools>=28.2.0 -selenium==2.53.6 +pip>=9.0.1 +setuptools>=34.3.1 +selenium==3.3.0 nose>=1.3.7 -pytest>=3.0.2 +pytest>=3.0.6 six>=1.10.0 -flake8==3.0.4 -requests==2.11.1 -urllib3==1.17 +flake8==3.3.0 +requests==2.13.0 +urllib3==1.20 BeautifulSoup==3.2.1 unittest2==1.1.0 chardet==2.3.0 -simplejson==3.8.2 -boto==2.42.0 -ipdb==0.9.4 -pyvirtualdisplay==0.2 +simplejson==3.10.0 +boto==2.46.1 +ipdb==0.10.2 +pyvirtualdisplay==0.2.1 -e . diff --git a/server_requirements.txt b/server_requirements.txt index 7da19949270..6a07ec8408a 100755 --- a/server_requirements.txt +++ b/server_requirements.txt @@ -1,18 +1,18 @@ -pip>=8.1.2 -setuptools>=28.2.0 -selenium==2.53.6 +pip>=9.0.1 +setuptools>=34.3.1 +selenium==3.3.0 nose>=1.3.7 -pytest>=3.0.2 +pytest>=3.0.6 six>=1.10.0 -flake8==3.0.4 -requests==2.11.1 -urllib3==1.17 +flake8==3.3.0 +requests==2.13.0 +urllib3==1.20 BeautifulSoup==3.2.1 unittest2==1.1.0 chardet==2.3.0 -simplejson==3.8.2 -boto==2.42.0 -ipdb==0.9.4 -pyvirtualdisplay==0.2 +simplejson==3.10.0 +boto==2.46.1 +ipdb==0.10.2 +pyvirtualdisplay==0.2.1 MySQL-python==1.2.5 -e . diff --git a/setup.py b/setup.py index 7c6cfee147b..35049010da4 100755 --- a/setup.py +++ b/setup.py @@ -14,22 +14,22 @@ description='Reliable Browser Automation - http://seleniumbase.com', license='The MIT License', install_requires=[ - 'pip>=8.1.2', - 'setuptools>=28.2.0', - 'selenium==2.53.6', + 'pip>=9.0.1', + 'setuptools>=34.3.1', + 'selenium==3.3.0', 'nose>=1.3.7', - 'pytest>=3.0.2', + 'pytest>=3.0.6', 'six>=1.10.0', - 'flake8==3.0.4', - 'requests==2.11.1', - 'urllib3==1.17', + 'flake8==3.3.0', + 'requests==2.13.0', + 'urllib3==1.20', 'BeautifulSoup==3.2.1', 'unittest2==1.1.0', 'chardet==2.3.0', - 'simplejson==3.8.2', - 'boto==2.42.0', - 'ipdb==0.9.4', - 'pyvirtualdisplay==0.2', + 'simplejson==3.10.0', + 'boto==2.46.1', + 'ipdb==0.10.2', + 'pyvirtualdisplay==0.2.1', ], packages=['seleniumbase', 'seleniumbase.core', From 97b05b4b97edabf5a993fe7e659f1caf2fb2f02c Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 9 Mar 2017 23:30:42 -0500 Subject: [PATCH 02/35] Ignore Geckodriver logs in git commits --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index fa82efcbca0..ac5ae9a6653 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ nosetests.xml # Other selenium-server-standalone.jar +geckodriver.log downloaded_files archived_files logs From 8cd946f0a7d6dfedde470f8cdec1c6921ac8fcf6 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 9 Mar 2017 23:40:05 -0500 Subject: [PATCH 03/35] Text alignment --- seleniumbase/plugins/selenium_plugin.py | 91 ++++++++++++++----------- 1 file changed, 50 insertions(+), 41 deletions(-) diff --git a/seleniumbase/plugins/selenium_plugin.py b/seleniumbase/plugins/selenium_plugin.py index 1d5c8c9c881..fb4a21fdab3 100755 --- a/seleniumbase/plugins/selenium_plugin.py +++ b/seleniumbase/plugins/selenium_plugin.py @@ -33,47 +33,56 @@ class SeleniumBrowser(Plugin): def options(self, parser, env): super(SeleniumBrowser, self).options(parser, env=env) - parser.add_option('--browser', action='store', - dest='browser', - choices=constants.Browser.VERSION.keys(), - default=constants.Browser.FIREFOX, - help="""Specifies the browser. Default: FireFox. - If you want to use Chrome, indicate that.""") - parser.add_option('--browser_version', action='store', - dest='browser_version', - default="latest", - help="""The browser version to use. Explicitly select - a version number or use "latest".""") - parser.add_option('--server', action='store', dest='servername', - default='localhost', - help="""Designates the server used by the test. - Default: localhost.""") - parser.add_option('--port', action='store', dest='port', - default='4444', - help="""Designates the port used by the test. - Default: 4444.""") - parser.add_option('--headless', action="store_true", - dest='headless', - default=False, - help="""Using this makes Webdriver run headlessly, - which is useful inside a Linux Docker.""") - parser.add_option('--demo_mode', action="store_true", - dest='demo_mode', - default=False, - help="""Using this slows down the automation so that - you can see what it's actually doing.""") - parser.add_option('--demo_sleep', action='store', dest='demo_sleep', - default=None, - help="""Setting this overrides the Demo Mode sleep - time that happens after browser actions.""") - parser.add_option('--highlights', action='store', - dest='highlights', default=None, - help="""Setting this overrides the default number of - highlight animation loops to have per call.""") - parser.add_option('--verify_delay', action='store', - dest='verify_delay', default=None, - help="""Setting this overrides the default wait time - before each MasterQA verification pop-up.""") + parser.add_option( + '--browser', action='store', + dest='browser', + choices=constants.Browser.VERSION.keys(), + default=constants.Browser.FIREFOX, + help="""Specifies the web browser. Default: Firefox. + If you want to use Chrome, indicate that.""") + parser.add_option( + '--browser_version', action='store', + dest='browser_version', + default="latest", + help="""The browser version to use. Explicitly select + a version number or use "latest".""") + parser.add_option( + '--server', action='store', dest='servername', + default='localhost', + help="""Designates the server used by the test. + Default: localhost.""") + parser.add_option( + '--port', action='store', dest='port', + default='4444', + help="""Designates the port used by the test. + Default: 4444.""") + parser.add_option( + '--headless', action="store_true", + dest='headless', + default=False, + help="""Using this makes Webdriver run headlessly, + which is useful inside a Linux Docker.""") + parser.add_option( + '--demo_mode', action="store_true", + dest='demo_mode', + default=False, + help="""Using this slows down the automation so that + you can see what it's actually doing.""") + parser.add_option( + '--demo_sleep', action='store', dest='demo_sleep', + default=None, + help="""Setting this overrides the Demo Mode sleep + time that happens after browser actions.""") + parser.add_option( + '--highlights', action='store', + dest='highlights', default=None, + help="""Setting this overrides the default number of + highlight animation loops to have per call.""") + parser.add_option( + '--verify_delay', action='store', + dest='verify_delay', default=None, + help="""Setting this overrides the default wait time + before each MasterQA verification pop-up.""") def configure(self, options, conf): super(SeleniumBrowser, self).configure(options, conf) From 1d49d2352fb05a154c2551948aa658e4498b159f Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 9 Mar 2017 23:47:33 -0500 Subject: [PATCH 04/35] Chrome is now the default web browser when unspecified --- conftest.py | 8 ++++---- seleniumbase/plugins/selenium_plugin.py | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/conftest.py b/conftest.py index 99612540638..f16622d65c1 100755 --- a/conftest.py +++ b/conftest.py @@ -12,10 +12,10 @@ def pytest_addoption(parser): parser.addoption('--browser', action="store", dest='browser', choices=constants.Browser.VERSION.keys(), - default=constants.Browser.FIREFOX, - help="""Specifies the web browser to use. Default=FireFox. - If you want to use Chrome, explicitly indicate that. - Example: (--browser=chrome)""") + default=constants.Browser.GOOGLE_CHROME, + help="""Specifies the web browser to use. Default=Chrome. + If you want to use Firefox, explicitly indicate that. + Example: (--browser=firefox)""") parser.addoption('--is_pytest', action="store_true", dest='is_pytest', default=True, diff --git a/seleniumbase/plugins/selenium_plugin.py b/seleniumbase/plugins/selenium_plugin.py index fb4a21fdab3..bbd02263368 100755 --- a/seleniumbase/plugins/selenium_plugin.py +++ b/seleniumbase/plugins/selenium_plugin.py @@ -37,9 +37,10 @@ def options(self, parser, env): '--browser', action='store', dest='browser', choices=constants.Browser.VERSION.keys(), - default=constants.Browser.FIREFOX, - help="""Specifies the web browser. Default: Firefox. - If you want to use Chrome, indicate that.""") + default=constants.Browser.GOOGLE_CHROME, + help="""Specifies the web browser to use. Default: Chrome. + If you want to use Firefox, explicitly indicate that. + Example: (--browser=firefox)""") parser.add_option( '--browser_version', action='store', dest='browser_version', From fc02fd30920c3c948016246de4e7d4b193d7073b Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 9 Mar 2017 23:52:03 -0500 Subject: [PATCH 05/35] Better than "Ready State: Complete" to be safe. --- seleniumbase/fixtures/page_actions.py | 1 + 1 file changed, 1 insertion(+) diff --git a/seleniumbase/fixtures/page_actions.py b/seleniumbase/fixtures/page_actions.py index 98d23c631f5..7fe0b914165 100755 --- a/seleniumbase/fixtures/page_actions.py +++ b/seleniumbase/fixtures/page_actions.py @@ -390,6 +390,7 @@ def wait_for_ready_state_complete(driver, timeout=settings.EXTREME_TIMEOUT): for x in range(int(timeout * 10)): ready_state = driver.execute_script("return document.readyState") if ready_state == u'complete': + time.sleep(0.01) # Better be sure everything is done loading return True else: now_ms = time.time() * 1000.0 From b945f950110547ea366533d4e9e19aa1d6e6f8e7 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 9 Mar 2017 23:54:05 -0500 Subject: [PATCH 06/35] Update documentation --- README.md | 18 +++++++++++------- help_docs/requirements_installation.md | 20 ++++++++++++++------ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index edf1f3d1cb3..0ed13a9ab99 100755 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ [![pypi](https://img.shields.io/pypi/v/seleniumbase.svg)](https://pypi.python.org/pypi/seleniumbase) [![Build Status](https://travis-ci.org/seleniumbase/SeleniumBase.svg?branch=master)](https://travis-ci.org/seleniumbase/SeleniumBase) [![GitHub stars](https://img.shields.io/github/stars/seleniumbase/seleniumbase.svg "GitHub stars")](https://github.com/seleniumbase/SeleniumBase/stargazers) [![Python version](https://img.shields.io/badge/python-2.7-22AADD.svg "Python version")](https://docs.python.org/2/) [![MIT License](http://img.shields.io/badge/license-MIT-22BBCC.svg "MIT License")](https://github.com/seleniumbase/SeleniumBase/blob/master/LICENSE) [![Join the chat at https://gitter.im/seleniumbase/SeleniumBase](https://badges.gitter.im/seleniumbase/SeleniumBase.svg)](https://gitter.im/seleniumbase/SeleniumBase?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -**Automation Platform for Testing and Business** +**Web Automation Platform for Testing and More** -(And the power to [speed up your manual testing](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/masterqa/ReadMe.md)) +(And the power to [speed up manual testing](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/masterqa/ReadMe.md)) ![](http://cdn2.hubspot.net/hubfs/100006/images/sb_demo.gif "SeleniumBase") @@ -29,13 +29,17 @@ SeleniumBase makes it easy to automate tedious business tasks. (*To learn about * To install ``python``, ``pip``, ``git``, and either ``virtualenv`` or ``virtualenvwrapper``, **[follow these instructions](https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/requirements_installation.md)**. -* Download web browsers such as [Chrome](https://www.google.com/chrome/browser/desktop/index.html) (or [Chromium](https://download-chromium.appspot.com/)) and also [Firefox v46.*](https://ftp.mozilla.org/pub/firefox/releases/46.0.1/) (or [Firefox ESR](https://www.mozilla.org/en-US/firefox/organizations/)) because Firefox versions 47.0 and above are no longer compatible with normal Selenium WebDriver. (If you go with Firefox 46.*, make sure to turn off auto-updates or else you'll be back at v47+ quickly!) +* Download web browsers such as [Chrome](https://www.google.com/chrome/browser/desktop/index.html) (or [Chromium](https://download-chromium.appspot.com/)) and [Firefox](https://www.mozilla.org/firefox/new/). -(NOTE: Firefox versions 47.0 and above are no longer compatible with normal Selenium WebDriver. [Get Firefox 46.*](https://ftp.mozilla.org/pub/firefox/releases/46.0.1/) instead, or you can [Get Firefox ESR](https://www.mozilla.org/en-US/firefox/organizations/). (If you go with Firefox 46.*, make sure to turn off auto-updates or else you'll be back at v47 quickly!) For more information regarding this, [read this post](http://stackoverflow.com/questions/37693106/selenium-2-53-not-working-on-firefox-47) from Stack Overflow. There's a [new version of Firefox driver](https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/WebDriver) coming soon. +* To run browser automation on Chrome, you'll need to download **[Chromedriver](https://sites.google.com/a/chromium.org/chromedriver/downloads)** and put it on your System **[PATH](http://java.com/en/download/help/path.xml)**. -* If you want to run automation on browsers other than Firefox, you'll need to download [Chromedriver](https://sites.google.com/a/chromium.org/chromedriver/downloads), [PhantomJS](http://phantomjs.org/download.html), [Edge Driver (Microsoft WebDriver)](https://www.microsoft.com/en-us/download/details.aspx?id=48212), and/or [Safari Driver](https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/using_safari_driver.md) separately. (Firefox drivers come with Selenium by default.) +* For Firefox, get [Geckodriver](https://github.com/mozilla/geckodriver/releases) on your System Path. -* For everything you download (such as ``pip`` and ``Chromedriver``) make sure those files get on your system [PATH](http://java.com/en/download/help/path.xml). (``Environmental Variables`` on a Windows machine) +* For Microsoft Edge, get [Edge Driver (Microsoft WebDriver)](https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/) on your System Path. + +* For Safari, get [Safari Driver](https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/using_safari_driver.md) on your System Path. + +* For PhantomJS headless browser automation, get [PhantomJS](http://phantomjs.org/download.html) on your System Path. Mac: @@ -124,7 +128,7 @@ nosetests my_first_test.py --with-selenium --browser=firefox -s nosetests my_first_test.py --with-selenium --browser=phantomjs -s ``` -After the test completes, in the console output you'll see a dot (``.``) on a new line, representing a passing test. (On test failures you'll see an ``F`` instead, and on test errors you'll see an ``E``). It looks more like a moving progress bar when you're running a ton of unit tests side by side. This is part of nosetests. After all tests complete (in this case there is only one), you'll see the "``Ran 1 test in ...``" line, followed by an "``OK``" if all nosetests passed. The ``--with-selenium`` option is required for running GUI tests. If no browser is specified, Firefox will become the default. The ``-s`` option is optional, and that makes sure that any standard output is printed immediately on the command line when tests have print statements in them, which makes debugging much easier. +After the test completes, in the console output you'll see a dot (``.``) on a new line, representing a passing test. (On test failures you'll see an ``F`` instead, and on test errors you'll see an ``E``). It looks more like a moving progress bar when you're running a ton of unit tests side by side. This is part of nosetests. After all tests complete (in this case there is only one), you'll see the "``Ran 1 test in ...``" line, followed by an "``OK``" if all nosetests passed. The ``--with-selenium`` option is required for running GUI tests. If no browser is specified, Chrome will become the default. The ``-s`` option is optional, and that makes sure that any standard output is printed immediately on the command line when tests have print statements in them, which makes debugging much easier. NOTE: The following two lines of code can be simplified... ``` python diff --git a/help_docs/requirements_installation.md b/help_docs/requirements_installation.md index 4418de2ba72..449def1af05 100755 --- a/help_docs/requirements_installation.md +++ b/help_docs/requirements_installation.md @@ -3,19 +3,27 @@ ### [Python 2.7](https://www.python.org/downloads/) -If you're a MAC user, that should already come preinstalled on your machine. Although Python 3 exists, you'll want Python 2 (both of these major versions are being improved in parallel). Python 2.7.10 is the one I've been using on my Mac. +If you're a MAC user, that should already come preinstalled on your machine. Although Python 3 exists, you'll want Python 2 (both of these major versions are being improved in parallel). Python 2.7.13 is the one I've been using on my Mac. -If you're a WINDOWS user, [download the latest 2.* version from here](https://www.python.org/downloads/release/python-2710/). +If you're a WINDOWS user, [download the latest 2.* version from here](https://www.python.org/downloads/release/python-2713/). -### [Pip](https://en.wikipedia.org/wiki/Pip_%28package_manager%29) -If "pip" did not come with your Python installation, you can [GET PIP HERE](https://pip.pypa.io/en/latest/installing/). +### [Pip](https://en.wikipedia.org/wiki/Pip_%28package_manager%29) -On a MAC, you can also install pip easily with the following command: +On a MAC, run the following command: ```bash sudo easy_install pip ``` -Then make sure it's on your path. + +On WINDOWS, run the following command: +```bash +python -m pip install -U pip setuptools +``` + +If you're having any trouble with that, you can [GET PIP HERE](https://pip.pypa.io/en/latest/installing/). + +When done, make sure pip is on your path. ($PATH on Mac/Linux. System Environment Variables on WINDOWS.) + ### [Homebrew](http://brew.sh/) (MAC-ONLY) (OPTIONAL) From a677fe9df264970dc4de9e549f9c9edf2dba98e7 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 9 Mar 2017 23:55:40 -0500 Subject: [PATCH 07/35] Flake8 spacing --- examples/gui_test_runner.py | 1 + seleniumbase/core/mysql_conf.py | 1 + 2 files changed, 2 insertions(+) diff --git a/examples/gui_test_runner.py b/examples/gui_test_runner.py index 342ace1b972..4e2e13bfc7a 100755 --- a/examples/gui_test_runner.py +++ b/examples/gui_test_runner.py @@ -101,6 +101,7 @@ def run_7(self): 'nosetests my_test_suite.py --with-selenium' ' --browser=chrome --with-db_reporting') + if __name__ == "__main__": root = Tk() root.minsize(612, 444) diff --git a/seleniumbase/core/mysql_conf.py b/seleniumbase/core/mysql_conf.py index 57fc5ceff1b..7682c11d4e8 100755 --- a/seleniumbase/core/mysql_conf.py +++ b/seleniumbase/core/mysql_conf.py @@ -12,6 +12,7 @@ class Apps: TESTCASE_REPOSITORY = "testcase_repository" + APP_CREDS = { Apps.TESTCASE_REPOSITORY: { From fafc3fbb26d64449329f1574f2d339d34c8368f5 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 9 Mar 2017 23:56:51 -0500 Subject: [PATCH 08/35] Set default desired capabilities --- seleniumbase/core/browser_launcher.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/seleniumbase/core/browser_launcher.py b/seleniumbase/core/browser_launcher.py index e50faa78653..1d5530c9691 100755 --- a/seleniumbase/core/browser_launcher.py +++ b/seleniumbase/core/browser_launcher.py @@ -1,6 +1,7 @@ from selenium import webdriver from seleniumbase.core import download_helper from seleniumbase.fixtures import constants +from selenium.webdriver.common.desired_capabilities import DesiredCapabilities def get_driver(browser_name): @@ -31,7 +32,9 @@ def get_driver(browser_name): ("application/pdf, application/zip, application/octet-stream, " "text/csv, text/xml, application/xml, text/plain, " "text/octet-stream")) - return webdriver.Firefox(profile) + firefox_capabilities = DesiredCapabilities.FIREFOX + return webdriver.Firefox( + firefox_profile=profile, capabilities=firefox_capabilities) except: return webdriver.Firefox() if browser_name == constants.Browser.INTERNET_EXPLORER: From cb16263e2f8502c3e07b8de2b5785a6a175a5cc8 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 9 Mar 2017 23:59:03 -0500 Subject: [PATCH 09/35] Add Geckodriver installation to Dockerfile --- Dockerfile | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Dockerfile b/Dockerfile index 7c391245220..0e13d15caa6 100755 --- a/Dockerfile +++ b/Dockerfile @@ -73,6 +73,17 @@ RUN apt-get -qy --no-install-recommends install \ && ln -s /opt/firefox/firefox /usr/bin/firefox \ && rm -f /tmp/firefox-esr.tar.bz2 +#====================================== +# Install Geckodriver / Firefox Driver +#====================================== +RUN export BASE_URL=https://github.com/mozilla/geckodriver/releases/download \ + && export VERSION=$(curl -sL \ + https://api.github.com/repos/mozilla/geckodriver/releases/latest | \ + grep tag_name | cut -d '"' -f 4) \ + && curl -sL \ + $BASE_URL/$VERSION/geckodriver-$VERSION-linux64.tar.gz | tar -xz \ +&& mv geckodriver /usr/local/bin/geckodriver + #=================== # Install PhantomJS #=================== @@ -98,6 +109,8 @@ COPY seleniumbase /SeleniumBase/seleniumbase/ COPY examples /SeleniumBase/examples/ COPY requirements.txt /SeleniumBase/requirements.txt COPY setup.py /SeleniumBase/setup.py +RUN pip install --upgrade pip +RUN pip install --upgrade setuptools RUN cd /SeleniumBase && ls && pip install -r requirements.txt #========================================== From 2d0afcfa48fe6bad6d453ca627bc9cb70c8d536d Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 9 Mar 2017 23:59:49 -0500 Subject: [PATCH 10/35] Add Geckodriver installation to Linuxfile --- integrations/linux/Linuxfile.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/integrations/linux/Linuxfile.sh b/integrations/linux/Linuxfile.sh index 45c14cab0da..215ccd2d0dc 100755 --- a/integrations/linux/Linuxfile.sh +++ b/integrations/linux/Linuxfile.sh @@ -50,6 +50,18 @@ sudo ln -s /opt/firefox/firefox /usr/bin/firefox sudo rm -f /tmp/firefox-esr.tar.bz2 sudo apt-get -f install -y --force-yes firefox +# Install Geckodriver / Firefox Driver +export BASE_URL=https://github.com/mozilla/geckodriver/releases/download +export VERSION=$(curl -sL https://api.github.com/repos/mozilla/geckodriver/releases/latest | grep tag_name | cut -d '"' -f 4) +sudo curl -sL $BASE_URL/$VERSION/geckodriver-$VERSION-linux64.tar.gz | tar -xz +sudo chmod +x geckodriver +sudo rm -f /usr/local/share/geckodriver +sudo rm -f /usr/local/bin/geckodriver +sudo rm -f /usr/bin/geckodriver +sudo mv -f geckodriver /usr/local/share/geckodriver +sudo ln -s /usr/local/share/geckodriver /usr/local/bin/geckodriver +sudo ln -s /usr/local/share/geckodriver /usr/bin/geckodriver + # Install more dependencies sudo apt-get update sudo apt-get install -y --force-yes xvfb From 3a0fe6d100f39cac8baf7669571e8323f4ba5df7 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 00:01:15 -0500 Subject: [PATCH 11/35] Use self.assertTrue() instead of assert() in example test --- examples/my_first_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/my_first_test.py b/examples/my_first_test.py index 273dcbe6047..34c25ce2284 100755 --- a/examples/my_first_test.py +++ b/examples/my_first_test.py @@ -8,11 +8,11 @@ def test_basic(self): self.assert_element('img[alt="Python"]') # Asserts element on page self.click('a[rel="license"]') # Clicks element on page xkcd_license = self.get_text('center') # Gets text from page element - assert('reuse any of my drawings' in xkcd_license) + self.assertTrue('reuse any of my drawings' in xkcd_license) self.open('http://xkcd.com/1481/') image_object = self.find_element('#comic img') # Returns the element caption = image_object.get_attribute('title') # Gets attr from element - assert('connections to the server' in caption) + self.assertTrue('connections to the server' in caption) self.click_link_text('Blag') # Clicks link containing the text self.assert_text('The blag', 'header h2') # Asserts text in element self.update_text('input#s', 'Robots!\n') # Updates textfield with text From 790184b09882cdbbd921171fd14f7edc4a3871be Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 00:03:02 -0500 Subject: [PATCH 12/35] Putting the Chrome verification before Firefox --- help_docs/verify_webdriver.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/help_docs/verify_webdriver.md b/help_docs/verify_webdriver.md index ef18b6d57d4..7cb53e6b5b1 100755 --- a/help_docs/verify_webdriver.md +++ b/help_docs/verify_webdriver.md @@ -2,21 +2,21 @@ *You can do this by checking inside a Python command prompt. (NOTE: xkcd is a webcomic)* -#### Verifying FirefoxDriver (comes with Selenium by default) +#### Verifying ChromeDriver ```bash python >>> from selenium import webdriver ->>> browser = webdriver.Firefox() +>>> browser = webdriver.Chrome() >>> browser.get("http://xkcd.com/1337/") >>> browser.close() >>> exit() ``` -#### Verifying ChromeDriver (you had to install this separately) +#### Verifying FirefoxDriver (Geckodriver) ```bash python >>> from selenium import webdriver ->>> browser = webdriver.Chrome() +>>> browser = webdriver.Firefox() >>> browser.get("http://xkcd.com/1337/") >>> browser.close() >>> exit() From 16bd4386447f3f0844cc36b95f02ba04d8e2600e Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 00:19:37 -0500 Subject: [PATCH 13/35] Handle StaleElementReferenceException gracefully --- seleniumbase/fixtures/base_case.py | 122 ++++++++++++++++++++++++++--- 1 file changed, 110 insertions(+), 12 deletions(-) diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index 8b7c8f03384..d98a6285cab 100755 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -28,8 +28,10 @@ from seleniumbase.fixtures import page_actions from seleniumbase.fixtures import page_utils from seleniumbase.fixtures import xpath_to_css +from selenium.common.exceptions import StaleElementReferenceException from selenium.webdriver.remote.webdriver import WebDriver from selenium.webdriver.common.by import By +from selenium.webdriver.common.keys import Keys from selenium.webdriver import ActionChains @@ -68,7 +70,14 @@ def click(self, selector, by=By.CSS_SELECTOR, self.driver, selector, by, timeout=timeout) self._demo_mode_highlight_if_active(selector, by) pre_action_url = self.driver.current_url - element.click() + try: + element.click() + except StaleElementReferenceException: + self.wait_for_ready_state_complete() + time.sleep(0.05) + element = page_actions.wait_for_element_visible( + self.driver, selector, by, timeout=timeout) + element.click() if settings.WAIT_FOR_RSC_ON_CLICKS: self.wait_for_ready_state_complete() if self.demo_mode: @@ -85,10 +94,20 @@ def double_click(self, selector, by=By.CSS_SELECTOR, self.driver, selector, by, timeout=timeout) self._demo_mode_highlight_if_active(selector, by) pre_action_url = self.driver.current_url - actions = ActionChains(self.driver) - actions.move_to_element(element) - actions.double_click(element) - actions.perform() + try: + actions = ActionChains(self.driver) + actions.move_to_element(element) + actions.double_click(element) + actions.perform() + except StaleElementReferenceException: + self.wait_for_ready_state_complete() + time.sleep(0.05) + element = page_actions.wait_for_element_visible( + self.driver, selector, by, timeout=timeout) + actions = ActionChains(self.driver) + actions.move_to_element(element) + actions.double_click(element) + actions.perform() if settings.WAIT_FOR_RSC_ON_CLICKS: self.wait_for_ready_state_complete() if self.demo_mode: @@ -139,7 +158,14 @@ def click_link_text(self, link_text, timeout=settings.SMALL_TIMEOUT): element = self.wait_for_link_text_visible(link_text, timeout=timeout) self._demo_mode_highlight_if_active(link_text, by=By.LINK_TEXT) pre_action_url = self.driver.current_url - element.click() + try: + element.click() + except StaleElementReferenceException: + self.wait_for_ready_state_complete() + time.sleep(0.05) + element = self.wait_for_link_text_visible( + link_text, timeout=timeout) + element.click() if settings.WAIT_FOR_RSC_ON_CLICKS: self.wait_for_ready_state_complete() if self.demo_mode: @@ -152,13 +178,28 @@ def get_text(self, selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT): element = page_actions.wait_for_element_visible( self.driver, selector, by, timeout) - return element.text + try: + element_text = element.text + except StaleElementReferenceException: + self.wait_for_ready_state_complete() + time.sleep(0.06) + element = page_actions.wait_for_element_visible( + self.driver, selector, by, timeout) + element_text = element.text + return element_text def get_attribute(self, selector, attribute, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT): element = page_actions.wait_for_element_present( self.driver, selector, by, timeout) - attribute_value = element.get_attribute(attribute) + try: + attribute_value = element.get_attribute(attribute) + except StaleElementReferenceException: + self.wait_for_ready_state_complete() + time.sleep(0.06) + element = page_actions.wait_for_element_present( + self.driver, selector, by, timeout) + attribute_value = element.get_attribute(attribute) if attribute_value is not None: return attribute_value else: @@ -173,7 +214,28 @@ def add_text(self, selector, new_value, by=By.CSS_SELECTOR, selector, by=by, timeout=timeout) self._demo_mode_highlight_if_active(selector, by) pre_action_url = self.driver.current_url - element.send_keys(new_value) + try: + if not new_value.endswith('\n'): + element.send_keys(new_value) + else: + new_value = new_value[:-1] + element.send_keys(new_value) + element.send_keys(Keys.RETURN) + if settings.WAIT_FOR_RSC_ON_PAGE_LOADS: + self.wait_for_ready_state_complete() + except StaleElementReferenceException: + self.wait_for_ready_state_complete() + time.sleep(0.06) + element = self.wait_for_element_visible( + selector, by=by, timeout=timeout) + if not new_value.endswith('\n'): + element.send_keys(new_value) + else: + new_value = new_value[:-1] + element.send_keys(new_value) + element.send_keys(Keys.RETURN) + if settings.WAIT_FOR_RSC_ON_PAGE_LOADS: + self.wait_for_ready_state_complete() if self.demo_mode: if self.driver.current_url != pre_action_url: self._demo_mode_pause_if_active() @@ -198,10 +260,39 @@ def update_text_value(self, selector, new_value, by=By.CSS_SELECTOR, element = self.wait_for_element_visible( selector, by=by, timeout=timeout) self._demo_mode_highlight_if_active(selector, by) - element.clear() + try: + element.clear() + except StaleElementReferenceException: + self.wait_for_ready_state_complete() + time.sleep(0.06) + element = self.wait_for_element_visible( + selector, by=by, timeout=timeout) + element.clear() self._demo_mode_pause_if_active(tiny=True) pre_action_url = self.driver.current_url - element.send_keys(new_value) + try: + if not new_value.endswith('\n'): + element.send_keys(new_value) + else: + new_value = new_value[:-1] + element.send_keys(new_value) + element.send_keys(Keys.RETURN) + if settings.WAIT_FOR_RSC_ON_PAGE_LOADS: + self.wait_for_ready_state_complete() + except StaleElementReferenceException: + self.wait_for_ready_state_complete() + time.sleep(0.06) + element = self.wait_for_element_visible( + selector, by=by, timeout=timeout) + element.clear() + if not new_value.endswith('\n'): + element.send_keys(new_value) + else: + new_value = new_value[:-1] + element.send_keys(new_value) + element.send_keys(Keys.RETURN) + if settings.WAIT_FOR_RSC_ON_PAGE_LOADS: + self.wait_for_ready_state_complete() if (retry and element.get_attribute('value') != new_value and ( not new_value.endswith('\n'))): logging.debug('update_text_value is falling back to jQuery!') @@ -362,7 +453,14 @@ def scroll_to(self, selector, by=By.CSS_SELECTOR, ''' Fast scroll to destination ''' element = self.wait_for_element_visible( selector, by=by, timeout=timeout) - self._scroll_to_element(element) + try: + self._scroll_to_element(element) + except StaleElementReferenceException: + self.wait_for_ready_state_complete() + time.sleep(0.05) + element = self.wait_for_element_visible( + selector, by=by, timeout=timeout) + self._scroll_to_element(element) def slow_scroll_to(self, selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT): From eaff759ef78ac3797b05fa036bfb417e5b4dcbd2 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 00:21:02 -0500 Subject: [PATCH 14/35] Slight wording change --- conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conftest.py b/conftest.py index f16622d65c1..57c3eefec7c 100755 --- a/conftest.py +++ b/conftest.py @@ -13,7 +13,7 @@ def pytest_addoption(parser): dest='browser', choices=constants.Browser.VERSION.keys(), default=constants.Browser.GOOGLE_CHROME, - help="""Specifies the web browser to use. Default=Chrome. + help="""Specifies the web browser to use. Default: Chrome. If you want to use Firefox, explicitly indicate that. Example: (--browser=firefox)""") parser.addoption('--is_pytest', action="store_true", From bcc2f38af6ac1ce410261101c5de7e109a92fc73 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 00:22:03 -0500 Subject: [PATCH 15/35] Make waiting for "Ready State: Complete" the default --- seleniumbase/config/settings.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/seleniumbase/config/settings.py b/seleniumbase/config/settings.py index ccdb0877d02..85f58f36113 100755 --- a/seleniumbase/config/settings.py +++ b/seleniumbase/config/settings.py @@ -49,15 +49,17 @@ HTML_REPORT = "report.html" RESULTS_TABLE = "results_table.csv" -''' This adds wait_for_ready_state_complete() after various browser actions. - By default, Selenium waits for the 'interactive' state before continuing. - Setting this to True may improve reliability at the cost of speed. - WARNING: Some websites are in a perpetual "interactive" state due to - dynamic content that never fully finishes loading (Use "False" there). ''' +''' +This adds wait_for_ready_state_complete() after various browser actions. +By default, Selenium waits for the 'interactive' state before continuing. +Setting this to True may improve reliability at the cost of speed. +WARNING: Some websites are in a perpetual "interactive" state due to +dynamic content that never fully finishes loading (Use "False" there). +''' # Called after self.open(url) or self.open_url(url), NOT self.driver.open(url) -WAIT_FOR_RSC_ON_PAGE_LOADS = False +WAIT_FOR_RSC_ON_PAGE_LOADS = True # Called after self.click(selector), NOT element.click() -WAIT_FOR_RSC_ON_CLICKS = False +WAIT_FOR_RSC_ON_CLICKS = True # #####>>>>>----- MasterQA SETTINGS -----<<<<<##### From ad0b4df83114ff7ea4fe1aad54a32260202dd9bb Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 00:25:11 -0500 Subject: [PATCH 16/35] Work around a Geckodriver bug dealing with pop-up alerts --- seleniumbase/masterqa/master_qa.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/seleniumbase/masterqa/master_qa.py b/seleniumbase/masterqa/master_qa.py index e5df3a719af..d5f5ef1b22d 100755 --- a/seleniumbase/masterqa/master_qa.py +++ b/seleniumbase/masterqa/master_qa.py @@ -2,6 +2,7 @@ import shutil import sys import time +from selenium.common.exceptions import WebDriverException from selenium.webdriver.remote.errorhandler import NoAlertPresentException from seleniumbase import BaseCase from seleniumbase.core.style_sheet import style @@ -85,11 +86,16 @@ def manual_page_check(self, *args): self.wait_for_special_alert_absent() text = self.execute_script('''return window.master_qa_result''') else: - self.execute_script('''if(confirm("%s")){window.alert("Success!")} - else{window.alert("Failure!")}''' % question) + try: + self.execute_script( + '''if(confirm("%s")){window.master_qa_result="Success!"} + else{window.master_qa_result="Failure!"}''' % question) + except WebDriverException: + # Fix for https://github.com/mozilla/geckodriver/issues/431 + pass time.sleep(0.05) self.wait_for_special_alert_absent() - text = self.wait_for_and_accept_alert() + text = self.execute_script('''return window.master_qa_result''') self.manual_check_count += 1 if "Success!" in text: self.manual_check_successes += 1 From 2058793ee23aa0309caee7b0efd4b005fa1cdf86 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 00:25:51 -0500 Subject: [PATCH 17/35] Version 1.3.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 35049010da4..b797a86e6c1 100755 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ setup( name='seleniumbase', - version='1.2.15', + version='1.3.0', url='http://seleniumbase.com', author='Michael Mintz', author_email='@mintzworld', From 33dbe9fd7a72ac98a7e0b240c8eb5095090442fe Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 00:44:23 -0500 Subject: [PATCH 18/35] Update the ReadMe --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0ed13a9ab99..60aacf1eb8e 100755 --- a/README.md +++ b/README.md @@ -31,7 +31,9 @@ SeleniumBase makes it easy to automate tedious business tasks. (*To learn about * Download web browsers such as [Chrome](https://www.google.com/chrome/browser/desktop/index.html) (or [Chromium](https://download-chromium.appspot.com/)) and [Firefox](https://www.mozilla.org/firefox/new/). -* To run browser automation on Chrome, you'll need to download **[Chromedriver](https://sites.google.com/a/chromium.org/chromedriver/downloads)** and put it on your System **[PATH](http://java.com/en/download/help/path.xml)**. +To run automation on various web browsers, you'll need to download a driver file for each one and place it on your System **[PATH](http://java.com/en/download/help/path.xml)**: + +* For Chrome, get [Chromedriver](https://sites.google.com/a/chromium.org/chromedriver/downloads) on your System Path. * For Firefox, get [Geckodriver](https://github.com/mozilla/geckodriver/releases) on your System Path. From ca1299401051a35c4120027946a127281769c7d1 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 00:58:58 -0500 Subject: [PATCH 19/35] Update the Linuxfile --- integrations/linux/Linuxfile.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/linux/Linuxfile.sh b/integrations/linux/Linuxfile.sh index 215ccd2d0dc..4ecd9d4d4bd 100755 --- a/integrations/linux/Linuxfile.sh +++ b/integrations/linux/Linuxfile.sh @@ -53,7 +53,7 @@ sudo apt-get -f install -y --force-yes firefox # Install Geckodriver / Firefox Driver export BASE_URL=https://github.com/mozilla/geckodriver/releases/download export VERSION=$(curl -sL https://api.github.com/repos/mozilla/geckodriver/releases/latest | grep tag_name | cut -d '"' -f 4) -sudo curl -sL $BASE_URL/$VERSION/geckodriver-$VERSION-linux64.tar.gz | tar -xz +sudo curl -sL $BASE_URL/$VERSION/geckodriver-$VERSION-linux64.tar.gz | sudo tar -xz sudo chmod +x geckodriver sudo rm -f /usr/local/share/geckodriver sudo rm -f /usr/local/bin/geckodriver From 601e6364b7289614780cdf16b5c0315e02082f21 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 01:36:43 -0500 Subject: [PATCH 20/35] Try chrome for travis.yml selenium --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index d5c79d27668..6deb946e0b5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,10 +11,10 @@ before_script: - "export DISPLAY=:99.0" - "sh -e /etc/init.d/xvfb start" script: - - "firefox --version" - - "nosetests examples/my_first_test.py --with-selenium --browser=firefox" + - "chrome --version" + - "nosetests examples/my_first_test.py --with-selenium --browser=chrome" env: matrix: - - BROWSER=firefox + - BROWSER=chrome notifications: email: false From 3e3d7b4ebe05abd94946b3b3635730a1879fad78 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 01:44:09 -0500 Subject: [PATCH 21/35] travis.yml chrome update --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6deb946e0b5..f58c409514e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,9 @@ before_script: - "export DISPLAY=:99.0" - "sh -e /etc/init.d/xvfb start" script: - - "chrome --version" + - "wget http://chromedriver.googlecode.com/files/chromedriver_linux32_23.0.1240.0.zip" + - "unzip chromedriver_linux32_23.0.1240.0.zip" + - "sudo mv chromedriver /usr/bin" - "nosetests examples/my_first_test.py --with-selenium --browser=chrome" env: matrix: From 16d2ee63cb1cd1ed9e95de6b6bfef8749ea41b0b Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 01:48:37 -0500 Subject: [PATCH 22/35] Update chromedriver link --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index f58c409514e..c23dc87d9e4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,8 +11,8 @@ before_script: - "export DISPLAY=:99.0" - "sh -e /etc/init.d/xvfb start" script: - - "wget http://chromedriver.googlecode.com/files/chromedriver_linux32_23.0.1240.0.zip" - - "unzip chromedriver_linux32_23.0.1240.0.zip" + - "wget https://chromedriver.storage.googleapis.com/2.28/chromedriver_linux32.zip" + - "unzip chromedriver_linux32.zip" - "sudo mv chromedriver /usr/bin" - "nosetests examples/my_first_test.py --with-selenium --browser=chrome" env: From 2eef1a925401423af343990d43d8ceea5b432823 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 01:53:45 -0500 Subject: [PATCH 23/35] update travis.yml --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index c23dc87d9e4..050da86be33 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,9 @@ install: - "pip install --upgrade pip" - "pip install -r requirements.txt" - "python setup.py install" +sudo: required before_script: + - "sudo apt-get update -qq" - "flake8 seleniumbase/*/*.py" - "export DISPLAY=:99.0" - "sh -e /etc/init.d/xvfb start" From a4b9d74011beab787172f836593f51d2fd09d0f2 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 01:57:24 -0500 Subject: [PATCH 24/35] Update travis.yml --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 050da86be33..dcde143dbef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,9 +13,10 @@ before_script: - "export DISPLAY=:99.0" - "sh -e /etc/init.d/xvfb start" script: + - "echo $PATH" - "wget https://chromedriver.storage.googleapis.com/2.28/chromedriver_linux32.zip" - "unzip chromedriver_linux32.zip" - - "sudo mv chromedriver /usr/bin" + - "sudo mv chromedriver /usr/local/bin" - "nosetests examples/my_first_test.py --with-selenium --browser=chrome" env: matrix: From 6bcf50471c3efed372f4e14773e9965a6a0f1510 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 02:02:35 -0500 Subject: [PATCH 25/35] Update travis.yml --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index dcde143dbef..d562aadd67b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,8 @@ script: - "echo $PATH" - "wget https://chromedriver.storage.googleapis.com/2.28/chromedriver_linux32.zip" - "unzip chromedriver_linux32.zip" - - "sudo mv chromedriver /usr/local/bin" + - "sudo chmod +x chromedriver" + - "sudo mv chromedriver /usr/bin/chromedriver" - "nosetests examples/my_first_test.py --with-selenium --browser=chrome" env: matrix: From 5cc754ad49bd2473e7020678ebceae934218b2a2 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 02:09:45 -0500 Subject: [PATCH 26/35] Update travis.yml --- .travis.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index d562aadd67b..b855397d817 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,4 @@ language: python -sudo: false python: - "2.7" install: @@ -8,16 +7,14 @@ install: - "python setup.py install" sudo: required before_script: - - "sudo apt-get update -qq" - "flake8 seleniumbase/*/*.py" - "export DISPLAY=:99.0" - "sh -e /etc/init.d/xvfb start" script: - - "echo $PATH" - - "wget https://chromedriver.storage.googleapis.com/2.28/chromedriver_linux32.zip" - - "unzip chromedriver_linux32.zip" - - "sudo chmod +x chromedriver" - - "sudo mv chromedriver /usr/bin/chromedriver" + - "wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -" + - sudo sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' + - sudo apt-get update + - sudo apt-get install google-chrome-stable - "nosetests examples/my_first_test.py --with-selenium --browser=chrome" env: matrix: From ba5c14dd4dc7fdfc55f5cf969476513471f8208a Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 02:22:11 -0500 Subject: [PATCH 27/35] Linux compatibility --- .travis.yml | 15 +++++------ server_requirements.txt | 3 +-- server_setup.py | 55 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 11 deletions(-) create mode 100755 server_setup.py diff --git a/.travis.yml b/.travis.yml index b855397d817..645d5103ce9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,23 +1,20 @@ language: python +sudo: false python: - "2.7" install: - "pip install --upgrade pip" - - "pip install -r requirements.txt" - - "python setup.py install" -sudo: required + - "pip install -r server_requirements.txt" + - "python server_setup.py install" before_script: - "flake8 seleniumbase/*/*.py" - "export DISPLAY=:99.0" - "sh -e /etc/init.d/xvfb start" script: - - "wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -" - - sudo sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' - - sudo apt-get update - - sudo apt-get install google-chrome-stable - - "nosetests examples/my_first_test.py --with-selenium --browser=chrome" + - "firefox --version" + - "nosetests examples/my_first_test.py --with-selenium --browser=firefox" env: matrix: - - BROWSER=chrome + - BROWSER=firefox notifications: email: false diff --git a/server_requirements.txt b/server_requirements.txt index 6a07ec8408a..bb3e4d981a2 100755 --- a/server_requirements.txt +++ b/server_requirements.txt @@ -1,6 +1,6 @@ pip>=9.0.1 setuptools>=34.3.1 -selenium==3.3.0 +selenium==2.53.6 nose>=1.3.7 pytest>=3.0.6 six>=1.10.0 @@ -15,4 +15,3 @@ boto==2.46.1 ipdb==0.10.2 pyvirtualdisplay==0.2.1 MySQL-python==1.2.5 --e . diff --git a/server_setup.py b/server_setup.py new file mode 100755 index 00000000000..4697bc29b41 --- /dev/null +++ b/server_setup.py @@ -0,0 +1,55 @@ +""" +The setup package to install SeleniumBase dependencies and plugins +""" + +from setuptools import setup, find_packages # noqa + +setup( + name='seleniumbase', + version='1.3.0', + url='http://seleniumbase.com', + author='Michael Mintz', + author_email='@mintzworld', + maintainer='Michael Mintz', + description='Reliable Browser Automation - http://seleniumbase.com', + license='The MIT License', + install_requires=[ + 'pip>=9.0.1', + 'setuptools>=34.3.1', + 'selenium==2.53.6', + 'nose>=1.3.7', + 'pytest>=3.0.6', + 'six>=1.10.0', + 'flake8==3.3.0', + 'requests==2.13.0', + 'urllib3==1.20', + 'BeautifulSoup==3.2.1', + 'unittest2==1.1.0', + 'chardet==2.3.0', + 'simplejson==3.10.0', + 'boto==2.46.1', + 'ipdb==0.10.2', + 'pyvirtualdisplay==0.2.1', + ], + packages=['seleniumbase', + 'seleniumbase.core', + 'seleniumbase.plugins', + 'seleniumbase.fixtures', + 'seleniumbase.masterqa', + 'seleniumbase.common', + 'seleniumbase.config'], + entry_points={ + 'nose.plugins': [ + 'base_plugin = seleniumbase.plugins.base_plugin:Base', + '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', + ('db_reporting = ' + 'seleniumbase.plugins.db_reporting_plugin:DBReporting'), + 's3_logging = seleniumbase.plugins.s3_logging_plugin:S3Logging', + ('hipchat_reporting = seleniumbase.plugins' + '.hipchat_reporting_plugin:HipchatReporting'), + ] + } + ) From 7094662aa3e8eab91c87816d4a79989f7d5ef3a3 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 03:02:59 -0500 Subject: [PATCH 28/35] Remove an unused requirement --- requirements.txt | 1 - server_requirements.txt | 1 - server_setup.py | 1 - 3 files changed, 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 76584b4727b..9f6eb281f43 100755 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,6 @@ urllib3==1.20 BeautifulSoup==3.2.1 unittest2==1.1.0 chardet==2.3.0 -simplejson==3.10.0 boto==2.46.1 ipdb==0.10.2 pyvirtualdisplay==0.2.1 diff --git a/server_requirements.txt b/server_requirements.txt index bb3e4d981a2..d93fdf76fee 100755 --- a/server_requirements.txt +++ b/server_requirements.txt @@ -10,7 +10,6 @@ urllib3==1.20 BeautifulSoup==3.2.1 unittest2==1.1.0 chardet==2.3.0 -simplejson==3.10.0 boto==2.46.1 ipdb==0.10.2 pyvirtualdisplay==0.2.1 diff --git a/server_setup.py b/server_setup.py index 4697bc29b41..9ee65000435 100755 --- a/server_setup.py +++ b/server_setup.py @@ -26,7 +26,6 @@ 'BeautifulSoup==3.2.1', 'unittest2==1.1.0', 'chardet==2.3.0', - 'simplejson==3.10.0', 'boto==2.46.1', 'ipdb==0.10.2', 'pyvirtualdisplay==0.2.1', From c8d73c51bf642f984cc35880281dafa3a5b1da06 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 03:03:15 -0500 Subject: [PATCH 29/35] Comments --- server_setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/server_setup.py b/server_setup.py index 9ee65000435..4dec5133a18 100755 --- a/server_setup.py +++ b/server_setup.py @@ -1,5 +1,6 @@ """ The setup package to install SeleniumBase dependencies and plugins +Uses the older Selenium 2.53.6 for compatibility reasons """ from setuptools import setup, find_packages # noqa From fd40762b9088bb1b4e9f174cd0e60b0adeff73b0 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 03:04:06 -0500 Subject: [PATCH 30/35] Remove an unused requirement --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index b797a86e6c1..f9c1bc13df1 100755 --- a/setup.py +++ b/setup.py @@ -26,7 +26,6 @@ 'BeautifulSoup==3.2.1', 'unittest2==1.1.0', 'chardet==2.3.0', - 'simplejson==3.10.0', 'boto==2.46.1', 'ipdb==0.10.2', 'pyvirtualdisplay==0.2.1', From ae812024860e91ca0a61f410c6cfd582ae962572 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 03:04:32 -0500 Subject: [PATCH 31/35] Avoid Geckodriver for Linux machine setup --- integrations/linux/Linuxfile.sh | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/integrations/linux/Linuxfile.sh b/integrations/linux/Linuxfile.sh index 4ecd9d4d4bd..45c14cab0da 100755 --- a/integrations/linux/Linuxfile.sh +++ b/integrations/linux/Linuxfile.sh @@ -50,18 +50,6 @@ sudo ln -s /opt/firefox/firefox /usr/bin/firefox sudo rm -f /tmp/firefox-esr.tar.bz2 sudo apt-get -f install -y --force-yes firefox -# Install Geckodriver / Firefox Driver -export BASE_URL=https://github.com/mozilla/geckodriver/releases/download -export VERSION=$(curl -sL https://api.github.com/repos/mozilla/geckodriver/releases/latest | grep tag_name | cut -d '"' -f 4) -sudo curl -sL $BASE_URL/$VERSION/geckodriver-$VERSION-linux64.tar.gz | sudo tar -xz -sudo chmod +x geckodriver -sudo rm -f /usr/local/share/geckodriver -sudo rm -f /usr/local/bin/geckodriver -sudo rm -f /usr/bin/geckodriver -sudo mv -f geckodriver /usr/local/share/geckodriver -sudo ln -s /usr/local/share/geckodriver /usr/local/bin/geckodriver -sudo ln -s /usr/local/share/geckodriver /usr/bin/geckodriver - # Install more dependencies sudo apt-get update sudo apt-get install -y --force-yes xvfb From b039c3f8e0cc5c1b0716899b1fff4e369b911b07 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 03:06:49 -0500 Subject: [PATCH 32/35] Update a ReadMe --- integrations/google_cloud/ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/google_cloud/ReadMe.md b/integrations/google_cloud/ReadMe.md index 8b6b0da3ffa..86c803dce4e 100755 --- a/integrations/google_cloud/ReadMe.md +++ b/integrations/google_cloud/ReadMe.md @@ -76,7 +76,7 @@ sudo pip install -r server_requirements.txt --upgrade #### Step 12. Install SeleniumBase (Make sure you already installed the requirements above) ```bash -sudo python setup.py install +sudo python server_setup.py install ``` #### Step 13. Run an [example test](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py) in Chrome to verify installation (Takes ~10 seconds) From 5c40aa4dc0c2623c61b48e260b27a0eeb4e4a03a Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 03:21:25 -0500 Subject: [PATCH 33/35] Use the latest version of Chromedriver in the Linuxfile --- integrations/linux/Linuxfile.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/linux/Linuxfile.sh b/integrations/linux/Linuxfile.sh index 45c14cab0da..9c2a501d87f 100755 --- a/integrations/linux/Linuxfile.sh +++ b/integrations/linux/Linuxfile.sh @@ -75,7 +75,7 @@ sudo apt-get -f install -y --force-yes sudo dpkg -i google-chrome-stable_current_amd64.deb # Install Chromedriver -sudo wget -N http://chromedriver.storage.googleapis.com/2.20/chromedriver_linux64.zip -P ~/Downloads +sudo wget -N http://chromedriver.storage.googleapis.com/2.28/chromedriver_linux64.zip -P ~/Downloads sudo unzip -o ~/Downloads/chromedriver_linux64.zip -d ~/Downloads sudo chmod +x ~/Downloads/chromedriver sudo rm -f /usr/local/share/chromedriver From 20d3175da731f1df98d4c65fcf5a534fb4d0454e Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 03:24:04 -0500 Subject: [PATCH 34/35] Flake8 all the files for .travis.yml --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 645d5103ce9..8f6bc894a71 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,10 @@ install: - "pip install -r server_requirements.txt" - "python server_setup.py install" before_script: + - "flake8 seleniumbase/*.py" - "flake8 seleniumbase/*/*.py" + - "flake8 seleniumbase/*/*/*.py" + - "flake8 seleniumbase/*/*/*/*.py" - "export DISPLAY=:99.0" - "sh -e /etc/init.d/xvfb start" script: From 7bba7129764cd72e5a5cebf967fff60ca9ae7d8d Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 10 Mar 2017 03:45:27 -0500 Subject: [PATCH 35/35] Docker updates --- Dockerfile | 7 ++++--- docker_requirements.txt | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) create mode 100755 docker_requirements.txt diff --git a/Dockerfile b/Dockerfile index 0e13d15caa6..b2db1640597 100755 --- a/Dockerfile +++ b/Dockerfile @@ -107,11 +107,12 @@ RUN exec "$@" #===================== COPY seleniumbase /SeleniumBase/seleniumbase/ COPY examples /SeleniumBase/examples/ -COPY requirements.txt /SeleniumBase/requirements.txt -COPY setup.py /SeleniumBase/setup.py +COPY docker_requirements.txt /SeleniumBase/docker_requirements.txt +COPY server_setup.py /SeleniumBase/server_setup.py RUN pip install --upgrade pip RUN pip install --upgrade setuptools -RUN cd /SeleniumBase && ls && pip install -r requirements.txt +RUN cd /SeleniumBase && ls && pip install -r docker_requirements.txt +RUN cd /SeleniumBase && python server_setup.py install #========================================== # Create entrypoint and grab example tests diff --git a/docker_requirements.txt b/docker_requirements.txt new file mode 100755 index 00000000000..186a2c5c4dc --- /dev/null +++ b/docker_requirements.txt @@ -0,0 +1,15 @@ +pip>=9.0.1 +setuptools>=34.3.1 +selenium==2.53.6 +nose>=1.3.7 +pytest>=3.0.6 +six>=1.10.0 +flake8==3.3.0 +requests==2.13.0 +urllib3==1.20 +BeautifulSoup==3.2.1 +unittest2==1.1.0 +chardet==2.3.0 +boto==2.46.1 +ipdb==0.10.2 +pyvirtualdisplay==0.2.1