Index: /eduCommons.buildout/tags/3.2.1-rc1/README.txt
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/README.txt	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/README.txt	(revision 444)
@@ -0,0 +1,327 @@
+=======================
+Using a custom buildout
+=======================
+
+Note: If you are using Windows, if you do not have PIL installed, or you are 
+not using Python 2.4 as your main system Python, please see the relevant 
+sections below.
+
+You probably got here by running something like:
+
+ $ paster create -t plone3_buildout
+ 
+Now, you need to run:
+
+ $ python bootstrap.py
+ 
+This will install zc.buildout for you. 
+
+To create an instance immediately, run:
+
+ $ bin/buildout
+ 
+This will download Plone's eggs and products for you, as well as other 
+dependencies, create a new Zope 2 installation (unless you specified
+an existing one when you ran "paster create"), and create a new Zope instance
+configured with these products.
+
+You can start your Zope instance by running:
+
+ $ bin/instance start
+ 
+or, to run in foreground mode:
+
+ $ bin/instance fg
+ 
+To run unit tests, you can use:
+
+ $ bin/instance test -s my.package
+ 
+Installing PIL
+--------------
+
+To use Plone, you need PIL, the Python Imaging Library. If you don't already
+have this, download and install it from http://www.pythonware.com/products/pil.
+
+Using a different Python installation
+--------------------------------------
+
+Buildout will use your system Python installation by default. However, Zope
+2.10 (and by extension, Plone) will only work with Python 2.4. You can verify
+which version of Python you have, by running:
+
+ $ python -V
+ 
+If that is not a 2.4 version, you need to install Python 2.4 from 
+http://python.org. If you wish to keep another version as your main system
+Python, edit buildout.cfg and add an 'executable' option to the "[buildout]"
+section, pointing to a python interpreter binary:
+
+ [buildout]
+ ...
+ executable = /path/to/python
+ 
+Working with buildout.cfg
+-------------------------
+
+You can change any option in buildout.cfg and re-run bin/buildout to reflect
+the changes. This may delete things inside the 'parts' directory, but should
+keep your Data.fs and source files intact. 
+
+To save time, you can run buildout in "offline" (-o) and non-updating (-N) 
+mode, which will prevent it from downloading things and checking for new 
+versions online:
+
+ $ bin/buildout -Nov
+ 
+Creating new eggs
+-----------------
+
+New packages you are working on (but which are not yet released as eggs and
+uploaded to the Python Package Index, aka PYPI) should be placed in src. You can do:
+
+ $ cd src/
+ $ paster create -t plone my.package
+ 
+Use "paster create --list-templates" to see all available templates. Answer
+the questions and you will get a new egg. Then tell buildout about your egg
+by editing buildout.cfg and adding your source directory to 'develop':
+
+ [buildout]
+ ...
+ develop =
+    src/my.package
+    
+You can list multiple packages here, separated by whitespace or indented
+newlines.
+
+You probably also want the Zope instance to know about the package. Add its
+package name to the list of eggs in the "[instance]" section, or under the
+main "[buildout]" section:
+
+ [instance]
+ ...
+ eggs =
+    ${buildout:eggs}
+    ${plone:eggs}
+    my.package
+    
+Leave the ${buildout:eggs} part in place - it tells the instance to use the
+eggs that buildout will have downloaded from the Python Package Index
+previously.
+
+If you also require a ZCML slug for your package, buildout can create one
+automatically. Just add the package to the 'zcml' option:
+
+ [instance]
+ ...
+ zcml =
+    my.package
+    
+When you are finished, re-run buildout. Offline, non-updating mode should 
+suffice:
+
+ $ bin/buildout -Nov
+ 
+Developing old-style products
+-----------------------------
+
+If you are developing old-style Zope 2 products (not eggs) then you can do so
+by placing the product code in the top-level 'products' directory. This is
+analogous to the 'Products/' directory inside a normal Zope 2 instance and is
+scanned on start-up for new products.
+
+Depending on a new egg
+----------------------
+
+If you want to use a new egg that is in the Python Package Index, all you need
+to do is to add it to the "eggs" option under the main "[buildout]" section:
+
+ [buildout]
+ ...
+ eggs =
+    my.package
+    
+If it's listed somewhere else than the Python Package Index, you can add a link
+telling buildout where to find it in the 'find-links' option:
+
+ [buildout]
+ ...
+ find-links =
+    http://dist.plone.org
+    http://download.zope.org/distribution/
+    http://effbot.org/downloads
+    http://some.host.com/packages
+    
+Using existing old-style products
+---------------------------------
+
+If you are using an old-style (non-egg) product, you can either add it as an 
+automatically downloaded archive or put it in the top-level "products" folder.
+The former is probably better, because it means you can redistribute your
+buildout.cfg more easily:
+
+ [productdistros]
+ recipe = plone.recipe.distros
+ urls =
+    http://plone.org/products/someproduct/releases/1.3/someproduct-1.3.tar.gz
+
+If someproduct-1.3.tar.gz extracts into several products inside a top-level
+directory, e.g. SomeProduct-1.3/PartOne and SomeProduct-1.3/PartTwo, then
+add it as a "nested package":
+
+ [productdistros]
+ recipe = plone.recipe.distros
+ urls =
+    http://plone.org/products/someproduct/releases/1.3/someproduct-1.3.tar.gz
+ nested-packages =
+    someproduct-1.3.tar.gz
+ 
+Alternatively, if it extracts to a directory which contains the version 
+number, add it as a "version suffix package":
+
+ [productdistros]
+ recipe = plone.recipe.distros
+ urls =
+    http://plone.org/products/someproduct/releases/1.3/someproduct-1.3.tar.gz
+ version-suffix-packages = 
+    someproduct-1.3.tar.gz
+    
+You can also track products by adding a new bundle checkout part. It 
+doesn't strictly have to be an svn bundle at all, any svn location will do,
+and cvs is also supported:
+
+ [buildout]
+ ...
+ parts =
+    plone
+    zope2
+    productdistros
+    myproduct
+    instance
+    zopepy
+
+Note that "myproduct" comes before the "instance" part. You then
+need to add a new section to buildout.cfg:
+
+ [myproduct]
+ recipe = plone.recipe.bundlecheckout
+ url = http://svn.plone.org/svn/collective/myproduct/trunk
+ 
+Finally, you need to tell Zope to find this new checkout and add it to its
+list of directories that are scanned for products:
+
+ [instance]
+ ...
+ products =
+    ${buildout:directory}/products
+    ${productdistros:location}
+    ${plonebundle:location}
+    ${myproduct:location}
+    
+Without this last step, the "myproduct" part is simply managing an svn 
+checkout and could potentially be used for something else instead.
+
+=============
+Using Windows
+=============
+
+To use buildout on Windows, you will need to install a few dependencies which
+other platforms manage on their own.
+
+Here are the steps you need to follow (thanks to Hanno Schlichting for these):
+
+Python (http://python.org)
+--------------------------
+
+  - Download and install Python 2.4.4 using the Windows installer from
+    http://www.python.org/ftp/python/2.4.4/python-2.4.4.msi
+    Select 'Install for all users' and it will put Python into the
+    "C:\Python24" folder by default.
+
+  - You also want the pywin32 extensions available from
+    http://downloads.sourceforge.net/pywin32/pywin32-210.win32-py2.4.exe?modtime=1159009237&big_mirror=0
+
+  - And as a last step you want to download the Python imaging library available
+    from http://effbot.org/downloads/PIL-1.1.6.win32-py2.4.exe
+
+  - If you develop Zope based applications you will usually only need Python 2.4
+    at the moment, so it's easiest to put the Python binary on the systems PATH,
+    so you don't need to specify its location manually each time you call it.
+
+    Thus, put "C:\Python24" and "C:\Python24\Scripts" onto the PATH. You can
+    find the PATH definition in the control panel under system preferences on
+    the advanced tab at the bottom. The button is called environment variables.
+    You want to add it at the end of the already existing PATH in the system
+    section. Paths are separated by a semicolons.
+
+  - You can test if this was successful by opening a new shell (cmd) and type
+    in 'python -V'. It should report version 2.4.4 (or whichever version you
+    installed).
+    
+    Opening a new shell can be done quickly by using the key combination
+    'Windows-r' or if you are using Parallels on a Mac 'Apple-r'. Type in 'cmd'
+    into the popup box that opens up and hit enter.
+
+
+Subversion (http://subversion.tigris.org)
+-----------------------------------------
+
+  - Download the nice installer from
+    http://subversion.tigris.org/files/documents/15/35379/svn-1.4.2-setup.exe
+
+  - Run the installer. It defaults to installing into
+    "C:\Program Files\Subversion".
+
+  - Now put the install locations bin subfolder (for example
+    "C:\Program Files\Subversion\bin") on your system PATH in the same way you
+    put Python on it.
+
+  - Open a new shell again and type in: 'svn --version' it should report
+    version 1.4.2 or newer.
+
+
+MinGW (http://www.mingw.org/)
+-----------------------------
+
+  This is a native port of the gcc compiler and its dependencies for Windows.
+  There are other approaches enabling you to compile Python C extensions on
+  Windows including Cygwin and using the official Microsoft C compiler, but this
+  is a lightweight approach that uses only freely available tools. As
+  it's used by a lot of people chances are high it will work for you and there's
+  plenty of documentation out there to help you in troubleshooting problems.
+
+  - Download the MinGW installer from
+    http://downloads.sourceforge.net/mingw/MinGW-5.1.3.exe?modtime=1168794334&big_mirror=1
+
+  - The installer will ask you which options you would like to install. Choose
+    base and make here. It will install into "C:\MinGW" by default. The install
+    might take some time as it's getting files from sourceforge.net and you
+    might need to hit 'retry' a couple of times.
+
+  - Now put the install location's bin subfolder (for example "C:\MinGW\bin") on
+    your system PATH in the same way you put Python on it.
+
+  - Test this again by typing in: 'gcc --version' on a newly opened shell and
+    it should report version 3.4.2 or newer.
+
+
+Configure Distutils to use MinGW
+--------------------------------
+
+  Some general information are available from
+  http://www.mingw.org/MinGWiki/index.php/Python%20extensions for example but
+  you don't need to read them all.
+
+  - Create a file called 'distutils.cfg' in "C:\Python24\Lib\distutils". Open it
+    with a text editor ('notepad distutils.cfg') and fill in the following lines:
+
+    [build]
+    compiler=mingw32
+
+    This will tell distutils to use MinGW as the default compiler, so you don't
+    need to specify it manually using "--compiler=mingw32" while calling a
+    package's setup.py with a command that involves building C extensions. This
+    is extremely useful if the build command is written down in a buildout
+    recipe where you cannot change the options without hacking the recipe
+    itself. The z2c.recipe.zope2install used in ploneout is one such example.
Index: /eduCommons.buildout/tags/3.2.1-rc1/bootstrap.py
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/bootstrap.py	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/bootstrap.py	(revision 444)
@@ -0,0 +1,55 @@
+##############################################################################
+#
+# Copyright (c) 2006 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.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id$
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+try:
+    import pkg_resources
+except ImportError:
+    ez = {}
+    exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+                         ).read() in ez
+    ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+    import pkg_resources
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+if sys.platform == 'win32':
+    cmd = '"%s"' % cmd # work around spawn lamosity on windows
+
+ws = pkg_resources.working_set
+assert os.spawnle(
+    os.P_WAIT, sys.executable, sys.executable,
+    '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
+    dict(os.environ,
+         PYTHONPATH=
+         ws.find(pkg_resources.Requirement.parse('setuptools')).location
+         ),
+    ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)
Index: /eduCommons.buildout/tags/3.2.1-rc1/buildout.cfg
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/buildout.cfg	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/buildout.cfg	(revision 444)
@@ -0,0 +1,180 @@
+[buildout]
+parts =
+    zope2
+    productdistros
+    instance
+    fss
+    zopepy
+    test
+    test-coverage
+    coverage-report
+
+# Add additional egg download sources here. dist.plone.org contains archives
+# of Plone packages.
+find-links =
+    http://dist.plone.org/thirdparty
+    http://dist.plone.org
+    http://download.zope.org/ppix/
+    http://download.zope.org/distribution/
+    http://effbot.org/downloads
+    ftp://xmlsoft.org/libxml2/python/libxml2-python-2.6.15.tar.gz
+    http://ufpr.dl.sourceforge.net/sourceforge/pyxml/PyXML-0.8.4.tar.gz
+    http://pypi.python.org/packages/source/p/plone.reload/plone.reload-0.10.tar.gz
+
+extends = http://dist.plone.org/release/3.2.1/versions.cfg
+versions = versions
+
+# Add additional eggs here
+# elementtree is required by Plone
+eggs =
+    Plone
+    PIL
+    elementtree
+    libxml2-python
+    PyXML
+    BeautifulSoup
+    infrae.subversion
+    collective.captcha
+    collective.plonebookmarklets
+    collective.contentlicensing
+    collective.imstransport
+    collective.jaop
+    collective.oaiintercom
+    collective.searchandreplace
+    collective.zipfiletransport
+    enpraxis.leftskin
+    enpraxis.staticsite
+    enpraxis.educommons
+    enpraxis.wordpressexchange
+    plone.reload
+    iw.fss
+    plone.mocktestcase
+    Products.CacheSetup
+    
+# Reference any eggs you are developing here, one per line
+# e.g.: develop = src/my.package
+develop =	
+    src/collective.plonebookmarklets
+    src/collective.contentlicensing
+    src/collective.imstransport
+    src/collective.jaop
+    src/collective.oaiintercom
+    src/collective.searchandreplace
+    src/collective.zipfiletransport
+    src/enpraxis.leftskin
+    src/enpraxis.staticsite
+    src/enpraxis.educommons
+    src/enpraxis.wordpressexchange
+
+[versions]
+zope.component = 3.5.1
+
+[zope2]
+recipe = plone.recipe.zope2install
+url = ${versions:zope2-url}
+fake-zope-eggs = true
+skip-fake-eggs =
+    ZConfig
+    ZODB3
+    pytz
+    zope.testing
+    zope.component
+    zope.i18n
+ 
+# Use this section to download additional old-style products.
+# List any number of URLs for product tarballs under URLs (separate
+# with whitespace, or break over several lines, with subsequent lines
+# indented). If any archives contain several products inside a top-level
+# directory, list the archive file name (i.e. the last part of the URL, 
+# normally with a .tar.gz suffix or similar) under 'nested-packages'.
+# If any archives extract to a product directory with a version suffix, list
+# the archive name under 'version-suffix-packages'.
+[productdistros]
+recipe = plone.recipe.distros
+urls =
+    http://www.infrae.com/download/ProxyIndex/1.2.1/ProxyIndex-1.2.1.tgz
+    http://plone.org/products/linguaplone/releases/2.1.1/LinguaPlone-2.1.1.tar.gz
+nested-packages =
+version-suffix-packages = 
+
+[instance]
+recipe = plone.recipe.zope2instance
+zope2-location = ${zope2:location}
+user = admin:test1234
+http-address = 8080
+debug-mode = on
+verbose-security = on
+zcml =
+    plone.mocktestcase
+
+# If you want Zope to know about any additional eggs, list them here.
+# This should include any development eggs you listed in develop-eggs above,
+# e.g. eggs = ${buildout:eggs} ${plone:eggs} my.package
+eggs =
+    ${buildout:eggs}
+
+# If you want to register ZCML slugs for any packages, list them here.
+# e.g. zcml = my.package my.other.package
+zcml = 
+    collective.plonebookmarklets
+    collective.contentlicensing
+    collective.imstransport
+    collective.jaop
+    collective.oaiintercom
+    collective.searchandreplace
+    collective.zipfiletransport
+    enpraxis.leftskin
+    enpraxis.leftskin-overrides
+    enpraxis.staticsite
+    enpraxis.educommons
+    enpraxis.educommons-overrides
+    enpraxis.wordpressexchange
+    iw.fss
+    plone.reload	
+
+		
+
+products =
+    ${buildout:directory}/products
+    ${productdistros:location}
+
+[zopepy]
+recipe = zc.recipe.egg
+eggs = ${instance:eggs}
+interpreter = zopepy
+extra-paths = ${zope2:location}/lib/python
+scripts = zopepy
+
+[test]
+recipe = collective.recipe.z2testrunner
+defaults = --ndiff -v
+zope2part = instance
+packages = collective.plonebookmarklets
+           collective.searchandreplace
+           collective.imstransport
+           collective.zipfiletransport
+					 collective.jaop
+					 collective.oaiintercom
+           enpraxis.educommons
+           enpraxis.leftskin
+           enpraxis.staticsite
+
+[test-coverage]
+recipe = collective.recipe.z2testrunner
+packages = ${test:packages}
+zope2part = instance
+defaults = --ndiff -v --coverage=${buildout:directory}/coverage
+
+[coverage-report]
+recipe = zc.recipe.egg
+eggs = z3c.coverage
+scripts = coverage=coverage-report
+arguments = ('${buildout:directory}/coverage', '${buildout:directory}/coverage/report')
+
+[fss]
+recipe = iw.recipe.fss
+zope-instances =
+    ${instance:location}
+storages =
+# The first is always generic
+    global /
Index: /eduCommons.buildout/tags/3.2.1-rc1/deployment.cfg
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/deployment.cfg	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/deployment.cfg	(revision 444)
@@ -0,0 +1,72 @@
+[buildout]
+extends =
+    buildout.cfg
+
+parts =
+    plone
+    zope2
+    productdistros
+    instance
+    fss
+    zopepy
+    test
+    test-coverage
+    coverage-report
+    zeoserver
+    plonesite
+
+find-links += 
+    http://localhost/files/
+
+# Do not load any development eggs
+develop =
+
+
+[zeoserver]
+recipe = plone.recipe.zope2zeoserver
+zope2-location = ${instance:zope2-location}
+zeo-address = ${instance:zeo-address}
+
+[instance]
+recipe = plone.recipe.zope2instance
+zope2-location = ${zope2:location}
+user = admin:test1234
+http-address = 8080
+effective-user = educommons
+zeo-client = true
+zeo-address = 8100
+zodb-cache-size = 1500
+zeo-client-cache-size = 300MB
+debug-mode = off
+verbose-security = off
+eggs += Products.CacheSetup
+environment-vars = 
+    PYTHON_EGG_CACHE ${buildout:directory}/var/.python-eggs
+
+[plonesite]
+recipe = collective.recipe.plonesite
+site-id = eduCommons
+instance = instance
+zeoserver = zeoserver
+profiles =
+    collective.contentlicensing:default
+    collective.imstransport:default
+    collective.plonebookmarklets:default
+    collective.zipfiletransport:default
+    collective.searchandreplace:default
+    enpraxis.leftskin:default
+    enpraxis.educommons:default
+    iw.fss:default
+    Products.LinguaPlone:LinguaPlone
+    Products.CacheSetup:default
+    Products.CMFPlacefulWorkflow:CMFPlacefulWorkflow
+    plone.app.iterate:plone.app.iterate
+    
+[fss]
+recipe = iw.recipe.fss
+zope-instances = 
+    ${instance:location}
+storages = 
+    global / directory ${buildout:directory}/var/fss_storage ${buildout:directory}/var/fss_backup
+
+
Index: /eduCommons.buildout/tags/3.2.1-rc1/products/README.txt
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/products/README.txt	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/products/README.txt	(revision 444)
@@ -0,0 +1,1 @@
+Old-style Zope products you are developing can be added here
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/EXTERNALS.txt
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/EXTERNALS.txt	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/EXTERNALS.txt	(revision 444)
@@ -0,0 +1,13 @@
+# svn propset svn:externals -F EXTERNALS.txt .
+# eduCommons eggs
+collective.plonebookmarklets https://svn.plone.org/svn/collective/collective.plonebookmarklets/trunk
+collective.contentlicensing https://svn.plone.org/svn/collective/collective.contentlicensing/trunk
+collective.imstransport https://svn.plone.org/svn/collective.imstransport/trunk
+collective.jaop https://svn.plone.org/svn/collective/collective.jaop/trunk 
+collective.oaiintercom https://svn.plone.org/svn/collective/collective.oaiintercom/trunk 
+collective.searchandreplace https://svn.plone.org/svn/collective/collective.searchandreplace/trunk 
+collective.zipfiletransport https://svn.plone.org/svn/collective/collective.zipfiletransport/trunk
+enpraxis.leftskin https://enpraxis.net/svn/eduCommons32/enpraxis.leftskin/trunk
+enpraxis.educommons https://enpraxis.net/svn/eduCommons32/enpraxis.educommons/trunk
+enpraxis.staticsite https://enpraxis.net/svn/eduCommons32/enpraxis.staticsite/trunk
+enpraxis.wordpressexchange https://enpraxis.net/svn/eduCommons32/enpraxis.wordpressexchange/trunk
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/CHANGES.txt
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/CHANGES.txt	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/CHANGES.txt	(revision 444)
@@ -0,0 +1,7 @@
+0.1 (2009-01-05)
+==================
+ - Created recipe with ZopeSkel [Santiago Suarez Ordonez].
+
+1.0 (2009-02-14)
+==================
+ - Ended code changes and uploaded the egg to pypi [Santiago Suarez Ordonez].
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/CONTRIBUTORS.txt
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/CONTRIBUTORS.txt	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/CONTRIBUTORS.txt	(revision 444)
@@ -0,0 +1,2 @@
+Santiago Suarez Ordonez, Author
+Juan Pablo Gimenez, Contributor
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/README.txt
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/README.txt	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/README.txt	(revision 444)
@@ -0,0 +1,7 @@
+.. contents::
+
+
+- Code repository: http://svn.rcom.com.ar/rcom.recipe.seleniumenv
+- Questions and comments to santiycr atrcom dotcom dotar
+- Report bugs at santiycr atrcom dotcom dotar
+
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/bootstrap.py
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/bootstrap.py	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/bootstrap.py	(revision 444)
@@ -0,0 +1,52 @@
+##############################################################################
+#
+# Copyright (c) 2006 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.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id$
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+ez = {}
+exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+                     ).read() in ez
+ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+import pkg_resources
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+if sys.platform == 'win32':
+    cmd = '"%s"' % cmd # work around spawn lamosity on windows
+
+ws = pkg_resources.working_set
+assert os.spawnle(
+    os.P_WAIT, sys.executable, sys.executable,
+    '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
+    dict(os.environ,
+         PYTHONPATH=
+         ws.find(pkg_resources.Requirement.parse('setuptools')).location
+         ),
+    ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/buildout.cfg
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/buildout.cfg	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/buildout.cfg	(revision 444)
@@ -0,0 +1,7 @@
+[buildout]
+develop = .
+parts = test
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = rcom.recipe.seleniumenv [tests]
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/PKG-INFO
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/PKG-INFO	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/PKG-INFO	(revision 444)
@@ -0,0 +1,192 @@
+Metadata-Version: 1.0
+Name: rcom.recipe.seleniumenv
+Version: 1.0dev-r316
+Summary: A recipe for setting a ready-to-use selenium RC environment
+Home-page: www.rcom.com.ar
+Author: Santiago Suarez Ordonez
+Author-email: santiycr@rcom.com.ar
+License: ZPL
+Description: .. contents::
+        
+        
+        - Code repository: http://svn.rcom.com.ar/rcom.recipe.seleniumenv
+        - Questions and comments to santiycr atrcom dotcom dotar
+        - Report bugs at santiycr atrcom dotcom dotar
+        
+        
+        Detailed Documentation
+        **********************
+        
+        Supported options
+        =================
+        
+        The recipe supports the following options:
+        
+        seleniumversion
+        The version of selenium to use, the version numbers can be taken from
+        http://release.seleniumhq.org/selenium-remote-control/. Default: nightlyBuild.
+        
+        eggs
+        The eggs to include in the runner path. Any product included in the path will be
+        accesible for the runner to search and run selenium tests from.
+        
+        java-cmd
+        The commando used to run the selenium server. Default: java.
+        
+        Example usage
+        =============
+        
+        The basic buildout that uses the recipe should look like the following::
+        
+        >>> write('buildout.cfg',
+        ... """
+        ... [buildout]
+        ... parts = seleniumenv
+        ...
+        ... [seleniumenv]
+        ... recipe = rcom.recipe.seleniumenv
+        ... seleniumversion = 1.0-beta-2
+        ... eggs = ${instance:eggs}
+        
+        
+        The seleniumrunner script
+        =========================
+        
+        The selenium runner is a scipt to find and run **selenium tests**, it will
+        be on your bin directory once the recipe is instanlled
+        It receives different parameters and it's main objective is to simplify the
+        tests execution and reporting procedure.
+        This script will wake-up the selenium RC server, search and run the tests
+        and then shutdown the server and report the tests result.
+        Once the recipe has been installed, a tests runner should be placed on the bin directory
+        
+        Running the tests
+        -----------------
+        
+        To run the suite of tests buldled with any product, the first thing to do after
+        the buildout has been run is to prepare a Plone site to test (if the user doesn't
+        have a Plone site to test, yet).
+        For this to be done, you must first wake up the instance::
+        
+        ./bin/instance start
+        
+        To run all the selenium tests for a product the user should pass at least two
+        parameters:
+        
+        -i instance
+        The Plone site's name.
+        
+        -s product
+        The product in which the runner will search for tests to run.
+        
+        An example test execution will be::
+        
+        $ ./bin/seleniumrunner -i testPloneSite -s namespace.product
+        
+        This will search all the **selenium** tests for the product and run them
+        on http://localhost:<port_used>/testPloneSite.
+        
+        For running  a particular test, the -t parameter should be passed to the runner::
+        
+        $ ./bin/seleniumrunner -i testPloneSite -s namespace.product -t exampleTest
+        
+        .. Note::
+        
+        Please notice that the exampleTest.py test should be stored in the
+        respective location and added to the __init__py file (See `Creating a test`_)
+        
+        Creating a test
+        ---------------
+        
+        The seleniumrunner script will look for all the classes that inherit from
+        unittest.TestCase on a specified package or module located under this kind of
+        path::
+        
+        namespace.product/namespace/product/tests/seleniumtests
+        
+        Tests development guidelines
+        ++++++++++++++++++++++++++++
+        
+        To create a test, there are certain basic rules to follow:
+        
+        #) The test should inherit from unittest.TestCase class (this can be done
+        indirectly also).
+        #) The test should use certain global variables for the code to work
+        on different environments and Plone instances. These are:
+        
+        - browser: For the browser used for the tests
+        
+        - port: For the port used to communicate with the server
+        
+        - url: For the url of the application under test
+        
+        - instance: The Plone site name (this depends on
+        the name used for the site's creation).
+        
+        This variables should never be changed inside the test code, as the
+        seleniumrunner script will set them at runtime according with the parameters
+        received.
+        
+        All this rules can be seen applied to the following `Example test`_.
+        
+        Example test
+        ++++++++++++
+        
+        The following is an example test, it can be used as the basic
+        structure for future tests::
+        
+        from selenium import selenium
+        import unittest
+        
+        class NewTest(unittest.TestCase):
+        def setUp(self):
+        self.verificationErrors = []
+        self.selenium = selenium("localhost", port, browser, url)
+        self.selenium.start()
+        
+        def test_new(self):
+        sel = self.selenium
+        sel.open(instance + "/login.html")
+        # Do specific tests in here
+        
+        def tearDown(self):
+        self.selenium.stop()
+        self.assertEqual([], self.verificationErrors)
+        
+        Notice that the test doesn't have much changes from the basic test exported using
+        `Selenium IDE <http://seleniumhq.org/projects/ide/>`_, the firefox extension. The
+        only difference are the variables used for the instanciation inside the *setUp* method.
+        
+        .. Note::
+        
+        Please notice that the "instance" variable will have to be used in
+        each *open* command for the users to provide the correct location
+        of the eduCommons plone site to test.
+        
+        Contributors
+        ************
+        
+        Santiago Suarez Ordonez, Author
+        Juan Pablo Gimenez, Contributor
+        
+        Change history
+        **************
+        
+        0.1 (2009-01-05)
+        ==================
+        - Created recipe with ZopeSkel [Santiago Suarez Ordonez].
+        
+        1.0 (2009-02-14)
+        ==================
+        - Ended code changes and uploaded the egg to pypi [Santiago Suarez Ordonez].
+        
+        Download
+        ********
+        
+Keywords: selenium rc testing plone ajax recipe
+Platform: UNKNOWN
+Classifier: Framework :: Buildout
+Classifier: Intended Audience :: Developers
+Classifier: Topic :: Software Development :: Build Tools
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: License :: OSI Approved :: Zope Public License
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/SOURCES.txt
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/SOURCES.txt	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/SOURCES.txt	(revision 444)
@@ -0,0 +1,24 @@
+CHANGES.txt
+CONTRIBUTORS.txt
+README.txt
+bootstrap.py
+buildout.cfg
+setup.cfg
+setup.py
+rcom/__init__.py
+rcom.recipe.seleniumenv.egg-info/PKG-INFO
+rcom.recipe.seleniumenv.egg-info/SOURCES.txt
+rcom.recipe.seleniumenv.egg-info/dependency_links.txt
+rcom.recipe.seleniumenv.egg-info/entry_points.txt
+rcom.recipe.seleniumenv.egg-info/namespace_packages.txt
+rcom.recipe.seleniumenv.egg-info/not-zip-safe
+rcom.recipe.seleniumenv.egg-info/requires.txt
+rcom.recipe.seleniumenv.egg-info/top_level.txt
+rcom/recipe/__init__.py
+rcom/recipe/seleniumenv/HTMLTestRunner.py
+rcom/recipe/seleniumenv/README.txt
+rcom/recipe/seleniumenv/__init__.py
+rcom/recipe/seleniumenv/defaults.cfg
+rcom/recipe/seleniumenv/seleniumRunnerBase.py
+rcom/recipe/seleniumenv/tests/__init__.py
+rcom/recipe/seleniumenv/tests/test_docs.py
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/dependency_links.txt
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/dependency_links.txt	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/dependency_links.txt	(revision 444)
@@ -0,0 +1,1 @@
+
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/entry_points.txt
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/entry_points.txt	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/entry_points.txt	(revision 444)
@@ -0,0 +1,3 @@
+[zc.buildout]
+default = rcom.recipe.seleniumenv:Recipe
+
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/namespace_packages.txt
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/namespace_packages.txt	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/namespace_packages.txt	(revision 444)
@@ -0,0 +1,2 @@
+rcom
+rcom.recipe
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/not-zip-safe
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/not-zip-safe	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/not-zip-safe	(revision 444)
@@ -0,0 +1,1 @@
+
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/requires.txt
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/requires.txt	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/requires.txt	(revision 444)
@@ -0,0 +1,8 @@
+setuptools
+zc.buildout
+hexagonit.recipe.download
+zc.recipe.egg
+
+[tests]
+zope.testing
+zc.buildout
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/top_level.txt
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/top_level.txt	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom.recipe.seleniumenv.egg-info/top_level.txt	(revision 444)
@@ -0,0 +1,1 @@
+rcom
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/__init__.py
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/__init__.py	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/__init__.py	(revision 444)
@@ -0,0 +1,6 @@
+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/__init__.py
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/__init__.py	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/__init__.py	(revision 444)
@@ -0,0 +1,6 @@
+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/HTMLTestRunner.py
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/HTMLTestRunner.py	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/HTMLTestRunner.py	(revision 444)
@@ -0,0 +1,774 @@
+"""
+A TestRunner for use with the Python unit testing framework. It
+generates a HTML report to show the result at a glance.
+
+The simplest way to use this is to invoke its main method. E.g.
+
+    import unittest
+    import HTMLTestRunner
+
+    ... define your tests ...
+
+    if __name__ == '__main__':
+        HTMLTestRunner.main()
+
+
+For more customization options, instantiates a HTMLTestRunner object.
+HTMLTestRunner is a counterpart to unittest's TextTestRunner. E.g.
+
+    # output to a file
+    fp = file('my_report.html', 'wb')
+    runner = HTMLTestRunner.HTMLTestRunner(
+                stream=fp,
+                title='My unit test',
+                description='This demonstrates the report output by HTMLTestRunner.'
+                )
+
+    # Use an external stylesheet.
+    # See the Template_mixin class for more customizable options
+    runner.STYLESHEET_TMPL = '<link rel="stylesheet" href="my_stylesheet.css" type="text/css">'
+
+    # run the test
+    runner.run(my_test_suite)
+
+
+------------------------------------------------------------------------
+Copyright (c) 2004-2006, Wai Yip Tung
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright notice,
+  this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in the
+  documentation and/or other materials provided with the distribution.
+* Neither the name Wai Yip Tung nor the names of its contributors may be
+  used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS 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 OWNER
+OR CONTRIBUTORS 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.
+"""
+
+# URL: http://tungwaiyip.info/software/HTMLTestRunner.html
+
+__author__ = "Wai Yip Tung"
+__version__ = "0.8.1"
+
+
+"""
+Changes in 0.8.1
+* Thank you for Wolfgang Borgert's patch.
+* Validated XHTML.
+* Added description of test classes and test cases.
+
+Changes in 0.8.0
+* Define Template_mixin class for customization.
+* Workaround a IE 6 bug that it does not treat <script> block as CDATA.
+
+Changes in 0.7.1
+* Back port to Python 2.3. Thank you Frank Horowitz.
+* Fix missing scroll bars in detail log. Thank you Podi.
+"""
+
+# TODO: color stderr
+# TODO: simplify javascript using ,ore than 1 class in the class attribute?
+
+import datetime
+import StringIO
+import sys
+import time
+import unittest
+from xml.sax import saxutils
+
+
+# ------------------------------------------------------------------------
+# The redirectors below is used to capture output during testing. Output
+# sent to sys.stdout and sys.stderr are automatically captured. However
+# in some cases sys.stdout is already cached before HTMLTestRunner is
+# invoked (e.g. calling logging.basicConfig). In order to capture those
+# output, use the redirectors for the cached stream.
+#
+# e.g.
+#   >>> logging.basicConfig(stream=HTMLTestRunner.stdout_redirector)
+#   >>>
+
+class OutputRedirector(object):
+    """ Wrapper to redirect stdout or stderr """
+    def __init__(self, fp):
+        self.fp = fp
+
+    def write(self, s):
+        self.fp.write(s)
+
+    def writelines(self, lines):
+        self.fp.writelines(lines)
+
+    def flush(self):
+        self.fp.flush()
+
+stdout_redirector = OutputRedirector(sys.stdout)
+stderr_redirector = OutputRedirector(sys.stderr)
+
+
+
+# ----------------------------------------------------------------------
+# Template
+
+class Template_mixin(object):
+    """
+    Define a HTML template for report customerization and generation.
+
+    Overall structure of an HTML report
+
+    HTML
+    +------------------------+
+    |<html>                  |
+    |  <head>                |
+    |                        |
+    |   STYLESHEET           |
+    |   +----------------+   |
+    |   |                |   |
+    |   +----------------+   |
+    |                        |
+    |  </head>               |
+    |                        |
+    |  <body>                |
+    |                        |
+    |   HEADING              |
+    |   +----------------+   |
+    |   |                |   |
+    |   +----------------+   |
+    |                        |
+    |   REPORT               |
+    |   +----------------+   |
+    |   |                |   |
+    |   +----------------+   |
+    |                        |
+    |   ENDING               |
+    |   +----------------+   |
+    |   |                |   |
+    |   +----------------+   |
+    |                        |
+    |  </body>               |
+    |</html>                 |
+    +------------------------+
+    """
+
+    STATUS = {
+    0: 'pass',
+    1: 'fail',
+    2: 'error',
+    }
+
+    DEFAULT_TITLE = 'Unit Test Report'
+    DEFAULT_DESCRIPTION = ''
+
+    # ------------------------------------------------------------------------
+    # HTML Template
+
+    HTML_TMPL = r"""<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+    <title>%(title)s</title>
+    <meta name="generator" content="%(generator)s"/>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+    %(stylesheet)s
+</head>
+<body>
+<script language="javascript" type="text/javascript"><!--
+output_list = Array();
+
+/* level - 0:Summary; 1:Failed; 2:All */
+function showCase(level) {
+    trs = document.getElementsByTagName("tr");
+    for (var i = 0; i < trs.length; i++) {
+        tr = trs[i];
+        id = tr.id;
+        if (id.substr(0,2) == 'ft') {
+            if (level < 1) {
+                tr.className = 'hiddenRow';
+            }
+            else {
+                tr.className = '';
+            }
+        }
+        if (id.substr(0,2) == 'pt') {
+            if (level > 1) {
+                tr.className = '';
+            }
+            else {
+                tr.className = 'hiddenRow';
+            }
+        }
+    }
+}
+
+function showClassDetail(cid, count) {
+    var id_list = Array(count);
+    var toHide = 1;
+    for (var i = 0; i < count; i++) {
+        tid0 = 't' + cid.substr(1) + '.' + (i+1);
+        tid = 'f' + tid0;
+        tr = document.getElementById(tid);
+        if (!tr) {
+            tid = 'p' + tid0;
+            tr = document.getElementById(tid);
+        }
+        id_list[i] = tid;
+        if (tr.className) {
+            toHide = 0;
+        }
+    }
+    for (var i = 0; i < count; i++) {
+        tid = id_list[i];
+        if (toHide) {
+            document.getElementById(tid).className = 'hiddenRow';
+        }
+        else {
+            document.getElementById(tid).className = '';
+        }
+    }
+}
+
+function html_escape(s) {
+    s = s.replace(/&/g,'&amp;');
+    s = s.replace(/</g,'&lt;');
+    s = s.replace(/>/g,'&gt;');
+    return s;
+}
+
+function showOutput(id, name) {
+    var w = window.open("", //url
+                    name,
+                    "resizable,scrollbars,status,width=800,height=450");
+    d = w.document;
+    d.write("<pre>");
+    d.write(html_escape(output_list[id]));
+    d.write("\n");
+    d.write("<a href='javascript:window.close()'>close</a>\n");
+    d.write("</pre>\n");
+    d.close();
+}
+--></script>
+
+%(heading)s
+%(report)s
+%(ending)s
+
+</body>
+</html>
+"""
+    # variables: (title, generator, stylesheet, heading, report, ending)
+
+
+    # ------------------------------------------------------------------------
+    # Stylesheet
+    #
+    # alternatively use a <link> for external style sheet, e.g.
+    #   <link rel="stylesheet" href="$url" type="text/css">
+
+    STYLESHEET_TMPL = """
+<style type="text/css" media="screen">
+body        { font-family: verdana, arial, helvetica, sans-serif; font-size: 80%; }
+table       { font-size: 100%; }
+pre         { }
+
+/* -- heading ---------------------------------------------------------------------- */
+h1 {
+}
+.heading {
+    margin-top: 0ex;
+    margin-bottom: 1ex;
+}
+
+.heading .attribute {
+    margin-top: 1ex;
+    margin-bottom: 0;
+}
+
+.heading .description {
+    margin-top: 4ex;
+    margin-bottom: 6ex;
+}
+
+/* -- report ------------------------------------------------------------------------ */
+#show_detail_line {
+    margin-top: 3ex;
+    margin-bottom: 1ex;
+}
+#result_table {
+    width: 80%;
+    border-collapse: collapse;
+    border: medium solid #777;
+}
+#header_row {
+    font-weight: bold;
+    color: white;
+    background-color: #777;
+}
+#result_table td {
+    border: thin solid #777;
+    padding: 2px;
+}
+#total_row  { font-weight: bold; }
+.passClass  { background-color: #6c6; }
+.failClass  { background-color: #c60; }
+.errorClass { background-color: #c00; }
+.passCase   { color: #6c6; }
+.failCase   { color: #c60; font-weight: bold; }
+.errorCase  { color: #c00; font-weight: bold; }
+.hiddenRow  { display: none; }
+.testcase   { margin-left: 2em; }
+
+
+/* -- ending ---------------------------------------------------------------------- */
+#ending {
+}
+
+</style>
+"""
+
+
+
+    # ------------------------------------------------------------------------
+    # Heading
+    #
+
+    HEADING_TMPL = """<div class='heading'>
+<h1>%(title)s</h1>
+%(parameters)s
+<p class='description'>%(description)s</p>
+</div>
+
+""" # variables: (title, parameters, description)
+
+    HEADING_ATTRIBUTE_TMPL = """<p class='attribute'><strong>%(name)s:</strong> %(value)s</p>
+""" # variables: (name, value)
+
+
+
+    # ------------------------------------------------------------------------
+    # Report
+    #
+
+    REPORT_TMPL = """
+<p id='show_detail_line'>Show
+<a href='javascript:showCase(0)'>Summary</a>
+<a href='javascript:showCase(1)'>Failed</a>
+<a href='javascript:showCase(2)'>All</a>
+</p>
+<table id='result_table'>
+<colgroup>
+<col align='left' />
+<col align='right' />
+<col align='right' />
+<col align='right' />
+<col align='right' />
+<col align='right' />
+</colgroup>
+<tr id='header_row'>
+    <td>Test Group/Test case</td>
+    <td>Count</td>
+    <td>Pass</td>
+    <td>Fail</td>
+    <td>Error</td>
+    <td>View</td>
+</tr>
+%(test_list)s
+<tr id='total_row'>
+    <td>Total</td>
+    <td>%(count)s</td>
+    <td>%(Pass)s</td>
+    <td>%(fail)s</td>
+    <td>%(error)s</td>
+    <td>&nbsp;</td>
+</tr>
+</table>
+""" # variables: (test_list, count, Pass, fail, error)
+
+    REPORT_CLASS_TMPL = r"""
+<tr class='%(style)s'>
+    <td>%(desc)s</td>
+    <td>%(count)s</td>
+    <td>%(Pass)s</td>
+    <td>%(fail)s</td>
+    <td>%(error)s</td>
+    <td><a href="javascript:showClassDetail('%(cid)s',%(count)s)">Detail</a></td>
+</tr>
+""" # variables: (style, desc, count, Pass, fail, error, cid)
+
+
+    REPORT_TEST_WITH_OUTPUT_TMPL = r"""
+<tr id='%(tid)s' class='%(Class)s'>
+    <td class='%(style)s'><div class='testcase'>%(desc)s</div></td>
+    <td colspan='5' align='center'><a href="javascript:showOutput('%(tid)s', '%(desc)s')">%(status)s</a>%(script)s</td>
+</tr>
+""" # variables: (tid, Class, style, desc, status)
+
+
+    REPORT_TEST_NO_OUTPUT_TMPL = r"""
+<tr id='%(tid)s' class='%(Class)s'>
+    <td class='%(style)s'><div class='testcase'>%(desc)s</div></td>
+    <td colspan='5' align='center'>%(status)s</td>
+</tr>
+""" # variables: (tid, Class, style, desc, status)
+
+
+    REPORT_TEST_OUTPUT_TMPL = r"""
+<script language="javascript" type="text/javascript">output_list['%(id)s'] = '%(output)s';</script>
+""" # variables: (id, output)
+
+
+
+    # ------------------------------------------------------------------------
+    # ENDING
+    #
+
+    ENDING_TMPL = """<div id='ending'>&nbsp;</div>"""
+
+# -------------------- The end of the Template class -------------------
+
+
+
+def jsEscapeString(s):
+    """ Escape s for use as a Javascript String """
+    return s.replace('\\','\\\\') \
+        .replace('\r', '\\r') \
+        .replace('\n', '\\n') \
+        .replace('"', '\\"') \
+        .replace("'", "\\'") \
+        .replace("&", '\\x26') \
+        .replace("<", '\\x3C') \
+        .replace(">", '\\x3E')
+    # Note: non-ascii unicode characters do not need to be encoded
+    # Note: previously we encode < as &lt;, etc. However IE6 fail to treat <script> block as CDATA.
+
+
+TestResult = unittest.TestResult
+
+class _TestResult(TestResult):
+    # note: _TestResult is a pure representation of results.
+    # It lacks the output and reporting ability compares to unittest._TextTestResult.
+
+    def __init__(self, verbosity=1):
+        TestResult.__init__(self)
+        self.stdout0 = None
+        self.stderr0 = None
+        self.success_count = 0
+        self.failure_count = 0
+        self.error_count = 0
+        self.verbosity = verbosity
+
+        # result is a list of result in 4 tuple
+        # (
+        #   result code (0: success; 1: fail; 2: error),
+        #   TestCase object,
+        #   Test output (byte string),
+        #   stack trace,
+        # )
+        self.result = []
+
+
+    def startTest(self, test):
+        TestResult.startTest(self, test)
+        # just one buffer for both stdout and stderr
+        self.outputBuffer = StringIO.StringIO()
+        stdout_redirector.fp = self.outputBuffer
+        stderr_redirector.fp = self.outputBuffer
+        self.stdout0 = sys.stdout
+        self.stderr0 = sys.stderr
+        sys.stdout = stdout_redirector
+        sys.stderr = stderr_redirector
+
+
+    def complete_output(self):
+        """
+        Disconnect output redirection and return buffer.
+        Safe to call multiple times.
+        """
+        if self.stdout0:
+            sys.stdout = self.stdout0
+            sys.stderr = self.stderr0
+            self.stdout0 = None
+            self.stderr0 = None
+        return self.outputBuffer.getvalue()
+
+
+    def stopTest(self, test):
+        # Usually one of addSuccess, addError or addFailure would have been called.
+        # But there are some path in unittest that would bypass this.
+        # We must disconnect stdout in stopTest(), which is guaranteed to be called.
+        self.complete_output()
+
+
+    def addSuccess(self, test):
+        self.success_count += 1
+        TestResult.addSuccess(self, test)
+        output = self.complete_output()
+        self.result.append((0, test, output, ''))
+        if self.verbosity > 1:
+            sys.stderr.write('ok ')
+            sys.stderr.write(str(test))
+            sys.stderr.write('\n')
+        else:
+            sys.stderr.write('.')
+
+    def addError(self, test, err):
+        self.error_count += 1
+        TestResult.addError(self, test, err)
+        _, _exc_str = self.errors[-1]
+        output = self.complete_output()
+        self.result.append((2, test, output, _exc_str))
+        if self.verbosity > 1:
+            sys.stderr.write('E  ')
+            sys.stderr.write(str(test))
+            sys.stderr.write('\n')
+        else:
+            sys.stderr.write('E')
+
+    def addFailure(self, test, err):
+        self.failure_count += 1
+        TestResult.addFailure(self, test, err)
+        _, _exc_str = self.failures[-1]
+        output = self.complete_output()
+        self.result.append((1, test, output, _exc_str))
+        if self.verbosity > 1:
+            sys.stderr.write('F  ')
+            sys.stderr.write(str(test))
+            sys.stderr.write('\n')
+        else:
+            sys.stderr.write('F')
+
+
+class HTMLTestRunner(Template_mixin):
+    """
+    """
+    def __init__(self, stream=sys.stdout, verbosity=1, title=None, description=None):
+        self.stream = stream
+        self.verbosity = verbosity
+        if title is None:
+            self.title = self.DEFAULT_TITLE
+        else:
+            self.title = title
+        if description is None:
+            self.description = self.DEFAULT_DESCRIPTION
+        else:
+            self.description = description
+
+        self.startTime = datetime.datetime.now()
+
+
+    def run(self, test):
+        "Run the given test case or test suite."
+        result = _TestResult(self.verbosity)
+        test(result)
+        self.stopTime = datetime.datetime.now()
+        self.generateReport(test, result)
+        print >>sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime)
+        return result
+
+
+    def sortResult(self, result_list):
+        # unittest does not seems to run in any particular order.
+        # Here at least we want to group them together by class.
+        rmap = {}
+        classes = []
+        for n,t,o,e in result_list:
+            cls = t.__class__
+            if not rmap.has_key(cls):
+                rmap[cls] = []
+                classes.append(cls)
+            rmap[cls].append((n,t,o,e))
+        r = [(cls, rmap[cls]) for cls in classes]
+        return r
+
+
+    def getReportAttributes(self, result):
+        """
+        Return report attributes as a list of (name, value).
+        Override this to add custom attributes.
+        """
+        startTime = str(self.startTime)[:19]
+        duration = str(self.stopTime - self.startTime)
+        status = []
+        if result.success_count: status.append('Pass %s'    % result.success_count)
+        if result.failure_count: status.append('Failure %s' % result.failure_count)
+        if result.error_count:   status.append('Error %s'   % result.error_count  )
+        if status:
+            status = ' '.join(status)
+        else:
+            status = 'none'
+        return [
+            ('Start Time', startTime),
+            ('Duration', duration),
+            ('Status', status),
+        ]
+
+
+    def generateReport(self, test, result):
+        report_attrs = self.getReportAttributes(result)
+        generator = 'HTMLTestRunner %s' % __version__
+        stylesheet = self._generate_stylesheet()
+        heading = self._generate_heading(report_attrs)
+        report = self._generate_report(result)
+        ending = self._generate_ending()
+        output = self.HTML_TMPL % dict(
+            title = saxutils.escape(self.title),
+            generator = generator,
+            stylesheet = stylesheet,
+            heading = heading,
+            report = report,
+            ending = ending,
+        )
+        self.stream.write(output.encode('utf8'))
+
+
+    def _generate_stylesheet(self):
+        return self.STYLESHEET_TMPL
+
+
+    def _generate_heading(self, report_attrs):
+        a_lines = []
+        for name, value in report_attrs:
+            line = self.HEADING_ATTRIBUTE_TMPL % dict(
+                    name = saxutils.escape(name),
+                    value = saxutils.escape(value),
+                )
+            a_lines.append(line)
+        heading = self.HEADING_TMPL % dict(
+            title = saxutils.escape(self.title),
+            parameters = ''.join(a_lines),
+            description = saxutils.escape(self.description),
+        )
+        return heading
+
+
+    def _generate_report(self, result):
+        rows = []
+        sortedResult = self.sortResult(result.result)
+        for cid, (cls, cls_results) in enumerate(sortedResult):
+            # subtotal for a class
+            np = nf = ne = 0
+            for n,t,o,e in cls_results:
+                if n == 0: np += 1
+                elif n == 1: nf += 1
+                else: ne += 1
+
+            # format class description
+            if cls.__module__ == "__main__":
+                name = cls.__name__
+            else:
+                name = "%s.%s" % (cls.__module__, cls.__name__)
+            doc = cls.__doc__ and cls.__doc__.split("\n")[0] or ""
+            desc = doc and '%s: %s' % (name, doc) or name
+
+            row = self.REPORT_CLASS_TMPL % dict(
+                style = ne > 0 and 'errorClass' or nf > 0 and 'failClass' or 'passClass',
+                desc = desc,
+                count = np+nf+ne,
+                Pass = np,
+                fail = nf,
+                error = ne,
+                cid = 'c%s' % (cid+1),
+            )
+            rows.append(row)
+
+            for tid, (n,t,o,e) in enumerate(cls_results):
+                self._generate_report_test(rows, cid, tid, n, t, o, e)
+
+        report = self.REPORT_TMPL % dict(
+            test_list = ''.join(rows),
+            count = str(result.success_count+result.failure_count+result.error_count),
+            Pass = str(result.success_count),
+            fail = str(result.failure_count),
+            error = str(result.error_count),
+        )
+        return report
+
+
+    def _generate_report_test(self, rows, cid, tid, n, t, o, e):
+        # e.g. 'pt1.1', 'ft1.1', etc
+        has_output = bool(o or e)
+        tid = (n == 0 and 'p' or 'f') + 't%s.%s' % (cid+1,tid+1)
+        name = t.id().split('.')[-1]
+        doc = t.shortDescription() or ""
+        desc = doc and ('%s: %s' % (name, doc)) or name
+        tmpl = has_output and self.REPORT_TEST_WITH_OUTPUT_TMPL or self.REPORT_TEST_NO_OUTPUT_TMPL
+
+        # o and e should be byte string because they are collected from stdout and stderr?
+        if isinstance(o,str):
+            # TODO: some problem with 'string_escape': it escape \n and mess up formating
+            # uo = unicode(o.encode('string_escape'))
+            uo = o.decode('latin-1')
+        else:
+            uo = o
+        if isinstance(e,str):
+            # TODO: some problem with 'string_escape': it escape \n and mess up formating
+            # ue = unicode(e.encode('string_escape'))
+            ue = e.decode('latin-1')
+        else:
+            ue = e
+
+        script = self.REPORT_TEST_OUTPUT_TMPL % dict(
+            id = tid,
+            output = jsEscapeString(uo+ue),
+        )
+
+        row = tmpl % dict(
+            tid = tid,
+            Class = (n == 0 and 'hiddenRow' or 'none'),
+            style = n == 2 and 'errorCase' or (n == 1 and 'failCase' or 'none'),
+            desc = desc,
+            script = script,
+            status = self.STATUS[n],
+        )
+        rows.append(row)
+        if not has_output:
+            return
+
+    def _generate_ending(self):
+        return self.ENDING_TMPL
+
+
+##############################################################################
+# Facilities for running tests from the command line
+##############################################################################
+
+# Note: Reuse unittest.TestProgram to launch test. In the future we may
+# build our own launcher to support more specific command line
+# parameters like test title, CSS, etc.
+class TestProgram(unittest.TestProgram):
+    """
+    A variation of the unittest.TestProgram. Please refer to the base
+    class for command line parameters.
+    """
+    def runTests(self):
+        # Pick HTMLTestRunner as the default test runner.
+        # base class's testRunner parameter is not useful because it means
+        # we have to instantiate HTMLTestRunner before we know self.verbosity.
+        if self.testRunner is None:
+            self.testRunner = HTMLTestRunner(verbosity=self.verbosity)
+        unittest.TestProgram.runTests(self)
+
+main = TestProgram
+
+##############################################################################
+# Executing this module from the command line
+##############################################################################
+
+if __name__ == "__main__":
+    main(module=None)
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/README.txt
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/README.txt	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/README.txt	(revision 444)
@@ -0,0 +1,145 @@
+Supported options
+=================
+
+The recipe supports the following options:
+
+seleniumversion
+    The version of selenium to use, the version numbers can be taken from
+    http://release.seleniumhq.org/selenium-remote-control/. Default: nightlyBuild.
+
+eggs
+    The eggs to include in the runner path. Any product included in the path will be
+    accesible for the runner to search and run selenium tests from.
+
+java-cmd
+    The commando used to run the selenium server. Default: java.
+
+Example usage
+=============
+
+The basic buildout that uses the recipe should look like the following::
+
+    >>> write('buildout.cfg',
+    ... """
+    ... [buildout]
+    ... parts = seleniumenv
+    ...
+    ... [seleniumenv]
+    ... recipe = rcom.recipe.seleniumenv
+    ... seleniumversion = 1.0-beta-2
+    ... eggs = ${instance:eggs}
+
+
+The seleniumrunner script
+=========================
+
+The selenium runner is a scipt to find and run **selenium tests**, it will
+be on your bin directory once the recipe is instanlled
+It receives different parameters and it's main objective is to simplify the
+tests execution and reporting procedure.
+This script will wake-up the selenium RC server, search and run the tests
+and then shutdown the server and report the tests result.
+Once the recipe has been installed, a tests runner should be placed on the bin directory
+
+Running the tests
+-----------------
+
+To run the suite of tests buldled with any product, the first thing to do after
+the buildout has been run is to prepare a Plone site to test (if the user doesn't
+have a Plone site to test, yet).
+For this to be done, you must first wake up the instance::
+
+    ./bin/instance start
+
+To run all the selenium tests for a product the user should pass at least two
+parameters:
+
+-i instance
+        The Plone site's name.
+
+-s product
+        The product in which the runner will search for tests to run.
+
+An example test execution will be::
+
+        $ ./bin/seleniumrunner -i testPloneSite -s namespace.product
+
+This will search all the **selenium** tests for the product and run them
+on http://localhost:<port_used>/testPloneSite.
+
+For running  a particular test, the -t parameter should be passed to the runner::
+
+        $ ./bin/seleniumrunner -i testPloneSite -s namespace.product -t exampleTest
+
+.. Note::
+
+    Please notice that the exampleTest.py test should be stored in the
+    respective location and added to the __init__py file (See `Creating a test`_)
+
+Creating a test
+---------------
+
+The seleniumrunner script will look for all the classes that inherit from
+unittest.TestCase on a specified package or module located under this kind of
+path::
+
+        namespace.product/namespace/product/tests/seleniumtests
+
+Tests development guidelines
+++++++++++++++++++++++++++++
+
+To create a test, there are certain basic rules to follow:
+
+#) The test should inherit from unittest.TestCase class (this can be done
+   indirectly also).
+#) The test should use certain global variables for the code to work
+   on different environments and Plone instances. These are:
+
+        - browser: For the browser used for the tests
+
+        - port: For the port used to communicate with the server
+
+        - url: For the url of the application under test
+
+        - instance: The Plone site name (this depends on
+          the name used for the site's creation).
+
+This variables should never be changed inside the test code, as the
+seleniumrunner script will set them at runtime according with the parameters
+received.
+
+All this rules can be seen applied to the following `Example test`_.
+
+Example test
+++++++++++++
+
+The following is an example test, it can be used as the basic
+structure for future tests::
+
+        from selenium import selenium
+        import unittest
+
+        class NewTest(unittest.TestCase):
+            def setUp(self):
+                self.verificationErrors = []
+                self.selenium = selenium("localhost", port, browser, url)
+                self.selenium.start()
+            
+            def test_new(self):
+                sel = self.selenium
+				sel.open(instance + "/login.html")
+                # Do specific tests in here
+
+            def tearDown(self):
+                self.selenium.stop()
+                self.assertEqual([], self.verificationErrors)
+
+Notice that the test doesn't have much changes from the basic test exported using
+`Selenium IDE <http://seleniumhq.org/projects/ide/>`_, the firefox extension. The 
+only difference are the variables used for the instanciation inside the *setUp* method.
+
+.. Note::
+
+    Please notice that the "instance" variable will have to be used in
+    each *open* command for the users to provide the correct location
+    of the eduCommons plone site to test.
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/__init__.py
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/__init__.py	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/__init__.py	(revision 444)
@@ -0,0 +1,63 @@
+import os, shutil, glob
+import pkg_resources
+import ConfigParser
+import hexagonit.recipe.download
+import zc.recipe.egg
+import stat
+
+class Recipe:
+    def __init__(self, buildout, name, options):
+        self.buildout = buildout
+        self.options = options
+        self.name = name
+        # this copies configuration set in defaults.cfg to our options namespace
+        config_file = pkg_resources.resource_stream(__name__, "defaults.cfg")
+        config = ConfigParser.ConfigParser()
+        config.readfp(config_file)
+        #Default options parsing
+        for key, value in config.items("seleniumenv"):
+            options.setdefault(key, value)
+        #Selenium url parsing
+        if options['seleniumversion'] == "nightlyBuild":
+            selurl = 'http://release.openqa.org/cgi-bin/selenium-remote-control-redirect.zip'
+        else:
+            selurl = 'http://release.seleniumhq.org/selenium-remote-control/%s/selenium-remote-control-%s-dist.zip' % (options['seleniumversion'],options['seleniumversion'])
+            self.selopt = {'url':selurl,
+                       'destination':os.path.join(buildout['buildout']['parts-directory'],"seleniumrc"),
+                        'strip-top-level-dir':'true',
+                        'ignore-existing':'true'
+                      } 
+
+    def install_runner(self):
+        #Setting the locations that the runner will use
+        self.options['executablepath'] = self.buildout['buildout']['executable']
+        reqs, ws = zc.recipe.egg.Eggs(self.buildout, self.name, self.options).working_set()
+        self.options['importpath']= "',\n\t\t'".join(ws.entries)
+        self.options['clientpath'] = glob.glob(os.path.join(self.buildout['buildout']['parts-directory'], "seleniumrc","selenium-python-client*"))[0]
+        self.options['sellocation'] = glob.glob( os.path.join(
+                                                            self.buildout['buildout']['parts-directory'],
+                                                            "seleniumrc",
+                                                            "selenium-server*"))[0]
+        self.options['http-address'] = self.buildout['instance']['http-address']
+        # And now passing the path to the bin directory
+        runner_path = os.path.join(self.buildout["buildout"]["bin-directory"], "seleniumRunner")
+        open(runner_path, "w").write(pkg_resources.resource_string(__name__, "seleniumRunnerBase.py") % self.options)
+        os.chmod(runner_path, (os.stat(runner_path).st_mode |
+                            stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH))
+        # Moving the HTMLTestRunner to the client's folder doesn't seem like the best
+        # to do, but I can't find a good place to put it to be able to import later
+        shutil.copy(
+                pkg_resources.resource_filename(__name__, "HTMLTestRunner.py"),
+                self.options['clientpath'])
+
+
+    def install(self):
+        # We download all the parts
+        parts = hexagonit.recipe.download.Recipe(self.buildout, "seleniumrc",
+                                                 self.selopt).install()
+        # Installs the script to launch selenium server
+        self.install_runner()
+        return parts
+        
+    def update(self):
+       pass 
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/defaults.cfg
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/defaults.cfg	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/defaults.cfg	(revision 444)
@@ -0,0 +1,4 @@
+## These are default values for packages downloading
+[seleniumenv]
+seleniumversion=nightlyBuild
+java-cmd=java
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/seleniumRunnerBase.py
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/seleniumRunnerBase.py	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/seleniumRunnerBase.py	(revision 444)
@@ -0,0 +1,105 @@
+#!%(executablepath)s
+
+import subprocess
+import unittest
+import platform
+import time
+import sys
+import os
+import signal
+from urllib import urlopen
+from optparse import OptionParser
+
+parser = OptionParser()
+parser.add_option("-s", "--product", dest="product", help="The product to search and run selenium tests. This is defaulted to enpraxis.educommons.") 
+parser.add_option("-t", "--test", dest="test", help="The particular test to run. All the test will be run if -t is not present.")
+parser.add_option("-i", "--instance", dest="instance", help="The Plone site's name. This is used for the url to test.")
+parser.add_option("-o", "--output", dest="html_file", help="The runner can generate an html summary of the execution.")
+parser.add_option("-p", "--port", dest="port", default=4444, type="int", help="The port in which wake up the server. Default: 4444.")
+parser.add_option("-b", "--browser", dest="browser", default="*firefox", help="The browser to use for the tests that are browser independent. Note: Some tests might still run on a different browser if they have been writen to do that. Defaults to *firefox")
+parser.add_option("-f", action="store_true", dest="forcedbrowser", help="Add the -f tag to force all the tests to use the browser desired.")
+parser.add_option("-v", action="store_true", dest="verbose", help="Verbose will print on stdout all the output from the selenium RC server.")
+
+(options, args) = parser.parse_args()
+
+# The test will be required until I find a way to get all the paths to add 
+# and be able to import all the products
+if not options.product:
+    parser.error("The product is a required parameter")
+if not options.instance:
+    parser.error("The instance's name is a required parameter")
+
+# Here we add "all" the products to the path
+# TODO: add ALL the installed products to the sys.path, to be able to find test in all of them
+product_list = [
+            '%(importpath)s']
+
+for product in product_list:
+    if options.product in product:
+        product = os.path.join(product,options.product.replace(".", os.sep),"tests")
+        break
+
+sys.path[0:0] = [
+                product,
+                '%(clientpath)s']
+
+# We set the parameters to pass to the server and launch it
+params = " -singleWindow"
+if options.verbose:
+    verbose = None
+else:
+    verbose = open(os.devnull,"w")
+if options.port:
+    params += " -port " + str(options.port)
+if options.forcedbrowser:
+    params += " -forcedBrowserModeRestOfLine " + options.browser
+server = subprocess.Popen("%(java-cmd)s -jar %(sellocation)s/selenium-server.jar" + params, shell=True, stdout=verbose)
+time.sleep(5)
+
+# Now we import the tests and set the required variables to locate the instance and selenium server
+package = __import__("seleniumtests")
+suite = unittest.TestSuite()
+if not options.test:
+    test_modules = [module_name for module_name in dir(package) if not module_name.startswith("_")]
+else:
+    test_modules = [options.test,]
+
+for module_name in test_modules:
+    try:
+        module = sys.modules["seleniumtests." + module_name]
+    except KeyError, e:
+        print "Couldn't find the tests script: ", e
+        continue
+    module.port = options.port
+    module.browser = options.browser
+    module.url = "http://localhost:%(http-address)s/"
+    module.instance = options.instance
+    #We add the tests to the suite
+    suite.addTests(unittest.defaultTestLoader.loadTestsFromModule(module))
+
+# And we run the tests
+if options.html_file:
+    import HTMLTestRunner
+    fp = file(options.html_file, 'wb')
+    runner = HTMLTestRunner.HTMLTestRunner(
+                stream=fp,
+                title='Selenium tests execution summary',
+                description='Product tested: ' + options.product
+                )
+    runner.run(suite)
+else:
+    unittest.TextTestRunner(verbosity=2).run(suite)
+
+# And we kill the server
+print "\nKilling Selenium Server"
+print urlopen("http://localhost:"+str(options.port)+"/selenium-server/driver/?cmd=shutDown").read()
+if (platform.system() == 'Windows'):
+    import win32api
+    handle = win32api.OpenProcess(1, 0, server.pid)
+    win32api.TerminateProcess(handle, 0)
+else:
+    os.kill(server.pid,signal.SIGTERM)
+
+try: verbose.close()
+except AttributeError, e:pass
+
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/tests/__init__.py
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/tests/__init__.py	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/tests/__init__.py	(revision 444)
@@ -0,0 +1,1 @@
+# package
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/tests/test_docs.py
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/tests/test_docs.py	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/rcom/recipe/seleniumenv/tests/test_docs.py	(revision 444)
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+"""
+Doctest runner for 'rcom.recipe.seleniumenv'.
+"""
+__docformat__ = 'restructuredtext'
+
+import unittest
+import zc.buildout.tests
+import zc.buildout.testing
+
+from zope.testing import doctest, renormalizing
+
+optionflags =  (doctest.ELLIPSIS |
+                doctest.NORMALIZE_WHITESPACE |
+                doctest.REPORT_ONLY_FIRST_FAILURE)
+
+def setUp(test):
+    zc.buildout.testing.buildoutSetUp(test)
+
+    # Install the recipe in develop mode
+    zc.buildout.testing.install_develop('rcom.recipe.seleniumenv', test)
+
+    # Install any other recipes that should be available in the tests
+    #zc.buildout.testing.install('collective.recipe.foobar', test)
+
+def test_suite():
+    suite = unittest.TestSuite((
+            doctest.DocFileSuite(
+                '../README.txt',
+                setUp=setUp,
+                tearDown=zc.buildout.testing.buildoutTearDown,
+                optionflags=optionflags,
+                checker=renormalizing.RENormalizing([
+                        # If want to clean up the doctest output you
+                        # can register additional regexp normalizers
+                        # here. The format is a two-tuple with the RE
+                        # as the first item and the replacement as the
+                        # second item, e.g.
+                        # (re.compile('my-[rR]eg[eE]ps'), 'my-regexps')
+                        zc.buildout.testing.normalize_path,
+                        ]),
+                ),
+            ))
+    return suite
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/setup.cfg
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/setup.cfg	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/setup.cfg	(revision 444)
@@ -0,0 +1,3 @@
+[egg_info]
+tag_build = dev
+tag_svn_revision = true
Index: /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/setup.py
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/setup.py	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/src/rcom.recipe.seleniumenv/setup.py	(revision 444)
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+"""
+This module contains the tool of rcom.recipe.seleniumenv
+"""
+import os
+from setuptools import setup, find_packages
+
+def read(*rnames):
+    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+version = '1.0'
+
+long_description = (
+    read('README.txt')
+    + '\n' +
+    'Detailed Documentation\n'
+    '**********************\n'
+    + '\n' +
+    read('rcom', 'recipe', 'seleniumenv', 'README.txt')
+    + '\n' +
+    'Contributors\n' 
+    '************\n'
+    + '\n' +
+    read('CONTRIBUTORS.txt')
+    + '\n' +
+    'Change history\n'
+    '**************\n'
+    + '\n' + 
+    read('CHANGES.txt')
+    + '\n' +
+   'Download\n'
+    '********\n'
+    )
+entry_point = 'rcom.recipe.seleniumenv:Recipe'
+entry_points = {"zc.buildout": ["default = %s" % entry_point]}
+
+tests_require=['zope.testing', 'zc.buildout']
+
+setup(name='rcom.recipe.seleniumenv',
+      version=version,
+      description="A recipe for setting a ready-to-use selenium RC environment",
+      long_description=long_description,
+      classifiers=[
+        'Framework :: Buildout',
+        'Intended Audience :: Developers',
+        'Topic :: Software Development :: Build Tools',
+        'Topic :: Software Development :: Libraries :: Python Modules',
+        'License :: OSI Approved :: Zope Public License',
+        ],
+      keywords='selenium rc testing plone ajax recipe',
+      author='Santiago Suarez Ordonez',
+      author_email='santiycr@rcom.com.ar',
+      url='www.rcom.com.ar',
+      license='ZPL',
+      packages=find_packages(exclude=['ez_setup']),
+      namespace_packages=['rcom', 'rcom.recipe'],
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'zc.buildout',
+                        'hexagonit.recipe.download',
+                        'zc.recipe.egg'
+                        ],
+      tests_require=tests_require,
+      extras_require=dict(tests=tests_require),
+      test_suite = 'rcom.recipe.seleniumenv.tests.test_docs.test_suite',
+      entry_points=entry_points,
+      )
Index: /eduCommons.buildout/tags/3.2.1-rc1/tests.cfg
===================================================================
--- /eduCommons.buildout/tags/3.2.1-rc1/tests.cfg	(revision 444)
+++ /eduCommons.buildout/tags/3.2.1-rc1/tests.cfg	(revision 444)
@@ -0,0 +1,50 @@
+[buildout]
+extends =
+    buildout.cfg
+
+parts +=
+    seleniumenv
+#    plonesite
+
+find-links +=
+    http://dist.plone.org
+    http://download.zope.org/ppix/
+    http://download.zope.org/distribution/
+    http://effbot.org/downloads
+
+# Add additional eggs here
+# elementtree is required by Plone
+eggs +=
+    collective.contentgenerator
+    
+#zcml +=
+#   collective.contentgenerator
+
+# Reference any eggs you are developing here, one per line
+# e.g.: develop = src/my.package
+develop +=
+    src/rcom.recipe.seleniumenv
+
+[seleniumenv]
+recipe = rcom.recipe.seleniumenv
+browsers = none
+seleniumversion = 1.0-beta-2
+eggs = ${instance:eggs}
+
+#[instance]
+#recipe = plone.recipe.zope2instance
+#file-storage = filestorage/test.fs
+
+#[plonesite]
+#recipe = collective.recipe.plonesite
+#site-id = educommons
+#instance = instance
+#products= 
+#	eduCommons
+#profiles-initial = collective.contentgenerator:intranet
+#profiles =
+#    my.package:default
+#    my.other.package:default
+#post-extras =
+#    ${buildout:directory}/my_script.py
+#    ${buildout:directory}/my_other_script.py
