[Checkins] SVN: Zelenium/trunk/ Move code to Launchpad, due to non-ZPL status of the included selenium-core JS.

Tres Seaver tseaver at palladion.com
Wed Apr 7 14:21:23 EDT 2010


Log message for revision 110604:
  Move code to Launchpad, due to non-ZPL status of the included selenium-core JS.

Changed:
  D   Zelenium/trunk/CHANGES.txt
  D   Zelenium/trunk/COPYRIGHT.txt
  D   Zelenium/trunk/LICENSE.txt
  U   Zelenium/trunk/README.txt
  D   Zelenium/trunk/__init__.py
  D   Zelenium/trunk/configure.zcml
  D   Zelenium/trunk/exclude.txt
  D   Zelenium/trunk/generator.py
  D   Zelenium/trunk/interfaces.py
  D   Zelenium/trunk/permissions.py
  D   Zelenium/trunk/scripts/
  D   Zelenium/trunk/selenium/
  D   Zelenium/trunk/tests/
  D   Zelenium/trunk/version.txt
  D   Zelenium/trunk/www/
  D   Zelenium/trunk/zuite.py

-=-
Deleted: Zelenium/trunk/CHANGES.txt
===================================================================
--- Zelenium/trunk/CHANGES.txt	2010-04-07 17:22:16 UTC (rev 110603)
+++ Zelenium/trunk/CHANGES.txt	2010-04-07 18:21:23 UTC (rev 110604)
@@ -1,181 +0,0 @@
-Zelenium Product Changelog
-
-  After Zelenium 0.8
-
-    - Applied a fix from Rob Miller to make Zelenium Zuite objects functional
-      in the presence of 'five:traverse', making 'index_html' the explicit
-      default view.
-
-    - Corrected the documentation in the README for capturing results of a test
-      run ('auto=1' -> 'auto=true', in line with the Selenium documentation).
-      Thanks to Yoshinori Okuji for pointing this out.
-
-  Zelenium 0.8 (2006/05/16)
-
-    - SVN tag:  svn+ssh://svn.zope.org/repos/main/Zelenium/tags/0.8
-
-    - Fixed unit tests by wrapping filesystem objects that are rendered
-      during ZIP file creation - code in OFS.Image wants to acquire
-      REQUEST and use RESPONSE.
-
-    - Found how to make the dependency on ExternalEditor optional (thanks
-      to Andreas Jung for the bug report).
-
-    - Stripped empty filenames out of manifest, to avoid infinite
-      recursion.
-
-    - Added the testsuite_name property that allows multiple test
-      suites to be built up from test cases within a single filesystem
-      directory.
-
-    - Upgrade to selenium version 0.6
-
-    - Suites now recurse through all "folderish" subobjects, looking
-      for tests (allows, for instance, tests to be loaded from disk via
-      CMF's FileSystemDirectoryView).  Thanks to Malcom Cleaton for the
-      patch!
-
-    - Define zelenium_globals in __init__.py to be able to
-      register the 'selenium' directory for use as a CMF skin directory.
-
-    - If debug-mode is set to "on" in zope.conf, filesystem-based testcases
-      files are reloaded every time they are used, to ease development of
-      filesystem-based test suites. This behavior emulates what the CMF
-      Filesystem Directory Views do with debug-mode on.
-
-    - Moved repository to Subversion:
-      svn+ssh://svn.zope.org/repos/main/Zelenium/
-
-  Zelenium-0.7 (2005/06/07)
-
-    - CVS tag:  'Zelenium-0_7'
-
-    - Upgrade to use the Selenium "core application" from Selenium 0.4.0.
-      See http://selenium.thoughtworks.com/release-notes.html for a summary
-      of changes.
-
-      o **N.B.**:  the semantics of 'click' have changed;  that command
-        no longer waits by default, and the 'nowait' modifier is no longer
-        meaningful.  Use 'clickAndWait' to get the desired semantics.
-
-  Zelenium-0.6 (2005/05/09)
-
-    - CVS tag:  'Zelenium-0_6'
-
-    - Add ability to suppress inclusion of Selenium support files in
-      snapshot / download.
-
-    - Add support for returning testcases from a mapped directory path,
-      including recursion through subdirectories of that path.  Currently,
-      the implementation has the following issues:
-
-      o It only creates OFS.Image.File objects for test cases (no templates,
-        scripts, etc.)
-
-    - Add unit tests for Zuite.__getitem__ behavior, including support files.
-
-  Zelenium-0.5.1 (2005/05/07)
-
-    - CVS tag:  'Zelenium-0_5_1'
-
-    - Make passing / failing test cases in results view more obvious in
-      printed representation by adding icons.  N.B.: at the moment, we do
-      this by sniffing the HTML of the test case for the "pink" backgrounds.
-
-    - Apply patch from the selenium-devel list to fix regression in
-      testcase HTML extraction in 'postTestResults'.
-
-    - Make the posted results folder into its own class, derived from
-      Folder (moving the template out to a PageTemplateFile).
-
-    - Further repaired recursive ZIPfile generation, including normalizing
-      URLs in generated HTML.
-
-    - Extended zuite unittests to test 'listTestCases' and
-      'manage_createSnapshot', as well as recursive ZIPfile generation.
-
-  Zelenium-0.5 (2005/05/04)
-
-    - CVS tag:  'Zelenium-0_5'
-
-    - Updated to use the "TestRunner core" from Selenium version 0.3.0.
-      See http://selenium.thoughtworks.com/release-notes.html for more
-      information.
-
-    - Add unit tests for Zuite class.
-
-    - Make ZIPfile generation work with nested suites.
-
-  Zelenium-0.4.1 (2005/05/02)
-
-    - CVS tag:  'Zelenium-0_4_1'
-
-    - Repair breakage of ExternalEditor link in 'manage_main'.
-
-    - Compensate in display of test tables for non-padded integers
-      in the IDs (make them sort properly).
-
-  Zelenium-0.4 (2005/04/27)
-
-    - CVS tag:  'Zelenium-0_4'
- 
-    - Make Zuite instances recursively include their Zuite children's
-      test cases (to allow easier organization of the test cases in a
-      hierarchy).
-
-    - Allow indiviual zuites to override the list of metatypes which
-      can be test cases, via a new 'testcase_metatypes' property.
-
-    - Force Zuite objects to show order support, even in the presence of
-      ExternalEditor, whose monkey patching seems to trip it up.  Surface
-      the EE icon, if the product is available
-
-      Note:  we are *forking* OFS/dtml/main.dtml and the version in
-      ExteranalEditor/manage_main.dtml to surface order support, which
-      is a pretty brutal hack.  We should probably get ExteranalEditor
-      fixed, instead, and rip out the forked copy.
-
-  Zelenium-0.3.1 (2005/04/26)
-
-    - CVS tag:  'Zelenium-0_3_1'
-
-    - Record server-side data during 'postResults':  Zope version string,
-      product names and versions.
-
-    - Captured additional request parameters in 'postResults':  user agent,
-      HTTP host, remote address).
-
-  Zelenium-0.3 (2005/04/25)
-
-    - CVS tag:  'Zelenium-0_3'
-
-    - Added 'postResults' handling code to capture results as a sub-
-      folder of the suite.
-
-  Zelenium-0.2.1 (2005/04/21)
-
-    - CVS tag:  'Zelenium-0_2_1'
-
-    - Correct the emitted HTML for input widgets (close the tr tag).
-
-    - Fix unpack bug in code which punts on requests to "foreign" hosts.
-
-    - Punt on handling XML-RPC requests (e.g., Epoz calls back to the
-      server to run Tidy).
-
-  Zelenium-0.2 (2005/04/20)
-
-    - CVS tag:  'Zelenium-0_2'
-
-    - Added script, 'generator.py', to create Selenium testcase files
-      from the request / response logfiles created by tcpwatch.
-
-    - Allowed test cases to be PageTemplates, as well as Files, to permit
-      indirecting through properties of the test suite (e.g., for
-      user id / password).
-
-  Zelenium-0.1 (2005/04/15)
-
-    - CVS tag:  'Zelenium-0_1'
-
-    - Initial release

