diff --git a/.travis.yml b/.travis.yml index 0e85afc..bd6896d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,15 @@ sudo: false language: python python: "3.6" addons: - firefox: "37.0.1" + firefox: "60.0.2" before_install: - "export DISPLAY=:99.0" + - wget https://github.com/mozilla/geckodriver/releases/download/v0.21.0/geckodriver-v0.21.0-linux64.tar.gz + - mkdir geckodriver + - tar -xzf geckodriver-v0.21.0-linux64.tar.gz -C geckodriver + - export PATH=$PATH:$PWD/geckodriver - "sh -e /etc/init.d/xvfb start" - - "npm install -g selenium-standalone@6.15.0" + - "npm install -g selenium-standalone@6.15.2" - "selenium-standalone install" - "selenium-standalone start &" env: diff --git a/CHANGES.rst b/CHANGES.rst index 01fcc34..e337cee 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,10 +1,16 @@ Changelog ========= +1.9.2 +----- + +- Bump minimum splinter version to 0.9.0 (jsfehler) +- Remove phantomjs support. (jsfehler) + 1.9.1 ----- -- Fix utf-8 decode warnings when taking screenshots with pytest-xdist active `#108 `_ (jsfehler) +- Fix utf-8 decode warnings when taking screenshots with pytest-xdist active `#108 `_ (jsfehler) 1.9.0 diff --git a/README.rst b/README.rst index ffe3ee4..1de5d7f 100644 --- a/README.rst +++ b/README.rst @@ -90,7 +90,7 @@ Fixtures @pytest.fixture(scope='session') def splinter_webdriver(): """Override splinter webdriver name.""" - return 'phantomjs' + return 'chrome' * splinter_remote_url Splinter's webdriver remote url to use (optional). Fixture gets the value from the command-line option @@ -198,7 +198,6 @@ Command-line options * firefox * remote * chrome - * phantomjs For more details refer to the documentation for splinter and selenium. @@ -220,7 +219,7 @@ Command-line options directory. * `--splinter-webdriver-executable` - Filesystem path of the webdriver executable. Used by phantomjs and chrome drivers. + Filesystem path of the webdriver executable. Used by chrome driver. Defaults to the None in which case the shell PATH variable setting determines the location of the executable. diff --git a/pytest_splinter/__init__.py b/pytest_splinter/__init__.py index a975387..1cb7788 100644 --- a/pytest_splinter/__init__.py +++ b/pytest_splinter/__init__.py @@ -1,2 +1,2 @@ """pytest-splinter package.""" -__version__ = '1.9.1' +__version__ = '1.9.2' diff --git a/pytest_splinter/plugin.py b/pytest_splinter/plugin.py index 6d96f2b..ef9283b 100644 --- a/pytest_splinter/plugin.py +++ b/pytest_splinter/plugin.py @@ -18,6 +18,8 @@ import splinter # pragma: no cover from _pytest import junitxml +from urllib3.exceptions import MaxRetryError + from selenium.webdriver.support import wait from selenium.webdriver.firefox.firefox_profile import FirefoxProfile from selenium.common.exceptions import WebDriverException @@ -322,7 +324,7 @@ def get_args(driver=None, # https://github.com/mozilla/geckodriver#firefox-capabilities kwargs['moz:firefoxOptions'] = driver_kwargs.get('moz:firefoxOptions', {}) kwargs['moz:firefoxOptions']['profile'] = profile.encoded - elif driver in ('phantomjs', 'chrome'): + elif driver in ('chrome',): if executable: kwargs['executable_path'] = executable @@ -570,7 +572,7 @@ def _take_screenshot_on_failure(): browser.visit_condition = splinter_browser_load_condition browser.visit_condition_timeout = splinter_browser_load_timeout browser.visit('about:blank') - except (IOError, HTTPException, WebDriverException): + except (IOError, HTTPException, WebDriverException, MaxRetryError): # we lost browser, try to restore the justice try: browser.quit() diff --git a/pytest_splinter/splinter_patches.py b/pytest_splinter/splinter_patches.py index 51bb40b..7fb0d68 100644 --- a/pytest_splinter/splinter_patches.py +++ b/pytest_splinter/splinter_patches.py @@ -2,7 +2,6 @@ from functools import partial from splinter.driver.webdriver import firefox -from splinter.driver.webdriver import phantomjs from splinter.driver.webdriver import remote from selenium.webdriver.common.action_chains import ActionChains # pragma: no cover @@ -21,17 +20,5 @@ def mouse_over(self): # Apply the monkey patch for Firefox WebDriverElement firefox.WebDriverElement.mouse_over = mouse_over - old_text = phantomjs.WebDriverElement.text - - def text(self): - """Get element text.""" - text = old_text.fget(self) - if not text and self.html: - text = self._element.get_attribute('outerText').strip().replace(u'\xa0', u' ') - return text - - # Apply the monkey patch for PhantomJs WebDriverElement - phantomjs.WebDriverElement.text = property(text) - phantomjs.WebDriverElement.mouse_over = mouse_over # Enable keep_alive for remove driver remote.Remote = partial(remote.Remote, keep_alive=True) diff --git a/pytest_splinter/webdriver_patches.py b/pytest_splinter/webdriver_patches.py index 7681e71..a7b3e73 100644 --- a/pytest_splinter/webdriver_patches.py +++ b/pytest_splinter/webdriver_patches.py @@ -8,9 +8,12 @@ import time # pragma: no cover import socket # pragma: no cover try: - from httplib import HTTPConnection, HTTPException + from httplib import HTTPException except ImportError: - from http.client import HTTPConnection, HTTPException + from http.client import HTTPException + +import urllib3 +from urllib3.exceptions import MaxRetryError from selenium.webdriver.remote import remote_connection # pragma: no cover from selenium.webdriver.firefox import webdriver # pragma: no cover @@ -39,12 +42,12 @@ def _request(self, *args, **kwargs): for _ in range(3): try: return old_request(self, *args, **kwargs) - except (socket.error, HTTPException, IOError, OSError) as exc: + except (socket.error, HTTPException, IOError, OSError, MaxRetryError) as exc: exception = exc - self._conn = HTTPConnection(self._conn.host, self._conn.port, timeout=self._timeout) + self._conn = urllib3.PoolManager(timeout=self._timeout) raise exception - # Apply the monkey patche for RemoteConnection + # Apply the monkey patch for RemoteConnection remote_connection.RemoteConnection._request = _request # Apply the monkey patch to Firefox webdriver to disable native events diff --git a/requirements-testing.txt b/requirements-testing.txt index 869b731..37d3a37 100644 --- a/requirements-testing.txt +++ b/requirements-testing.txt @@ -4,5 +4,5 @@ pytest-localserver pylama pylama_pylint astroid>=1.4.5 -selenium<3 -splinter<=0.7.5 +selenium +splinter>=0.9.0 diff --git a/setup.py b/setup.py index 7f1d23b..d622a06 100755 --- a/setup.py +++ b/setup.py @@ -26,9 +26,10 @@ url='https://github.com/pytest-dev/pytest-splinter', install_requires=[ 'setuptools', - 'splinter>=0.7.3', - 'selenium>=2.47.1', + 'splinter>=0.9.0', + 'selenium', 'pytest>=3.0.0', + 'urllib3', ], classifiers=[ 'Development Status :: 6 - Mature', diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 92a3638..62062ff 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -44,11 +44,25 @@ def test_session_browser(session_browser): def test_status_code(browser, simple_page, splinter_webdriver): """Check the browser fixture.""" - if splinter_webdriver == "zope.testbrowser": - pytest.skip("zope testbrowser doesn't support status code") + if splinter_webdriver in ("firefox", "zope.testbrowser",): + skip_msg = "{} doesn't support status code".format(splinter_webdriver) + pytest.skip(skip_msg) assert browser.status_code == 200 +def test_status_code_not_implemented(browser, simple_page, splinter_webdriver): + """Ensure the browsers which should not have status_code still don't.""" + if splinter_webdriver in ("firefox", "zope.testbrowser",): + not_implemented = False + try: + browser.status_code == 200 + except NotImplementedError: + not_implemented = True + assert not_implemented + else: + pytest.skip('{} supports status code'.format(splinter_webdriver)) + + @pytest.mark.parametrize( ( 'file_extension', @@ -61,20 +75,26 @@ def test_status_code(browser, simple_page, splinter_webdriver): ) def test_download_file(httpserver, browser, splinter_file_download_dir, file_extension, mime_type, splinter_webdriver): """Test file downloading and accessing it afterwise.""" - if splinter_webdriver in ["zope.testbrowser", "phantomjs"]: + if splinter_webdriver in ["zope.testbrowser"]: pytest.skip("{0} doesn't support file downloading".format(splinter_webdriver)) + if splinter_webdriver in ["firefox"]: + pytest.skip("Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1366035") file_name = 'some.{0}'.format(file_extension) httpserver.serve_content( 'Some text file', code=200, headers={ 'Content-Disposition': 'attachment; filename={0}'.format(file_name), 'Content-Type': mime_type}) + browser.visit(httpserver.url) time.sleep(1) - assert open(os.path.join(splinter_file_download_dir, file_name)).read() == 'Some text file' + + file_path = os.path.join(splinter_file_download_dir, file_name) + with open(file_path, 'r') as f: + assert f.read() == 'Some text file' @pytest.mark.parametrize('cookie_name', ['name1', 'name2']) -@pytest.mark.parametrize('splinter_webdriver', ['firefox', 'phantomjs']) +@pytest.mark.parametrize('splinter_webdriver', ['firefox']) def test_clean_cookies(httpserver, browser, cookie_name, splinter_webdriver, splinter_session_scoped_browser): """Test that browser has always clean state (no cookies set).""" if splinter_webdriver == "zope.testbrowser": @@ -94,7 +114,7 @@ def test_clean_cookies(httpserver, browser, cookie_name, splinter_webdriver, spl @pytest.mark.skipif('sys.version_info[0] > 2') -# @pytest.mark.parametrize('splinter_webdriver', ['firefox', 'phantomjs']) +# @pytest.mark.parametrize('splinter_webdriver', ['firefox']) def test_get_text(simple_page, browser, splinter_webdriver): """Test that webelement correctly gets text.""" if splinter_webdriver == "zope.testbrowser": @@ -148,10 +168,8 @@ def test_current_window_is_main(browser, splinter_webdriver): def test_executable(): """Test argument construction for webdrivers.""" - arg1 = get_args(driver='phantomjs', executable='/tmp') - arg2 = get_args(driver='chrome', executable='/tmp') + arg1 = get_args(driver='chrome', executable='/tmp') assert arg1['executable_path'] == '/tmp' - assert arg2['executable_path'] == '/tmp' def assert_valid_html_screenshot_content(content): diff --git a/tox.ini b/tox.ini index be6a06a..3dc664b 100644 --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,7 @@ envlist=linters,py27,py27-xdist,py27-pytest-latest,py36 skip_missing_interpreters = true [testenv] -commands= py.test tests --junitxml={envlogdir}/junit-{envname}.xml +commands= py.test {posargs} tests --junitxml={envlogdir}/junit-{envname}.xml deps = -e. -r{toxinidir}/requirements-testing.txt