diff --git a/.travis.yml b/.travis.yml index 3125407a4..6656d1a7f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,13 +3,20 @@ 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 after installing future + ##- 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..db4493473 --- /dev/null +++ b/.travis_python_dep.sh @@ -0,0 +1,24 @@ +#!/bin/bash +set -ev +PYTHON_VERSION=`python -c "import sys; print(sys.version[:3])"` +if [ "${PYTHON_VERSION}" = "2.6" ]; then + pip install robotframework + pip install selenium + pip install decorator + pip install docutils + # pip install future + # pip install mockito +elif [ "${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 + 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..e46411ce6 100644 --- a/build_dist.py +++ b/build_dist.py @@ -1,6 +1,11 @@ #!/usr/bin/env python -import os, sys, shutil, subprocess, argparse +from __future__ import print_function +import os +import sys +import shutil +import subprocess +import argparse THIS_DIR = os.path.dirname(os.path.abspath(__file__)) DIST_DIR = os.path.join(THIS_DIR, "dist") @@ -9,9 +14,9 @@ sys.path.append(os.path.join(THIS_DIR, "demo")) def main(): - parser = argparse.ArgumentParser(description="Builds a Se2Lib distribution") - parser.add_argument('py_26_path', action='store', help='Python 2.6 executbale file path') - parser.add_argument('py_27_path', action='store', help='Python 2.7 executbale file path') + parser = argparse.ArgumentParser(description="Builds a Selenium2Library distribution") + parser.add_argument('py_26_path', action='store', help='Python 2.6 executable file path') + parser.add_argument('py_27_path', action='store', help='Python 2.7 executable file path') parser.add_argument('--release', action='store_true') parser.add_argument('--winonly', action='store_true') args = parser.parse_args() @@ -33,7 +38,7 @@ def clear_dist_folder(): def run_doc_gen(): import generate - print + print() generate.main() def run_register(args): @@ -50,12 +55,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,8 +71,8 @@ def _run_setup(py_path, type, params, upload): if upload: setup_args.append("upload") - print - print("Running: %s" % ' '.join(setup_args)) + print() + print("Running: {0}".format(' '.join(setup_args))) returncode = subprocess.call(setup_args) if returncode != 0: print("Error running setup.py") diff --git a/demo/demoapp/server.py b/demo/demoapp/server.py index 08576e0c9..16c6842c7 100644 --- a/demo/demoapp/server.py +++ b/demo/demoapp/server.py @@ -14,6 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import print_function + """Simple HTTP server requiring only Python and no other preconditions. Server is started by running this script with argument 'start' and @@ -55,25 +57,25 @@ def do_QUIT(self): def do_POST(self): # We could also process paremeters here using something like below. # length = self.headers['Content-Length'] - # print self.rfile.read(int(length)) + # print(self.rfile.read(int(length))) self.do_GET() def start_server(host=DEFAULT_HOST, port=DEFAULT_PORT): - print "Demo application starting on port %s" % port + print("Demo application starting on port {0}".format(port)) root = os.path.dirname(os.path.abspath(__file__)) os.chdir(root) server = StoppableHttpServer((host, int(port)), StoppableHttpRequestHandler) server.serve_forever() def stop_server(host=DEFAULT_HOST, port=DEFAULT_PORT): - print "Demo application on port %s stopping" % port + print("Demo application on port {0} stopping".format(port)) conn = httplib.HTTPConnection("%s:%s" % (host, port)) conn.request("QUIT", "/") conn.getresponse() def print_help(): - print __doc__ + print(__doc__) if __name__ == '__main__': @@ -82,4 +84,4 @@ def print_help(): 'stop': stop_server, 'help': print_help}[sys.argv[1]](*sys.argv[2:]) except (IndexError, KeyError, TypeError): - print 'Usage: %s start|stop|help [port]' % os.path.basename(sys.argv[0]) + print("Usage: {0} start|stop|help [port]".format(os.path.basename(sys.argv[0]))) diff --git a/demo/package.py b/demo/package.py index e02a706e7..0c7f56439 100755 --- a/demo/package.py +++ b/demo/package.py @@ -1,6 +1,9 @@ #!/usr/bin/env python -import os, sys +from __future__ import print_function + +import os +import sys from time import localtime from zipfile import ZipFile, ZIP_DEFLATED @@ -26,14 +29,14 @@ def main(): for dirname in FILES: for filename in FILES[dirname]: path = os.path.join('.', dirname.replace('/', os.sep), filename) - print 'Adding: ', os.path.normpath(path) + print("Adding: {0}".format(os.path.normpath(path))) zipfile.write(path, os.path.join(name, path)) zipfile.close() target_path = os.path.join('..', 'dist', zipname) if os.path.exists(target_path): os.remove(target_path) os.rename(zipname, target_path) - print 'Created: ', os.path.abspath(target_path) + print("Created: {0}".format(os.path.abspath(target_path))) finally: os.chdir(cwd) diff --git a/demo/rundemo.py b/demo/rundemo.py index 3ed0051c2..b18ec8984 100755 --- a/demo/rundemo.py +++ b/demo/rundemo.py @@ -1,5 +1,7 @@ #! /usr/bin/env python +from __future__ import print_function + """Runner Script for Robot Framework SeleniumLibrary Demo Tests are run by giving a path to the tests to be executed as an argument to @@ -32,10 +34,10 @@ try: import Selenium2Library -except ImportError, e: - print 'Importing Selenium2Library module failed (%s).' % e - print 'Please make sure you have Selenium2Library properly installed.' - print 'See INSTALL.rst for troubleshooting information.' +except ImportError as e: + print("Importing Selenium2Library module failed ({0})".format(e)) + print("Please make sure you have Selenium2Library properly installed.") + print("See INSTALL.rst for troubleshooting information.") sys.exit(1) @@ -55,12 +57,12 @@ def stop_demo_application(): call(['python', DEMOAPP, 'stop'], stdout=TemporaryFile(), stderr=STDOUT) def print_help(): - print __doc__ + print(__doc__) def print_usage(): - print 'Usage: rundemo.py [options] datasource' - print ' or: rundemo.py demoapp start|stop' - print ' or: rundemo.py help' + print("Usage: rundemo.py [options] datasource") + print(" or: rundemo.py demoapp start|stop") + print(" or: rundemo.py help") if __name__ == '__main__': diff --git a/doc/buildhtml.py b/doc/buildhtml.py index 5c5db1ead..7b3db71bb 100644 --- a/doc/buildhtml.py +++ b/doc/buildhtml.py @@ -4,6 +4,7 @@ # Author: David Goodger # Copyright: This module has been placed in the public domain. +from __future__ import print_function """ Generates .html from all the .txt files in a directory. @@ -29,7 +30,7 @@ import docutils from docutils import ApplicationError from docutils import core, frontend, utils -from docutils.error_reporting import ErrorOutput, ErrorString +from docutils.utils.error_reporting import ErrorOutput, ErrorString from docutils.parsers import rst from docutils.readers import standalone, pep from docutils.writers import html4css1, pep_html @@ -197,13 +198,12 @@ def visit(self, directory, names): settings = self.get_settings('', directory) errout = ErrorOutput(encoding=settings.error_encoding) if settings.prune and (os.path.abspath(directory) in settings.prune): - print >>errout, ('/// ...Skipping directory (pruned): %s' % - directory) + print("/// ...Skipping directory (pruned): {0}".format(directory), file=errout) sys.stderr.flush() names[:] = [] return if not self.initial_settings.silent: - print >>errout, '/// Processing directory: %s' % directory + print("/// Processing directory: {0}".format(directory), file=errout) sys.stderr.flush() # settings.ignore grows many duplicate entries as we recurse # if we add patterns in config files or on the command line. @@ -232,7 +232,7 @@ def process_txt(self, directory, name): settings._source = os.path.normpath(os.path.join(directory, name)) settings._destination = settings._source[:-4]+'.html' if not self.initial_settings.silent: - print >>errout, ' ::: Processing: %s' % name + print(" ::: Processing: {0}".format(name), file=errout) sys.stderr.flush() try: if not settings.dry_run: @@ -242,8 +242,8 @@ def process_txt(self, directory, name): parser_name='restructuredtext', writer_name=pub_struct.writer_name, settings=settings) - except ApplicationError, error: - print >>errout, ' %s' % ErrorString(error) + except ApplicationError as error: + print(" {0}".format(ErrorString(error)), file=errout) if __name__ == "__main__": diff --git a/doc/generate.py b/doc/generate.py index 08ca44889..8eb445538 100755 --- a/doc/generate.py +++ b/doc/generate.py @@ -1,14 +1,17 @@ #!/usr/bin/env python + +from __future__ import print_function from os.path import join, dirname + try: from robot.libdoc import libdoc except: def main(): - print """Robot Framework 2.7 or later required for generating documentation""" + print('"""Robot Framework 2.7 or later required for generating documentation"""') else: def main(): libdoc(join(dirname(__file__),'..','src','Selenium2Library'), join(dirname(__file__),'Selenium2Library.html')) if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/doc/generate_readmes.py b/doc/generate_readmes.py index be6828b74..8dd6ad4eb 100644 --- a/doc/generate_readmes.py +++ b/doc/generate_readmes.py @@ -1,8 +1,11 @@ #!/usr/bin/env python -import os, shutil +from __future__ import print_function +import os +import shutil from buildhtml import Builder + THIS_DIR = os.path.dirname(os.path.abspath(__file__)) ROOT_DIR = os.path.join(THIS_DIR, "..") SRC_DIR = os.path.join(ROOT_DIR, "src") @@ -19,7 +22,7 @@ def main(): try: import docutils except: - print "Readme files will not be built into HTML, docutils not installed" + print("Readme files will not be built into HTML, docutils not installed") return for readme_relative_path in README_FILES: (readme_dir, readme_name) = _parse_readme_path(readme_relative_path) @@ -36,7 +39,7 @@ def main(): os.remove(target_readme_html_path) os.rename(readme_html_path, target_readme_html_path) - print " ::: Saved: %s" % target_readme_html_name + print(" ::: Saved: {0}".format(target_readme_html_name)) def _parse_readme_path(readme_relative_path): readme_abs_path = os.path.join(ROOT_DIR, readme_relative_path.replace('/', os.sep)) diff --git a/src/Selenium2Library/__init__.py b/src/Selenium2Library/__init__.py index 75884e9ea..f6eca9b61 100644 --- a/src/Selenium2Library/__init__.py +++ b/src/Selenium2Library/__init__.py @@ -1,5 +1,5 @@ import os -from keywords import * +from Selenium2Library.keywords import * from version import VERSION from utils import LibraryListener diff --git a/src/Selenium2Library/keywords/_runonfailure.py b/src/Selenium2Library/keywords/_runonfailure.py index 4e9057107..737e02f91 100644 --- a/src/Selenium2Library/keywords/_runonfailure.py +++ b/src/Selenium2Library/keywords/_runonfailure.py @@ -57,7 +57,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..59632fa24 100644 --- a/src/Selenium2Library/keywords/_screenshot.py +++ b/src/Selenium2Library/keywords/_screenshot.py @@ -1,5 +1,6 @@ import robot -import os, errno +import os +import errno from Selenium2Library import utils from keywordgroup import KeywordGroup diff --git a/src/Selenium2Library/keywords/_tableelement.py b/src/Selenium2Library/keywords/_tableelement.py index 55eea39c8..443f9eaa7 100644 --- a/src/Selenium2Library/keywords/_tableelement.py +++ b/src/Selenium2Library/keywords/_tableelement.py @@ -64,7 +64,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/keywordgroup.py b/src/Selenium2Library/keywords/keywordgroup.py index 672603afd..bb9a8c037 100644 --- a/src/Selenium2Library/keywords/keywordgroup.py +++ b/src/Selenium2Library/keywords/keywordgroup.py @@ -13,7 +13,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 diff --git a/src/ez_setup.py b/src/ez_setup.py index b74adc065..1860de251 100644 --- a/src/ez_setup.py +++ b/src/ez_setup.py @@ -1,4 +1,7 @@ #!python + +from __future__ import print_function + """Bootstrap setuptools installation If you want to use setuptools in your package's setup.py, just include this @@ -62,7 +65,8 @@ 'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a', } -import sys, os +import sys +import os try: from hashlib import md5 except ImportError: from md5 import md5 @@ -70,10 +74,8 @@ 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, ( - "md5 validation of %s failed! (Possible download problem?)" - % egg_name - ) + print("md5 validation of {0} failed! (Possible download problem?)".format(egg_name), + file=sys.stderr) sys.exit(2) return data @@ -103,14 +105,12 @@ 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, ( - "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]) + print("The required version of setuptools (>={0}) is not available, and\n".format(version), file=sys.stderr) + print("can't be installed while this script is running. Please install\n", file=sys.stderr) + print(" a more recent version first, using 'easy_install -U setuptools'.", file=sys.stderr) + print("\n\n(Currently using {0})".format(e.args[0]), file=sys.stderr) sys.exit(2) except pkg_resources.DistributionNotFound: pass @@ -129,7 +129,8 @@ 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 urllib2 + import 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) @@ -216,10 +217,10 @@ def main(argv, version=DEFAULT_VERSION): os.unlink(egg) else: if setuptools.__version__ == '0.0.1': - print >>sys.stderr, ( - "You have an obsolete version of setuptools installed. Please\n" - "remove it from your system entirely before rerunning this script." - ) + print("You have an obsolete version of setuptools installed. Please\n", + file=sys.stderr) + print("remove it from your system entirely before rerunning this script.", + file=sys.stderr) sys.exit(2) req = "setuptools>="+version @@ -238,8 +239,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 {0} or greater has been installed.".format(version)) + print("Run 'ez_setup.py -U setuptools' to reinstall or upgrade.") def update_md5(filenames): """Update our built-in md5 registry""" @@ -262,7 +263,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/resources/statuschecker.py b/test/resources/statuschecker.py index 20b6a849d..6c9e389fe 100755 --- a/test/resources/statuschecker.py +++ b/test/resources/statuschecker.py @@ -14,6 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import print_function + """Robot Framework Test Status Checker Usage: statuschecker.py infile [outfile] @@ -177,14 +179,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 {0}".format(os.path.abspath(infile))) rc = process_output(infile, outfile) if outfile: - print "Output: %s" % os.path.abspath(outfile) + print("Output: {0}".format(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..ef70c25f1 100644 --- a/test/resources/testserver/testserver.py +++ b/test/resources/testserver/testserver.py @@ -1,5 +1,7 @@ # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/336012 +from __future__ import print_function + import SimpleHTTPServer import BaseHTTPServer import httplib @@ -18,7 +20,7 @@ def do_QUIT(self): def do_POST(self): # We could also process paremeters here using something like below. # length = self.headers['Content-Length'] - # print self.rfile.read(int(length)) + # print(self.rfile.read(int(length))) self.do_GET() def send_head(self): @@ -94,7 +96,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: {0} start|stop".format(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..4726ac5a3 100755 --- a/test/run_tests.py +++ b/test/run_tests.py @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import print_function + import env import os import sys @@ -53,8 +55,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{0}".format(' '.join(command))) syslog = os.path.join(env.RESULTS_DIR, 'syslog.txt') call(command, shell=os.sep=='\\', env=dict(os.environ, ROBOT_SYSLOG_FILE=syslog)) @@ -69,13 +71,13 @@ def process_output(args): 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{0}".format(' '.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("{0} critical test{1} failed".format(rc, 's' if rc != 1 else '')) return rc def _has_robot_27(): @@ -89,18 +91,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{0} unit tests failed - not running acceptance tests!".format(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..64c403a53 100755 --- a/test/run_unit_tests.py +++ b/test/run_unit_tests.py @@ -1,18 +1,21 @@ +from __future__ import print_function + import env -import os, sys +import os +import sys import unittest from Selenium2Library import utils 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: {0}".format( ' 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..782491730 100644 --- a/test/unit/keywords/test_browsermanagement.py +++ b/test/unit/keywords/test_browsermanagement.py @@ -96,7 +96,7 @@ def test_bad_browser_name(self): try: bm._make_browser("fireox") self.fail("Exception not raised") - except ValueError, e: + except ValueError as e: self.assertEquals("fireox is not a supported browser.", e.message) def test_create_webdriver(self):