Deleted: Zelenium/trunk/COPYRIGHT.txt
===================================================================
--- Zelenium/trunk/COPYRIGHT.txt	2010-04-07 17:22:16 UTC (rev 110603)
+++ Zelenium/trunk/COPYRIGHT.txt	2010-04-07 18:21:23 UTC (rev 110604)
@@ -1,15 +0,0 @@
-Zelenium Zope Product
----------------------
-
-Copyright (c) 2005 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. 
-
-(See selenium/COPYRIGHT.txt for the license pertaining to files in that
-directory).

Deleted: Zelenium/trunk/LICENSE.txt
===================================================================
--- Zelenium/trunk/LICENSE.txt	2010-04-07 17:22:16 UTC (rev 110603)
+++ Zelenium/trunk/LICENSE.txt	2010-04-07 18:21:23 UTC (rev 110604)
@@ -1,58 +0,0 @@
-Zope Public License (ZPL) Version 2.1
-=====================================
-
-A copyright notice accompanies this license document that
-identifies the copyright holders.
-
-This license has been certified as open source. It has also
-been designated as GPL compatible by the Free Software
-Foundation (FSF).
-
-Redistribution and use in source and binary forms, with or
-without modification, are permitted provided that the
-following conditions are met:
-
- - Redistributions in source code must retain the
-   accompanying copyright notice, this list of conditions,
-   and the following disclaimer.
-
- - Redistributions in binary form must reproduce the accompanying
-   copyright notice, this list of conditions, and the
-   following disclaimer in the documentation and/or other
-   materials provided with the distribution.
-
- - Names of the copyright holders must not be used to
-   endorse or promote products derived from this software
-   without prior written permission from the copyright
-   holders.
-
- - The right to distribute this software or to use it for
-   any purpose does not give you the right to use
-   Servicemarks (sm) or Trademarks (tm) of the copyright
-   holders. Use of them is covered by separate agreement
-   with the copyright holders.
-
- - If any files are modified, you must cause the modified
-   files to carry prominent notices stating that you changed
-   the files and the date of any change.
-
-Disclaimer
-----------
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS''
-AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
-NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
-NO EVENT SHALL THE COPYRIGHT HOLDERS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGE.
-
-(See selenium/LICENSE.txt for the license pertaining to files in that
-directory).

Modified: Zelenium/trunk/README.txt
===================================================================
--- Zelenium/trunk/README.txt	2010-04-07 17:22:16 UTC (rev 110603)
+++ Zelenium/trunk/README.txt	2010-04-07 18:21:23 UTC (rev 110604)
@@ -1,174 +1,15 @@
 Zelenium Product README
+=======================
 
-  Overview
+Overview
+--------
 
-    This product allows developers to create TTW Selenium test suites
-    inside their Zope instance, in order to do browser-based functional
-    testing of their site.
+This product allows developers to create TTW Selenium test suites
+inside their Zope instance, in order to do browser-based functional
+testing of their site.
 
+Because it contains third-party code (the Selenium Javascript libraries,
+in particular), licensed under non-ZPL licenses, the trunk of the project
+has moved its development to Launchpad.  To check it out::
 
-  Installing the Product
-
-    1. Unpack the tarball in a temporary location.
-
-    2. Copy or move the 'Zelenium' directory to the 'Products' directory
-       of your INSTANCE_HOME.
-
-    3. Restart Zope.
-
-
-  Using Zelenium
-
-    You can add a 'Zuite' object at any location within your Zope
-    site.  It behaves as a standard ordered folder, with a couple of 
-    differences:
-
-      - It's 'index_html' is the "TestRunner.html" view familiar
-        from Selenium.
-
-      - It derives the test suite (in the upper left corner iframe)
-        from all OFS.Image.File objects whose names start with 'test'.
-        You can use the OrderedFolder support to modify the order in
-        which the test case files are run.
-
-      - It provides a "Zip" action, which allows you to export the
-        test suite, all test cases, and the supporting Selenium
-        Javascript / CSS files as a single, self-contained zipfile.
-
-
-  Reporting Bugs against Zelenium
-
-    Please use the "collector",
-      http://www.zope.org/Members/tseaver/Zelenium/issues
-    to report any bugs you find against the product, as well as to
-    submit patches, request features, etc.
-
-
-  Adding Tests
-
-    Tests are just 'File' instances whose names begin with 'test'.
-    They should have a content type of 'text/html', and should contain
-    a table which defines the steps which make up the test case.
-
-    See http://selenium.thoughtworks.com/testrunner.html for documentation
-    on the table structure and the Selenese language.
-
-
-  Using Additional Metatypes as Test Cases
-
-    On the "Properties" tab of your test suite, you can add / modify
-    the list of meta_types which the suite will allow as test cases.
-    Adding "Script (Python)", for instance, allows you to define
-    test cases in PythonScripts.
-
-
-  Nesting Test Suites
-
-    Each test suite automatically includes the test cases of any
-    suite it contains.  You can take advantage of this feature to
-    organize your test cases in a hierarchy, running them in separate
-    segments, or all at once.
-
-  Including Tests from the Filesystem
-
-    Test suites now have a property, 'filesystem_path';  if set, the
-    suite will recursively load testcases from files in / under the
-    directory pointed to by that path.
-
-    The list of files to be included is computed via the following
-    rules:
-
-     - If the testsuite_name property contains the name of a file that
-       exists in the directory, it is presumed to contain a list of
-       files containing tests, one per line. The test cases will be
-       presented in the order indicated in the file, and test cases
-       may be included more than once.
-
-     - If the testsuite_name property is empty but the directory
-       contains  a file, '.objects', it is presumed to
-       contain a list of files to be included, one per line;  only those
-       files / subdirectories (if present) will be included.  In this case,
-       the test cases will be presented in the order indicated in the file,
-       followed by any test cases from subdirectories.
-
-     - Otherwise, if the suite's property, 'filename_glob' is non-empty,
-       it will be expanded (via Python's 'glob.glob') to compute the list
-       of filenames.  The test cases will be presented in alphabetical
-       order, followed by any test cases from subdirectories.
-
-     - Otherwise, any file will be considered a testcase.  The test cases
-       will be presented in alphabetical order, followed by any test cases
-       from subdirectories.
-
-  Exporting an Archive
-
-    On the "Zip" tab, supply a filename and click the "Download" button.
-    The Zuite object will construct a zip file with the following
-    contents:
-
-      'index.html' -- the "TestRunner.html" framework page
-
-      'TestSuite.html' -- the list of test case files (rendered as
-        static HTML)
-
-      'test*" -- your test case files (appending '.html' if the IDs
-        do not have extensions)
-
-      Each of the supporting '.js' and '.css' files which drive the
-      browserbot.
-
-
-  Creating a Snapshot
-
-    On the "Zip" tab, supply a filename and click the "Download" button.
-    The Zuite object will construct a zip file with the same contents
-    described above, and then save it as a File object in its own contents.
-
-
-  Generating Testcases using tcpwatch
-
-    1. Download the 'tcpwatch' product from Shane Hathaway's site:
-
-       http://hathawaymix.org/Software/TCPWatch
-
-    2. Unpack and run tcpwatch in its "HTTP proxy" mode, with recoring
-       turned on.  E.g., the following command runs the proxy on
-       port 9999, recording the request / response data to the directory
-       '/tmp/recorded_scenario'::
-
-        $ python /path/to/tcpwatch/ tcpwatch.py \
-            -p 9999 -r /tmp/recorded_scenario 
-
-    3. Configure your browser to use an HTTP proxy on localhost, port 9999.
-
-    4. Click through your site, exercising the features you are testing.
-
-    5. Stop the proxy.  Run the 'generator.py' script, pointing to the
-       directory where tcpwatch was recording::
-
-        $ python /path/to/Zelenium/generator.py \
-           --logfile-directory=/tmp/recorded_scenario \
-           --output-file=test_case_name.html
-
-    6. Edit the generated test case, removing / correcting the various
-       steps.
-
-    7. Upload the test case to a Zelenium Zuite and run it.
-
-
-  Capturing Results from the Test Run
-
-    Selenium has a feature which allows the testrunner to upload
-    result data from an automated test run to the server.
-
-    Invoke the test suite from your browser as usual, but append the
-    query string '?auto=true', to the URL, e.g.::
-
-      http://localhost:8080/test_suite?auto=true
-
-    Selenium will run all test cases, and then upload its result data
-    to the 'postResults' method of your suite. (Note that you no longer
-    need the 'postResults' PythonScript in the root of your site, because
-    the latest version of Selenium posts to that name relative to the
-    test suite).
-
+  $ bzr co lp:~tseaver/zelenium/trunk

