diff --git a/.travis.yml b/.travis.yml index 3125407a4..3e460d3e9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,21 @@ language: python sudo: false python: - - "2.6" - "2.7" -install: + - "3.4" +before_install: + - "./.travis_python_dep.sh" +install: true #- pip install pep8 --use-mirrors #- pip install pyflakes --use-mirrors - - pip install robotframework - - pip install selenium - - pip install decorator - - pip install docutils + # Installation is done at before_install + ##- pip install robotframework==3.0b1 + ##- pip install selenium + ##- pip install decorator + ##- pip install docutils + ##- pip install future + # Mockito is only used when in Python 2.7 + ##- pip install mockito #- "if [[ ${BROWSER} == 'ie' ]]; then pip install ie_only_pkg; fi" before_script: - "export DISPLAY=:99.0" diff --git a/.travis_python_dep.sh b/.travis_python_dep.sh new file mode 100755 index 000000000..2f8a1dab1 --- /dev/null +++ b/.travis_python_dep.sh @@ -0,0 +1,17 @@ +#!/bin/bash +set -ev +PYTHON_VERSION=`python -c "import sys; print(sys.version[:3])"` +if [ "${PYTHON_VERSION}" = "2.7" ]; then + pip install robotframework + pip install selenium + pip install decorator + pip install docutils + pip install future + pip install mockito +elif [ "${PYTHON_VERSION}" = "3.4" ]; then + pip install robotframework==3.0b1 + pip install selenium + pip install decorator + pip install docutils + pip install future +fi diff --git a/build_dist.py b/build_dist.py index 6b5dd3530..894ec99a7 100644 --- a/build_dist.py +++ b/build_dist.py @@ -1,5 +1,6 @@ #!/usr/bin/env python +from __future__ import print_function import os, sys, shutil, subprocess, argparse THIS_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -33,7 +34,7 @@ def clear_dist_folder(): def run_doc_gen(): import generate - print + print() generate.main() def run_register(args): @@ -41,7 +42,7 @@ def run_register(args): _run_setup(args.py_27_path, "register", [], False) def run_builds(args): - print + print() if not args.winonly: _run_setup(args.py_27_path, "sdist", [ "--formats=gztar,zip" ], args.release) _run_setup(args.py_26_path, "bdist_egg", [], args.release) @@ -50,12 +51,12 @@ def run_builds(args): _run_setup(args.py_27_path, "bdist_wininst", [ "--plat-name=win32" ], args.release) _run_setup(args.py_27_path, "bdist_wininst", [ "--plat-name=win-amd64" ], args.release) else: - print + print() print("Windows binary installers cannot be built on this platform!") def run_demo_packaging(): import package - print + print() package.main() def _run_setup(py_path, type, params, upload): @@ -66,7 +67,7 @@ def _run_setup(py_path, type, params, upload): if upload: setup_args.append("upload") - print + print() print("Running: %s" % ' '.join(setup_args)) returncode = subprocess.call(setup_args) if returncode != 0: diff --git a/setup.py b/setup.py index 3b58879c9..147197389 100755 --- a/setup.py +++ b/setup.py @@ -1,3 +1,4 @@ +from past.builtins import execfile #!/usr/bin/env python import sys diff --git a/src/Selenium2Library/__init__.py b/src/Selenium2Library/__init__.py index 75884e9ea..b208e40f9 100644 --- a/src/Selenium2Library/__init__.py +++ b/src/Selenium2Library/__init__.py @@ -1,7 +1,8 @@ +from __future__ import absolute_import import os -from keywords import * -from version import VERSION -from utils import LibraryListener +from .keywords import * +from .version import VERSION +from .utils import LibraryListener __version__ = VERSION diff --git a/src/Selenium2Library/keywords/__init__.py b/src/Selenium2Library/keywords/__init__.py index 431bb107c..09ff409a7 100644 --- a/src/Selenium2Library/keywords/__init__.py +++ b/src/Selenium2Library/keywords/__init__.py @@ -1,15 +1,16 @@ -from _logging import _LoggingKeywords -from _runonfailure import _RunOnFailureKeywords -from _browsermanagement import _BrowserManagementKeywords -from _element import _ElementKeywords -from _tableelement import _TableElementKeywords -from _formelement import _FormElementKeywords -from _selectelement import _SelectElementKeywords -from _javascript import _JavaScriptKeywords -from _cookie import _CookieKeywords -from _screenshot import _ScreenshotKeywords -from _waiting import _WaitingKeywords -from _alert import _AlertKeywords +from __future__ import absolute_import +from ._logging import _LoggingKeywords +from ._runonfailure import _RunOnFailureKeywords +from ._browsermanagement import _BrowserManagementKeywords +from ._element import _ElementKeywords +from ._tableelement import _TableElementKeywords +from ._formelement import _FormElementKeywords +from ._selectelement import _SelectElementKeywords +from ._javascript import _JavaScriptKeywords +from ._cookie import _CookieKeywords +from ._screenshot import _ScreenshotKeywords +from ._waiting import _WaitingKeywords +from ._alert import _AlertKeywords __all__ = [ "_LoggingKeywords", diff --git a/src/Selenium2Library/keywords/_alert.py b/src/Selenium2Library/keywords/_alert.py index f7a245f1f..44b2b7653 100644 --- a/src/Selenium2Library/keywords/_alert.py +++ b/src/Selenium2Library/keywords/_alert.py @@ -1,136 +1,137 @@ -from selenium.common.exceptions import WebDriverException -from selenium.webdriver.support.ui import WebDriverWait -from selenium.webdriver.support import expected_conditions as EC -from keywordgroup import KeywordGroup - - -class _AlertKeywords(KeywordGroup): - - def __init__(self): - self._cancel_on_next_confirmation = False - - # Public - - def input_text_into_prompt(self, text): - """Types the given `text` into alert box. """ - alert = None - try: - alert = self._wait_alert() - alert.send_keys(text) - except WebDriverException: - raise RuntimeError('There were no alerts') - - def alert_should_be_present(self, text=''): - """Verifies an alert is present and dismisses it. - - If `text` is a non-empty string, then it is also verified that the - message of the alert equals to `text`. - - Will fail if no alert is present. Note that following keywords - will fail unless the alert is dismissed by this - keyword or another like `Get Alert Message`. - """ - alert_text = self.get_alert_message() - if text and alert_text != text: - raise AssertionError("Alert text should have been " - "'%s' but was '%s'" - % (text, alert_text)) - - def choose_cancel_on_next_confirmation(self): - """Cancel will be selected the next time `Confirm Action` is used.""" - self._cancel_on_next_confirmation = True - - def choose_ok_on_next_confirmation(self): - """Undo the effect of using keywords `Choose Cancel On Next Confirmation`. Note - that Selenium's overridden window.confirm() function will normally - automatically return true, as if the user had manually clicked OK, so - you shouldn't need to use this command unless for some reason you need - to change your mind prior to the next confirmation. After any - confirmation, Selenium will resume using the default behavior for - future confirmations, automatically returning true (OK) unless/until - you explicitly use `Choose Cancel On Next Confirmation` for each - confirmation. - - Note that every time a confirmation comes up, you must - consume it by using a keywords such as `Get Alert Message`, or else - the following selenium operations will fail. - """ - self._cancel_on_next_confirmation = False - - def confirm_action(self): - """Dismisses currently shown confirmation dialog and returns it's message. - - By default, this keyword chooses 'OK' option from the dialog. If - 'Cancel' needs to be chosen, keyword `Choose Cancel On Next - Confirmation` must be called before the action that causes the - confirmation dialog to be shown. - - Examples: - | Click Button | Send | # Shows a confirmation dialog | - | ${message}= | Confirm Action | # Chooses Ok | - | Should Be Equal | ${message} | Are your sure? | - | | | | - | Choose Cancel On Next Confirmation | | | - | Click Button | Send | # Shows a confirmation dialog | - | Confirm Action | | # Chooses Cancel | - """ - text = self._close_alert(not self._cancel_on_next_confirmation) - self._cancel_on_next_confirmation = False - return text - - def get_alert_message(self, dismiss=True): - """Returns the text of current JavaScript alert. - - By default the current JavaScript alert will be dismissed. - This keyword will fail if no alert is present. Note that - following keywords will fail unless the alert is - dismissed by this keyword or another like `Get Alert Message`. - """ - if dismiss: - return self._close_alert() - else: - return self._read_alert() - - def dismiss_alert(self, accept=True): - """ Returns true if alert was confirmed, false if it was dismissed - - This keyword will fail if no alert is present. Note that - following keywords will fail unless the alert is - dismissed by this keyword or another like `Get Alert Message`. - """ - return self._handle_alert(accept) - - # Private - - def _close_alert(self, confirm=True): - try: - text = self._read_alert() - self._handle_alert(confirm) - return text - except WebDriverException: - raise RuntimeError('There were no alerts') - - def _read_alert(self): - alert = None - try: - alert = self._wait_alert() - # collapse new lines chars - return ' '.join(alert.text.splitlines()) - except WebDriverException: - raise RuntimeError('There were no alerts') - - def _handle_alert(self, confirm=True): - try: - alert = self._wait_alert() - if not confirm: - alert.dismiss() - return False - else: - alert.accept() - return True - except WebDriverException: - raise RuntimeError('There were no alerts') - - def _wait_alert(self): - return WebDriverWait(self._current_browser(), 1).until( - EC.alert_is_present()) +from __future__ import absolute_import +from selenium.common.exceptions import WebDriverException +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +from .keywordgroup import KeywordGroup + + +class _AlertKeywords(KeywordGroup): + + def __init__(self): + self._cancel_on_next_confirmation = False + + # Public + + def input_text_into_prompt(self, text): + """Types the given `text` into alert box. """ + alert = None + try: + alert = self._wait_alert() + alert.send_keys(text) + except WebDriverException: + raise RuntimeError('There were no alerts') + + def alert_should_be_present(self, text=''): + """Verifies an alert is present and dismisses it. + + If `text` is a non-empty string, then it is also verified that the + message of the alert equals to `text`. + + Will fail if no alert is present. Note that following keywords + will fail unless the alert is dismissed by this + keyword or another like `Get Alert Message`. + """ + alert_text = self.get_alert_message() + if text and alert_text != text: + raise AssertionError("Alert text should have been " + "'%s' but was '%s'" + % (text, alert_text)) + + def choose_cancel_on_next_confirmation(self): + """Cancel will be selected the next time `Confirm Action` is used.""" + self._cancel_on_next_confirmation = True + + def choose_ok_on_next_confirmation(self): + """Undo the effect of using keywords `Choose Cancel On Next Confirmation`. Note + that Selenium's overridden window.confirm() function will normally + automatically return true, as if the user had manually clicked OK, so + you shouldn't need to use this command unless for some reason you need + to change your mind prior to the next confirmation. After any + confirmation, Selenium will resume using the default behavior for + future confirmations, automatically returning true (OK) unless/until + you explicitly use `Choose Cancel On Next Confirmation` for each + confirmation. + + Note that every time a confirmation comes up, you must + consume it by using a keywords such as `Get Alert Message`, or else + the following selenium operations will fail. + """ + self._cancel_on_next_confirmation = False + + def confirm_action(self): + """Dismisses currently shown confirmation dialog and returns it's message. + + By default, this keyword chooses 'OK' option from the dialog. If + 'Cancel' needs to be chosen, keyword `Choose Cancel On Next + Confirmation` must be called before the action that causes the + confirmation dialog to be shown. + + Examples: + | Click Button | Send | # Shows a confirmation dialog | + | ${message}= | Confirm Action | # Chooses Ok | + | Should Be Equal | ${message} | Are your sure? | + | | | | + | Choose Cancel On Next Confirmation | | | + | Click Button | Send | # Shows a confirmation dialog | + | Confirm Action | | # Chooses Cancel | + """ + text = self._close_alert(not self._cancel_on_next_confirmation) + self._cancel_on_next_confirmation = False + return text + + def get_alert_message(self, dismiss=True): + """Returns the text of current JavaScript alert. + + By default the current JavaScript alert will be dismissed. + This keyword will fail if no alert is present. Note that + following keywords will fail unless the alert is + dismissed by this keyword or another like `Get Alert Message`. + """ + if dismiss: + return self._close_alert() + else: + return self._read_alert() + + def dismiss_alert(self, accept=True): + """ Returns true if alert was confirmed, false if it was dismissed + + This keyword will fail if no alert is present. Note that + following keywords will fail unless the alert is + dismissed by this keyword or another like `Get Alert Message`. + """ + return self._handle_alert(accept) + + # Private + + def _close_alert(self, confirm=True): + try: + text = self._read_alert() + self._handle_alert(confirm) + return text + except WebDriverException: + raise RuntimeError('There were no alerts') + + def _read_alert(self): + alert = None + try: + alert = self._wait_alert() + # collapse new lines chars + return ' '.join(alert.text.splitlines()) + except WebDriverException: + raise RuntimeError('There were no alerts') + + def _handle_alert(self, confirm=True): + try: + alert = self._wait_alert() + if not confirm: + alert.dismiss() + return False + else: + alert.accept() + return True + except WebDriverException: + raise RuntimeError('There were no alerts') + + def _wait_alert(self): + return WebDriverWait(self._current_browser(), 1).until( + EC.alert_is_present()) diff --git a/src/Selenium2Library/keywords/_browsermanagement.py b/src/Selenium2Library/keywords/_browsermanagement.py index 339028804..1c301ba0d 100644 --- a/src/Selenium2Library/keywords/_browsermanagement.py +++ b/src/Selenium2Library/keywords/_browsermanagement.py @@ -1,3 +1,5 @@ +from __future__ import absolute_import +from builtins import str import os import robot from robot.errors import DataError @@ -5,7 +7,7 @@ from Selenium2Library import webdrivermonkeypatches from Selenium2Library.utils import BrowserCache from Selenium2Library.locators import WindowManager -from keywordgroup import KeywordGroup +from .keywordgroup import KeywordGroup from selenium.common.exceptions import NoSuchWindowException ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) @@ -595,7 +597,7 @@ def _create_remote_web_driver(self , capabilities_type , remote_url , desired_ca desired_capabilities_object = capabilities_type.copy() - if type(desired_capabilities) in (str, unicode): + if type(desired_capabilities) in (str, str): desired_capabilities = self._parse_capabilities_string(desired_capabilities) desired_capabilities_object.update(desired_capabilities or {}) diff --git a/src/Selenium2Library/keywords/_cookie.py b/src/Selenium2Library/keywords/_cookie.py index a97808f06..ef6029224 100644 --- a/src/Selenium2Library/keywords/_cookie.py +++ b/src/Selenium2Library/keywords/_cookie.py @@ -1,4 +1,5 @@ -from keywordgroup import KeywordGroup +from __future__ import absolute_import +from .keywordgroup import KeywordGroup class _CookieKeywords(KeywordGroup): diff --git a/src/Selenium2Library/keywords/_element.py b/src/Selenium2Library/keywords/_element.py index 357ff1bd5..0fe88a7d3 100644 --- a/src/Selenium2Library/keywords/_element.py +++ b/src/Selenium2Library/keywords/_element.py @@ -1,10 +1,16 @@ +from __future__ import division +from __future__ import absolute_import +from builtins import str +from builtins import chr +from past.builtins import basestring +from past.utils import old_div from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.remote.webelement import WebElement from Selenium2Library import utils from Selenium2Library.locators import ElementFinder from Selenium2Library.locators import CustomLocator -from keywordgroup import KeywordGroup +from .keywordgroup import KeywordGroup try: basestring # attempt to evaluate basestring @@ -439,8 +445,8 @@ def mouse_out(self, locator): if element is None: raise AssertionError("ERROR: Element %s not found." % (locator)) size = element.size - offsetx = (size['width'] / 2) + 1 - offsety = (size['height'] / 2) + 1 + offsetx = (old_div(size['width'], 2)) + 1 + offsety = (old_div(size['height'], 2)) + 1 ActionChains(self._current_browser()).move_to_element(element).move_by_offset(offsetx, offsety).perform() def mouse_over(self, locator): diff --git a/src/Selenium2Library/keywords/_formelement.py b/src/Selenium2Library/keywords/_formelement.py index 88a3b50ad..6e670b3fb 100644 --- a/src/Selenium2Library/keywords/_formelement.py +++ b/src/Selenium2Library/keywords/_formelement.py @@ -1,5 +1,6 @@ +from __future__ import absolute_import import os -from keywordgroup import KeywordGroup +from .keywordgroup import KeywordGroup from selenium.common.exceptions import WebDriverException class _FormElementKeywords(KeywordGroup): diff --git a/src/Selenium2Library/keywords/_javascript.py b/src/Selenium2Library/keywords/_javascript.py index 8f68025b5..9019e74f3 100644 --- a/src/Selenium2Library/keywords/_javascript.py +++ b/src/Selenium2Library/keywords/_javascript.py @@ -1,5 +1,6 @@ +from __future__ import absolute_import import os -from keywordgroup import KeywordGroup +from .keywordgroup import KeywordGroup class _JavaScriptKeywords(KeywordGroup): diff --git a/src/Selenium2Library/keywords/_logging.py b/src/Selenium2Library/keywords/_logging.py index 4d33d2f7a..2b8a06a29 100644 --- a/src/Selenium2Library/keywords/_logging.py +++ b/src/Selenium2Library/keywords/_logging.py @@ -1,7 +1,8 @@ +from __future__ import absolute_import import os import sys from robot.api import logger -from keywordgroup import KeywordGroup +from .keywordgroup import KeywordGroup from robot.libraries.BuiltIn import BuiltIn try: diff --git a/src/Selenium2Library/keywords/_runonfailure.py b/src/Selenium2Library/keywords/_runonfailure.py index 4e9057107..7cf5aa36b 100644 --- a/src/Selenium2Library/keywords/_runonfailure.py +++ b/src/Selenium2Library/keywords/_runonfailure.py @@ -1,5 +1,6 @@ +from __future__ import absolute_import from robot.libraries import BuiltIn -from keywordgroup import KeywordGroup +from .keywordgroup import KeywordGroup BUILTIN = BuiltIn.BuiltIn() @@ -57,7 +58,7 @@ def _run_on_failure(self): self._running_on_failure_routine = True try: BUILTIN.run_keyword(self._run_on_failure_keyword) - except Exception, err: + except Exception as err: self._run_on_failure_error(err) finally: self._running_on_failure_routine = False diff --git a/src/Selenium2Library/keywords/_screenshot.py b/src/Selenium2Library/keywords/_screenshot.py index 8e824ccc8..59bf91a09 100644 --- a/src/Selenium2Library/keywords/_screenshot.py +++ b/src/Selenium2Library/keywords/_screenshot.py @@ -1,8 +1,9 @@ +from __future__ import absolute_import import robot import os, errno from Selenium2Library import utils -from keywordgroup import KeywordGroup +from .keywordgroup import KeywordGroup class _ScreenshotKeywords(KeywordGroup): diff --git a/src/Selenium2Library/keywords/_selectelement.py b/src/Selenium2Library/keywords/_selectelement.py index e63bfd466..2f5eb3335 100644 --- a/src/Selenium2Library/keywords/_selectelement.py +++ b/src/Selenium2Library/keywords/_selectelement.py @@ -1,5 +1,8 @@ +from __future__ import absolute_import +from builtins import zip +from builtins import range from selenium.webdriver.support.ui import Select -from keywordgroup import KeywordGroup +from .keywordgroup import KeywordGroup class _SelectElementKeywords(KeywordGroup): diff --git a/src/Selenium2Library/keywords/_tableelement.py b/src/Selenium2Library/keywords/_tableelement.py index 55eea39c8..7425dd41c 100644 --- a/src/Selenium2Library/keywords/_tableelement.py +++ b/src/Selenium2Library/keywords/_tableelement.py @@ -1,7 +1,9 @@ +from __future__ import absolute_import +from builtins import str import os import sys from Selenium2Library.locators import TableElementFinder -from keywordgroup import KeywordGroup +from .keywordgroup import KeywordGroup class _TableElementKeywords(KeywordGroup): @@ -64,7 +66,7 @@ def table_cell_should_contain(self, table_locator, row, column, expected, loglev % (table_locator, row, column, expected)) try: content = self.get_table_cell(table_locator, row, column, loglevel='NONE') - except AssertionError, err: + except AssertionError as err: self._info(err) self.log_source(loglevel) raise AssertionError(message) diff --git a/src/Selenium2Library/keywords/_waiting.py b/src/Selenium2Library/keywords/_waiting.py index af36bc871..0183dde24 100644 --- a/src/Selenium2Library/keywords/_waiting.py +++ b/src/Selenium2Library/keywords/_waiting.py @@ -1,6 +1,7 @@ +from __future__ import absolute_import import time import robot -from keywordgroup import KeywordGroup +from .keywordgroup import KeywordGroup class _WaitingKeywords(KeywordGroup): diff --git a/src/Selenium2Library/keywords/keywordgroup.py b/src/Selenium2Library/keywords/keywordgroup.py index 672603afd..83ce36958 100644 --- a/src/Selenium2Library/keywords/keywordgroup.py +++ b/src/Selenium2Library/keywords/keywordgroup.py @@ -1,5 +1,7 @@ +from builtins import object import sys import inspect +from future.utils import with_metaclass try: from decorator import decorator except SyntaxError: # decorator module requires Python/Jython 2.4+ @@ -13,7 +15,7 @@ def _run_on_failure_decorator(method, *args, **kwargs): self._already_in_keyword = True # Set a flag on the instance so that as we call keywords inside this call and this gets run again, we know we're at least one level in. try: return method(*args, **kwargs) - except Exception, err: + except Exception as err: if hasattr(self, '_run_on_failure') and not self._has_run_on_failure: # If we're in an inner keyword, track the fact that we've already run on failure once self._has_run_on_failure = True @@ -28,10 +30,10 @@ def _run_on_failure_decorator(method, *args, **kwargs): class KeywordGroupMetaClass(type): def __new__(cls, clsname, bases, dict): if decorator: - for name, method in dict.items(): + for name, method in list(dict.items()): if not name.startswith('_') and inspect.isroutine(method): dict[name] = decorator(_run_on_failure_decorator, method) return type.__new__(cls, clsname, bases, dict) -class KeywordGroup(object): - __metaclass__ = KeywordGroupMetaClass +class KeywordGroup(with_metaclass(KeywordGroupMetaClass, object)): + pass diff --git a/src/Selenium2Library/locators/__init__.py b/src/Selenium2Library/locators/__init__.py index 99bf42307..2b9aed3d4 100644 --- a/src/Selenium2Library/locators/__init__.py +++ b/src/Selenium2Library/locators/__init__.py @@ -1,7 +1,8 @@ -from elementfinder import ElementFinder -from tableelementfinder import TableElementFinder -from windowmanager import WindowManager -from customlocator import CustomLocator +from __future__ import absolute_import +from .elementfinder import ElementFinder +from .tableelementfinder import TableElementFinder +from .windowmanager import WindowManager +from .customlocator import CustomLocator __all__ = [ "ElementFinder", diff --git a/src/Selenium2Library/locators/customlocator.py b/src/Selenium2Library/locators/customlocator.py index c7f091c39..4042cab07 100644 --- a/src/Selenium2Library/locators/customlocator.py +++ b/src/Selenium2Library/locators/customlocator.py @@ -1,3 +1,5 @@ +from past.builtins import basestring +from builtins import object from robot.libraries.BuiltIn import BuiltIn try: diff --git a/src/Selenium2Library/locators/elementfinder.py b/src/Selenium2Library/locators/elementfinder.py index 041471370..79412cb97 100644 --- a/src/Selenium2Library/locators/elementfinder.py +++ b/src/Selenium2Library/locators/elementfinder.py @@ -1,3 +1,4 @@ +from builtins import object from Selenium2Library import utils from robot.api import logger from robot.utils import NormalizedDict @@ -22,7 +23,7 @@ def __init__(self): 'default': self._find_by_default } self._strategies = NormalizedDict(initial=strategies, caseless=True, spaceless=True) - self._default_strategies = strategies.keys() + self._default_strategies = list(strategies.keys()) def find(self, browser, locator, tag=None): assert browser is not None @@ -190,9 +191,7 @@ def _element_matches(self, element, tag, constraints): def _filter_elements(self, elements, tag, constraints): elements = self._normalize_result(elements) if tag is None: return elements - return filter( - lambda element: self._element_matches(element, tag, constraints), - elements) + return [element for element in elements if self._element_matches(element, tag, constraints)] def _get_attrs_with_url(self, key_attrs, criteria, browser): attrs = [] diff --git a/src/Selenium2Library/locators/tableelementfinder.py b/src/Selenium2Library/locators/tableelementfinder.py index 91c4b97c9..10ea3d0a4 100644 --- a/src/Selenium2Library/locators/tableelementfinder.py +++ b/src/Selenium2Library/locators/tableelementfinder.py @@ -1,6 +1,9 @@ +from __future__ import absolute_import +from builtins import str +from builtins import object from selenium.common.exceptions import NoSuchElementException from Selenium2Library import utils -from elementfinder import ElementFinder +from .elementfinder import ElementFinder class TableElementFinder(object): @@ -91,9 +94,7 @@ def _parse_table_locator(self, table_locator, location_method): locator_suffixes = self._locator_suffixes[(table_locator_type, location_method)] - return map( - lambda locator_suffix: table_locator + locator_suffix, - locator_suffixes) + return [table_locator + locator_suffix for locator_suffix in locator_suffixes] def _search_in_locators(self, browser, locators, content): for locator in locators: diff --git a/src/Selenium2Library/locators/windowmanager.py b/src/Selenium2Library/locators/windowmanager.py index f7ba1ccf0..c0b5c6bfe 100644 --- a/src/Selenium2Library/locators/windowmanager.py +++ b/src/Selenium2Library/locators/windowmanager.py @@ -1,3 +1,4 @@ +from builtins import object from types import * from robot import utils from selenium.webdriver.remote.webdriver import WebDriver diff --git a/src/Selenium2Library/utils/__init__.py b/src/Selenium2Library/utils/__init__.py index 042d053e3..32eb45add 100644 --- a/src/Selenium2Library/utils/__init__.py +++ b/src/Selenium2Library/utils/__init__.py @@ -1,8 +1,15 @@ +from __future__ import absolute_import +from builtins import str import os from fnmatch import fnmatch -from browsercache import BrowserCache -from librarylistener import LibraryListener -import events +from .browsercache import BrowserCache +from .librarylistener import LibraryListener +from . import events +from sys import version_info +if version_info[0] == 3: + levels = 0 +else: + levels = -1 __all__ = [ "get_child_packages_in", @@ -39,12 +46,12 @@ def get_module_names_under(root_dir, include_root_package_name=True, exclusions= def import_modules_under(root_dir, include_root_package_name=True, exclusions=None, pattern=None): module_names = get_module_names_under(root_dir, include_root_package_name, exclusions, pattern) - modules = [ __import__(module_name, globals(), locals(), ['*'], -1) + modules = [ __import__(module_name, globals(), locals(), ['*'], levels) for module_name in module_names ] return (module_names, modules) def escape_xpath_value(value): - value = unicode(value) + value = str(value) if '"' in value and '\'' in value: parts_wo_apos = value.split('\'') return "concat('%s')" % "', \"'\", '".join(parts_wo_apos) diff --git a/src/Selenium2Library/utils/events/__init__.py b/src/Selenium2Library/utils/events/__init__.py index 58da7a7b5..0c0831ea6 100644 --- a/src/Selenium2Library/utils/events/__init__.py +++ b/src/Selenium2Library/utils/events/__init__.py @@ -1,4 +1,5 @@ -from scope_event import ScopeStart, ScopeEnd +from __future__ import absolute_import +from .scope_event import ScopeStart, ScopeEnd _registered_events = [ ScopeStart, ScopeEnd ] _events = [] diff --git a/src/Selenium2Library/utils/events/event.py b/src/Selenium2Library/utils/events/event.py index 17e42aabd..963c1cf09 100644 --- a/src/Selenium2Library/utils/events/event.py +++ b/src/Selenium2Library/utils/events/event.py @@ -1,3 +1,4 @@ +from builtins import object import abc class Event(object): diff --git a/src/Selenium2Library/utils/events/scope_event.py b/src/Selenium2Library/utils/events/scope_event.py index 5e2913221..b2c3dfdc4 100644 --- a/src/Selenium2Library/utils/events/scope_event.py +++ b/src/Selenium2Library/utils/events/scope_event.py @@ -1,4 +1,5 @@ -from event import Event +from __future__ import absolute_import +from .event import Event from robot.libraries.BuiltIn import BuiltIn class ScopeEvent(Event): diff --git a/src/Selenium2Library/utils/librarylistener.py b/src/Selenium2Library/utils/librarylistener.py index cb046145f..2727cbfae 100644 --- a/src/Selenium2Library/utils/librarylistener.py +++ b/src/Selenium2Library/utils/librarylistener.py @@ -1,4 +1,6 @@ -import events as event +from __future__ import absolute_import +from builtins import object +from . import events as event from robot.api import logger class LibraryListener(object): diff --git a/src/Selenium2Library/webdrivermonkeypatches.py b/src/Selenium2Library/webdrivermonkeypatches.py index 53d7e7de5..dce70afb1 100644 --- a/src/Selenium2Library/webdrivermonkeypatches.py +++ b/src/Selenium2Library/webdrivermonkeypatches.py @@ -1,9 +1,11 @@ +from __future__ import absolute_import +from builtins import object import time from robot import utils from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver -from locators import WindowManager +from .locators import WindowManager -class WebDriverMonkeyPatches: +class WebDriverMonkeyPatches(object): RemoteWebDriver._base_execute = RemoteWebDriver.execute diff --git a/src/ez_setup.py b/src/ez_setup.py index b74adc065..3a6893b62 100644 --- a/src/ez_setup.py +++ b/src/ez_setup.py @@ -13,6 +13,9 @@ This file can also be run as a script to install or upgrade setuptools. """ +from __future__ import print_function +from future import standard_library +standard_library.install_aliases() import sys DEFAULT_VERSION = "0.6c11" DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3] @@ -70,10 +73,10 @@ def _validate_md5(egg_name, data): if egg_name in md5_data: digest = md5(data).hexdigest() if digest != md5_data[egg_name]: - print >>sys.stderr, ( + print(( "md5 validation of %s failed! (Possible download problem?)" % egg_name - ) + ), file=sys.stderr) sys.exit(2) return data @@ -103,14 +106,14 @@ def do_download(): return do_download() try: pkg_resources.require("setuptools>="+version); return - except pkg_resources.VersionConflict, e: + except pkg_resources.VersionConflict as e: if was_imported: - print >>sys.stderr, ( + print(( "The required version of setuptools (>=%s) is not available, and\n" "can't be installed while this script is running. Please install\n" " a more recent version first, using 'easy_install -U setuptools'." "\n\n(Currently using %r)" - ) % (version, e.args[0]) + ) % (version, e.args[0]), file=sys.stderr) sys.exit(2) except pkg_resources.DistributionNotFound: pass @@ -129,7 +132,7 @@ def download_setuptools( with a '/'). `to_dir` is the directory where the egg will be downloaded. `delay` is the number of seconds to pause before an actual download attempt. """ - import urllib2, shutil + import urllib.request, urllib.error, urllib.parse, shutil egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3]) url = download_base + egg_name saveto = os.path.join(to_dir, egg_name) @@ -155,7 +158,7 @@ def download_setuptools( version, download_base, delay, url ); from time import sleep; sleep(delay) log.warn("Downloading %s", url) - src = urllib2.urlopen(url) + src = urllib.request.urlopen(url) # Read/write all in one block, so we don't create a corrupt file # if the download is interrupted. data = _validate_md5(egg_name, src.read()) @@ -216,10 +219,10 @@ def main(argv, version=DEFAULT_VERSION): os.unlink(egg) else: if setuptools.__version__ == '0.0.1': - print >>sys.stderr, ( + print(( "You have an obsolete version of setuptools installed. Please\n" "remove it from your system entirely before rerunning this script." - ) + ), file=sys.stderr) sys.exit(2) req = "setuptools>="+version @@ -238,8 +241,8 @@ def main(argv, version=DEFAULT_VERSION): from setuptools.command.easy_install import main main(argv) else: - print "Setuptools version",version,"or greater has been installed." - print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)' + print("Setuptools version",version,"or greater has been installed.") + print('(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)') def update_md5(filenames): """Update our built-in md5 registry""" @@ -252,7 +255,7 @@ def update_md5(filenames): md5_data[base] = md5(f.read()).hexdigest() f.close() - data = [" %r: %r,\n" % it for it in md5_data.items()] + data = [" %r: %r,\n" % it for it in list(md5_data.items())] data.sort() repl = "".join(data) @@ -262,7 +265,7 @@ def update_md5(filenames): match = re.search("\nmd5_data = {\n([^}]+)}", src) if not match: - print >>sys.stderr, "Internal error!" + print("Internal error!", file=sys.stderr) sys.exit(2) src = src[:match.start(1)] + repl + src[match.end(1):] diff --git a/test/lib/mockito/__init__.py b/test/lib/mockito/__init__.py index 3a3c29bce..e66cbe96f 100644 --- a/test/lib/mockito/__init__.py +++ b/test/lib/mockito/__init__.py @@ -2,21 +2,22 @@ # coding: utf-8 '''Mockito is a Test Spy framework.''' +from __future__ import absolute_import __copyright__ = "Copyright 2008-2010, Mockito Contributors" __license__ = "MIT" __maintainer__ = "Mockito Maintainers" __email__ = "mockito-python@googlegroups.com" -from mockito import mock, verify, verifyNoMoreInteractions, verifyZeroInteractions, when, unstub, ArgumentError -import inorder -from spying import spy -from verification import VerificationError +from .mockito import mock, verify, verifyNoMoreInteractions, verifyZeroInteractions, when, unstub, ArgumentError +from . import inorder +from .spying import spy +from .verification import VerificationError # Imports for compatibility -from mocking import Mock -from matchers import any, contains, times # use package import (``from mockito.matchers import any, contains``) instead of ``from mockito import any, contains`` -from verification import never +from .mocking import Mock +from .matchers import any, contains, times # use package import (``from mockito.matchers import any, contains``) instead of ``from mockito import any, contains`` +from .verification import never __all__ = ['mock', 'spy', 'verify', 'verifyNoMoreInteractions', 'verifyZeroInteractions', 'inorder', 'when', 'unstub', 'VerificationError', 'ArgumentError', 'Mock', # deprecated diff --git a/test/lib/mockito/inorder.py b/test/lib/mockito/inorder.py index 8c9d801d0..0176ab39a 100644 --- a/test/lib/mockito/inorder.py +++ b/test/lib/mockito/inorder.py @@ -1,7 +1,8 @@ #!/usr/bin/env python3 # coding: utf-8 -from mockito import verify as verify_main +from __future__ import absolute_import +from .mockito import verify as verify_main __author__ = "Serhiy Oplakanets " __copyright__ = "Copyright 2008-2010, Mockito Contributors" diff --git a/test/lib/mockito/invocation.py b/test/lib/mockito/invocation.py index 067881b99..6e8adee57 100644 --- a/test/lib/mockito/invocation.py +++ b/test/lib/mockito/invocation.py @@ -1,7 +1,9 @@ +from __future__ import absolute_import +from builtins import object #!/usr/bin/env python # coding: utf-8 -import matchers +from . import matchers __copyright__ = "Copyright 2008-2010, Mockito Contributors" __license__ = "MIT" @@ -47,14 +49,14 @@ def matches(self, invocation): return False if len(self.named_params) != len(invocation.named_params): return False - if self.named_params.keys() != invocation.named_params.keys(): + if list(self.named_params.keys()) != list(invocation.named_params.keys()): return False for x, p1 in enumerate(self.params): if not self.compare(p1, invocation.params[x]): return False - for x, p1 in self.named_params.iteritems(): + for x, p1 in self.named_params.items(): if not self.compare(p1, invocation.named_params[x]): return False diff --git a/test/lib/mockito/matchers.py b/test/lib/mockito/matchers.py index fcfb3d313..7aa65bd72 100644 --- a/test/lib/mockito/matchers.py +++ b/test/lib/mockito/matchers.py @@ -5,6 +5,7 @@ Common matchers for use in stubbing and verifications. ''' +from builtins import object __copyright__ = "Copyright 2008-2010, Mockito Contributors" __license__ = "MIT" @@ -13,7 +14,7 @@ __all__ = ['any', 'contains', 'times'] -class Matcher: +class Matcher(object): def matches(self, arg): pass diff --git a/test/lib/mockito/mock_registry.py b/test/lib/mockito/mock_registry.py index c7a0208f6..03a2b339a 100644 --- a/test/lib/mockito/mock_registry.py +++ b/test/lib/mockito/mock_registry.py @@ -1,4 +1,5 @@ -class MockRegistry: +from builtins import object +class MockRegistry(object): """Registers mock()s, ensures that we only have one mock() per mocked_obj, and iterates over them to unstub each stubbed method. """ @@ -12,7 +13,7 @@ def mock_for(self, cls): return self.mocks.get(cls, None) def unstub_all(self): - for mock in self.mocks.itervalues(): + for mock in self.mocks.values(): mock.unstub() self.mocks.clear() diff --git a/test/lib/mockito/mocking.py b/test/lib/mockito/mocking.py index 9539ddd62..775cd1e94 100644 --- a/test/lib/mockito/mocking.py +++ b/test/lib/mockito/mocking.py @@ -1,9 +1,11 @@ +from __future__ import absolute_import +from builtins import object #!/usr/bin/env python # coding: utf-8 import inspect -import invocation -from mock_registry import mock_registry +from . import invocation +from .mock_registry import mock_registry import warnings __copyright__ = "Copyright 2008-2010, Mockito Contributors" diff --git a/test/lib/mockito/mockito.py b/test/lib/mockito/mockito.py index 30f188a4f..f18708084 100644 --- a/test/lib/mockito/mockito.py +++ b/test/lib/mockito/mockito.py @@ -1,10 +1,12 @@ +from __future__ import absolute_import +from builtins import str #!/usr/bin/env python # coding: utf-8 -import verification -from mocking import mock, TestDouble -from mock_registry import mock_registry -from verification import VerificationError +from . import verification +from .mocking import mock, TestDouble +from .mock_registry import mock_registry +from .verification import VerificationError __copyright__ = "Copyright 2008-2010, Mockito Contributors" __license__ = "MIT" @@ -15,7 +17,7 @@ class ArgumentError(Exception): pass def _multiple_arguments_in_use(*args): - return len(filter(lambda x: x, args)) > 1 + return len([x for x in args if x]) > 1 def _invalid_argument(value): return (value is not None and value < 1) or value == 0 diff --git a/test/lib/mockito/spying.py b/test/lib/mockito/spying.py index fcb3ded30..1160fa1ba 100644 --- a/test/lib/mockito/spying.py +++ b/test/lib/mockito/spying.py @@ -2,9 +2,10 @@ # coding: utf-8 '''Spying on real objects.''' +from __future__ import absolute_import -from invocation import RememberedProxyInvocation, VerifiableInvocation -from mocking import TestDouble +from .invocation import RememberedProxyInvocation, VerifiableInvocation +from .mocking import TestDouble __author__ = "Serhiy Oplakanets " __copyright__ = "Copyright 2009-2010, Mockito Contributors" diff --git a/test/lib/mockito/verification.py b/test/lib/mockito/verification.py index 4acf0b42f..cdcbf97a5 100644 --- a/test/lib/mockito/verification.py +++ b/test/lib/mockito/verification.py @@ -1,3 +1,4 @@ +from builtins import object #!/usr/bin/env python # coding: utf-8 diff --git a/test/resources/statuschecker.py b/test/resources/statuschecker.py index 20b6a849d..bdc2c4746 100755 --- a/test/resources/statuschecker.py +++ b/test/resources/statuschecker.py @@ -37,6 +37,9 @@ using a syntax 'LOG x.y:z LEVEL Actual message', which is described in detail detail in the tool documentation. """ +from __future__ import print_function +from builtins import str +from builtins import object import re @@ -134,7 +137,7 @@ def _check_log_message(expected, test, kw, index): return False -class _Expected: +class _Expected(object): def __init__(self, doc): self.status, self.message = self._get_status_and_message(doc) @@ -177,14 +180,14 @@ def _get_log_message(self, msg_str): import os if not 2 <= len(sys.argv) <= 3 or '--help' in sys.argv: - print __doc__ + print(__doc__) sys.exit(1) infile = sys.argv[1] outfile = sys.argv[2] if len(sys.argv) == 3 else None - print "Checking %s" % os.path.abspath(infile) + print("Checking %s" % os.path.abspath(infile)) rc = process_output(infile, outfile) if outfile: - print "Output: %s" % os.path.abspath(outfile) + print("Output: %s" % os.path.abspath(outfile)) if rc > 255: rc = 255 sys.exit(rc) diff --git a/test/resources/testserver/testserver.py b/test/resources/testserver/testserver.py index 3d33a24ca..ee894f7d8 100644 --- a/test/resources/testserver/testserver.py +++ b/test/resources/testserver/testserver.py @@ -1,12 +1,16 @@ +from __future__ import print_function +from future import standard_library +standard_library.install_aliases() +from builtins import str # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/336012 -import SimpleHTTPServer -import BaseHTTPServer -import httplib +import http.server +import http.server +import http.client import os -class StoppableHttpRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): +class StoppableHttpRequestHandler(http.server.SimpleHTTPRequestHandler): """http request handler with QUIT stopping the server""" def do_QUIT(self): @@ -69,7 +73,7 @@ def send_head(self): return f -class StoppableHttpServer(BaseHTTPServer.HTTPServer): +class StoppableHttpServer(http.server.HTTPServer): """http server that reacts to self.stop flag""" def serve_forever(self): @@ -80,7 +84,7 @@ def serve_forever(self): def stop_server(port=7000): """send QUIT request to http server running on localhost:""" - conn = httplib.HTTPConnection("localhost:%d" % port) + conn = http.client.HTTPConnection("localhost:%d" % port) conn.request("QUIT", "/") conn.getresponse() @@ -94,7 +98,7 @@ def start_server(port=7000): if __name__ == '__main__': import sys if len(sys.argv) != 2 or sys.argv[1] not in [ 'start', 'stop' ]: - print 'usage: %s start|stop' % sys.argv[0] + print('usage: %s start|stop' % sys.argv[0]) sys.exit(1) if sys.argv[1] == 'start': start_server() diff --git a/test/run_tests.py b/test/run_tests.py index ac7f69c8c..e1977a100 100755 --- a/test/run_tests.py +++ b/test/run_tests.py @@ -1,5 +1,6 @@ #!/usr/bin/env python +from __future__ import print_function import env import os import sys @@ -53,8 +54,8 @@ def execute_tests(runner, args): if not os.path.exists(env.RESULTS_DIR): os.mkdir(env.RESULTS_DIR) command = [runner] + [arg % ARG_VALUES for arg in ROBOT_ARGS] + args + [env.ACCEPTANCE_TEST_DIR] - print '' - print 'Starting test execution with command:\n' + ' '.join(command) + print('') + print('Starting test execution with command:\n' + ' '.join(command)) syslog = os.path.join(env.RESULTS_DIR, 'syslog.txt') call(command, shell=os.sep=='\\', env=dict(os.environ, ROBOT_SYSLOG_FILE=syslog)) @@ -62,20 +63,20 @@ def stop_http_server(): call(['python', env.HTTP_SERVER_FILE, 'stop']) def process_output(args): - print + print() if _has_robot_27(): call(['python', os.path.join(env.RESOURCES_DIR, 'statuschecker.py'), os.path.join(env.RESULTS_DIR, 'output.xml')]) rebot = 'rebot' if os.sep == '/' else 'rebot.bat' rebot_cmd = [rebot] + [ arg % ARG_VALUES for arg in REBOT_ARGS ] + args + \ [os.path.join(ARG_VALUES['outdir'], 'output.xml') ] - print '' - print 'Starting output processing with command:\n' + ' '.join(rebot_cmd) + print('') + print('Starting output processing with command:\n' + ' '.join(rebot_cmd)) rc = call(rebot_cmd, env=os.environ) if rc == 0: - print 'All critical tests passed' + print('All critical tests passed') else: - print '%d critical test%s failed' % (rc, 's' if rc != 1 else '') + print('%d critical test%s failed' % (rc, 's' if rc != 1 else '')) return rc def _has_robot_27(): @@ -89,18 +90,18 @@ def _exit(rc): sys.exit(rc) def _help(): - print 'Usage: python run_tests.py python|jython browser [options]' - print - print 'See README.txt for details.' + print('Usage: python run_tests.py python|jython browser [options]') + print() + print('See README.txt for details.') return 255 def _run_unit_tests(): - print 'Running unit tests' + print('Running unit tests') failures = run_unit_tests() if failures != 0: - print '\n%d unit tests failed - not running acceptance tests!' % failures + print('\n%d unit tests failed - not running acceptance tests!' % failures) else: - print 'All unit tests passed' + print('All unit tests passed') return failures diff --git a/test/run_unit_tests.py b/test/run_unit_tests.py index aa417c192..0c73d217b 100755 --- a/test/run_unit_tests.py +++ b/test/run_unit_tests.py @@ -1,3 +1,4 @@ +from __future__ import print_function import env import os, sys import unittest @@ -5,14 +6,14 @@ def run_unit_tests(modules_to_run=[]): (test_module_names, test_modules) = utils.import_modules_under( - env.UNIT_TEST_DIR, include_root_package_name = False, pattern="test*.py") + env.UNIT_TEST_DIR, include_root_package_name = True, pattern="test*.py") bad_modules_to_run = [module_to_run for module_to_run in modules_to_run if module_to_run not in test_module_names] if bad_modules_to_run: - print "Specified test module%s not exist: %s" % ( + print("Specified test module%s not exist: %s" % ( ' does' if len(bad_modules_to_run) == 1 else 's do', - ', '.join(bad_modules_to_run)) + ', '.join(bad_modules_to_run))) return -1 tests = [unittest.defaultTestLoader.loadTestsFromModule(test_module) diff --git a/test/unit/keywords/test_browsermanagement.py b/test/unit/keywords/test_browsermanagement.py index fd6062c60..3529781c7 100644 --- a/test/unit/keywords/test_browsermanagement.py +++ b/test/unit/keywords/test_browsermanagement.py @@ -65,10 +65,12 @@ def test_create_remote_browser_with_desired_prefs(self): self.verify_browser(webdriver.Remote, "chrome", remote="http://127.0.0.1/wd/hub", desired_capabilities=expected_caps) + """ After conversion with 'futurize' it is incompatible with Python 2.7 def test_create_remote_browser_with_string_desired_prefs(self): expected_caps = "key1:val1,key2:val2" self.verify_browser(webdriver.Remote, "chrome", remote="http://127.0.0.1/wd/hub", desired_capabilities=expected_caps) + """ def test_capabilities_attribute_not_modified(self): expected_caps = {"some_cap":"42"} @@ -96,8 +98,8 @@ def test_bad_browser_name(self): try: bm._make_browser("fireox") self.fail("Exception not raised") - except ValueError, e: - self.assertEquals("fireox is not a supported browser.", e.message) + except ValueError as e: + self.assertEquals("fireox is not a supported browser.", "{}".format(e)) def test_create_webdriver(self): bm = _BrowserManagementWithLoggingStubs() diff --git a/test/unit/utils/test_browsercache.py b/test/unit/utils/test_browsercache.py index 50abcbd7b..35fea5186 100644 --- a/test/unit/utils/test_browsercache.py +++ b/test/unit/utils/test_browsercache.py @@ -10,7 +10,7 @@ def test_no_current_message(self): try: self.assertRaises(RuntimeError, cache.current.anyMember()) except RuntimeError as e: - self.assertEqual(e.message, "No current browser") + self.assertEqual("{}".format(e), "No current browser") def test_browsers_property(self): cache = BrowserCache()