pax_global_header 0000666 0000000 0000000 00000000064 13437501147 0014517 g ustar 00root root 0000000 0000000 52 comment=59f55bfb720b043f3c10044669465dfd63c4822c
erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/ 0000775 0000000 0000000 00000000000 13437501147 0022417 5 ustar 00root root 0000000 0000000 erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/ 0000775 0000000 0000000 00000000000 13437501147 0024077 5 ustar 00root root 0000000 0000000 erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/ 0000775 0000000 0000000 00000000000 13437501147 0025667 5 ustar 00root root 0000000 0000000 erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/__init__.py 0000664 0000000 0000000 00000001072 13437501147 0030000 0 ustar 00root root 0000000 0000000 """ 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'
)
erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/configure.zcml 0000664 0000000 0000000 00000000535 13437501147 0030542 0 ustar 00root root 0000000 0000000
erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/exclude.txt 0000664 0000000 0000000 00000000031 13437501147 0030053 0 ustar 00root root 0000000 0000000 .css
.gif
.ico
/misc_
/p_ erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/generator.py 0000664 0000000 0000000 00000036655 13437501147 0030246 0 ustar 00root root 0000000 0000000 """ 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 = """\
%(TEST_CASE_TITLE)s
%(TEST_CASE_TITLE)s
|
"""
_TEST_CASE_FOOTER = """
"""
_GET_REQUEST_SKELETON = """
open |
%(REQUEST_URI)s |
|
"""
_POST_REQUEST_SKELETON = """
click |
submit |
|
"""
_REDIRECT_SKELETON = """
verifyLocation |
%(REDIRECTED_URL)s |
|
"""
_INPUT_FIELD_SKELETON = """
type |
%(FIELD_NAME)s |
%(FIELD_VALUE)s |
"""
_SELECT_FIELD_SKELETON = """
select |
%(FIELD_NAME)s |
%(FIELD_VALUE)s |
"""
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()
erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/interfaces.py 0000664 0000000 0000000 00000000226 13437501147 0030364 0 ustar 00root root 0000000 0000000 """ Zelenium interfaces
$Id$
"""
from zope.interface import Interface
class IZuite(Interface):
""" Marker interface for IZuite objects.
"""
erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/permissions.py 0000664 0000000 0000000 00000000227 13437501147 0030615 0 ustar 00root root 0000000 0000000 """ Zelenium product permissions
$Id$
"""
from AccessControl.Permissions import view as View
ManageSeleniumTestCases = 'Manage Selenium test cases'
erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/scripts/ 0000775 0000000 0000000 00000000000 13437501147 0027356 5 ustar 00root root 0000000 0000000 startWebServer.bat 0000664 0000000 0000000 00000000043 13437501147 0032746 0 ustar 00root root 0000000 0000000 erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/scripts @echo off
python ./tinyWebServer.py stopWebServer.bat 0000664 0000000 0000000 00000000073 13437501147 0032601 0 ustar 00root root 0000000 0000000 erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/scripts @echo off
python ./tinyWebClient.py localhost 8000 QUIT /
tinyWebClient.py 0000664 0000000 0000000 00000000567 13437501147 0032441 0 ustar 00root root 0000000 0000000 erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/scripts import sys
import httplib
if ( len(sys.argv) != 5 ):
print "usage tinyWebClient.py host port method path"
else:
host = sys.argv[1]
port = sys.argv[2]
method = sys.argv[3]
path = sys.argv[4]
info = (host, port)
print "%s:%s" % info
conn = httplib.HTTPConnection("%s:%s" % info)
conn.request(method, path)
print conn.getresponse().msg
tinyWebServer.py 0000664 0000000 0000000 00000004434 13437501147 0032466 0 ustar 00root root 0000000 0000000 erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/scripts # Copyright 2004 ThoughtWorks, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# minimal web server.
# serves files relative to the current directory.
# cgi-bin directory serves Python CGIs.
import BaseHTTPServer
import CGIHTTPServer
import time
import httplib
import sys
PORT = 8000
class HTTPHandler(CGIHTTPServer.CGIHTTPRequestHandler):
"""
Simple Web Server that can handle query strings in a request URL and
can be stopped with a request
"""
quitRequestReceived = False
def do_GET(self):
# SimpleHTTPServer doesn't know how to handle query strings in
# 'GET' requests, so we're processing them here:
if self.path.find('?') != -1:
self.path, self.query_string = self.path.split('?', 1)
else:
self.query_string = ''
# Add a delay before serving up the slow-loading test page
if self.path.find('test_slowloading_page') != -1:
time.sleep(0.3)
# Carry on with the rest of the processing...
CGIHTTPServer.CGIHTTPRequestHandler.do_GET(self)
def do_QUIT(self):
self.send_response(200)
self.end_headers()
HTTPHandler.quitRequestReceived = True
if __name__ == '__main__':
port = PORT
if len(sys.argv) > 1:
port = int(sys.argv[1])
server_address = ('', port)
httpd = BaseHTTPServer.HTTPServer(server_address, HTTPHandler)
print "serving at port", port
print "To run the entire JsUnit test suite, open"
print (" http://localhost:8000/jsunit/testRunner.html?testPage="
"http://localhost:8000/tests/JsUnitSuite.html&autoRun=true")
print "To run the acceptance test suite, open"
print " http://localhost:8000/TestRunner.html"
while not HTTPHandler.quitRequestReceived :
httpd.handle_request()
erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/selenium/ 0000775 0000000 0000000 00000000000 13437501147 0027510 5 ustar 00root root 0000000 0000000 erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/selenium/VERSION.txt0000664 0000000 0000000 00000000150 13437501147 0031372 0 ustar 00root root 0000000 0000000 selenium.rc.version=2.6
selenium.rc.revision=.0
selenium.core.version=2.6
selenium.core.revision=.0
erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/selenium/core/ 0000775 0000000 0000000 00000000000 13437501147 0030440 5 ustar 00root root 0000000 0000000 Blank.html 0000664 0000000 0000000 00000000215 13437501147 0032274 0 ustar 00root root 0000000 0000000 erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/selenium/core
InjectedRemoteRunner.html 0000664 0000000 0000000 00000000264 13437501147 0035344 0 ustar 00root root 0000000 0000000 erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/selenium/core
selenium-rc initial page
RemoteRunner.hta 0000664 0000000 0000000 00000010630 13437501147 0033504 0 ustar 00root root 0000000 0000000 erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/selenium/core
Selenium Remote Control
RemoteRunner.html 0000664 0000000 0000000 00000010630 13437501147 0033674 0 ustar 00root root 0000000 0000000 erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/selenium/core
Selenium Remote Control
SeleniumLog.html 0000664 0000000 0000000 00000005713 13437501147 0033500 0 ustar 00root root 0000000 0000000 erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/selenium/core
Selenium Log Console
Selenium Log Console
TestPrompt.html 0000664 0000000 0000000 00000012560 13437501147 0033374 0 ustar 00root root 0000000 0000000 erp5-59f55bfb720b043f3c10044669465dfd63c4822c-product-Zelenium/product/Zelenium/selenium/core
Select a Test Suite