Deleted: Zelenium/trunk/__init__.py
===================================================================
--- Zelenium/trunk/__init__.py	2010-04-07 17:22:16 UTC (rev 110603)
+++ Zelenium/trunk/__init__.py	2010-04-07 18:21:23 UTC (rev 110604)
@@ -1,21 +0,0 @@
-""" Zelenium product initialization
-
-This product uses the Selenium javascript to run browser-driven tests.
-
-$Id$
-"""
-
-import zuite
-import permissions
-
-zelenium_globals = globals()
-
-def initialize(context):
-
-    context.registerClass( zuite.Zuite
-                         , permission=permissions.ManageSeleniumTestCases
-                         , constructors=( zuite.manage_addZuiteForm
-                                        , zuite.manage_addZuite
-                                        )
-                         , icon='www/check.gif'
-                         )

Deleted: Zelenium/trunk/configure.zcml
===================================================================
--- Zelenium/trunk/configure.zcml	2010-04-07 17:22:16 UTC (rev 110603)
+++ Zelenium/trunk/configure.zcml	2010-04-07 18:21:23 UTC (rev 110604)
@@ -1,16 +0,0 @@
-<configure xmlns="http://namespaces.zope.org/zope"
-           xmlns:browser="http://namespaces.zope.org/browser">
-
-  <browser:defaultView
-     for=".interfaces.IZuite"
-     name="index_html"
-     />
-
-  <browser:page
-     for=".interfaces.IZuite"
-     name="index_html"
-     template="www/suiteView.zpt"
-     permission="zope2.View"/>
-
-</configure>
-

Deleted: Zelenium/trunk/exclude.txt
===================================================================
--- Zelenium/trunk/exclude.txt	2010-04-07 17:22:16 UTC (rev 110603)
+++ Zelenium/trunk/exclude.txt	2010-04-07 18:21:23 UTC (rev 110604)
@@ -1,5 +0,0 @@
-.css
-.gif
-.ico
-/misc_
-/p_
\ No newline at end of file

