[Checkins] SVN: zc.selenium/trunk/src/zc/selenium/selenium.py
In-package selenium test runner.
Jim Fulton
jim at zope.com
Fri Feb 2 15:56:09 EST 2007
Log message for revision 72335:
In-package selenium test runner.
Changed:
A zc.selenium/trunk/src/zc/selenium/selenium.py
-=-
Added: zc.selenium/trunk/src/zc/selenium/selenium.py
===================================================================
--- zc.selenium/trunk/src/zc/selenium/selenium.py 2007-02-02 19:06:24 UTC (rev 72334)
+++ zc.selenium/trunk/src/zc/selenium/selenium.py 2007-02-02 20:56:08 UTC (rev 72335)
@@ -0,0 +1,191 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Script to run Selenium tests.
+
+$Id$
+"""
+from Queue import Queue, Empty
+import optparse
+import os
+import random
+import socket
+import sys
+import threading
+import time
+import urllib2
+import webbrowser
+
+
+# Compute a default port; this is simple and doesn't ensure that the
+# port is available, but does better than just hardcoding a port
+# number. The goal is to avoid browser cache effects due to resource
+# changes (especially in JavaScript resources).
+#
+DEFAULT_PORT = "8034"
+
+def run_zope(config, port):
+ # This removes the script directory from sys.path, which we do
+ # since there are no modules here.
+ #
+ from zope.app.server.main import main
+ main(["-C", config, "-X", "http0/address=" + port] + sys.argv[1:])
+
+def run_tests(zope_thread, auto_start, browser_name, port):
+ start_time = time.time()
+
+ # wait for the server to start
+ old_timeout = socket.getdefaulttimeout()
+ socket.setdefaulttimeout(5)
+ url = ('http://localhost:%s/@@/selenium/TestRunner.html'
+ '?test=tests%%2FTestSuite.html&resultsUrl=/@@/selenium_results'
+ % port)
+ time.sleep(1)
+ while zope_thread.isAlive():
+ try:
+ urllib2.urlopen(url)
+ except urllib2.URLError:
+ time.sleep(1)
+ else:
+ break
+ socket.setdefaulttimeout(old_timeout)
+
+ if not zope_thread.isAlive():
+ return
+
+ # start the tests
+ browser = webbrowser.get(browser_name)
+ if auto_start:
+ extra = '&auto=true'
+ else:
+ extra = ''
+
+ browser.open(url + extra)
+
+ # wait for the test results to come in (the reason we don't do a
+ # blocking-get here is because it keeps Ctrl-C from working)
+ exit_now = False
+ while zope_thread.isAlive():
+ try:
+ time.sleep(0.1)
+ except KeyboardInterrupt:
+ exit_now = True
+
+ try:
+ results = messages.get(False)
+ except Empty:
+ if exit_now:
+ break
+ else:
+ break
+
+ time.sleep(1) # wait for the last request to finish so stdout is quiet
+
+ if exit_now:
+ return False
+
+ print
+ print 'Selenium test result:', results['result']
+ print '%s tests passed, %s tests failed.' % (
+ results['numTestPasses'], results['numTestFailures'])
+ print ('%s commands passed, %s commands failed, %s commands had errors.'
+ % (results['numCommandPasses'], results['numCommandFailures'],
+ results['numCommandErrors']))
+ print 'Elapsed time: %s seconds' % int(time.time() - start_time)
+ print
+
+ return results['result'] == 'passed'
+
+def random_port():
+ """Compute a random port number.
+
+ This is simple and doesn't ensure that the port is available, but
+ does better than just hardcoding a port number. The goal is to
+ avoid browser cache effects due to resource changes (especially in
+ JavaScript resources).
+
+ """
+ port_offsets = range(1024)
+ port_offsets.remove(0)
+ port_offsets.remove(80) # ignore 8080 since that's often in use
+ return str(random.choice(port_offsets) + 8000)
+
+def parseOptions():
+ if '--' in sys.argv:
+ sep_index = sys.argv.index('--')
+ extra_args = sys.argv[sep_index+1:]
+ del sys.argv[sep_index:]
+ else:
+ extra_args = []
+
+ # First arg is zope.conf file. This is provided by wrapper script
+ config = sys.argv.pop(1)
+
+ usage = 'usage: %prog [options] [-- runzope_options]'
+ parser = optparse.OptionParser(usage)
+ parser.add_option('-b', '--browser', metavar="BROWSER", default=None,
+ help='choose browser to use (mozilla, netscape, '
+ 'kfm, internet-config)')
+ parser.add_option('-k', '--keep-running',
+ action='store_true',
+ help='keep running after finishing the tests')
+ parser.add_option('-A', '--no-auto-start', dest='auto_start',
+ action='store_false', default=True,
+ help='don\'t automatically start the tests (implies -k)')
+ parser.add_option('-S', '--server-only', dest='server_only',
+ action='store_true',
+ help="Just start the Zope server. Don't run any tests")
+ parser.add_option('-p', '--port', dest='port', default=DEFAULT_PORT,
+ help='port to run server on')
+ parser.add_option('-r', '--random-port', dest='random_port',
+ action='store_true',
+ help='use a random port for the server')
+
+ options, positional = parser.parse_args()
+ options.config = config
+ sys.argv[1:] = extra_args
+ return options
+
+def main():
+ global messages
+ messages = Queue()
+
+ # Hack around fact that zc.selenium.results expects zope to be run
+ from __main__:
+ if __name__ != '__main__':
+ sys.modules['__main__'] = sys.modules[__name__]
+
+ options = parseOptions()
+ if options.random_port:
+ options.port = random_port()
+
+ if options.server_only:
+ run_zope(options.config, port=options.port)
+ sys.exit(0)
+
+ zope_thread = threading.Thread(
+ target=run_zope, args=(options.config, options.port))
+ zope_thread.setDaemon(True)
+ zope_thread.start()
+ test_result = run_tests(
+ zope_thread, options.auto_start, options.browser, options.port)
+
+ if options.keep_running or not options.auto_start:
+ while True:
+ time.sleep(10000)
+ else:
+ # exit with 0 if all tests passed, 1 if any failed
+ sys.exit(not test_result)
+
+if __name__ == '__main__':
+ main()
Property changes on: zc.selenium/trunk/src/zc/selenium/selenium.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
More information about the Checkins
mailing list