[KSS-checkins] r49297 - in kukit/kss.demo/branch/kss-zope-transition/kss/demo: . browser selenium_utils tests
reebalazs at codespeak.net
reebalazs at codespeak.net
Sun Dec 2 21:04:48 CET 2007
Author: reebalazs
Date: Sun Dec 2 21:04:47 2007
New Revision: 49297
Added:
kukit/kss.demo/branch/kss-zope-transition/kss/demo/selenium_utils/builder.py
Removed:
kukit/kss.demo/branch/kss-zope-transition/kss/demo/events.py
kukit/kss.demo/branch/kss-zope-transition/kss/demo/kss.demo-meta.zcml
kukit/kss.demo/branch/kss-zope-transition/kss/demo/meta.zcml
kukit/kss.demo/branch/kss-zope-transition/kss/demo/registry.py
Modified:
kukit/kss.demo/branch/kss-zope-transition/kss/demo/browser/registry.py
kukit/kss.demo/branch/kss-zope-transition/kss/demo/configure.zcml
kukit/kss.demo/branch/kss-zope-transition/kss/demo/interfaces.py
kukit/kss.demo/branch/kss-zope-transition/kss/demo/tests/test_demoview.py
Log:
Register demos from plugins
Modified: kukit/kss.demo/branch/kss-zope-transition/kss/demo/browser/registry.py
==============================================================================
--- kukit/kss.demo/branch/kss-zope-transition/kss/demo/browser/registry.py (original)
+++ kukit/kss.demo/branch/kss-zope-transition/kss/demo/browser/registry.py Sun Dec 2 21:04:47 2007
@@ -1,9 +1,10 @@
-from kss.demo.interfaces import IKSSDemoRegistry
+from kss.zope.interfaces import IKSSPluginRegistry
from zope.publisher.interfaces.browser import IBrowserPublisher
from zope.publisher.interfaces import NotFound
from zope.component import getUtility
from zope.interface import implements
+from kss.demo.selenium_utils.builder import getSeleniumTestsFromSuite, cookSeleniumTests
try:
from Products.Five import BrowserView
BrowserView # make pyflakes happy
@@ -14,8 +15,8 @@
def getSortedDemos(self):
"""Get demos"""
- registry = getUtility(IKSSDemoRegistry)
- return registry.getSortedDemos()
+ registry = getUtility(IKSSPluginRegistry)
+ return registry.zope_demos()
def getDemoGroups(self):
"""Get demos groupped by plugin_namespace, category"""
@@ -89,6 +90,13 @@
into the file seltest_all.pty in the directory
of kss.demo.selenium_utils .
"""
- registry = getUtility(IKSSDemoRegistry)
- registry.cookSeleniumTests()
- return "Selenium tests cooked OK. (%i)" % (len(registry.selenium_tests), )
+ registry = getUtility(IKSSPluginRegistry)
+ suites = registry.zope_selenium_testsuites()
+ # Extract filenames from all suites
+ filenames = []
+ for owner_instance, suite in suites:
+ filenames.extend(getSeleniumTestsFromSuite(owner_instance, suite))
+ # Cook them. This will create seltest_all.py.
+ cookSeleniumTests(filenames)
+ # We are done.
+ return "Selenium tests cooked OK. (%i) suites, (%i) files" % (len(suites), len(filenames))
Modified: kukit/kss.demo/branch/kss-zope-transition/kss/demo/configure.zcml
==============================================================================
--- kukit/kss.demo/branch/kss-zope-transition/kss/demo/configure.zcml (original)
+++ kukit/kss.demo/branch/kss-zope-transition/kss/demo/configure.zcml Sun Dec 2 21:04:47 2007
@@ -50,16 +50,4 @@
<!-- Finally, include the browser packages -->
<include package=".browser" />
- <!-- Bind my own listener to dispatch events to
- demo components.
- -->
- <subscriber handler=".events.dispatchRegistration"/>
-
- <!-- Register my registry as a global utility -->
- <utility
- factory=".registry.KSSDemoRegistry"
- provides="kss.demo.interfaces.IKSSDemoRegistry"
- permission="zope.Public"
- />
-
</configure>
Deleted: /kukit/kss.demo/branch/kss-zope-transition/kss/demo/events.py
==============================================================================
--- /kukit/kss.demo/branch/kss-zope-transition/kss/demo/events.py Sun Dec 2 21:04:47 2007
+++ (empty file)
@@ -1,43 +0,0 @@
-
-import zope.component
-from zope.component.interfaces import (
- IUtilityRegistration,
- IRegistrationEvent,
- )
-from interfaces import (
- IKSSDemoResource,
- IKSSSeleniumTestResource,
- IKSSDemoRegistrationEvent,
- IKSSDemoRegistryEvent,
- IKSSDemoRegistry
- )
-from zope.interface import implements
-
-class KSSDemoRegistrationEvent(object):
- """Redispatch of registration for demo resource utilities"""
- implements(IKSSDemoRegistrationEvent)
-
-class KSSDemoRegistryEvent(object):
- """Redispatch of registration for demo registry utilities"""
- implements(IKSSDemoRegistryEvent)
-
- at zope.component.adapter(IUtilityRegistration, IRegistrationEvent)
-def dispatchRegistration(registration, event):
- """When a demo utility is registered, add it to the registry.
- When a demo utility is registered,
- event handler registered for the particular component registered,
- the registration and the event.
- """
- component = registration.component
- # Only dispatch registration of the interesting utilities.
- if IKSSDemoResource.providedBy(component) or \
- IKSSSeleniumTestResource.providedBy(component):
- new_event = KSSDemoRegistrationEvent()
- handlers = zope.component.subscribers((component, registration, event, new_event), None)
- for handler in handlers:
- pass # getting them does the work
- if IKSSDemoRegistry.providedBy(component):
- new_event = KSSDemoRegistryEvent()
- handlers = zope.component.subscribers((component, registration, event, new_event), None)
- for handler in handlers:
- pass # getting them does the work
Modified: kukit/kss.demo/branch/kss-zope-transition/kss/demo/interfaces.py
==============================================================================
--- kukit/kss.demo/branch/kss-zope-transition/kss/demo/interfaces.py (original)
+++ kukit/kss.demo/branch/kss-zope-transition/kss/demo/interfaces.py Sun Dec 2 21:04:47 2007
@@ -50,101 +50,3 @@
description=u'Relative directory path, contains *.html selenium tests',
required=False,
)
-
-# --
-# Resource definition interfaces
-# --
-
-class IKSSDemoResource(Interface):
- """An utility that a demo needs to register"""
-
- # list of IKSSDemo
- demos = List(
- title=u"demos",
- description=u'The ordered list of demos contained in this plugin',
- required=True,
- )
-
-class IKSSSeleniumTestResource(Interface):
- """An utility that a demo needs to register"""
-
- # list of IKSSSeleniumTestDir
- selenium_tests = List(
- title=u"selenium tests",
- description=u'The list of selenium test directories contained in this plugin',
- required=True,
- )
-
-# --
-# The registry itself
-# --
-
-class IKSSDemoRegistry(Interface):
- """Faciliates registration of demos.
-
- Implementations must look after the IKSSDemoResource
- adapters, and use their content to set up themselves.
- """
-
- def registerDemo(demo):
- """Register a demo
-
- It has the attributes specified in IKSSDemo:
-
- plugin_namespace - string with the name of the plugin.
- Or: "" when it is the core part.
-
- category - text that will appear as the title of the
- category. "" if out of category.
-
- demo_page - (relative) url of the demo page. This should
- traverse on ISimpleContent.
-
- title - Title of the demo. This also identifies it
- for removal.
- """
-
- def unregisterDemo(demo):
- """Unregister the given demo."""
-
- def getSortedDemos():
- """Get the (sorted) list of demos"""
-
-class IKSSSeleniumTestRegistry(Interface):
- """Faciliates registration of demos.
-
- Implementations must look after the IKSSSeleniumTestResource
- adapters, and use their content to set up themselves.
- """
-
- def registerSeleniumTestFile(test_filename):
- """Register a selenium test directory
-
- It test_dir has the "filename" attributes specified in IKSSSeleniumTest.
- """
-
- def unregisterSeleniumTestFile(test_filename):
- """Unregister the given test directory."""
-
- def cookSeleniumTests():
- """Cook selenium tests
-
- The *.html tests from each plugin are produced
- into the file seltest_all.pty in the directory
- of kss.demo.selenium_utils .
- """
-
-# --
-# Event that gets redispatched, for allowing
-# the listeners to filter on component
-# --
-
-class IKSSDemoRegistrationEvent(Interface):
- """Redispatched event for registration of
- IKSSDemoRegistration utilities (resources).
- """
-
-class IKSSDemoRegistryEvent(Interface):
- """Redispatched event for registration of
- IKSSDemoRegistry utilities.
- """
Deleted: /kukit/kss.demo/branch/kss-zope-transition/kss/demo/kss.demo-meta.zcml
==============================================================================
--- /kukit/kss.demo/branch/kss-zope-transition/kss/demo/kss.demo-meta.zcml Sun Dec 2 21:04:47 2007
+++ (empty file)
@@ -1,3 +0,0 @@
-
-<include package="kss.demo" file="meta.zcml" />
-
Deleted: /kukit/kss.demo/branch/kss-zope-transition/kss/demo/meta.zcml
==============================================================================
--- /kukit/kss.demo/branch/kss-zope-transition/kss/demo/meta.zcml Sun Dec 2 21:04:47 2007
+++ (empty file)
@@ -1,6 +0,0 @@
-<configure
- xmlns="http://namespaces.zope.org/meta">
-
- <include package=".configfeature" file="meta.zcml"/>
-
-</configure>
Deleted: /kukit/kss.demo/branch/kss-zope-transition/kss/demo/registry.py
==============================================================================
--- /kukit/kss.demo/branch/kss-zope-transition/kss/demo/registry.py Sun Dec 2 21:04:47 2007
+++ (empty file)
@@ -1,254 +0,0 @@
-from zope.interface import implements
-from zope.component import (
- adapter,
- getSiteManager,
- )
-from interfaces import (
- IKSSDemoRegistry,
- IKSSSeleniumTestRegistry,
- IKSSDemoResource,
- IKSSSeleniumTestResource,
- IKSSDemoRegistrationEvent,
- IKSSDemoRegistryEvent,
- )
-from zope.component.interfaces import (
- IUtilityRegistration,
- IRegistered,
- IUnregistered,
- )
-import sys, os, re, textwrap
-from elementtree import HTMLTreeBuilder
-from string import Template
-import kss.demo.selenium_utils
-# shut the mouth of pyflakes
-kss.demo.selenium_utils
-
-# --
-# Registry implementation for use with Zope
-# --
-
-def getRootDirOfModule(module_name):
- return os.path.dirname(sys.modules[module_name].__file__)
-
-def getRootDirOfClass(cls):
- return getRootDirOfModule(cls.__module__)
-
-def getRootDirOfInstance(obj):
- return getRootDirOfClass(obj.__class__)
-
-# Create a mesh of provided interfaces
-# This is needed, because an utility must have a single interface.
-class IRegistry(IKSSDemoRegistry, IKSSSeleniumTestRegistry):
- pass
-
-class KSSDemoRegistry(object):
- """KSS demo registry.
- """
- implements(IRegistry)
-
- def __init__(self):
- # We will set up my handlers to get notified of new plugins
- # (works via redispatching by events.py)
- site = getSiteManager()
- # registry for demos
- self.demos_dict = {}
- self.demos = []
- self.demos_are_sorted = False
- site.registerHandler(self.registerDemosFromPlugin)
- site.registerHandler(self.unregisterDemosFromPlugin)
- site.registerHandler(self.registerEarlierDemos)
- # registry for selenium tests
- self.selenium_tests = []
- site.registerHandler(self.registerSeleniumTestsFromPlugin)
- site.registerHandler(self.unregisterSeleniumTestsFromPlugin)
- # ... the rest of setup will be done from registerEarlierDemos
-
- @adapter(IKSSDemoRegistry, IUtilityRegistration, IRegistered, IKSSDemoRegistryEvent)
- def registerEarlierDemos(self, registry, registration=None, event=None, new_event=None):
- """Make sure that the resources registered earlier, are added
- (so this is a listener to the registration of myself
- which is needed because CA is not ready at time of the __init__)
- """
- if registry != self:
- # The utility only register on itself.
- return
- site = getSiteManager()
- for name, plugin in site.getUtilitiesFor(IKSSDemoResource):
- for demo in plugin.demos:
- self.registerDemo(demo)
-
- @adapter(IKSSDemoResource, IUtilityRegistration, IRegistered, IKSSDemoRegistrationEvent)
- def registerDemosFromPlugin(self, plugin, registration=None, event=None, new_event=None):
- """Add a demo collection to the registry.
- """
- for demo in plugin.demos:
- self.registerDemo(demo)
-
- @adapter(IKSSDemoResource, IUtilityRegistration, IUnregistered, IKSSDemoRegistrationEvent)
- def unregisterDemosFromPlugin(self, plugin, registration=None, event=None, new_event=None):
- """Remove a demo collection from the registry.
- """
- for demo in plugin.demos:
- self.unregisterDemo(demo)
-
- def registerDemo(self, demo):
- """Register a demo
-
- It has the attributes specified in IKSSDemo:
-
- plugin_namespace - string with the name of the plugin.
- Or: "" when it is the core part.
-
- category - text that will appear as the title of the
- category. "" if out of category.
-
- demo_page - (relative) url of the demo page. This should
- traverse on ISimpleContent.
-
- title - Title of the demo. This also identifies it
- for removal.
- """
- key = demo.plugin_namespace, demo.category, demo.page_url
- if key in self.demos:
- raise Exception, 'The demo for %s has already been registered. Cannot add.' % (key, )
- self.demos_dict[key] = demo
- self.demos.append(demo)
- self.demos_are_sorted = False
-
- def unregisterDemo(self, demo):
- """Unregister the given demo."""
- key = demo.plugin_namespace, demo.category, demo.demo_page
- try:
- value = self.demos_dict[key]
- except KeyError:
- raise Exception, 'The demo for %s is yet unregistered. Cannot remove.' % (key, )
- del self.demos_dict[key]
- self.demos.remove(value)
-
- def getSortedDemos(self):
- """Get the (sorted) list of demos"""
- if not self.demos_are_sorted:
- self.demos.sort(key=lambda demo: (
- demo.plugin_namespace,
- demo.category,
- ))
- self.demos_are_sorted = True
- return list(self.demos)
-
- # --
- # Selenium tests
- # --
-
- @staticmethod
- def _getSeleniumTestsFromPlugin(plugin):
- test_filenames = []
- root_dir = getRootDirOfInstance(plugin)
- for selenium_test_directory in plugin.selenium_tests:
- tests_root_dir = os.path.join(root_dir, selenium_test_directory.test_directory)
- for test_filename in os.listdir(tests_root_dir):
- if test_filename.lower().endswith('.html') or \
- test_filename.endswith('.htm'):
- test_filenames.append(os.path.join(tests_root_dir, test_filename))
- return test_filenames
-
- @adapter(IKSSSeleniumTestResource, IUtilityRegistration, IRegistered, IKSSDemoRegistrationEvent)
- def registerSeleniumTestsFromPlugin(self, plugin, registration=None, event=None, new_event=None):
- """Add a demo collection to the registry.
- """
- for test_filename in self._getSeleniumTestsFromPlugin(plugin):
- self.registerSeleniumTestFile(test_filename)
-
- @adapter(IKSSSeleniumTestResource, IUtilityRegistration, IUnregistered, IKSSDemoRegistrationEvent)
- def unregisterSeleniumTestsFromPlugin(self, plugin, registration=None, event=None, new_event=None):
- """Remove a demo collection from the registry.
- """
- for test_filename in self._getSeleniumTestsFromPlugin(plugin):
- self.registerSeleniumTestFile(test_filename)
-
- def registerSeleniumTestFile(self, test_filename):
- """Register a selenium test by absolute filename
- """
- if test_filename in self.selenium_tests:
- raise Exception, 'The selenium test for %s has already been registered. Cannot add.' % (test_filename, )
- self.selenium_tests.append(test_filename)
-
- def unregisterSeleniumTestFile(self, test_filename):
- """Unregister the given selenium test."""
- try:
- del self.selenium_tests[test_filename]
- except KeyError:
- raise Exception, 'The selenium test for %s is yet unregistered. Cannot remove.' % (test_filename, )
-
- template = Template(textwrap.dedent('''\
- from seleniumtestcase import SeleniumTestCase
- import unittest, time
-
- class seltest_$testname(SeleniumTestCase):
-
- $tests
-
- def test_suite():
- return unittest.makeSuite(seltest_$testname)
-
- if __name__ == "__main__":
- unittest.main()
- '''))
-
- variable_regexp = re.compile('\$\{(?P<varname>\w*)\}')
- @classmethod
- def formatcommand(cls, command, *args):
- if not command:
- return '' # Change this to raise an exception?
-
- arguments = []
- for arg in args:
- if not arg:
- continue
- matched = cls.variable_regexp.match(arg)
- if matched is None:
- arguments.append('"%s"'%arg)
- else:
- arguments.append("self.getVar('%s')"%matched.group('varname'))
- return 'self.%s(%s)' % (command, ', '.join(arguments))
-
- def cookSeleniumTests(self):
- """Cook selenium tests
-
- The *.html tests from each plugin are produced
- into the file seltest_all.pty in the directory
- of kss.demo.selenium_utils .
- """
- # Try to open the file for writing.
- output_dir = getRootDirOfModule('kss.demo.selenium_utils')
- output_filename = os.path.join(output_dir, 'seltest_all.py')
- try:
- f = open(output_filename, 'wb')
- except IOError, exc:
- raise IOError, ('Cannot open file "%s" for writing. '
- 'Make sure zope process has write access in directory. '
- '["%s"]') \
- % (output_filename, exc)
-
- htmlparser = HTMLTreeBuilder.TreeBuilder()
- tests = []
- for filename in self.selenium_tests:
- tree = HTMLTreeBuilder.parse(filename)
- root = tree.getroot()
-
- try:
- testname = root.find('.//title').text
- except AttributeError:
- continue
- commands = []
- for row in root.findall('.//tbody/tr'):
- commands.append(self.formatcommand(*[td.text for td in row.findall('td')]))
-
- testfilename = 'seltest_%s.py' % testname
- testbody=' def test_%s(self):\n'%testname+' '*8+'\n '.join(commands)+'\n'
- tests.append(testbody)
-
- f.write(self.template.substitute(dict(
- testname=testname,
- tests='\n'.join(tests),
- )))
- f.close()
Added: kukit/kss.demo/branch/kss-zope-transition/kss/demo/selenium_utils/builder.py
==============================================================================
--- (empty file)
+++ kukit/kss.demo/branch/kss-zope-transition/kss/demo/selenium_utils/builder.py Sun Dec 2 21:04:47 2007
@@ -0,0 +1,110 @@
+
+import sys, os, re, textwrap
+from elementtree import HTMLTreeBuilder
+from string import Template
+
+# --
+# This is used to build the seltest_all.py file into the same directory.
+# --
+
+# root directory finding code
+def getRootDirOfModule(module_name):
+ return os.path.dirname(sys.modules[module_name].__file__)
+
+def getRootDirOfClass(cls):
+ return getRootDirOfModule(cls.__module__)
+
+def getRootDirOfInstance(obj):
+ return getRootDirOfClass(obj.__class__)
+
+def getSeleniumTestsFromSuite(owner_instance, suite):
+ """Get absolute filenames of all tests from the suite.
+ Suite contains the directory that we need to find.
+ owner_instance is used for the directory finding,
+ the suite's directory is traversed relative from that.
+ """
+ test_filenames = []
+ # The owner instance is only used to traverse the sute directory
+ # relative from it.
+ root_dir = getRootDirOfInstance(owner_instance)
+ tests_root_dir = os.path.join(root_dir, suite.test_directory)
+ for test_filename in os.listdir(tests_root_dir):
+ if test_filename.lower().endswith('.html') or \
+ test_filename.endswith('.htm'):
+ test_filenames.append(os.path.join(tests_root_dir, test_filename))
+ return test_filenames
+
+template = Template(textwrap.dedent('''\
+ from seleniumtestcase import SeleniumTestCase
+ import unittest, time
+
+ class seltest_$testname(SeleniumTestCase):
+
+ $tests
+
+ def test_suite():
+ return unittest.makeSuite(seltest_$testname)
+
+ if __name__ == "__main__":
+ unittest.main()
+ '''))
+
+variable_regexp = re.compile('\$\{(?P<varname>\w*)\}')
+
+def formatcommand(command, *args):
+ if not command:
+ return '' # Change this to raise an exception?
+
+ arguments = []
+ for arg in args:
+ if not arg:
+ continue
+ matched = variable_regexp.match(arg)
+ if matched is None:
+ arguments.append('"%s"'%arg)
+ else:
+ arguments.append("self.getVar('%s')"%matched.group('varname'))
+ return 'self.%s(%s)' % (command, ', '.join(arguments))
+
+
+
+def cookSeleniumTests(filenames):
+ """Cook selenium tests
+ """
+ # Try to open the file for writing.
+ output_dir = getRootDirOfModule('kss.demo.selenium_utils')
+ output_filename = os.path.join(output_dir, 'seltest_all.py')
+ try:
+ f = open(output_filename, 'wb')
+ except IOError, exc:
+ raise IOError, ('Cannot open file "%s" for writing. '
+ 'Make sure zope process has write access in directory. '
+ '["%s"]') \
+ % (output_filename, exc)
+
+ htmlparser = HTMLTreeBuilder.TreeBuilder()
+ tests = []
+
+ # Now, we find all filenames that are inthe suite passed to us.
+
+ for filename in filenames:
+ tree = HTMLTreeBuilder.parse(filename)
+ root = tree.getroot()
+
+ try:
+ testname = root.find('.//title').text
+ except AttributeError:
+ continue
+ commands = []
+ for row in root.findall('.//tbody/tr'):
+ commands.append(formatcommand(*[td.text for td in row.findall('td')]))
+
+ testfilename = 'seltest_%s.py' % testname
+ testbody=' def test_%s(self):\n'%testname+' '*8+'\n '.join(commands)+'\n'
+ tests.append(testbody)
+
+ f.write(template.substitute(dict(
+ testname=testname,
+ tests='\n'.join(tests),
+ )))
+ f.close()
Modified: kukit/kss.demo/branch/kss-zope-transition/kss/demo/tests/test_demoview.py
==============================================================================
--- kukit/kss.demo/branch/kss-zope-transition/kss/demo/tests/test_demoview.py (original)
+++ kukit/kss.demo/branch/kss-zope-transition/kss/demo/tests/test_demoview.py Sun Dec 2 21:04:47 2007
@@ -36,7 +36,6 @@
class layer(KSSViewTestCase.layer):
@classmethod
def setUp(cls):
- load_config('meta.zcml', package=kss.demo)
load_config('configure.zcml', package=kss.demo)
def afterSetUp(self):
More information about the Kukit-checkins
mailing list