Deleted: Zelenium/trunk/generator.py
===================================================================
--- Zelenium/trunk/generator.py	2010-04-07 17:22:16 UTC (rev 110603)
+++ Zelenium/trunk/generator.py	2010-04-07 18:21:23 UTC (rev 110604)
@@ -1,495 +0,0 @@
-""" Script:  generator
-
-Generate a Selenium testcase using request / response logiles from tcpwatch.
-
-$Id$
-"""
-
-import sys
-import re
-import getopt
-import glob
-import cgi
-import mimetools
-import urllib
-import urlparse
-import multifile
-import StringIO
-
-_TEST_CASE_HEADER = """\
-<html>
-<head>
-<title>%(TEST_CASE_TITLE)s</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
- <tbody>
-  <tr>
-   <td rowspan="1" colspan="3">%(TEST_CASE_TITLE)s<br>
-  </td>
- </tr>
-"""
-
-_TEST_CASE_FOOTER = """
- </tbody>
-</table>
-</body>
-</html>
-"""
-
-_GET_REQUEST_SKELETON = """
-  <tr>
-   <td>open</td>
-   <td>%(REQUEST_URI)s</td>
-   <td>&nbsp;</td>
-  </tr>
-"""
-
-_POST_REQUEST_SKELETON = """
-  <tr>
-   <td>click</td>
-   <td>submit</td>
-   <td>&nbsp;</td>
-  </tr>
-"""
-
-_REDIRECT_SKELETON = """
-  <tr>
-   <td>verifyLocation</td>
-   <td>%(REDIRECTED_URL)s</td>
-   <td>&nbsp;</td>
-  </tr>
-"""
-
-_INPUT_FIELD_SKELETON = """
-  <tr>
-   <td>type</td>
-   <td>%(FIELD_NAME)s</td>
-   <td>%(FIELD_VALUE)s</td>
-  </tr>
-"""
-
-_SELECT_FIELD_SKELETON = """
-  <tr>
-   <td>select</td>
-   <td>%(FIELD_NAME)s</td>
-   <td>%(FIELD_VALUE)s</td>
-  </tr>
-"""
-
-class ScenarioGenerator:
-    """
-        Convert a series of HTTP requests files (as generated by
-        LoggingProxy) into a scenario file (to be consumed by
-        FT_Runner).
-    """
-    _verbosity              = 1
-    _logfile_directory      = '/tmp'
-    _logfile_prefix         = 'watch'
-    _logfile_extension_req  = 'request'
-    _logfile_extension_resp = 'response'
-    _output_file            = None
-    _exclude_patterns       = []
-    _exclude_file           = None
-    _exclude_regex          = None
-    _site_host              = None
-    _site_path              = None
-    _test_case_title        = None
-
-    def __init__( self, args ):
-
-        self.parseOptions( args )
-
-    def printUsage( self, msg=None ):
-        """
-            Dump a help message, and bail out.
-        """
-        sys.stderr.write( """
-  %(GENERATOR_EXE)s [-?vq] \\
-                     [-l log_dir] [-f log_prefix] [-e log_extension] \\
-                     [-o file] [-x pattern] [-X file] \\
-                     [-h site_host] [-r site_path]
-
-    -?, --help                      Print this help message
-
-    -v, --verbose                   Increment verbosity (default is '1')
-
-    -q, --quiet                     Set verbosity to '0'
-
-    -l, --logfile-directory         Directory from which to read log files
-                                    (default '%(LOGFILE_DIRECTORY)s')
-
-    -f, --logfile-prefix            Prefix for log file names
-                                    (default '%(LOGFILE_PREFIX)s')
-
-    -e, --logfile-extension         Extension for log file request names
-                                    (default '%(LOGFILE_EXTENSION_REQ)s')
-
-    -E, --logfile-response          Extension for log file response names
-                                    (default '%(LOGFILE_EXTENSION_RESP)s')
-
-    -o, --output-file               Write to 'file', instead of default
-                                    (%(LOGFILE_PREFIX)s.zft). 
-                                    Use '-' to write to stdout.
-
-    -x, --exclude-pattern           Exclude requests which match 'pattern'
-                                    (e.g., to suppress stylesheet or images).
-
-    -X, --exclude-file              Exclude requests which match any pattern
-                                    read from 'file' (one pattern per line).
-
-    -h, --site-host                 Specify the host / port of the site being
-                                    tested.
-
-    -p, --site-path                 Specify the path to the "base" of the
-                                    site being tested.
-
-%(MESSAGE)s\n""" % { 'GENERATOR_EXE'        : sys.argv[0]
-                   , 'LOGFILE_DIRECTORY'    : self._logfile_directory
-                   , 'LOGFILE_PREFIX'       : self._logfile_prefix
-                   , 'LOGFILE_EXTENSION_REQ'    : self._logfile_extension_req
-                   , 'LOGFILE_EXTENSION_RESP'    : self._logfile_extension_resp
-                   , 'MESSAGE'              : msg or ''
-                   } )
-        sys.exit( 1 )
-
-    def parseOptions( self, args ):
-        """
-            Parse command-line options.
-        """
-        verbosity = self._verbosity
-        logfile_directory = logfile_prefix = None
-        logfile_extension_req = logfile_extension_resp = None
-        output_file = exclude_file = site_host = site_path = None
-        test_case_title = None
-
-        try:
-            opts, ignored = getopt.getopt( args
-                                         , "?vql:f:e:E:o:x:X:h:p:T:"
-                                         , [ 'help'
-                                           , 'verbose'
-                                           , 'quiet'
-                                           , 'logfile-directory='
-                                           , 'logfile-prefix='
-                                           , 'logfile-extension='
-                                           , 'logfile-extension-response='
-                                           , 'output-file='
-                                           , 'exclude-pattern'
-                                           , 'exclude-file'
-                                           , 'site-host='
-                                           , 'site-path='
-                                           , 'test-case-title='
-                                           ]
-                                         )
-        except getopt.GetoptError, msg:
-            self.printUsage( msg=msg)
-
-        for o, v in opts:
-
-            if o == '-?' or o == '--help':
-                self.printUsage()
-
-            if o == '-v' or o == '--verbose':
-                verbosity = verbosity + 1
-
-            if o == '-q' or o == '--quiet':
-                verbosity = 0
-
-            if o == '-l' or o == '--logfile-directory':
-                logfile_directory = v
-
-            if o == '-f' or o == '--logfile-prefix':
-                logfile_prefix = v
-
-            if o == '-e' or o == '--logfile-extension':
-                logfile_extension_req = v
-
-            if o == '-E' or o == '--logfile-extension-response':
-                logfile_extension_resp = v
-
-            if o == '-o' or o == '--output-file':
-                output_file = v
-
-            if o == '-x' or o == '--exclude-pattern':
-                self._addExcludePattern( v )
-
-            if o == '-X' or o == '--exclude-file':
-                exclude_file = v
-
-            if o == '-h' or o == '--site-host':
-                site_host = v
-
-            if o == '-p' or o == '--site-path':
-                site_path = v
-
-            if o == '-T' or o == '--test-case-title':
-                test_case_title = v
-
-        self._verbosity = verbosity
-
-        if logfile_directory is not None:
-            self._logfile_directory = logfile_directory
-
-        if logfile_prefix is not None:
-            self._logfile_prefix = logfile_prefix
-
-        if logfile_extension_req is not None:
-            self._logfile_extension_req = logfile_extension_req
-
-        if logfile_extension_resp is not None:
-            self._logfile_extension_resp = logfile_extension_resp
-
-        if site_host is not None:
-            self._site_host = site_host
-
-        if site_path is not None:
-            self._site_path = site_path
-
-        if test_case_title is not None:
-            self._test_case_title = test_case_title
-
-        if output_file == '-':
-            self._output_file = sys.stdout
-        elif output_file is not None:
-            self._output_file = open( output_file, 'w' )
-        else:
-            self._output_file = sys.stdout
-
-        if exclude_file is not None:
-            self._exclude_file = exclude_file
-
-    def _log( self, msg, level ):
-        """
-            Write a note to stderr (if verbosity enabled).
-        """
-        if level <= self._verbosity:
-            sys.stderr.write( "%s\n" % msg )
-
-    def _print( self, fmt, **kw ):
-        """
-            Dump the appropriately-formatted values to our output
-            file.
-        """
-        self._output_file.write( fmt % kw )
-
-
-    def _addExcludePattern( self, pattern ):
-        """
-            Add a pattern to our list of excluded patterns.
-        """
-        self._exclude_patterns.append( r'(%s)' % pattern )
-        self._exclude_regex = None
-
-    def _getExcludeRegex( self
-                        ):
-        """
-            Return a regex which, if matched, indicates that we should
-            skip the file.
-        """
-        if self._exclude_regex is None:
-
-            if self._exclude_file:
-                f = open( self._exclude_file )
-                for line in f.readlines():
-                    line = line.strip()
-                    self._addExcludePattern( line )
-
-            if self._exclude_patterns:
-                self._exclude_regex = re.compile(
-                                        '|'.join( self._exclude_patterns ) )
-        return self._exclude_regex
-
-    def _stripSitePath(self, uri, parms):
-        """
-            Strip off our site-host and site-path from 'uri'.
-        """
-        ( scheme
-        , netloc
-        , path
-        , url_parm
-        , query
-        , fragment
-        ) = urlparse.urlparse( uri )
-
-        site_host = urlparse.urlunparse( ( scheme, netloc, '', '', '', '' ) )
-
-        if scheme and parms.get( 'site_host' ) is None:
-            parms[ 'site_host' ] = site_host
-
-        if site_host != parms[ 'site_host' ]: # XXX foreign site!  Punt!
-            return None, None
-
-        if self._site_path and path.startswith( self._site_path ):
-            path = path[ len( self._site_path ) : ]
-
-        uri = urlparse.urlunparse(
-                            ( '', '', path, url_parm, query, fragment ) )
-
-        return uri, query
-
-    def processFile( self
-                   , infilename
-                   , outfilename
-                   , parms={}
-                   , REQUEST_LINE=re.compile( r'^([^\s]+)\s+'
-                                              r'([^\s]+)\s+'
-                                              r'([^\s]+)$' )
-                   , RESPONSE_LINE=re.compile( r'^([^\s]+)\s+'
-                                               r'([0-9][0-9][0-9])\s+'
-                                               r'(.*)$' )
-                   ):
-        """
-            Process a single request file;  record global context
-            in parms.
-        """
-        self._log( 'Scanning request file: %s' % infilename, 1 )
-
-        parms[ 'content_type' ] = None
-
-        f = open( infilename )
-        all_text = f.read()
-        body_end = f.tell()
-        f.seek( 0 )
-
-        exclude = self._getExcludeRegex()
-        if exclude is not None and exclude.search( all_text ):
-            self._log( '** matches exclude regex, skipping', 1 )
-            return 
-
-        request = f.readline().rstrip()
-        match = REQUEST_LINE.match( request )
-
-        if not match:
-            self._log( 'Invalid request line: %s' % request, 0 )
-            return
-
-        http_verb, uri, http_version = match.groups()
-
-        uri, query = self._stripSitePath( uri, parms )
-
-        if uri is None:
-            return # XXX foreign site
-
-        headers = mimetools.Message( f )
-
-        body_start = f.tell()
-        content_length = body_end - body_start
-
-        content_type = parms[ 'content_type' ] = headers.gettype()
-        parms[ 'encoding' ] = headers.getencoding()
-
-        cgi_environ = { 'REQUEST_METHOD' : http_verb
-                      , 'QUERY_STRING'   : query
-                      , 'CONTENT_TYPE'   : headers.typeheader
-                      , 'CONTENT_LENGTH' : content_length
-                      }
-
-        if http_verb == 'POST':
-
-            if content_type == 'text/xml':   # XXX XML-RPC, punt!
-                return
-
-            form_data = cgi.FieldStorage( fp=f
-                                        , environ=cgi_environ
-                                        , keep_blank_values=1
-                                      # , headers=headers.dict  XXX
-                                        )
-            for k in form_data.keys():
-
-                v = form_data.getvalue( k )
-
-                # TODO: handle uploaded files.
-
-                self._print( _INPUT_FIELD_SKELETON
-                           , FIELD_NAME=k
-                           , FIELD_VALUE=v
-                           )
-
-            payload = f.read()
-            f.close()
-
-            self._print( _POST_REQUEST_SKELETON
-                       , REQUEST_URI=uri
-                       )
-        else:
-            self._print( _GET_REQUEST_SKELETON
-                       , REQUEST_URI=uri
-                       )
-
-        if outfilename:
-            self._log( 'Scanning response file: %s' % outfilename, 1 )
-            response_file = open( outfilename )
-            # could exclude here as well
-            status = response_file.readline().rstrip()
-            match = RESPONSE_LINE.match( status )
-            http_verb, code, reason = match.groups()        
-            response_headers = mimetools.Message( response_file )
-            response_file.close()
-        else:
-            code = 200
-
-        if code in ('301', '302', '307'):
-            response_location = response_headers[ 'Location' ]
-            response_uri, query = self._stripSitePath( response_location
-                                                     , parms
-                                                     )
-            self._print( _REDIRECT_SKELETON
-                       , REDIRECTED_URL=response_uri
-                       )
-
-
-        return 
-
-    def processScenario( self ):
-        """
-            Read all files in '_logfile_directory' whose prefix
-            matches '_logfile_prefix', '_logfile_extension_req', and
-            '_logfile_extension_resp';
-            create a scenario file with one section per request file,
-            dumping to specified output file.
-        """
-        self._print( _TEST_CASE_HEADER
-                   , TEST_CASE_TITLE=self._test_case_title or 'TEST CASE'
-                   )
-
-        glob__in_pattern = '%s/%s*.%s' % ( self._logfile_directory
-                                         , self._logfile_prefix
-                                         , self._logfile_extension_req
-                                         )
-
-        glob__out_pattern = '%s/%s*.%s' % ( self._logfile_directory
-                                          , self._logfile_prefix
-                                          , self._logfile_extension_resp
-                                          )
-
-        parms = { 'site_host' : self._site_host
-                , 'site_path' : self._site_path
-                }
-
-        infilenames = glob.glob( glob__in_pattern )
-        infilenames.sort()
-        outfilenames = glob.glob( glob__out_pattern )
-        outfilenames.sort()
-        for infilename in infilenames:
-            # find the response file name that matches this request file
-            outfilename = re.sub( self._logfile_extension_req + '$'
-                                , self._logfile_extension_resp
-                                , infilename
-                                )
-            # XXX error if missing?  Optional outfile processing?
-            if outfilename in outfilenames:
-                self.processFile( infilename
-                                , outfilename
-                                , parms
-                                )
-            else:
-                self.processFile( infilename
-                                , None
-                                , parms
-                                )
-                
-        self._print( _TEST_CASE_FOOTER )
-
-if __name__ == '__main__':
-
-    ScenarioGenerator( sys.argv[1:] ).processScenario()

Deleted: Zelenium/trunk/interfaces.py
===================================================================
--- Zelenium/trunk/interfaces.py	2010-04-07 17:22:16 UTC (rev 110603)
+++ Zelenium/trunk/interfaces.py	2010-04-07 18:21:23 UTC (rev 110604)
@@ -1,9 +0,0 @@
-""" Zelenium interfaces
-
-$Id$
-"""
-from zope.interface import Interface
-
-class IZuite(Interface):
-    """ Marker interface for IZuite objects.
-    """

Deleted: Zelenium/trunk/permissions.py
===================================================================
--- Zelenium/trunk/permissions.py	2010-04-07 17:22:16 UTC (rev 110603)
+++ Zelenium/trunk/permissions.py	2010-04-07 18:21:23 UTC (rev 110604)
@@ -1,8 +0,0 @@
-""" Zelenium product permissions
-
-$Id$
-"""
-
-from AccessControl.Permissions import view as View
-
-ManageSeleniumTestCases = 'Manage Selenium test cases'

Deleted: Zelenium/trunk/version.txt
===================================================================
--- Zelenium/trunk/version.txt	2010-04-07 17:22:16 UTC (rev 110603)
+++ Zelenium/trunk/version.txt	2010-04-07 18:21:23 UTC (rev 110604)
@@ -1 +0,0 @@
-Zelenium-0.8+

Deleted: Zelenium/trunk/zuite.py
===================================================================
--- Zelenium/trunk/zuite.py	2010-04-07 17:22:16 UTC (rev 110603)
+++ Zelenium/trunk/zuite.py	2010-04-07 18:21:23 UTC (rev 110604)
@@ -1,740 +0,0 @@
-""" Classes:  Zuite
-
-Zuite instances are collections of Zelenium test cases.
-
-$Id$
-"""
-import glob
-import logging
-import os
-import re
-from urllib import unquote
-import zipfile
-import StringIO
-import types
-
-from zope.interface import implements
-
-from AccessControl.SecurityInfo import ClassSecurityInfo
-from App.special_dtml import DTMLFile
-from App.ImageFile import ImageFile
-from App.config import getConfiguration
-from DateTime.DateTime import DateTime
-from Globals import package_home
-from Globals import InitializeClass
-from OFS.Folder import Folder
-from OFS.Image import File
-from OFS.OrderedFolder import OrderedFolder
-from Products.PageTemplates.PageTemplateFile import PageTemplateFile
-
-from interfaces import IZuite
-from permissions import ManageSeleniumTestCases
-from permissions import View
-
-logger = logging.getLogger('event.Zelenium')
-
-_NOW = None   # set only for testing
-
-_PINK_BACKGROUND = re.compile('bgcolor="#ffcfcf"')
-
-_EXCLUDE_NAMES = ( 'CVS', '.svn', '.objects' )
-        
-#winzip awaits latin1
-_DEFAULTENCODING = 'latin1'
-
-
-def _getNow():
-    if _NOW is not None:
-        return _NOW
-
-    return DateTime()
-
-_WWW_DIR = os.path.join( package_home( globals() ), 'www' )
-
-#
-#   Selenium support files.
-#
-_SUPPORT_DIR = os.path.join( package_home( globals() ), 'selenium' )
-_SUPPORT_FILES = {}
-
-def _makeFile(filename, prefix=None, id=None):
-
-    if prefix:
-        path = os.path.join( prefix, filename )
-    else:
-        path = filename
-
-    if id is None:
-        id = os.path.split( path )[ 1 ]
-
-    return File( id=id, title='', file=open(path).read() )
-
-
-def registerFiles(directory, prefix):
-    for filename in os.listdir(directory):
-        ignored, extension = os.path.splitext(filename)
-
-        if extension.lower() in ('.js', '.html', '.css', '.png'):
-            _SUPPORT_FILES['%s_%s' % (prefix, filename)] = _makeFile( filename, prefix=directory)
-
-_MARKER = object()
-
-
-def _recurseFSTestCases( result, prefix, fsobjs ):
-
-    test_cases = dict( [ ( x.getId(), x )
-                            for x in fsobjs.get( 'testcases', () ) ] )
-    subdirs = fsobjs.get( 'subdirs', {} )
-
-    for name in fsobjs.get( 'ordered', [] ):
-
-        if name in test_cases:
-            test_case = test_cases[ name ]
-            name = test_case.getId()
-            path = '/'.join( prefix + ( name, ) )
-            result.append( { 'id' : name
-                            , 'title' : test_case.title_or_id()
-                            , 'url' : path
-                            , 'path' : path
-                            , 'test_case' : test_case
-                            } )
-
-        if name in subdirs:
-            info = subdirs[ name ]
-            _recurseFSTestCases( result
-                               , prefix + ( name, )
-                               , info
-                               )
-
-class Zuite( OrderedFolder ):
-    """ TTW-manageable browser test suite
-
-    A Zuite instance is an ordered folder, whose 'index_html' provides the
-    typical "TestRunner.html" view from Selenium.  It generates the
-    "TestSuite.html" view from its 'objectItems' list (which allows the
-    user to control ordering), selecting File and PageTemplate objects
-    whose names start with 'test'.
-    """
-    meta_type = 'Zuite'
-
-    manage_options = ( OrderedFolder.manage_options
-                     + ( { 'label' : 'Zip', 'action' : 'manage_zipfile' },
-                       )
-                     )
-
-    implements(IZuite)
-
-    test_case_metatypes = ( 'File'
-                          , 'Page Template'
-                          )
-    filesystem_path = ''
-    filename_glob = ''
-    testsuite_name = ''
-    _v_filesystem_objects = None
-    _v_selenium_objects = None
-
-    _properties = ( { 'id' : 'test_case_metatypes'
-                    , 'type' : 'lines'
-                    , 'mode' : 'w'
-                    }
-                  , { 'id' : 'filesystem_path'
-                    , 'type' : 'string'
-                    , 'mode' : 'w'
-                    }
-                  , { 'id' : 'filename_glob'
-                    , 'type' : 'string'
-                    , 'mode' : 'w'
-                    }
-                  , { 'id' : 'testsuite_name'
-                    , 'type' : 'string'
-                    , 'mode' : 'w'
-                    }
-                  )
-
-    security = ClassSecurityInfo()
-    security.declareObjectProtected( View )
-
-    security.declareProtected( ManageSeleniumTestCases, 'manage_main' )
-    manage_main = DTMLFile( 'suiteMain', _WWW_DIR )
-
-    security.declareProtected( View, 'index_html' )
-    index_html = PageTemplateFile( 'suiteView', _WWW_DIR )
-
-    security.declareProtected( View, 'test_suite_html' )
-    test_suite_html = PageTemplateFile( 'suiteTests', _WWW_DIR )
-
-    security.declareProtected( View, 'splash_html' )
-    splash_html = PageTemplateFile( 'suiteSplash', _WWW_DIR )
- 
-    security.declareProtected( View, 'test_prompt_html' )
-    test_prompt_html = PageTemplateFile( 'testPrompt', _WWW_DIR )
- 
-    security.declareProtected(ManageSeleniumTestCases, 'manage_zipfile')
-    manage_zipfile = PageTemplateFile( 'suiteZipFile', _WWW_DIR )
-
-
-    def __getitem__( self, key, default=_MARKER ):
-
-        if key in self.objectIds():
-            return self._getOb( key )
-
-        if key in _SUPPORT_FILES.keys():
-            return _SUPPORT_FILES[ key ].__of__( self )
-
-        proxy = _FilesystemProxy( key
-                                , self._listFilesystemObjects()
-                                ).__of__( self )
-
-        localdefault = object()
-
-        value = proxy.get( key, localdefault )
-
-        if value is not localdefault:
-            return value
-       
-        proxy = _FilesystemProxy( key
-                                , self._listSeleniumObjects()
-                                ).__of__( self )
-
-        value = proxy.get( key, default )
-
-        if value is not _MARKER:
-            return value
-
-        raise KeyError, key
-
-
-    security.declareProtected( View, 'listTestCases' )
-    def listTestCases( self, prefix=() ):
-        """ Return a list of our contents which qualify as test cases.
-        """
-        result = []
-        self._recurseListTestCases(result, prefix, self)
-        return result
-    
-    def _recurseListTestCases( self, result, prefix, ob ):
-        for tcid, test_case in ob.objectItems():
-            if isinstance( test_case, self.__class__ ):
-                result.extend( test_case.listTestCases(
-                                        prefix=prefix + ( tcid, ) ) )
-            elif test_case.isPrincipiaFolderish:
-                self._recurseListTestCases(result, prefix+(tcid,), test_case)
-            elif test_case.meta_type in self.test_case_metatypes:
-                path = '/'.join( prefix + ( tcid, ) )
-                result.append( { 'id' : tcid
-                               , 'title' : test_case.title_or_id()
-                               , 'url' : path
-                               , 'path' : path
-                               , 'test_case' : test_case
-                               } )
-
-        fsobjs = self._listFilesystemObjects()
-
-        _recurseFSTestCases( result, prefix, fsobjs )
-
-
-    security.declareProtected(ManageSeleniumTestCases, 'getZipFileName')
-    def getZipFileName(self):
-        """ Generate a suitable name for the zip file.
-        """
-        now = _getNow()
-        now_str = now.ISO()[:10]
-        return '%s-%s.zip' % ( self.getId(), now_str )
-
-
-    security.declareProtected(ManageSeleniumTestCases, 'manage_getZipFile')
-    def manage_getZipFile( self
-                         , archive_name=None
-                         , include_selenium=True
-                         , RESPONSE=None
-                         ):
-        """ Export the test suite as a zip file.
-        """
-        if archive_name is None or archive_name.strip() == '':
-            archive_name = self.getZipFileName()
-
-        bits = self._getZipFile( include_selenium )
-
-        if RESPONSE is None:
-            return bits
-
-        RESPONSE.setHeader('Content-type', 'application/zip')
-        RESPONSE.setHeader('Content-length', str( len( bits ) ) )
-        RESPONSE.setHeader('Content-disposition',
-                            'inline;filename=%s' % archive_name )
-        RESPONSE.write(bits)
-
-
-    security.declareProtected(ManageSeleniumTestCases, 'manage_createSnapshot')
-    def manage_createSnapshot( self
-                             , archive_name=None
-                             , include_selenium=True
-                             , RESPONSE=None
-                             ):
-        """ Save the test suite as a zip file *in the zuite*.
-        """
-        if archive_name is None or archive_name.strip() == '':
-            archive_name = self.getZipFileName()
-
-        archive = File( archive_name
-                      , title=''
-                      , file=self._getZipFile( include_selenium )
-                      )
-        self._setObject( archive_name, archive )
-
-        if RESPONSE is not None:
-            RESPONSE.redirect( '%s/manage_main?manage_tabs_message=%s'
-                              % ( self.absolute_url()
-                                , 'Snapshot+added'
-                                ) )
-
-
-    security.declarePublic('postResults')
-    def postResults(self, REQUEST):
-        """ Record the results of a test run.
-
-        o Create a folder with properties representing the summary results,
-          and files containing the suite and the individual test runs.
-
-        o REQUEST will have the following form fields:
-
-          result -- one of "failed" or "passed"
-
-          totalTime -- time in floating point seconds for the run
-
-          numTestPasses -- count of test runs which passed
-
-          numTestFailures -- count of test runs which failed
-
-          numCommandPasses -- count of commands which passed
-
-          numCommandFailures -- count of commands which failed
-
-          numCommandErrors -- count of commands raising non-assert errors
-
-          suite -- Colorized HTML of the suite table
-
-          testTable.<n> -- Colorized HTML of each test run
-        """
-        completed = DateTime()
-        result_id = 'result_%s' % completed.strftime( '%Y%m%d_%H%M%S' )
-        self._setObject( result_id, ZuiteResults( result_id ) )
-        result = self._getOb( result_id )
-        rfg = REQUEST.form.get
-        reg = REQUEST.environ.get
-
-        result._updateProperty( 'completed'
-                              , completed
-                              )
-
-        result._updateProperty( 'passed'
-                              , rfg( 'result' ).lower() == 'passed'
-                              )
-
-        result._updateProperty( 'time_secs'
-                              , float( rfg( 'totalTime', 0 ) )
-                              )
-
-        result._updateProperty( 'tests_passed'
-                              , int( rfg( 'numTestPasses', 0 ) )
-                              )
-
-        result._updateProperty( 'tests_failed'
-                              , int( rfg( 'numTestFailures', 0 ) )
-                              )
-
-        result._updateProperty( 'commands_passed'
-                              , int( rfg( 'numCommandPasses', 0 ) )
-                              )
-
-        result._updateProperty( 'commands_failed'
-                              , int( rfg( 'numCommandFailures', 0 ) )
-                              )
-
-        result._updateProperty( 'commands_with_errors'
-                              , int( rfg( 'numCommandErrors', 0 ) )
-                              )
-
-        result._updateProperty( 'user_agent'
-                              , reg( 'HTTP_USER_AGENT', 'unknown' )
-                              )
-
-        result._updateProperty( 'remote_addr'
-                              , reg( 'REMOTE_ADDR', 'unknown' )
-                              )
-
-        result._updateProperty( 'http_host'
-                              , reg( 'HTTP_HOST', 'unknown' )
-                              )
-
-        result._updateProperty( 'server_software'
-                              , reg( 'SERVER_SOFTWARE', 'unknown' )
-                              )
-
-        result._updateProperty( 'product_info'
-                              , self._listProductInfo()
-                              )
-
-        result._setObject( 'suite.html'
-                         , File( 'suite.html'
-                               , 'Test Suite'
-                               , unquote( rfg( 'suite' ) )
-                               , 'text/html'
-                               )
-                         )
-
-        test_ids = [ x for x in REQUEST.form.keys()
-                        if x.startswith( 'testTable' ) ]
-        test_ids.sort()
-
-        for test_id in test_ids:
-            body = unquote( rfg( test_id ) )
-            result._setObject( test_id
-                             , File( test_id
-                                   , 'Test case: %s' % test_id
-                                   , body
-                                   , 'text/html'
-                                   ) )
-            testcase = result._getOb( test_id )
-
-            # XXX:  this is silly, but we have no other metadata.
-            testcase._setProperty( 'passed'
-                                 , _PINK_BACKGROUND.search( body ) is None
-                                 , 'boolean'
-                                 )
-
-
-    #
-    #   Helper methods
-    #
-    security.declarePrivate('_listFilesystemObjects')
-    def _listFilesystemObjects( self ):
-        """ Return a mapping of any filesystem objects we "hold".
-        """
-        if ( self._v_filesystem_objects is not None and
-             not getConfiguration().debug_mode ):
-            return self._v_filesystem_objects
-
-        if not self.filesystem_path:
-            return { 'testcases' : (), 'subdirs' : {} }
-
-        path = os.path.abspath( self.filesystem_path )
-
-        self._v_filesystem_objects = self._grubFilesystem( path )
-        return self._v_filesystem_objects
-
-    security.declarePrivate('_listSeleniumObjects')
-    def _listSeleniumObjects( self ):
-        """ Return a mapping of any filesystem objects we "hold".
-        """
-        if ( self._v_selenium_objects is not None and
-             not getConfiguration().debug_mode ):
-            return self._v_selenium_objects
-
-        self._v_selenium_objects = self._grubFilesystem(_SUPPORT_DIR)
-        return self._v_selenium_objects
-
-    security.declarePrivate('_grubFilesystem')
-    def _grubFilesystem( self, path ):
-
-        info = { 'testcases' : (), 'subdirs' : {} }
-
-        # Look for a specified test suite
-        # or a '.objects' file with an explicit manifiest
-        manifest = os.path.join( path, self.testsuite_name or '.objects' )
-
-        if os.path.isfile( manifest ):
-            filenames = filter(None,[ x.strip() for x in open( manifest ).readlines() ])
-
-        elif self.filename_glob:
-            globbed = glob.glob( os.path.join( path, self.filename_glob ) )
-            filenames = [ os.path.split( x )[ 1 ] for x in globbed ]
-
-        else:   # guess
-            filenames = [ x for x in os.listdir( path )
-                                if x not in _EXCLUDE_NAMES ]
-            filenames.sort()
-
-        info[ 'ordered' ] = filenames
-
-        for name in filenames:
-
-            fqfn = os.path.join( path, name )
-
-            if os.path.isfile( fqfn ):
-                testcase = _makeFile( fqfn )
-                info[ 'testcases' ] += ( testcase, )
-
-            elif os.path.isdir( fqfn ):
-                info[ 'subdirs' ][ name ] = self._grubFilesystem( fqfn )
-
-            else:
-
-                logger.warning(
-                    '%r was neither a file nor directory and so has been ignored',
-                    fqfn
-                    )
-
-        return info
-
-
-    security.declarePrivate('_getFilename')
-    def _getFilename(self, name):
-        """ Convert 'name' to a suitable filename, if needed.
-        """
-        if '.' not in name:
-            return '%s.html' % name
-
-        return name
-
-
-    security.declarePrivate( '_getZipFile' )
-    def _getZipFile( self, include_selenium=True ):
-        """ Generate a zip file containing both tests and scaffolding.
-        """
-        stream = StringIO.StringIO()
-        archive = zipfile.ZipFile( stream, 'w' )
-
-
-        def convertToBytes(body):
-            if isinstance(body, types.UnicodeType):
-                return body.encode(_DEFAULTENCODING)
-            else:
-                return body
-
-        archive.writestr( 'index.html'
-                        , convertToBytes(self.index_html( suite_name='testSuite.html' ) ) )
-
-        test_cases = self.listTestCases()
-
-        paths = { '' : [] }
-
-        def _ensurePath( prefix, element ):
-            elements = paths.setdefault( prefix, [] )
-            if element not in elements:
-                elements.append( element )
-
-        for info in test_cases:
-            # ensure suffixes
-            path = self._getFilename( info[ 'path' ] )
-            info[ 'path' ] = path
-            info[ 'url' ] = self._getFilename( info[ 'url' ] )
-
-            elements = path.split( os.path.sep )
-            _ensurePath( '', elements[ 0 ] )
-
-            for i in range( 1, len( elements ) ):
-                prefix = '/'.join( elements[ : i ] )
-                _ensurePath( prefix, elements[ i ] )
-
-        archive.writestr( 'testSuite.html'
-                        , convertToBytes(self.test_suite_html( test_cases=test_cases ) ) )
-
-        for pathname, filenames in paths.items():
-
-            if pathname == '':
-                filename = '.objects'
-            else:
-                filename = '%s/.objects' % pathname
-
-            archive.writestr( convertToBytes(filename)
-                            , convertToBytes(u'\n'.join( filenames ) ) )
-
-        for info in test_cases:
-            test_case = info[ 'test_case' ]
-
-            if getattr( test_case, '__call__', None ) is not None:
-                body = test_case()  # XXX: DTML?
-            else:
-                body = test_case.manage_FTPget()
-
-            archive.writestr( convertToBytes(info[ 'path' ])
-                            , convertToBytes(body) )
-
-        if include_selenium:
-
-            for k, v in _SUPPORT_FILES.items():
-                archive.writestr( convertToBytes(k),
-                       convertToBytes(v.__of__(self).manage_FTPget() ) )
-
-        archive.close()
-        return stream.getvalue()
-
-    security.declarePrivate('_listProductInfo')
-    def _listProductInfo( self ):
-        """ Return a list of strings of form '%(name)s %(version)s'.
-
-        o Each line describes one product installed in the Control_Panel.
-        """
-        result = []
-        cp = self.getPhysicalRoot().Control_Panel
-        products = cp.Products.objectItems()
-        products.sort()
-
-        for product_name, product in products:
-            version = product.version or 'unreleased'
-            result.append( '%s %s' % ( product_name, version ) )
-
-        return result
-
-
-InitializeClass( Zuite )
-
-
-class ZuiteResults( Folder ):
-
-    security = ClassSecurityInfo()
-    meta_type = 'Zuite Results'
-
-    _properties = ( { 'id' : 'test_case_metatypes'
-                    , 'type' : 'lines'
-                    , 'mode' : 'w'
-                    },
-                    { 'id' : 'completed'
-                    , 'type' : 'date'
-                    , 'mode' : 'w'
-                    },
-                    { 'id' : 'passed'
-                    , 'type' : 'boolean'
-                    , 'mode' : 'w'
-                    },
-                    { 'id' : 'time_secs'
-                    , 'type' : 'float'
-                    , 'mode' : 'w'
-                    },
-                    { 'id' : 'tests_passed'
-                    , 'type' : 'int'
-                    , 'mode' : 'w'
-                    },
-                    { 'id' : 'tests_failed'
-                    , 'type' : 'int'
-                    , 'mode' : 'w'
-                    },
-                    { 'id' : 'commands_passed'
-                    , 'type' : 'int'
-                    , 'mode' : 'w'
-                    },
-                    { 'id' : 'commands_failed'
-                    , 'type' : 'int'
-                    , 'mode' : 'w'
-                    },
-                    { 'id' : 'commands_with_errors'
-                    , 'type' : 'int'
-                    , 'mode' : 'w'
-                    },
-                    { 'id' : 'user_agent'
-                    , 'type' : 'string'
-                    , 'mode' : 'w'
-                    },
-                    { 'id' : 'remote_addr'
-                    , 'type' : 'string'
-                    , 'mode' : 'w'
-                    },
-                    { 'id' : 'http_host'
-                    , 'type' : 'string'
-                    , 'mode' : 'w'
-                    },
-                    { 'id' : 'server_software'
-                    , 'type' : 'string'
-                    , 'mode' : 'w'
-                    },
-                    { 'id' : 'product_info'
-                    , 'type' : 'lines'
-                    , 'mode' : 'w'
-                    },
-                  )
-
-    security.declareObjectProtected( View )
-
-    security.declarePublic( 'index_html' )
-    index_html = PageTemplateFile( 'resultsView', _WWW_DIR )
-
-    security.declareProtected( View, 'error_icon' )
-    error_icon = ImageFile( 'error.gif', _WWW_DIR )
-
-    security.declareProtected( View, 'check_icon' )
-    check_icon = ImageFile( 'check.gif', _WWW_DIR )
-
-
-    def __getitem__( self, key, default=_MARKER ):
-
-        if key in self.objectIds():
-            return self._getOb( key )
-
-        if key == 'error.gif':
-            return self.error_icon
-
-        if key == 'check.gif':
-            return self.check_icon
-
-        if default is not _MARKER:
-            return default
-
-        raise KeyError, key
-
-InitializeClass( ZuiteResults )
-
-class _FilesystemProxy( Folder ):
-
-    security = ClassSecurityInfo()
-
-    def __init__( self, id, fsobjs ):
-
-        self._setId( id )
-        self._fsobjs = fsobjs
-
-    def __getitem__( self, key ):
-
-        return self.get( key )
-
-    security.declareProtected( View, 'index_html' )
-    index_html = PageTemplateFile( 'suiteView', _WWW_DIR )
-
-    security.declareProtected( View, 'test_suite_html' )
-    test_suite_html = PageTemplateFile( 'suiteTests', _WWW_DIR )
-
-    security.declareProtected( View, 'get' )
-    def get( self, key, default=_MARKER ):
-
-        for tc in self._fsobjs[ 'testcases' ]:
-            if tc.getId() == key:
-                return tc.__of__( self.aq_parent )
-
-        if key in self._fsobjs[ 'subdirs' ]:
-            return self.__class__( key, self._fsobjs[ 'subdirs' ][ key ]
-                                 ).__of__( self.aq_parent )
-
-        if key in _SUPPORT_FILES.keys():
-            return _SUPPORT_FILES[ key ].__of__( self )
-
-        if default is not _MARKER:
-            return default
-
-        raise KeyError, key
-
-    security.declareProtected( View, 'listTestCases' )
-    def listTestCases( self, prefix=() ):
-        """ Return a list of our contents which qualify as test cases.
-        """
-        result = []
-        _recurseFSTestCases( result, prefix, self._fsobjs )
-        return result
-
-InitializeClass( _FilesystemProxy )
-
-#
-#   Factory methods
-#
-manage_addZuiteForm = PageTemplateFile( 'addZuite', _WWW_DIR )
-
-def manage_addZuite(dispatcher, id, title='', REQUEST=None):
-    """ Add a new Zuite to dispatcher's objects.
-    """
-    zuite = Zuite(id)
-    zuite.title = title
-    dispatcher._setObject(id, zuite)
-    zuite = dispatcher._getOb(id)
-
-    if REQUEST is not None:
-        REQUEST['RESPONSE'].redirect('%s/manage_main'
-                                       % zuite.absolute_url() )



More information about the checkins mailing list