From reebalazs at codespeak.net Fri Apr 4 22:43:39 2008 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Fri, 4 Apr 2008 22:43:39 +0200 (CEST) Subject: [KSS-checkins] r53362 - in kukit/kss.demo/branch/1.4-kss-test/kss/demo: . browser selenium_utils tests Message-ID: <20080404204339.2BEF416AA89@codespeak.net> Author: reebalazs Date: Fri Apr 4 22:43:37 2008 New Revision: 53362 Added: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_layer.py (contents, props changed) kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_layers.txt (contents, props changed) kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suite.py (contents, props changed) kukit/kss.demo/branch/1.4-kss-test/kss/demo/tests/base.py (contents, props changed) kukit/kss.demo/branch/1.4-kss-test/kss/demo/tests/test_doc.py (contents, props changed) Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/__init__.py kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser/registry.py kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser/setDevMode.html kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser/setProdMode.html kukit/kss.demo/branch/1.4-kss-test/kss/demo/registry.py kukit/kss.demo/branch/1.4-kss-test/kss/demo/resource.py kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_utils/builder.py kukit/kss.demo/branch/1.4-kss-test/kss/demo/tests/test_demoview.py Log: Implement selenium layers properly. Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/__init__.py ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/__init__.py (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/__init__.py Fri Apr 4 22:43:37 2008 @@ -1,4 +1,15 @@ +from resource import ( + KSSSeleniumTestCase, + KSSSeleniumTestDirectory, + KSSSeleniumTestCaseList, + KSSSeleniumEmptyTestCase, + KSSSeleniumSandboxCreationTestCase, + KSSDemo, + ) +from selenium_layer import KSSSeleniumTestLayerBase +from selenium_suite import KSSSeleniumTestSuite + try: import Products.Five except ImportError: Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser/registry.py ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser/registry.py (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser/registry.py Fri Apr 4 22:43:37 2008 @@ -5,6 +5,7 @@ from zope.component import getUtility from zope.interface import implements from kss.demo.selenium_utils.builder import cookSeleniumTests +from kss.demo.selenium_layer import LayerTree import os.path import re import urllib @@ -71,16 +72,15 @@ """Get selenium tests annotated with title and href.""" registry = getUtility(IKSSDemoRegistry) results = [] - for suite in registry.test_suites: - if not suite.application.lower() == application.strip().lower(): - continue - relative_urls = suite.get_relative_urls(self) - for relative_url in relative_urls: - results.append(dict( - href = relative_url, - title = self._url_to_title(relative_url), - )) - return results + # Filter suites that we need. + suites = [suite for suite in registry.test_suites + if suite.application.lower() == application.strip().lower()] + # Build a tree with the suite, to find the optimal setup / teardown sequence. + tree = LayerTree(suites) + return [dict( + href = relative_url, + title = self._url_to_title(relative_url), + ) for relative_url in tree.get_relative_urls(self)] @staticmethod def _url_to_title(url): Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser/setDevMode.html ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser/setDevMode.html (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser/setDevMode.html Fri Apr 4 22:43:37 2008 @@ -1,7 +1,7 @@ -basic_commands +Set development mode Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser/setProdMode.html ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser/setProdMode.html (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser/setProdMode.html Fri Apr 4 22:43:37 2008 @@ -1,7 +1,7 @@ -basic_commands +Set production mode
Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/registry.py ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/registry.py (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/registry.py Fri Apr 4 22:43:37 2008 @@ -12,7 +12,7 @@ IKSSDemoRegistryEvent, IKSSSeleniumTestSuite ) -from resource import KSSSeleniumTestSuite +from selenium_suite import KSSSeleniumTestSuite from zope.component.interfaces import ( IUtilityRegistration, IRegistered, Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/resource.py ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/resource.py (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/resource.py Fri Apr 4 22:43:37 2008 @@ -2,7 +2,6 @@ from interfaces import ( IKSSDemo, IKSSSeleniumTestCaseCollection, - IKSSSeleniumTestSuite, ) import itertools import sys, os.path @@ -36,18 +35,15 @@ "Abstract base class to help collection implementation" def find_test_root_dir(self): - # XXX This must be called directly from the __init__ of the class - # and it is able to find out the directory where the class - # was defined from. # # Zope CA magic used to find where the class is defined from frame = sys._getframe(2) - locals = frame.f_locals + f_locals = frame.f_locals # Try to make sure we were called from a class def - if (locals is frame.f_globals) or ('__module__' not in locals): - raise TypeError("classProvides can be used only from a class definition.") + if (f_locals is frame.f_globals) or ('__module__' not in f_locals): + raise TypeError("The %r suite class can be used only from inside a class definition." % (self.__class__, )) # store it - self.test_root_dir = getRootDirOfModule(locals['__module__']) + self.test_root_dir = getRootDirOfModule(f_locals['__module__']) def find_absolute_path(self, filename): "Returns the absolute path of the filename based on the test root directory." @@ -70,7 +66,7 @@ test_filename = self.find_absolute_path(self.test_filename) return [test_filename] - def get_relative_urls(self, view): + def get_relative_urls(self, view, tree=None): return self.make_relative_urls_from_paths(self.get_testcase_paths()) class KSSSeleniumTestDirectory(KSSSeleniumTestCaseCollectionBase): @@ -96,7 +92,7 @@ test_filenames = (filename[1] for filename in test_filenames) return test_filenames - def get_relative_urls(self, view): + def get_relative_urls(self, view, tree=None): return self.make_relative_urls_from_paths(self.get_testcase_paths()) class KSSSeleniumTestCaseList(KSSSeleniumTestCaseCollectionBase): @@ -111,8 +107,8 @@ def get_testcase_paths(self): return itertools.chain(*[case.get_testcase_paths() for case in self.cases]) - def get_relative_urls(self, view): - return itertools.chain(*[case.get_relative_urls(view) for case in self.cases]) + def get_relative_urls(self, view, tree=None): + return itertools.chain(*(case.get_relative_urls(view, tree) for case in self.cases)) class KSSSeleniumEmptyTestCase(KSSSeleniumTestCaseCollectionBase): """An empty test case.""" @@ -121,11 +117,11 @@ def get_testcase_paths(self): return () - def get_relative_urls(self, view): + def get_relative_urls(self, view, tree=None): return () -class KSSSandboxCreationTestCase(KSSSeleniumTestCaseCollectionBase): +class KSSSeleniumSandboxCreationTestCase(KSSSeleniumTestCaseCollectionBase): """A method that can be used for sandbox creation. It is a factory-generated test. It visits a page with a button @@ -148,93 +144,10 @@ def get_testcase_paths(self): return () - def get_relative_urls(self, view): + def get_relative_urls(self, view, tree=None): relative_url = "@@kss-selenium-create-sandbox-test.html?method_name=%s&admin_username=%s&admin_password=%s" % ( self.method_name, view.request.get('admin_username', ''), view.request.get('admin_password', '')) return (relative_url, ) -# -- -# The Suite itself is a collection, but provides a way to use layers with setup and -# tesrdown from the registry. -# -- - -class KSSSeleniumTestLayerBase(object): - setup = KSSSeleniumEmptyTestCase() - teardown = KSSSeleniumEmptyTestCase() - - -# XXX TODO Currently the tuest suite handles the setup and teardown -# of the layer. The suites with the same layer should have a common -# setup. Very easy to implement. -class KSSSeleniumTestSuite(KSSSeleniumTestCaseCollectionBase): - """Represents a selenium suite, - that makes part of an applicaion and a component, - as well as an optional (test) layer. - """ - implements(IKSSSeleniumTestSuite) - - # convenience access for page templates - __allow_access_to_unprotected_subobjects__ = 1 - - tests = KSSSeleniumEmptyTestCase() - component = u'' - application = u'' - # default is an empty layer. - layer = KSSSeleniumTestLayerBase - dual_mode = True - - # resources we use for dual mode - set_devel_mode = KSSSeleniumTestCase('browser/setDevMode.html') - set_prod_mode = KSSSeleniumTestCase('browser/setProdMode.html') - - def __init__(self, tests=None, component=u'', application=u'', layer=None, dual_mode=None): - if tests is not None: - self.tests = tests - self.test_root_dir = self.tests.test_root_dir - if component: - self.component = component - if application: - self.application = application - if layer is not None: - self.layer = layer - if dual_mode is not None: - self.dual_mode = dual_mode - - def get_testcase_paths(self): - return itertools.chain( - * (case.get_testcase_paths() for case in self.iterables) - ) - - def get_relative_urls(self, view): - return itertools.chain( - * (case.get_relative_urls(view) for case in self.iterables) - ) - - @property - def iterables(self): - # Check if we have tests at all. If no, we don't need the - # setup/teardown. - # - # The next expression decided if the iterator yields any resuls - # TODO make an empty() on the interface ? - if tuple(itertools.islice(self.tests.get_relative_urls(self), 0, 1)): - if self.dual_mode: - return ( - self.layer.setup, - self.set_devel_mode, - self.tests, - self.set_prod_mode, - self.tests, - self.layer.teardown, - ) - else: - return ( - self.layer.setup, - self.tests, - self.layer.teardown, - ) - else: - # No tests, nothing to do. - return () Added: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_layer.py ============================================================================== --- (empty file) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_layer.py Fri Apr 4 22:43:37 2008 @@ -0,0 +1,202 @@ +"""\ +Layers for Selenium tests + +The goal of this structures to allow to generate the setup / teardown +sequence in an optimal way. Since we have to group tests to be +executed in the same layer, and trim away layers with no tests, +this must be done for each list of selected testcases. +""" + +import itertools +from resource import KSSSeleniumEmptyTestCase, KSSSeleniumTestCase + +class metalayer(type): + def __init__(cls, name, bases, attrs): + # If setup or teardown are not declared, we consider + # them as empty. + if 'setup' not in attrs: + attrs['setup'] = KSSSeleniumEmptyTestCase() + if 'teardown' not in attrs: + attrs['teardown'] = KSSSeleniumEmptyTestCase() + # Set up the class + super(metalayer, cls).__init__(name, bases, attrs) + +class KSSSeleniumTestLayerBase(object): + __metaclass__ = metalayer + setup = KSSSeleniumEmptyTestCase() + teardown = KSSSeleniumEmptyTestCase() + +class LayerTreeNode(object): + """An active tree node + + It participates in a Tree, it contains a list of suites. + If the list of suites is empty, that means this layer + is "inactive" in the tree: it is needed for the setup / teardown + sequence, but contains no tests itself. + """ + + # resources we use for dual mode + set_devel_mode = KSSSeleniumTestCase('browser/setDevMode.html') + set_prod_mode = KSSSeleniumTestCase('browser/setProdMode.html') + + def __init__(self, tree, layer): + self.tree = tree + self.suites = [] + self.layer = layer + self.base_layer = None + self.child_nodes = [] + + def add_suite(self, suite): + assert suite.layer == self.layer, "Suite must have the same layer." + self.suites.append(suite) + + def add_parents(self): + layer = self.layer + # A layer must be a subclass of the base class. + assert issubclass(layer, KSSSeleniumTestLayerBase), \ + "Layers must be classes inheriting from KSSSeleniumTestLayerBase." + # Find out the bases. We only consider bases + # that inherit from the base class. + try: + bases = layer.__bases__ + except AttributeError: + raise Exception, "Layers must be classes." + bases = (base for base in bases if issubclass(base, KSSSeleniumTestLayerBase)) + # We are only interested in the first base. + # (In case of multi inheritence we could have more bases, + # and although this is hardly imaginable as use case, it is supported anyway.) + bases = tuple(itertools.islice(bases, 0, 1)) + # There must be one base, + # unless we are at the root node. + if not bases: + # We found the root. + assert layer == KSSSeleniumTestLayerBase, "This should not happen." + self.tree.root = self + else: + if len(bases) > 1: + raise Exception, "Double inheritence of layers is not supported." + base_layer = bases[0] + # Add this layer to the tree as well, and remember it. + base_node = self.tree.add_layer(base_layer) + # Mark ourselves as a child node. + self.base_node = base_node + base_node.child_nodes.append(self) + + def get_testcase_paths_for_layer(self): + """Give the absolute paths "owned" for the layer itself.""" + # order does not matter here. + # Just needed to enable these resources. + # Also: enable the set devel / prod resources always. + if self.base_layer is not None: + base_layer_tests = self.tree.lookup_layer(self.base_layer).get_testcase_paths_for_layer(), + else: + # We are at the root. + base_layer_tests = () + # Compose all paths + return itertools.chain( + base_layer_tests, + self.layer.setup.get_testcase_paths(), + self.layer.teardown.get_testcase_paths(), + self.set_devel_mode.get_testcase_paths(), + self.set_prod_mode.get_testcase_paths(), + ) + + def get_relative_urls_for_own_tests(self, view): + """Generate the tests in all suites in this layer subtree. No setup or teardown. + + This is needed to decide if we can prune a part of the tree (if there are no tests, + setup and teardown are not needed either.) + """ + return itertools.chain( + # Our own tests + itertools.chain(*(suite.tests.get_relative_urls(view, self.tree) for suite in self.suites)), + # Tests from the child layers + itertools.chain(*(node.get_relative_urls_for_own_tests(view) for node in self.child_nodes)), + ) + + def get_relative_urls(self, view): + """Generate the walking order for the node and its subtree.""" + # Look ahead check if we have any tests at all. + suite_tests_lookahead = self.get_relative_urls_for_own_tests(view) + # Do we have tests at all? + # If not, we just don't want to emit setup and teardown at all. + if tuple(itertools.islice(suite_tests_lookahead, 0, 1)): + # Does any of our suites have dual mode? + suites_by_duality = {True: [], False: []} + for suite in self.suites: + suites_by_duality[suite.dual_mode].append(suite) + # Create the tests for suites. + # Look ahead check if we have any dual tests at all. + dual_tests_lookahead = itertools.chain(*(suite.tests.get_relative_urls(view, self.tree) for suite in suites_by_duality[True])) + if tuple(itertools.islice(dual_tests_lookahead, 0, 1)): + # We do have some dual tests. So we need to run them twice and set + # development and production modes for this. + dual_tests = itertools.chain( + # Dual mode tests from the suites in this layer, in Development mode + self.set_devel_mode.get_relative_urls(view, self.tree), + itertools.chain(*(suite.tests.get_relative_urls(view, self.tree) for suite in suites_by_duality[True])), + # Dual mode tests from the suites in this layer, in Production mode + self.set_prod_mode.get_relative_urls(view, self.tree), + itertools.chain(*(suite.tests.get_relative_urls(view, self.tree) for suite in suites_by_duality[True])), + ) + else: + # No dual mode tests + dual_tests = () + # Now put them together with setup and teardown + return itertools.chain( + # Setup from parent layer + self.layer.setup.get_relative_urls(view, self.tree), + # Dual mode tests from the suites in this layer + dual_tests, + # Single mode tests from the suites in this layer + itertools.chain(*(suite.tests.get_relative_urls(view, self.tree) for suite in suites_by_duality[False])), + # Add tests recursively from contained layers + itertools.chain(*(node.get_relative_urls(view) for node in self.child_nodes)), + # Teardown to parent layer + self.layer.teardown.get_relative_urls(view, self.tree), + ) + else: + # No tests at all. + return () + +class LayerTree(object): + """Builds an inheritence tree from the suites passed in. + """ + def __init__(self, suites=()): + self.suites = [] + self.nodes = {} + self.root = None + self.add_suites(suites) + + def add_suites(self, suites): + for suite in suites: + self.add_suite(suite) + + def add_suite(self, suite): + # make sure we have the layer + node = self.add_layer(suite.layer) + # Add the suite to the node. + node.add_suite(suite) + + def add_layer(self, layer): + # We must fetch the layer node from the tree, + # or create it and its inheritence path to the root layer. + try: + node = self.nodes[layer] + except KeyError: + # create and remember the tree node + node = self.nodes[layer] = LayerTreeNode(self, layer) + # Recursively process parents of the node + node.add_parents() + # caller may access the node + return node + + def lookup_layer(self, layer): + return self.nodes[layer] + + def get_relative_urls(self, view): + """Generate all tests in the tree.""" + if not self.root: + # no root, no tests. + return () + return self.root.get_relative_urls(view) Added: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_layers.txt ============================================================================== --- (empty file) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_layers.txt Fri Apr 4 22:43:37 2008 @@ -0,0 +1,282 @@ +==================== +Selenium test layers +==================== + +We can make our own layer by inheritance from the base class. + + >>> from kss.demo import KSSSeleniumTestLayerBase + +Create the class: + + >>> class aLayer(KSSSeleniumTestLayerBase): + ... pass + +Since we did not overwrite setup and teardown, they must be emtpy. + + >>> aLayer.setup + + >>> aLayer.teardown + + + +Specifying setup and teardown for a layer +----------------------------------------- + +A more sensible use case is to create some setup and teardown for +ourselves. We will create test cases that refer to non-existent +files, now. + + >>> from kss.demo import KSSSeleniumTestCase + + >>> class aLayer(KSSSeleniumTestLayerBase): + ... setup = KSSSeleniumTestCase('1') + ... teardown = KSSSeleniumTestCase('2') + + >>> aLayer.setup + + >>> aLayer.teardown + + +We also check the actual urls that will result the testing +sequence. Note that get_relative_urls would take the view +in normal use, but it is not important for this test. + + >>> tuple(aLayer.setup.get_relative_urls(None)) + ('@@resource?path=1',) + >>> tuple(aLayer.teardown.get_relative_urls(None)) + ('@@resource?path=2',) + +If I inherit from this layer, and I do not overwrite setup +or teardown, it still gets an empty value. + + >>> class zLayer(KSSSeleniumTestLayerBase): + ... setup = KSSSeleniumTestCase('3') + + >>> zLayer.setup + + >>> tuple(zLayer.setup.get_relative_urls(None)) + ('@@resource?path=3',) + + >>> zLayer.teardown + + + +Inheriting layers +----------------- + +Now, let us inherit a layer from another layer. + + >>> class bLayer(aLayer): + ... setup = KSSSeleniumTestCase('5') + ... teardown = KSSSeleniumTestCase('6') + +And another one. + + >>> class cLayer(aLayer): + ... setup = KSSSeleniumTestCase('7') + ... teardown = KSSSeleniumTestCase('8') + +Even we inherit more. + + >>> class dLayer(cLayer): + ... setup = KSSSeleniumTestCase('9') + ... teardown = KSSSeleniumTestCase('10') + + >>> class eLayer(cLayer): + ... setup = KSSSeleniumTestCase('11') + ... teardown = KSSSeleniumTestCase('12') + + +This results in the following inheritence structure:: + + a + | + ------ + | | + b c + | + ------ + | | + d e + + +Using layers from suites +======================== + +We define suites that use the above layers. + + >>> from kss.demo import KSSSeleniumTestSuite + +The following definition to define a suite would fail: + + >>> aSuite = KSSSeleniumTestSuite( + ... tests = KSSSeleniumTestCase('ta'), + ... layer = aLayer, + ... ) + Traceback (most recent call last): + ... + TypeError: The suite class can be used only from inside a class definition. + +As the error message says, we must define the class from inside another +class. This is used to locate files relatively from the module where the +definition is. So we have to define them from a dummy plugin (however the plugin +itself play no role in testing). + + >>> class DummyPlugin(object): + ... + ... aSuite = KSSSeleniumTestSuite( + ... tests = KSSSeleniumTestCase('ta'), + ... layer = aLayer, + ... ) + >>> aSuite = DummyPlugin.aSuite + +The layers whose tests are active, will build a tree to compute the +optimal setup-teardown order. + + >>> from kss.demo.selenium_layer import LayerTree + + >>> tree = LayerTree((aSuite, )) + >>> tuple(tree.get_relative_urls(None)) + ('@@resource?path=1', '@@resource?path=...setDevMode.html', '@@resource?path=ta', '@@resource?path=...setProdMode.html', '@@resource?path=ta', '@@resource?path=2') + +As we can see in the above results, the tests are generated properly with setup and teardown. + +If more cases use the same layer, they are grouped. They also just need to change +the production mode twice: + + >>> class DummyPlugin2(object): + ... + ... a2Suite = KSSSeleniumTestSuite( + ... tests = KSSSeleniumTestCase('ta2'), + ... layer = aLayer, + ... ) + >>> a2Suite = DummyPlugin2.a2Suite + + >>> tree = LayerTree((aSuite, a2Suite)) + >>> tuple(tree.get_relative_urls(None)) + ('@@resource?path=1', '@@resource?path=...setDevMode.html', '@@resource?path=ta', '@@resource?path=ta2', '@@resource?path=...setProdMode.html', '@@resource?path=ta', '@@resource?path=ta2', '@@resource?path=2') + +Now, let's see the tests for the other suites: + + >>> class DummyPlugin3(object): + ... + ... bSuite = KSSSeleniumTestSuite( + ... tests = KSSSeleniumTestCase('tb'), + ... layer = bLayer, + ... ) + ... + ... cSuite = KSSSeleniumTestSuite( + ... tests = KSSSeleniumTestCase('tc'), + ... layer = cLayer, + ... ) + ... + ... dSuite = KSSSeleniumTestSuite( + ... tests = KSSSeleniumTestCase('td'), + ... layer = dLayer, + ... ) + ... + ... d2Suite = KSSSeleniumTestSuite( + ... tests = KSSSeleniumTestCase('td2'), + ... layer = dLayer, + ... ) + ... eSuite = KSSSeleniumTestSuite( + ... tests = KSSSeleniumTestCase('te'), + ... layer = eLayer, + ... ) + ... + >>> bSuite = DummyPlugin3.bSuite + >>> cSuite = DummyPlugin3.cSuite + >>> dSuite = DummyPlugin3.dSuite + >>> d2Suite = DummyPlugin3.d2Suite + >>> eSuite = DummyPlugin3.eSuite + +And see what happens if only suite "d" is selected. We can see that the setup and teardown sequence is correct. + + >>> tree = LayerTree((dSuite, )) + >>> tuple(tree.get_relative_urls(None)) + ('@@resource?path=1', '@@resource?path=7', '@@resource?path=9', '@@resource?path=...setDevMode.html', '@@resource?path=td', '@@resource?path=...setProdMode.html', '@@resource?path=td', '@@resource?path=10', '@@resource?path=8', '@@resource?path=2') + + +Replay this with a bunch of other tests added. Setup and teardown is executed ideally. +In this case we have more dev / prod mode changes, since these are the fastest +they are wrapped inside the layer. + + >>> tree = LayerTree((cSuite, dSuite, d2Suite)) + >>> tuple(tree.get_relative_urls(None)) + ('@@resource?path=1', '@@resource?path=7', '@@resource?path=...setDevMode.html', '@@resource?path=tc', '@@resource?path=...setProdMode.html', '@@resource?path=tc', '@@resource?path=9', '@@resource?path=...setDevMode.html', '@@resource?path=td', '@@resource?path=td2', '@@resource?path=...setProdMode.html', '@@resource?path=td', '@@resource?path=td2', '@@resource?path=10', '@@resource?path=8', '@@resource?path=2') + +So far we have only tried single path setups. Let's now try a split route. +The setup and teardown work correctly in one level. + + >>> tree = LayerTree((aSuite, bSuite, cSuite)) + >>> tuple(tree.get_relative_urls(None)) + ('@@resource?path=1', '@@resource?path=...setDevMode.html', '@@resource?path=ta', '@@resource?path=...setProdMode.html', '@@resource?path=ta', '@@resource?path=5', '@@resource?path=...setDevMode.html', '@@resource?path=tb', '@@resource?path=...setProdMode.html', '@@resource?path=tb', '@@resource?path=6', '@@resource?path=7', '@@resource?path=...setDevMode.html', '@@resource?path=tc', '@@resource?path=...setProdMode.html', '@@resource?path=tc', '@@resource?path=8', '@@resource?path=2') + + +Another functionality is that certain tests may mark that they don't want +to be in dual mode: + + >>> class DummyPlugin4(object): + ... + ... b2Suite = KSSSeleniumTestSuite( + ... tests = KSSSeleniumTestCase('tb2'), + ... layer = bLayer, + ... dual_mode = False, + ... ) + >>> b2Suite = DummyPlugin4.b2Suite + + >>> tree = LayerTree((b2Suite, )) + >>> tuple(tree.get_relative_urls(None)) + ('@@resource?path=1', '@@resource?path=5', '@@resource?path=tb2', '@@resource?path=6', '@@resource?path=2') + +This is also true if both dual and single mode tests are in the same layer. In this case +the tests will wun in the end, which in practice means Production mode. + + >>> tree = LayerTree((bSuite, b2Suite)) + >>> tuple(tree.get_relative_urls(None)) + ('@@resource?path=1', '@@resource?path=5', '@@resource?path=...setDevMode.html', '@@resource?path=tb', '@@resource?path=...setProdMode.html', '@@resource?path=tb', '@@resource?path=tb2', '@@resource?path=6', '@@resource?path=2') + +Now let's add a bunch of suites: + + >>> tree = LayerTree((aSuite, a2Suite, bSuite, b2Suite, cSuite, dSuite, d2Suite, eSuite)) + >>> tuple(tree.get_relative_urls(None)) + ('@@resource?path=1', '@@resource?path=...setDevMode.html', '@@resource?path=ta', '@@resource?path=ta2', '@@resource?path=...setProdMode.html', '@@resource?path=ta', '@@resource?path=ta2', '@@resource?path=5', '@@resource?path=...setDevMode.html', '@@resource?path=tb', '@@resource?path=...setProdMode.html', '@@resource?path=tb', '@@resource?path=tb2', '@@resource?path=6', '@@resource?path=7', '@@resource?path=...setDevMode.html', '@@resource?path=tc', '@@resource?path=...setProdMode.html', '@@resource?path=tc', '@@resource?path=9', '@@resource?path=...setDevMode.html', '@@resource?path=td', '@@resource?path=td2', '@@resource?path=...setProdMode.html', '@@resource?path=td', '@@resource?path=td2', '@@resource?path=10', '@@resource?path=11', '@@resource?path=...setDevMode.html', '@@resource?path=te', '@@resource?path=...setProdMode.html', '@@resource?path=te', '@@resource?path=12', '@@resource?path=8', '@@resource?path=2') + + +Finally, we still need to check the following: +Suites that are empty are skipped, and no setup teardown or devel / prod mode is generated for them. + + >>> class DummyPlugin5(object): + ... + ... a3Suite = KSSSeleniumTestSuite( + ... + ... ) + ... + ... b3Suite = KSSSeleniumTestSuite( + ... ) + >>> a3Suite = DummyPlugin5.a3Suite + >>> b3Suite = DummyPlugin5.b3Suite + + >>> tree = LayerTree((a3Suite, )) + >>> tuple(tree.get_relative_urls(None)) + () + + >>> tree = LayerTree((a3Suite, aSuite)) + >>> tuple(tree.get_relative_urls(None)) + ('@@resource?path=1', '@@resource?path=...setDevMode.html', '@@resource?path=ta', '@@resource?path=...setProdMode.html', '@@resource?path=ta', '@@resource?path=2') + + >>> tree = LayerTree((a3Suite, b3Suite)) + >>> tuple(tree.get_relative_urls(None)) + () + + >>> tree = LayerTree((a3Suite, b3Suite, bSuite)) + >>> tuple(tree.get_relative_urls(None)) + ('@@resource?path=1', '@@resource?path=5', '@@resource?path=...setDevMode.html', '@@resource?path=tb', '@@resource?path=...setProdMode.html', '@@resource?path=tb', '@@resource?path=6', '@@resource?path=2') + + >>> tree = LayerTree((aSuite, a3Suite, b3Suite, bSuite)) + >>> tuple(tree.get_relative_urls(None)) + ('@@resource?path=1', '@@resource?path=...setDevMode.html', '@@resource?path=ta', '@@resource?path=...setProdMode.html', '@@resource?path=ta', '@@resource?path=5', '@@resource?path=...setDevMode.html', '@@resource?path=tb', '@@resource?path=...setProdMode.html', '@@resource?path=tb', '@@resource?path=6', '@@resource?path=2') + + +And this concludes the layer tests. + Added: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suite.py ============================================================================== --- (empty file) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suite.py Fri Apr 4 22:43:37 2008 @@ -0,0 +1,65 @@ + +import itertools +from resource import ( + KSSSeleniumTestCaseCollectionBase, + KSSSeleniumEmptyTestCase, + ) +from interfaces import IKSSSeleniumTestSuite +from selenium_layer import LayerTree, KSSSeleniumTestLayerBase +from zope.interface import implements + +# -- +# The Suite itself is a collection, but provides a way to use layers with setup and +# tesrdown from the registry. +# -- + +class KSSSeleniumTestSuite(KSSSeleniumTestCaseCollectionBase): + """Represents a selenium suite, + that makes part of an applicaion and a component, + as well as an optional (test) layer. + """ + implements(IKSSSeleniumTestSuite) + + # convenience access for page templates + __allow_access_to_unprotected_subobjects__ = 1 + + tests = KSSSeleniumEmptyTestCase() + component = u'' + application = u'' + # default is an empty layer. + layer = KSSSeleniumTestLayerBase + dual_mode = True + + def __init__(self, tests=None, component=u'', application=u'', layer=None, dual_mode=None): + if tests is not None: + self.tests = tests + if component: + self.component = component + if application: + self.application = application + if layer is not None: + self.layer = layer + if dual_mode is not None: + self.dual_mode = dual_mode + + def get_testcase_paths(self, tree=None): + # No need to care for order. We only need to give + # access to resources that we "own": + # from our setup, own tests, and + # teardown. + # + if not tree: + # Just handle this suite individually. + tree = LayerTree() + tree.add_suites((self, )) + return itertools.chain( + self.tests.get_testcase_paths(), + tree.lookup_layer(self.layer).get_testcase_paths_for_layer() + ) + + def get_relative_urls(self, view, tree=None): + # Just handle this suite individually, + # even if we had a tree passed in. + tree = LayerTree() + tree.add_suites((self, )) + return tree.get_relative_urls(view) Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_utils/builder.py ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_utils/builder.py (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_utils/builder.py Fri Apr 4 22:43:37 2008 @@ -8,7 +8,12 @@ # root directory finding code def getRootDirOfModule(module_name): - return os.path.dirname(sys.modules[module_name].__file__) + if module_name == '__builtin__': + # This may happen in tests and interactively, + # and it's sensible to use an absolute path in this case. + return '' + else: + return os.path.dirname(sys.modules[module_name].__file__) def getRootDirOfClass(cls): return getRootDirOfModule(cls.__module__) Added: kukit/kss.demo/branch/1.4-kss-test/kss/demo/tests/base.py ============================================================================== --- (empty file) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/tests/base.py Fri Apr 4 22:43:37 2008 @@ -0,0 +1,13 @@ + +from Products.Five.zcml import load_config +from kss.core.tests.base import KSSViewTestCase +import kss.demo + +class KSSDemoTestLayer(KSSViewTestCase.layer): + @classmethod + def setUp(cls): + load_config('meta.zcml', package=kss.demo) + load_config('configure.zcml', package=kss.demo) + +class KSSDemoTestCaseBase(KSSViewTestCase): + layer = KSSDemoTestLayer Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/tests/test_demoview.py ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/tests/test_demoview.py (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/tests/test_demoview.py Fri Apr 4 22:43:37 2008 @@ -17,30 +17,22 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # -import unittest, os -from zope.testing import doctest -from Testing.ZopeTestCase import ZopeTestCase -from kss.core.tests.base import KSSViewTestCase -from Products.Five.zcml import load_string, load_config -import kss.demo +import unittest +from base import KSSDemoTestCaseBase try: import Products.Five + Products = Products # to satisfy pyflakes except AttributeError: from kss.demo.simplecontent_z3 import SimpleContent + SimpleContent = SimpleContent # to satisfy pyflakes else: from kss.demo.simplecontent import SimpleContent -class KSSDemoTestCase(KSSViewTestCase): - - class layer(KSSViewTestCase.layer): - @classmethod - def setUp(cls): - load_config('meta.zcml', package=kss.demo) - load_config('configure.zcml', package=kss.demo) +class KSSDemoTestCase(KSSDemoTestCaseBase): def afterSetUp(self): - KSSViewTestCase.afterSetUp(self) + KSSDemoTestCaseBase.afterSetUp(self) self.setDebugRequest() self.folder._setObject('demo', SimpleContent('Demo', 'Demo')) self.view = self.folder.demo.restrictedTraverse('getDivContent') Added: kukit/kss.demo/branch/1.4-kss-test/kss/demo/tests/test_doc.py ============================================================================== --- (empty file) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/tests/test_doc.py Fri Apr 4 22:43:37 2008 @@ -0,0 +1,28 @@ +# Copyright (c) 2008 +# Authors: +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. +# +import unittest +import doctest +from zope.testing.doctestunit import DocFileSuite + +def test_suite(): + return unittest.TestSuite(( + DocFileSuite('selenium_layers.txt', + package = 'kss.demo', + optionflags = doctest.ELLIPSIS, + ), + )) From reebalazs at codespeak.net Fri Apr 4 23:29:03 2008 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Fri, 4 Apr 2008 23:29:03 +0200 (CEST) Subject: [KSS-checkins] r53364 - in kukit/kss.demo/branch/1.4-kss-test/kss/demo: . tests Message-ID: <20080404212903.B57B116AAE6@codespeak.net> Author: reebalazs Date: Fri Apr 4 23:29:01 2008 New Revision: 53364 Added: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suites.txt (contents, props changed) Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/tests/test_doc.py Log: Add more tests Added: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suites.txt ============================================================================== --- (empty file) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suites.txt Fri Apr 4 23:29:01 2008 @@ -0,0 +1,145 @@ + +==================== +Selenium test suites +==================== + +Selenium test suites can be set up from plugin resource definitions. + + >>> from kss.demo import ( + ... KSSSeleniumTestSuite, + ... KSSSeleniumTestCase, + ... ) + + >>> class Plugin(object): + ... + ... selenium_tests = ( + ... KSSSeleniumTestSuite( + ... tests = KSSSeleniumTestCase('1'), + ... ), + ... ) + >>> suite1 = Plugin.selenium_tests[0] + +A suite is like a testcase collection, so it provides its allowed +resource filenames. These are used to secure the resource handling +(to select which files can be served from the filesystem). + + >>> tuple(suite1.get_testcase_paths()) + ('1', '...setDevMode.html', '...setProdMode.html') + +(Normally we would see an absolute path in place of '1', but the module +finder does not work from within doctests.) + +And the list of test urls as well. (We use in place of the view which +is not important in this case.) + + >>> tuple(suite1.get_relative_urls(None)) + ('@@resource?path=...setDevMode.html', '@@resource?path=1', '@@resource?path=...setProdMode.html', '@@resource?path=1') + + +Dual and single mode +-------------------- + +The `suite1` suite also executes the tests twice, both in development and production mode. +If we want single mode for a given suite, we can set it with setting the `dual_mode` +parameter of the suite to False. + + >>> class Plugin2(object): + ... + ... selenium_tests = ( + ... KSSSeleniumTestSuite( + ... tests = KSSSeleniumTestCase('2'), + ... dual_mode = False, + ... ), + ... ) + >>> suite2 = Plugin2.selenium_tests[0] + + >>> tuple(suite2.get_relative_urls(None)) + ('@@resource?path=2',) + + +Using test layers +----------------- + +We can define a layer to the suite, with its own setup and teardown. + + >>> from kss.demo import KSSSeleniumTestLayerBase + + >>> class aLayer(KSSSeleniumTestLayerBase): + ... setup = KSSSeleniumTestCase('sa') + ... teardown = KSSSeleniumTestCase('ta') + +Now we add a suite with this layer. + + >>> class Plugin3(object): + ... + ... selenium_tests = ( + ... KSSSeleniumTestSuite( + ... tests = KSSSeleniumTestCase('3'), + ... layer = aLayer, + ... ), + ... ) + >>> suite3 = Plugin3.selenium_tests[0] + +Check the results: + + >>> tuple(suite3.get_testcase_paths()) + ('3', 'sa', 'ta', '...setDevMode.html', '...setProdMode.html') + + >>> tuple(suite3.get_relative_urls(None)) + ('@@resource?path=sa', '@@resource?path=...setDevMode.html', '@@resource?path=3', '@@resource?path=...setProdMode.html', '@@resource?path=3', '@@resource?path=ta') + + +Inheritence of layers +--------------------- + +Layers can inherit from each other. + + >>> class bLayer(aLayer): + ... setup = KSSSeleniumTestCase('sb') + ... teardown = KSSSeleniumTestCase('tb') + + >>> class Plugin4(object): + ... + ... selenium_tests = ( + ... KSSSeleniumTestSuite( + ... tests = KSSSeleniumTestCase('4'), + ... layer = bLayer, + ... ), + ... ) + >>> suite4 = Plugin4.selenium_tests[0] + + >>> tuple(suite4.get_testcase_paths()) + ('4', 'sb', 'tb', '...setDevMode.html', '...setProdMode.html') + + >>> tuple(suite4.get_relative_urls(None)) + ('@@resource?path=sa', '@@resource?path=sb', '@@resource?path=...setDevMode.html', '@@resource?path=4', '@@resource?path=...setProdMode.html', '@@resource?path=4', '@@resource?path=tb', '@@resource?path=ta') + + +Generating tests for a set of resources +--------------------------------------- + +Normally, the tests are not collected from suites individually, but a tree is built from a set +of suites providing an optimal setup and teardown sequence. This is done by the demo utility itself. +The list of suites is originating from various different plugins. + + >>> class Plugin5(object): + ... + ... selenium_tests = ( + ... KSSSeleniumTestSuite( + ... tests = KSSSeleniumTestCase('5a'), + ... layer = aLayer, + ... ), + ... KSSSeleniumTestSuite( + ... tests = KSSSeleniumTestCase('5b'), + ... layer = bLayer, + ... ), + ... ) + + >>> from kss.demo.selenium_layer import LayerTree + >>> tree = LayerTree(Plugin5.selenium_tests + (suite2, )) + >>> tuple(tree.get_relative_urls(None)) + ('@@resource?path=2', '@@resource?path=sa', '@@resource?path=...setDevMode.html', '@@resource?path=5a', '@@resource?path=...setProdMode.html', '@@resource?path=5a', '@@resource?path=sb', '@@resource?path=...setDevMode.html', '@@resource?path=5b', '@@resource?path=...setProdMode.html', '@@resource?path=5b', '@@resource?path=tb', '@@resource?path=ta') + +More testing of the layers can be found in the selenium_layers.txt file. + + Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/tests/test_doc.py ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/tests/test_doc.py (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/tests/test_doc.py Fri Apr 4 23:29:01 2008 @@ -25,4 +25,8 @@ package = 'kss.demo', optionflags = doctest.ELLIPSIS, ), + DocFileSuite('selenium_suites.txt', + package = 'kss.demo', + optionflags = doctest.ELLIPSIS, + ), )) From reebalazs at codespeak.net Fri Apr 4 23:49:36 2008 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Fri, 4 Apr 2008 23:49:36 +0200 (CEST) Subject: [KSS-checkins] r53366 - kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser Message-ID: <20080404214936.B614A16AB10@codespeak.net> Author: reebalazs Date: Fri Apr 4 23:49:36 2008 New Revision: 53366 Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser/setDevMode.html kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser/setProdMode.html Log: change titles in devel / prod mode suite Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser/setDevMode.html ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser/setDevMode.html (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser/setDevMode.html Fri Apr 4 23:49:36 2008 @@ -6,7 +6,7 @@
- + Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser/setProdMode.html ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser/setProdMode.html (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/browser/setProdMode.html Fri Apr 4 23:49:36 2008 @@ -6,7 +6,7 @@
basic_commands
Set development mode
open
- + From reebalazs at codespeak.net Sat Apr 5 00:07:51 2008 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 5 Apr 2008 00:07:51 +0200 (CEST) Subject: [KSS-checkins] r53368 - kukit/kss.demo/branch/1.4-kss-test/kss/demo Message-ID: <20080404220751.6E31116AAFE@codespeak.net> Author: reebalazs Date: Sat Apr 5 00:07:50 2008 New Revision: 53368 Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suites.txt Log: Add more tests Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suites.txt ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suites.txt (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suites.txt Sat Apr 5 00:07:50 2008 @@ -88,6 +88,41 @@ >>> tuple(suite3.get_relative_urls(None)) ('@@resource?path=sa', '@@resource?path=...setDevMode.html', '@@resource?path=3', '@@resource?path=...setProdMode.html', '@@resource?path=3', '@@resource?path=ta') +To use more tests in the setup of a layer, no extra effort is needed +since the testcase resource already provide KSSSeleniumTestCaseList +to construct collection from other testcases. + + >>> from kss.demo import KSSSeleniumTestCaseList + + >>> class a2Layer(KSSSeleniumTestLayerBase): + ... setup = KSSSeleniumTestCaseList( + ... KSSSeleniumTestCase('sa1'), + ... KSSSeleniumTestCase('sa2'), + ... ) + ... teardown = KSSSeleniumTestCaseList( + ... KSSSeleniumTestCase('ta1'), + ... KSSSeleniumTestCase('ta2'), + ... ) + + + >>> class Plugin3b(object): + ... + ... selenium_tests = ( + ... KSSSeleniumTestSuite( + ... tests = KSSSeleniumTestCase('3b'), + ... layer = a2Layer, + ... ), + ... ) + >>> suite3b = Plugin3b.selenium_tests[0] + +Check the results: + + >>> tuple(suite3b.get_testcase_paths()) + ('3b', 'sa1', 'sa2', 'ta1', 'ta2', '...setDevMode.html', '...setProdMode.html') + + >>> tuple(suite3b.get_relative_urls(None)) + ('@@resource?path=sa1', '@@resource?path=sa2', '@@resource?path=...setDevMode.html', '@@resource?path=3b', '@@resource?path=...setProdMode.html', '@@resource?path=3b', '@@resource?path=ta1', '@@resource?path=ta2') + Inheritence of layers --------------------- From reebalazs at codespeak.net Sat Apr 5 12:02:52 2008 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 5 Apr 2008 12:02:52 +0200 (CEST) Subject: [KSS-checkins] r53380 - in kukit/kss.demo/branch/1.4-kss-test/kss/demo: . tests Message-ID: <20080405100252.D7A7F16ABA0@codespeak.net> Author: reebalazs Date: Sat Apr 5 12:02:49 2008 New Revision: 53380 Added: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_testcases.txt (contents, props changed) Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suites.txt kukit/kss.demo/branch/1.4-kss-test/kss/demo/tests/test_doc.py Log: And add more tests. Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suites.txt ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suites.txt (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suites.txt Sat Apr 5 12:02:49 2008 @@ -178,3 +178,42 @@ More testing of the layers can be found in the selenium_layers.txt file. +Filtering of testcases +---------------------- + +Test suites can be given a ``component`` and ``application`` property. They are +both strings. + +``component`` should be the dotted component name of the owner of this test. +For example, ``plone.app.fancylib`` or ``kss.plugins.superplugin``. + +``application`` identified the application that tests for the usage of this +component. For example, ``Plone``. This is usually a bigger category then the +component, as an application consists of many components. + +If the application property is not specified, this means that the test does not +belong to a specific application, so it is either a kss core or a +plugin test. + +Filtering at the moment is only implemented by the ``application`` property. +This means all the tests of an application can be executed together. + + >>> class Plugin6(object): + ... + ... selenium_tests = ( + ... KSSSeleniumTestSuite( + ... tests = KSSSeleniumTestCase('6a'), + ... component = 'kss.plugins.superplugin', + ... ), + ... KSSSeleniumTestSuite( + ... tests = KSSSeleniumTestCase('6b'), + ... component = 'plone.app.fancylib', + ... application = 'Plone', + ... ), + ... ) + +The filtering is done from the resource registry. How the test sequence is +actually constructed from a selection of suites, is demonstrated in the +``selenium_layers.txt`` document. + + Added: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_testcases.txt ============================================================================== --- (empty file) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_testcases.txt Sat Apr 5 12:02:49 2008 @@ -0,0 +1,238 @@ + +=================== +Selenium test cases +=================== + +Selenium test cases in kss.demo are defined by "test collections". +A collection selects a number of tests. This is why they are called collections, +although in reality they are testcases which however can be constructed +from other collections. + +There are two methods that every collection has, and they are executed +during the creation of the test suite. + +Every collection implements an ``get_resolve_urls``. This returns +an iterator that yields a list of relative test urls. If resolved, +they should render a selenium test case in html format. The order +of the resources specifies their execution order. The method +needs to be called with the rendering view as a parameter. + +In addition, they also implement a ``get_testcase_paths`` method. +This, unlike the previous one, returns an iterator to a list of +absolute filenames. The order of these is not important. It must +contain all the filenames that the collection wants to publish +via the ``@@resource?path=...`` view provided by kss.demo. So, +each item in this list corresponds to an item in the ``get_resolve_urls`` +results. + +New collection types can be implemented by classes, as long as they +implement the ``ISeleniumTestCollection`` interface, in the way specified +below. kss.demo supplies the following collection types, that +allow to specify a set of testcases in a flexible way. + + +Creation of testcase collections +-------------------------------- + +The collections use implicit magic (the same one used by the +Zope CA for the ``implements``) to locate the directory of the +python file that instantiates the collection. This allows that +filenames that are used as parameters, will be expanded to their +absolute class automatically. If we create a collection in itself, +we will get an error: + + >>> from kss.demo import KSSSeleniumTestCase + + >>> tests = KSSSeleniumTestCase('my_testcase.html') + Traceback (most recent call last): + ... + TypeError: The suite class can be used only from inside a class definition. + + The correct way is to use it from inside a class definition. This way + the html file will be located relative to this directory: + + >>> from kss.demo import KSSSeleniumTestSuite + + >>> class Plugin(object): + ... + ... selenium_tests = ( + ... KSSSeleniumTestSuite( + ... tests = KSSSeleniumTestCase('my_testcase.html'), + ... ), + ... ) + + +Test cases by filename +---------------------- + +This collection will contain a single test that we specify by filepath. +The path will be applied relatively to the directory where the file +containing the instantiation resides. + + >>> class Suite: + ... tests = KSSSeleniumTestCase('my_testcase.html') + >>> case1 = Suite.tests + +The ``get_relative_url`` will only return a single resource url: + + >>> tuple(case1.get_relative_urls(None)) + ('@@resource?path=...my_testcase.html',) + +Note that we gave ``None`` as a parameter. This should be normally +the view that does the rendering, needed to be passed to each collection. +We will see a case later when this will be important. + +The ``get_testcase_paths`` method also just returns a single absolute +filepath. (In the case of the test they will really not be absolute, +because the locator magic does not work well with doctests.) + + >>> tuple(case1.get_testcase_paths()) + ('...my_testcase.html',) + + +Test cases by directory +----------------------- + +This is the usual way of working with tests. We specify a directory, +and every ``*.html`` file in that directory is picked into the testcase +collection. + + >>> from kss.demo import KSSSeleniumTestDirectory + + >>> class Suite2: + ... tests = KSSSeleniumTestDirectory('selenium_tests') + >>> case2 = Suite2.tests + + We don't have this directory here. So in both cases we get an error. + + >>> tuple(case2.get_relative_urls(None)) + Traceback (most recent call last): + ... + OSError: [Errno 2] No such file or directory: 'selenium_tests' + + >>> tuple(case2.get_testcase_paths()) + Traceback (most recent call last): + ... + OSError: [Errno 2] No such file or directory: 'selenium_tests' + + For the sake of the test, we will find a testcase directory + from kss.core. Note this would not be needed from real code, + you'd just need to use the directory name. + + >>> import sys, os.path, kss.core.plugins.core.demo + >>> rootdir = os.path.dirname(sys.modules['kss.core.plugins.core.demo'].__file__) + >>> dirpath = os.path.join(rootdir, 'selenium_tests') + + >>> class Suite2: + ... tests = KSSSeleniumTestDirectory(dirpath) + >>> case2 = Suite2.tests + + There are many tests in this list. (These are the tests for the kss core plugin.) + + >>> tuple(case2.get_relative_urls(None)) + ('@@resource?path=...0_ecmaunit_tests.html', ...) + + >>> tuple(case2.get_testcase_paths()) + ('...0_ecmaunit_tests.html', ...) + + +Empty test cases +---------------- + +These are used for default values. + + >>> from kss.demo import KSSSeleniumEmptyTestCase + + >>> class Suite3: + ... tests = KSSSeleniumEmptyTestCase() + >>> case3 = Suite3.tests + + >>> tuple(case3.get_relative_urls(None)) + () + + >>> tuple(case3.get_testcase_paths()) + () + + +Test case lists +--------------- + +These can be used to compose collections from other collections. + + >>> from kss.demo import KSSSeleniumTestCaseList + + >>> class Suite4: + ... tests = KSSSeleniumTestCaseList( + ... KSSSeleniumTestCase('testcase1.html'), + ... KSSSeleniumTestCase('testcase2.html'), + ... ) + >>> case4 = Suite4.tests + + >>> tuple(case4.get_relative_urls(None)) + ('@@resource?path=...testcase1.html', '@@resource?path=...testcase2.html') + + >>> tuple(case4.get_testcase_paths()) + ('...testcase1.html', '...testcase2.html') + +Of course, they can also resurse. + + >>> class Suite5: + ... tests = KSSSeleniumTestCaseList( + ... KSSSeleniumTestCase('testcase1.html'), + ... KSSSeleniumTestCaseList( + ... KSSSeleniumTestCase('testcase2.html'), + ... KSSSeleniumTestCase('testcase3.html'), + ... ), + ... ) + >>> case5 = Suite5.tests + + >>> tuple(case5.get_relative_urls(None)) + ('@@resource?path=...testcase1.html', '@@resource?path=...testcase2.html', '@@resource?path=...testcase3.html') + + >>> tuple(case5.get_testcase_paths()) + ('...testcase1.html', '...testcase2.html', '...testcase3.html') + + +Support for sandbox creation +---------------------------- + +A more special testcase is used to create a sandbox (a site with some content, or +some initial data that each tests need). This test suite +will be rendered by the browser view and take parameters. These are used as +credentials for the content creation (as normal login to Zope could not be used +from the setup), and to specify the url of the view that will carry out the +creation. + +For this test, we will need a real (although fake) view. + + >>> class FakeRequest(object): + ... admin_username = 'admin' + ... admin_password = 'admin' + ... def get(self, key, default=None): + ... return getattr(self, key, default) + >>> class FakeView(object): + ... content = None + ... request = FakeRequest() + >>> fake_view = FakeView() + + >>> from kss.demo import KSSSeleniumSandboxCreationTestCase + + >>> class Suite6: + ... tests = KSSSeleniumSandboxCreationTestCase('@@kss_create_my_sandbox') + >>> case6 = Suite6.tests + + >>> tuple(case6.get_relative_urls(fake_view)) + ('@@kss-selenium-create-sandbox-test.html?method_name=@@kss_create_my_sandbox&admin_username=admin&admin_password=admin',) + +This view will generate a testcase which is an informational form with a button. If +this button is pressed, the view specified with ``method_name`` will be executed. +This will receive the credentials, and it will check them against the Zope +authentication information, before acting as Administrator. + +The collection does not return paths, since it does not use the ```@@resource?path=...``` +view. + + >>> tuple(case6.get_testcase_paths()) + () + + Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/tests/test_doc.py ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/tests/test_doc.py (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/tests/test_doc.py Sat Apr 5 12:02:49 2008 @@ -21,6 +21,10 @@ def test_suite(): return unittest.TestSuite(( + DocFileSuite('selenium_testcases.txt', + package = 'kss.demo', + optionflags = doctest.ELLIPSIS, + ), DocFileSuite('selenium_layers.txt', package = 'kss.demo', optionflags = doctest.ELLIPSIS, From reebalazs at codespeak.net Sun Apr 6 11:00:02 2008 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sun, 6 Apr 2008 11:00:02 +0200 (CEST) Subject: [KSS-checkins] r53419 - kukit/kss.demo/branch/1.4-kss-test/kss/demo Message-ID: <20080406090002.45BCE16A6B4@codespeak.net> Author: reebalazs Date: Sun Apr 6 11:00:00 2008 New Revision: 53419 Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_testcases.txt Log: Fix a typo. Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_testcases.txt ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_testcases.txt (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_testcases.txt Sun Apr 6 11:00:00 2008 @@ -174,7 +174,7 @@ >>> tuple(case4.get_testcase_paths()) ('...testcase1.html', '...testcase2.html') -Of course, they can also resurse. +Of course, they can also recurse. >>> class Suite5: ... tests = KSSSeleniumTestCaseList( From reebalazs at codespeak.net Sun Apr 6 11:00:49 2008 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sun, 6 Apr 2008 11:00:49 +0200 (CEST) Subject: [KSS-checkins] r53420 - kukit/kss.demo/branch/1.4-kss-test/kss/demo Message-ID: <20080406090049.96CEA16A6B4@codespeak.net> Author: reebalazs Date: Sun Apr 6 11:00:48 2008 New Revision: 53420 Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_testcases.txt Log: Fix some grammar. Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_testcases.txt ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_testcases.txt (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_testcases.txt Sun Apr 6 11:00:48 2008 @@ -197,7 +197,7 @@ ---------------------------- A more special testcase is used to create a sandbox (a site with some content, or -some initial data that each tests need). This test suite +some initial data that each test needs). This test suite will be rendered by the browser view and take parameters. These are used as credentials for the content creation (as normal login to Zope could not be used from the setup), and to specify the url of the view that will carry out the From reebalazs at codespeak.net Sun Apr 6 11:07:42 2008 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sun, 6 Apr 2008 11:07:42 +0200 (CEST) Subject: [KSS-checkins] r53421 - kukit/kss.demo/branch/1.4-kss-test/kss/demo Message-ID: <20080406090742.6758416A6C3@codespeak.net> Author: reebalazs Date: Sun Apr 6 11:07:41 2008 New Revision: 53421 Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_layers.txt kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suites.txt kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_testcases.txt Log: Reformat paragraphs Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_layers.txt ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_layers.txt (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_layers.txt Sun Apr 6 11:07:41 2008 @@ -117,10 +117,10 @@ ... TypeError: The suite class can be used only from inside a class definition. -As the error message says, we must define the class from inside another -class. This is used to locate files relatively from the module where the -definition is. So we have to define them from a dummy plugin (however the plugin -itself play no role in testing). +As the error message says, we must define the class from inside +another class. This is used to locate files relatively from the +module where the definition is. So we have to define them from a +dummy plugin (however the plugin itself play no role in testing). >>> class DummyPlugin(object): ... @@ -130,8 +130,8 @@ ... ) >>> aSuite = DummyPlugin.aSuite -The layers whose tests are active, will build a tree to compute the -optimal setup-teardown order. +The layers whose tests are active, will build a tree to compute +the optimal setup-teardown order. >>> from kss.demo.selenium_layer import LayerTree @@ -139,10 +139,11 @@ >>> tuple(tree.get_relative_urls(None)) ('@@resource?path=1', '@@resource?path=...setDevMode.html', '@@resource?path=ta', '@@resource?path=...setProdMode.html', '@@resource?path=ta', '@@resource?path=2') -As we can see in the above results, the tests are generated properly with setup and teardown. +As we can see in the above results, the tests are generated +properly with setup and teardown. -If more cases use the same layer, they are grouped. They also just need to change -the production mode twice: +If more cases use the same layer, they are grouped. They also +just need to change the production mode twice: >>> class DummyPlugin2(object): ... @@ -190,31 +191,33 @@ >>> d2Suite = DummyPlugin3.d2Suite >>> eSuite = DummyPlugin3.eSuite -And see what happens if only suite "d" is selected. We can see that the setup and teardown sequence is correct. +And see what happens if only suite "d" is selected. We can see +that the setup and teardown sequence is correct. >>> tree = LayerTree((dSuite, )) >>> tuple(tree.get_relative_urls(None)) ('@@resource?path=1', '@@resource?path=7', '@@resource?path=9', '@@resource?path=...setDevMode.html', '@@resource?path=td', '@@resource?path=...setProdMode.html', '@@resource?path=td', '@@resource?path=10', '@@resource?path=8', '@@resource?path=2') -Replay this with a bunch of other tests added. Setup and teardown is executed ideally. -In this case we have more dev / prod mode changes, since these are the fastest -they are wrapped inside the layer. +Replay this with a bunch of other tests added. Setup and teardown +is executed ideally. In this case we have more dev / prod mode +changes, since these are the fastest they are wrapped inside the +layer. >>> tree = LayerTree((cSuite, dSuite, d2Suite)) >>> tuple(tree.get_relative_urls(None)) ('@@resource?path=1', '@@resource?path=7', '@@resource?path=...setDevMode.html', '@@resource?path=tc', '@@resource?path=...setProdMode.html', '@@resource?path=tc', '@@resource?path=9', '@@resource?path=...setDevMode.html', '@@resource?path=td', '@@resource?path=td2', '@@resource?path=...setProdMode.html', '@@resource?path=td', '@@resource?path=td2', '@@resource?path=10', '@@resource?path=8', '@@resource?path=2') -So far we have only tried single path setups. Let's now try a split route. -The setup and teardown work correctly in one level. +So far we have only tried single path setups. Let's now try a +split route. The setup and teardown work correctly in one level. >>> tree = LayerTree((aSuite, bSuite, cSuite)) >>> tuple(tree.get_relative_urls(None)) ('@@resource?path=1', '@@resource?path=...setDevMode.html', '@@resource?path=ta', '@@resource?path=...setProdMode.html', '@@resource?path=ta', '@@resource?path=5', '@@resource?path=...setDevMode.html', '@@resource?path=tb', '@@resource?path=...setProdMode.html', '@@resource?path=tb', '@@resource?path=6', '@@resource?path=7', '@@resource?path=...setDevMode.html', '@@resource?path=tc', '@@resource?path=...setProdMode.html', '@@resource?path=tc', '@@resource?path=8', '@@resource?path=2') -Another functionality is that certain tests may mark that they don't want -to be in dual mode: +Another functionality is that certain tests may mark that they +don't want to be in dual mode: >>> class DummyPlugin4(object): ... @@ -229,8 +232,9 @@ >>> tuple(tree.get_relative_urls(None)) ('@@resource?path=1', '@@resource?path=5', '@@resource?path=tb2', '@@resource?path=6', '@@resource?path=2') -This is also true if both dual and single mode tests are in the same layer. In this case -the tests will wun in the end, which in practice means Production mode. +This is also true if both dual and single mode tests are in the +same layer. In this case the tests will wun in the end, which in +practice means Production mode. >>> tree = LayerTree((bSuite, b2Suite)) >>> tuple(tree.get_relative_urls(None)) @@ -243,8 +247,9 @@ ('@@resource?path=1', '@@resource?path=...setDevMode.html', '@@resource?path=ta', '@@resource?path=ta2', '@@resource?path=...setProdMode.html', '@@resource?path=ta', '@@resource?path=ta2', '@@resource?path=5', '@@resource?path=...setDevMode.html', '@@resource?path=tb', '@@resource?path=...setProdMode.html', '@@resource?path=tb', '@@resource?path=tb2', '@@resource?path=6', '@@resource?path=7', '@@resource?path=...setDevMode.html', '@@resource?path=tc', '@@resource?path=...setProdMode.html', '@@resource?path=tc', '@@resource?path=9', '@@resource?path=...setDevMode.html', '@@resource?path=td', '@@resource?path=td2', '@@resource?path=...setProdMode.html', '@@resource?path=td', '@@resource?path=td2', '@@resource?path=10', '@@resource?path=11', '@@resource?path=...setDevMode.html', '@@resource?path=te', '@@resource?path=...setProdMode.html', '@@resource?path=te', '@@resource?path=12', '@@resource?path=8', '@@resource?path=2') -Finally, we still need to check the following: -Suites that are empty are skipped, and no setup teardown or devel / prod mode is generated for them. +Finally, we still need to check the following: Suites that are +empty are skipped, and no setup teardown or devel / prod mode is +generated for them. >>> class DummyPlugin5(object): ... Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suites.txt ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suites.txt (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suites.txt Sun Apr 6 11:07:41 2008 @@ -3,7 +3,8 @@ Selenium test suites ==================== -Selenium test suites can be set up from plugin resource definitions. +Selenium test suites can be set up from plugin resource +definitions. >>> from kss.demo import ( ... KSSSeleniumTestSuite, @@ -20,17 +21,18 @@ >>> suite1 = Plugin.selenium_tests[0] A suite is like a testcase collection, so it provides its allowed -resource filenames. These are used to secure the resource handling -(to select which files can be served from the filesystem). +resource filenames. These are used to secure the resource +handling (to select which files can be served from the +filesystem). >>> tuple(suite1.get_testcase_paths()) ('1', '...setDevMode.html', '...setProdMode.html') -(Normally we would see an absolute path in place of '1', but the module -finder does not work from within doctests.) +(Normally we would see an absolute path in place of '1', but the +module finder does not work from within doctests.) -And the list of test urls as well. (We use in place of the view which -is not important in this case.) +And the list of test urls as well. (We use in place of the view +which is not important in this case.) >>> tuple(suite1.get_relative_urls(None)) ('@@resource?path=...setDevMode.html', '@@resource?path=1', '@@resource?path=...setProdMode.html', '@@resource?path=1') @@ -39,9 +41,10 @@ Dual and single mode -------------------- -The `suite1` suite also executes the tests twice, both in development and production mode. -If we want single mode for a given suite, we can set it with setting the `dual_mode` -parameter of the suite to False. +The `suite1` suite also executes the tests twice, both in +development and production mode. If we want single mode for a +given suite, we can set it with setting the `dual_mode` parameter +of the suite to False. >>> class Plugin2(object): ... @@ -60,7 +63,8 @@ Using test layers ----------------- -We can define a layer to the suite, with its own setup and teardown. +We can define a layer to the suite, with its own setup and +teardown. >>> from kss.demo import KSSSeleniumTestLayerBase @@ -88,9 +92,10 @@ >>> tuple(suite3.get_relative_urls(None)) ('@@resource?path=sa', '@@resource?path=...setDevMode.html', '@@resource?path=3', '@@resource?path=...setProdMode.html', '@@resource?path=3', '@@resource?path=ta') -To use more tests in the setup of a layer, no extra effort is needed -since the testcase resource already provide KSSSeleniumTestCaseList -to construct collection from other testcases. +To use more tests in the setup of a layer, no extra effort is +needed since the testcase resource already provide +KSSSeleniumTestCaseList to construct collection from other +testcases. >>> from kss.demo import KSSSeleniumTestCaseList @@ -153,9 +158,11 @@ Generating tests for a set of resources --------------------------------------- -Normally, the tests are not collected from suites individually, but a tree is built from a set -of suites providing an optimal setup and teardown sequence. This is done by the demo utility itself. -The list of suites is originating from various different plugins. +Normally, the tests are not collected from suites individually, +but a tree is built from a set of suites providing an optimal +setup and teardown sequence. This is done by the demo utility +itself. The list of suites is originating from various different +plugins. >>> class Plugin5(object): ... @@ -175,28 +182,32 @@ >>> tuple(tree.get_relative_urls(None)) ('@@resource?path=2', '@@resource?path=sa', '@@resource?path=...setDevMode.html', '@@resource?path=5a', '@@resource?path=...setProdMode.html', '@@resource?path=5a', '@@resource?path=sb', '@@resource?path=...setDevMode.html', '@@resource?path=5b', '@@resource?path=...setProdMode.html', '@@resource?path=5b', '@@resource?path=tb', '@@resource?path=ta') -More testing of the layers can be found in the selenium_layers.txt file. +More testing of the layers can be found in the +selenium_layers.txt file. Filtering of testcases ---------------------- -Test suites can be given a ``component`` and ``application`` property. They are -both strings. +Test suites can be given a ``component`` and ``application`` +property. They are both strings. -``component`` should be the dotted component name of the owner of this test. -For example, ``plone.app.fancylib`` or ``kss.plugins.superplugin``. - -``application`` identified the application that tests for the usage of this -component. For example, ``Plone``. This is usually a bigger category then the -component, as an application consists of many components. - -If the application property is not specified, this means that the test does not -belong to a specific application, so it is either a kss core or a -plugin test. - -Filtering at the moment is only implemented by the ``application`` property. -This means all the tests of an application can be executed together. +``component`` should be the dotted component name of the owner of +this test. For example, ``plone.app.fancylib`` or +``kss.plugins.superplugin``. + +``application`` identified the application that tests for the +usage of this component. For example, ``Plone``. This is usually +a bigger category then the component, as an application consists +of many components. + +If the application property is not specified, this means that the +test does not belong to a specific application, so it is either a +kss core or a plugin test. + +Filtering at the moment is only implemented by the +``application`` property. This means all the tests of an +application can be executed together. >>> class Plugin6(object): ... @@ -212,8 +223,8 @@ ... ), ... ) -The filtering is done from the resource registry. How the test sequence is -actually constructed from a selection of suites, is demonstrated in the -``selenium_layers.txt`` document. +The filtering is done from the resource registry. How the test +sequence is actually constructed from a selection of suites, is +demonstrated in the ``selenium_layers.txt`` document. Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_testcases.txt ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_testcases.txt (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_testcases.txt Sun Apr 6 11:07:41 2008 @@ -3,43 +3,45 @@ Selenium test cases =================== -Selenium test cases in kss.demo are defined by "test collections". -A collection selects a number of tests. This is why they are called collections, -although in reality they are testcases which however can be constructed -from other collections. +Selenium test cases in kss.demo are defined by "test +collections". A collection selects a number of tests. This is +why they are called collections, although in reality they are +testcases which however can be constructed from other +collections. -There are two methods that every collection has, and they are executed -during the creation of the test suite. +There are two methods that every collection has, and they are +executed during the creation of the test suite. Every collection implements an ``get_resolve_urls``. This returns -an iterator that yields a list of relative test urls. If resolved, -they should render a selenium test case in html format. The order -of the resources specifies their execution order. The method -needs to be called with the rendering view as a parameter. +an iterator that yields a list of relative test urls. If +resolved, they should render a selenium test case in html format. +The order of the resources specifies their execution order. The +method needs to be called with the rendering view as a parameter. In addition, they also implement a ``get_testcase_paths`` method. This, unlike the previous one, returns an iterator to a list of absolute filenames. The order of these is not important. It must contain all the filenames that the collection wants to publish via the ``@@resource?path=...`` view provided by kss.demo. So, -each item in this list corresponds to an item in the ``get_resolve_urls`` -results. +each item in this list corresponds to an item in the +``get_resolve_urls`` results. -New collection types can be implemented by classes, as long as they -implement the ``ISeleniumTestCollection`` interface, in the way specified -below. kss.demo supplies the following collection types, that -allow to specify a set of testcases in a flexible way. +New collection types can be implemented by classes, as long as +they implement the ``ISeleniumTestCollection`` interface, in the +way specified below. kss.demo supplies the following collection +types, that allow to specify a set of testcases in a flexible +way. Creation of testcase collections -------------------------------- -The collections use implicit magic (the same one used by the -Zope CA for the ``implements``) to locate the directory of the -python file that instantiates the collection. This allows that -filenames that are used as parameters, will be expanded to their -absolute class automatically. If we create a collection in itself, -we will get an error: +The collections use implicit magic (the same one used by the Zope +CA for the ``implements``) to locate the directory of the python +file that instantiates the collection. This allows that filenames +that are used as parameters, will be expanded to their absolute +class automatically. If we create a collection in itself, we will +get an error: >>> from kss.demo import KSSSeleniumTestCase @@ -48,8 +50,8 @@ ... TypeError: The suite class can be used only from inside a class definition. - The correct way is to use it from inside a class definition. This way - the html file will be located relative to this directory: +The correct way is to use it from inside a class definition. This +way the html file will be located relative to this directory: >>> from kss.demo import KSSSeleniumTestSuite @@ -65,9 +67,9 @@ Test cases by filename ---------------------- -This collection will contain a single test that we specify by filepath. -The path will be applied relatively to the directory where the file -containing the instantiation resides. +This collection will contain a single test that we specify by +filepath. The path will be applied relatively to the directory +where the file containing the instantiation resides. >>> class Suite: ... tests = KSSSeleniumTestCase('my_testcase.html') @@ -78,13 +80,15 @@ >>> tuple(case1.get_relative_urls(None)) ('@@resource?path=...my_testcase.html',) -Note that we gave ``None`` as a parameter. This should be normally -the view that does the rendering, needed to be passed to each collection. -We will see a case later when this will be important. - -The ``get_testcase_paths`` method also just returns a single absolute -filepath. (In the case of the test they will really not be absolute, -because the locator magic does not work well with doctests.) +Note that we gave ``None`` as a parameter. This should be +normally the view that does the rendering, needed to be passed to +each collection. We will see a case later when this will be +important. + +The ``get_testcase_paths`` method also just returns a single +absolute filepath. (In the case of the test they will really not +be absolute, because the locator magic does not work well with +doctests.) >>> tuple(case1.get_testcase_paths()) ('...my_testcase.html',) @@ -93,9 +97,9 @@ Test cases by directory ----------------------- -This is the usual way of working with tests. We specify a directory, -and every ``*.html`` file in that directory is picked into the testcase -collection. +This is the usual way of working with tests. We specify a +directory, and every ``*.html`` file in that directory is picked +into the testcase collection. >>> from kss.demo import KSSSeleniumTestDirectory @@ -103,7 +107,8 @@ ... tests = KSSSeleniumTestDirectory('selenium_tests') >>> case2 = Suite2.tests - We don't have this directory here. So in both cases we get an error. +We don't have this directory here. So in both cases we get an +error. >>> tuple(case2.get_relative_urls(None)) Traceback (most recent call last): @@ -115,9 +120,9 @@ ... OSError: [Errno 2] No such file or directory: 'selenium_tests' - For the sake of the test, we will find a testcase directory - from kss.core. Note this would not be needed from real code, - you'd just need to use the directory name. +For the sake of the test, we will find a testcase directory from +kss.core. Note this would not be needed from real code, you'd +just need to use the directory name. >>> import sys, os.path, kss.core.plugins.core.demo >>> rootdir = os.path.dirname(sys.modules['kss.core.plugins.core.demo'].__file__) @@ -127,7 +132,8 @@ ... tests = KSSSeleniumTestDirectory(dirpath) >>> case2 = Suite2.tests - There are many tests in this list. (These are the tests for the kss core plugin.) +There are many tests in this list. (These are the tests for the +kss core plugin.) >>> tuple(case2.get_relative_urls(None)) ('@@resource?path=...0_ecmaunit_tests.html', ...) @@ -196,12 +202,13 @@ Support for sandbox creation ---------------------------- -A more special testcase is used to create a sandbox (a site with some content, or -some initial data that each test needs). This test suite -will be rendered by the browser view and take parameters. These are used as -credentials for the content creation (as normal login to Zope could not be used -from the setup), and to specify the url of the view that will carry out the -creation. +A more special testcase is used to create a sandbox (a site with +some content, or some initial data that each test needs). This +test suite will be rendered by the browser view and take +parameters. These are used as credentials for the content +creation (as normal login to Zope could not be used from the +setup), and to specify the url of the view that will carry out +the creation. For this test, we will need a real (although fake) view. @@ -224,13 +231,14 @@ >>> tuple(case6.get_relative_urls(fake_view)) ('@@kss-selenium-create-sandbox-test.html?method_name=@@kss_create_my_sandbox&admin_username=admin&admin_password=admin',) -This view will generate a testcase which is an informational form with a button. If -this button is pressed, the view specified with ``method_name`` will be executed. -This will receive the credentials, and it will check them against the Zope +This view will generate a testcase which is an informational form +with a button. If this button is pressed, the view specified with +``method_name`` will be executed. This will receive the +credentials, and it will check them against the Zope authentication information, before acting as Administrator. -The collection does not return paths, since it does not use the ```@@resource?path=...``` -view. +The collection does not return paths, since it does not use the +``@@resource?path=...`` view. >>> tuple(case6.get_testcase_paths()) () From reebalazs at codespeak.net Sun Apr 6 11:19:30 2008 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sun, 6 Apr 2008 11:19:30 +0200 (CEST) Subject: [KSS-checkins] r53422 - kukit/kss.demo/branch/1.4-kss-test/kss/demo Message-ID: <20080406091930.C652C16A710@codespeak.net> Author: reebalazs Date: Sun Apr 6 11:19:28 2008 New Revision: 53422 Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_layers.txt kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suites.txt kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_testcases.txt Log: Minor changes in tests Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_layers.txt ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_layers.txt (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_layers.txt Sun Apr 6 11:19:28 2008 @@ -233,7 +233,7 @@ ('@@resource?path=1', '@@resource?path=5', '@@resource?path=tb2', '@@resource?path=6', '@@resource?path=2') This is also true if both dual and single mode tests are in the -same layer. In this case the tests will wun in the end, which in +same layer. In this case the tests will run in the end, which in practice means Production mode. >>> tree = LayerTree((bSuite, b2Suite)) Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suites.txt ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suites.txt (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_suites.txt Sun Apr 6 11:19:28 2008 @@ -26,7 +26,7 @@ filesystem). >>> tuple(suite1.get_testcase_paths()) - ('1', '...setDevMode.html', '...setProdMode.html') + ('...1', '...setDevMode.html', '...setProdMode.html') (Normally we would see an absolute path in place of '1', but the module finder does not work from within doctests.) @@ -35,7 +35,7 @@ which is not important in this case.) >>> tuple(suite1.get_relative_urls(None)) - ('@@resource?path=...setDevMode.html', '@@resource?path=1', '@@resource?path=...setProdMode.html', '@@resource?path=1') + ('@@resource?path=...setDevMode.html', '@@resource?path=...1', '@@resource?path=...setProdMode.html', '@@resource?path=1') Dual and single mode @@ -57,7 +57,7 @@ >>> suite2 = Plugin2.selenium_tests[0] >>> tuple(suite2.get_relative_urls(None)) - ('@@resource?path=2',) + ('@@resource?path=...2',) Using test layers @@ -87,10 +87,10 @@ Check the results: >>> tuple(suite3.get_testcase_paths()) - ('3', 'sa', 'ta', '...setDevMode.html', '...setProdMode.html') + ('...3', '...sa', '...ta', '...setDevMode.html', '...setProdMode.html') >>> tuple(suite3.get_relative_urls(None)) - ('@@resource?path=sa', '@@resource?path=...setDevMode.html', '@@resource?path=3', '@@resource?path=...setProdMode.html', '@@resource?path=3', '@@resource?path=ta') + ('@@resource?path=...sa', '@@resource?path=...setDevMode.html', '@@resource?path=...3', '@@resource?path=...setProdMode.html', '@@resource?path=...3', '@@resource?path=...ta') To use more tests in the setup of a layer, no extra effort is needed since the testcase resource already provide @@ -123,10 +123,10 @@ Check the results: >>> tuple(suite3b.get_testcase_paths()) - ('3b', 'sa1', 'sa2', 'ta1', 'ta2', '...setDevMode.html', '...setProdMode.html') + ('...3b', '...sa1', '...sa2', '...ta1', '...ta2', '...setDevMode.html', '...setProdMode.html') >>> tuple(suite3b.get_relative_urls(None)) - ('@@resource?path=sa1', '@@resource?path=sa2', '@@resource?path=...setDevMode.html', '@@resource?path=3b', '@@resource?path=...setProdMode.html', '@@resource?path=3b', '@@resource?path=ta1', '@@resource?path=ta2') + ('@@resource?path=...sa1', '@@resource?path=...sa2', '@@resource?path=...setDevMode.html', '@@resource?path=...3b', '@@resource?path=...setProdMode.html', '@@resource?path=...3b', '@@resource?path=...ta1', '@@resource?path=...ta2') Inheritence of layers @@ -149,10 +149,10 @@ >>> suite4 = Plugin4.selenium_tests[0] >>> tuple(suite4.get_testcase_paths()) - ('4', 'sb', 'tb', '...setDevMode.html', '...setProdMode.html') + ('...4', '...sb', '...tb', '...setDevMode.html', '...setProdMode.html') >>> tuple(suite4.get_relative_urls(None)) - ('@@resource?path=sa', '@@resource?path=sb', '@@resource?path=...setDevMode.html', '@@resource?path=4', '@@resource?path=...setProdMode.html', '@@resource?path=4', '@@resource?path=tb', '@@resource?path=ta') + ('@@resource?path=...sa', '@@resource?path=...sb', '@@resource?path=...setDevMode.html', '@@resource?path=...4', '@@resource?path=...setProdMode.html', '@@resource?path=...4', '@@resource?path=...tb', '@@resource?path=...ta') Generating tests for a set of resources @@ -180,7 +180,7 @@ >>> from kss.demo.selenium_layer import LayerTree >>> tree = LayerTree(Plugin5.selenium_tests + (suite2, )) >>> tuple(tree.get_relative_urls(None)) - ('@@resource?path=2', '@@resource?path=sa', '@@resource?path=...setDevMode.html', '@@resource?path=5a', '@@resource?path=...setProdMode.html', '@@resource?path=5a', '@@resource?path=sb', '@@resource?path=...setDevMode.html', '@@resource?path=5b', '@@resource?path=...setProdMode.html', '@@resource?path=5b', '@@resource?path=tb', '@@resource?path=ta') + ('@@resource?path=...2', '@@resource?path=...sa', '@@resource?path=...setDevMode.html', '@@resource?path=...5a', '@@resource?path=...setProdMode.html', '@@resource?path=...5a', '@@resource?path=...sb', '@@resource?path=...setDevMode.html', '@@resource?path=...5b', '@@resource?path=...setProdMode.html', '@@resource?path=...5b', '@@resource?path=...tb', '@@resource?path=...ta') More testing of the layers can be found in the selenium_layers.txt file. Modified: kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_testcases.txt ============================================================================== --- kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_testcases.txt (original) +++ kukit/kss.demo/branch/1.4-kss-test/kss/demo/selenium_testcases.txt Sun Apr 6 11:19:28 2008 @@ -40,7 +40,7 @@ CA for the ``implements``) to locate the directory of the python file that instantiates the collection. This allows that filenames that are used as parameters, will be expanded to their absolute -class automatically. If we create a collection in itself, we will +path automatically. If we create a collection in itself, we will get an error: >>> from kss.demo import KSSSeleniumTestCase @@ -122,7 +122,7 @@ For the sake of the test, we will find a testcase directory from kss.core. Note this would not be needed from real code, you'd -just need to use the directory name. +just need to use the relative directory name. >>> import sys, os.path, kss.core.plugins.core.demo >>> rootdir = os.path.dirname(sys.modules['kss.core.plugins.core.demo'].__file__) From gotcha at codespeak.net Sun Apr 6 11:44:45 2008 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 6 Apr 2008 11:44:45 +0200 (CEST) Subject: [KSS-checkins] r53425 - kukit/kss.buildout/branch/jscoverage Message-ID: <20080406094445.DBF1B16A69E@codespeak.net> Author: gotcha Date: Sun Apr 6 11:44:45 2008 New Revision: 53425 Added: kukit/kss.buildout/branch/jscoverage/ - copied from r53424, kukit/kss.buildout/trunk/ Log: jscoverage support From gotcha at codespeak.net Sun Apr 6 11:45:17 2008 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 6 Apr 2008 11:45:17 +0200 (CEST) Subject: [KSS-checkins] r53426 - kukit/kss.core/branch/jscoverage Message-ID: <20080406094517.7BD2216A69E@codespeak.net> Author: gotcha Date: Sun Apr 6 11:45:17 2008 New Revision: 53426 Added: kukit/kss.core/branch/jscoverage/ - copied from r53425, kukit/kss.core/trunk/ Log: jscoverage support From gotcha at codespeak.net Sun Apr 6 11:45:39 2008 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 6 Apr 2008 11:45:39 +0200 (CEST) Subject: [KSS-checkins] r53427 - kukit/kss.demo/branch/jscoverage Message-ID: <20080406094539.7457316A69E@codespeak.net> Author: gotcha Date: Sun Apr 6 11:45:39 2008 New Revision: 53427 Added: kukit/kss.demo/branch/jscoverage/ - copied from r53426, kukit/kss.demo/trunk/ Log: jscoverage support From gotcha at codespeak.net Sun Apr 6 11:46:08 2008 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 6 Apr 2008 11:46:08 +0200 (CEST) Subject: [KSS-checkins] r53428 - kukit/kukit.js/branch/jscoverage Message-ID: <20080406094608.F357416A69E@codespeak.net> Author: gotcha Date: Sun Apr 6 11:46:08 2008 New Revision: 53428 Added: kukit/kukit.js/branch/jscoverage/ - copied from r53427, kukit/kukit.js/trunk/ Log: jscoverage support From gotcha at codespeak.net Sun Apr 6 13:35:15 2008 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 6 Apr 2008 13:35:15 +0200 (CEST) Subject: [KSS-checkins] r53436 - kukit/kss.buildout/branch/jscoverage/src Message-ID: <20080406113515.A8C3D16A69C@codespeak.net> Author: gotcha Date: Sun Apr 6 13:35:12 2008 New Revision: 53436 Modified: kukit/kss.buildout/branch/jscoverage/src/ (props changed) kukit/kss.buildout/branch/jscoverage/src/EXTERNALS.txt Log: jscoverage support Modified: kukit/kss.buildout/branch/jscoverage/src/EXTERNALS.txt ============================================================================== --- kukit/kss.buildout/branch/jscoverage/src/EXTERNALS.txt (original) +++ kukit/kss.buildout/branch/jscoverage/src/EXTERNALS.txt Sun Apr 6 13:35:12 2008 @@ -1,5 +0,0 @@ -# created by: svn propset svn:externals -F ./EXTERNALS.TXT . - -kss.core https://codespeak.net/svn/kukit/kss.core/trunk -kss.demo https://codespeak.net/svn/kukit/kss.demo/trunk - From gotcha at codespeak.net Sun Apr 6 13:36:33 2008 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 6 Apr 2008 13:36:33 +0200 (CEST) Subject: [KSS-checkins] r53437 - in kukit/kss.core/trunk/kss/core: . pluginregistry/browser plugins/core/demo Message-ID: <20080406113633.E068916A69C@codespeak.net> Author: gotcha Date: Sun Apr 6 13:36:32 2008 New Revision: 53437 Modified: kukit/kss.core/trunk/kss/core/ (props changed) kukit/kss.core/trunk/kss/core/EXTERNALS.TXT kukit/kss.core/trunk/kss/core/pluginregistry/browser/develui.pt kukit/kss.core/trunk/kss/core/plugins/core/demo/zopeconfig.py Log: jscoverage support Modified: kukit/kss.core/trunk/kss/core/EXTERNALS.TXT ============================================================================== --- kukit/kss.core/trunk/kss/core/EXTERNALS.TXT (original) +++ kukit/kss.core/trunk/kss/core/EXTERNALS.TXT Sun Apr 6 13:36:32 2008 @@ -1,8 +0,0 @@ -# -# results of svn propget svn:externals -# http://codespeak.net/svn/kukit/kss.core/trunk -# -# You can update your working dir by: -# svn propset svn:externals -F EXTERNALS.TXT . -# -kukit http://codespeak.net/svn/kukit/kukit.js/trunk/ Modified: kukit/kss.core/trunk/kss/core/pluginregistry/browser/develui.pt ============================================================================== --- kukit/kss.core/trunk/kss/core/pluginregistry/browser/develui.pt (original) +++ kukit/kss.core/trunk/kss/core/pluginregistry/browser/develui.pt Sun Apr 6 13:36:32 2008 @@ -106,7 +106,8 @@

Current KSS log level is - DEBUG.

Modified: kukit/kss.core/trunk/kss/core/plugins/core/demo/zopeconfig.py ============================================================================== --- kukit/kss.core/trunk/kss/core/plugins/core/demo/zopeconfig.py (original) +++ kukit/kss.core/trunk/kss/core/plugins/core/demo/zopeconfig.py Sun Apr 6 13:36:32 2008 @@ -18,6 +18,7 @@ implements(IResource) demos = ( + KSSDemo('', '', "loglevel.html", "Log Level"), KSSDemo('', '', "basic_commands.html", "Change tag content"), KSSDemo('', '', "two_selects.html", "Two selects"), KSSDemo('', '', "autoupdate.html", "Auto update"), From gotcha at codespeak.net Sun Apr 6 14:10:43 2008 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 6 Apr 2008 14:10:43 +0200 (CEST) Subject: [KSS-checkins] r53439 - kukit/kss.core/trunk/kss/core Message-ID: <20080406121043.20EB116A70A@codespeak.net> Author: gotcha Date: Sun Apr 6 14:10:42 2008 New Revision: 53439 Modified: kukit/kss.core/trunk/kss/core/ (props changed) kukit/kss.core/trunk/kss/core/EXTERNALS.TXT Log: fix externals Modified: kukit/kss.core/trunk/kss/core/EXTERNALS.TXT ============================================================================== --- kukit/kss.core/trunk/kss/core/EXTERNALS.TXT (original) +++ kukit/kss.core/trunk/kss/core/EXTERNALS.TXT Sun Apr 6 14:10:42 2008 @@ -0,0 +1,10 @@ +# You can check externals by issuing: +# +# svn propget svn:externals . +# +# You can update your working dir by issuing: +# +# svn propset svn:externals -F EXTERNALS.TXT . +# +kukit http://codespeak.net/svn/kukit/kukit.js/branch/jscoverage/ + From gotcha at codespeak.net Sun Apr 6 14:12:47 2008 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 6 Apr 2008 14:12:47 +0200 (CEST) Subject: [KSS-checkins] r53440 - in kukit/kss.buildout/branch/jscoverage: . src Message-ID: <20080406121247.B0FCB16A725@codespeak.net> Author: gotcha Date: Sun Apr 6 14:12:46 2008 New Revision: 53440 Added: kukit/kss.buildout/branch/jscoverage/IGNORE.txt Modified: kukit/kss.buildout/branch/jscoverage/src/ (props changed) kukit/kss.buildout/branch/jscoverage/src/EXTERNALS.txt Log: fix externals and ignore Added: kukit/kss.buildout/branch/jscoverage/IGNORE.txt ============================================================================== --- (empty file) +++ kukit/kss.buildout/branch/jscoverage/IGNORE.txt Sun Apr 6 14:12:46 2008 @@ -0,0 +1,16 @@ +# You can check svn:ignore by issuing: +# +# svn propget svn:ignore . +# +# You can update your working dir by issuing: +# +# svn propset svn:ignore -F IGNORE.txt . +# +develop-eggs +var +parts +downloads +.installed.cfg +tags +bin + Modified: kukit/kss.buildout/branch/jscoverage/src/EXTERNALS.txt ============================================================================== --- kukit/kss.buildout/branch/jscoverage/src/EXTERNALS.txt (original) +++ kukit/kss.buildout/branch/jscoverage/src/EXTERNALS.txt Sun Apr 6 14:12:46 2008 @@ -0,0 +1,11 @@ +# You can check externals by issuing: +# +# svn propget svn:externals . +# +# You can update your working dir by issuing: +# +# svn propset svn:externals -F EXTERNALS.txt . +# +kss.core https://codespeak.net/svn/kukit/kss.core/branch/jscoverage +kss.demo https://codespeak.net/svn/kukit/kss.demo/branch/jscoverage + From gotcha at codespeak.net Sun Apr 6 14:14:19 2008 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 6 Apr 2008 14:14:19 +0200 (CEST) Subject: [KSS-checkins] r53441 - kukit/kss.buildout/branch/jscoverage Message-ID: <20080406121419.654F416A70A@codespeak.net> Author: gotcha Date: Sun Apr 6 14:14:18 2008 New Revision: 53441 Added: kukit/kss.buildout/branch/jscoverage/mkbranch.sh (contents, props changed) Log: first attempt for a branching script Added: kukit/kss.buildout/branch/jscoverage/mkbranch.sh ============================================================================== --- (empty file) +++ kukit/kss.buildout/branch/jscoverage/mkbranch.sh Sun Apr 6 14:14:18 2008 @@ -0,0 +1,20 @@ +#!/bin/sh +NAME="jscoverage" +LOGMSG="jscoverage support" + +#svn cp http://codespeak.net/svn/kukit/kss.buildout/trunk http://codespeak.net/svn/kukit/kss.buildout/branch/$NAME -m "$LOGMSG" +#svn cp http://codespeak.net/svn/kukit/kss.core/trunk http://codespeak.net/svn/kukit/kss.core/branch/$NAME -m "$LOGMSG" +#svn cp http://codespeak.net/svn/kukit/kss.demo/trunk http://codespeak.net/svn/kukit/kss.demo/branch/$NAME -m "$LOGMSG" +#svn cp http://codespeak.net/svn/kukit/kukit.js/trunk http://codespeak.net/svn/kukit/kukit.js/branch/$NAME -m "$LOGMSG" +#svn sw http://codespeak.net/svn/kukit/kss.buildout/branch/$NAME . +#svn sw https://codespeak.net/svn/kukit/kss.core/branch/$NAME src/kss.core +#svn sw https://codespeak.net/svn/kukit/kss.demo/branch/$NAME src/kss.demo +#svn sw https://codespeak.net/svn/kukit/kukit.js/branch/$NAME src/kss.core/kss/core +EXTERNALS="src/EXTERNALS.txt" +sed "s/trunk/branch\/$NAME/" $EXTERNALS >$EXTERNALS.out +mv $EXTERNALS.out $EXTERNALS +svn propset svn:externals -F $EXTERNALS src +EXTERNALS="src/kss.core/kss/core/EXTERNALS.TXT" +sed "s/trunk/branch\/$NAME/" $EXTERNALS >$EXTERNALS.out +mv $EXTERNALS.out $EXTERNALS +svn propset svn:externals -F $EXTERNALS src/kss.core/kss/core From gotcha at codespeak.net Sun Apr 6 14:31:33 2008 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 6 Apr 2008 14:31:33 +0200 (CEST) Subject: [KSS-checkins] r53442 - in kukit/kss.demo/trunk/kss/demo: . browser jscoverage jscoverage/browser Message-ID: <20080406123133.2437616A641@codespeak.net> Author: gotcha Date: Sun Apr 6 14:31:31 2008 New Revision: 53442 Added: kukit/kss.demo/trunk/kss/demo/jscoverage/ (props changed) kukit/kss.demo/trunk/kss/demo/jscoverage/IGNORE.txt kukit/kss.demo/trunk/kss/demo/jscoverage/__init__.py kukit/kss.demo/trunk/kss/demo/jscoverage/browser/ kukit/kss.demo/trunk/kss/demo/jscoverage/browser/__init__.py kukit/kss.demo/trunk/kss/demo/jscoverage/browser/backToIndex.html kukit/kss.demo/trunk/kss/demo/jscoverage/browser/configure.zcml kukit/kss.demo/trunk/kss/demo/jscoverage/browser/coverage.py kukit/kss.demo/trunk/kss/demo/jscoverage/browser/interfaces.py kukit/kss.demo/trunk/kss/demo/jscoverage/browser/kss_demo_suite_jscoverage.pt kukit/kss.demo/trunk/kss/demo/jscoverage/browser/setJscoverage.html kukit/kss.demo/trunk/kss/demo/jscoverage/browser/unsetJscoverage.html kukit/kss.demo/trunk/kss/demo/jscoverage/configure.zcml Modified: kukit/kss.demo/trunk/kss/demo/browser/header_macros.pt kukit/kss.demo/trunk/kss/demo/browser/kss_demo_index.pt kukit/kss.demo/trunk/kss/demo/configure.zcml Log: add jscoverage support Modified: kukit/kss.demo/trunk/kss/demo/browser/header_macros.pt ============================================================================== --- kukit/kss.demo/trunk/kss/demo/browser/header_macros.pt (original) +++ kukit/kss.demo/trunk/kss/demo/browser/header_macros.pt Sun Apr 6 14:31:31 2008 @@ -49,14 +49,23 @@ - + + + - - Modified: kukit/kss.demo/trunk/kss/demo/browser/kss_demo_index.pt ============================================================================== --- kukit/kss.demo/trunk/kss/demo/browser/kss_demo_index.pt (original) +++ kukit/kss.demo/trunk/kss/demo/browser/kss_demo_index.pt Sun Apr 6 14:31:31 2008 @@ -1,5 +1,6 @@ + KSS demos and tests @@ -16,6 +17,19 @@ +

Coverage

+
    +
  • Link to Zelenium object (instrumented): +
    + + + +
  • +
  • + Coverage report +
  • +

Zelenium object link must be an absolute path from the domain root, or a relative path from the demo SimpleContent's parent. Modified: kukit/kss.demo/trunk/kss/demo/configure.zcml ============================================================================== --- kukit/kss.demo/trunk/kss/demo/configure.zcml (original) +++ kukit/kss.demo/trunk/kss/demo/configure.zcml Sun Apr 6 14:31:31 2008 @@ -7,7 +7,7 @@ > - + @@ -93,4 +93,6 @@ permission="zope.Public" /> + + Added: kukit/kss.demo/trunk/kss/demo/jscoverage/IGNORE.txt ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/jscoverage/IGNORE.txt Sun Apr 6 14:31:31 2008 @@ -0,0 +1,10 @@ +# You can check svn:ignore by issuing: +# +# svn propget svn:ignore . +# +# You can update your working dir by issuing: +# +# svn propset svn:ignore -F IGNORE.txt . +# +js + Added: kukit/kss.demo/trunk/kss/demo/jscoverage/__init__.py ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/jscoverage/__init__.py Sun Apr 6 14:31:31 2008 @@ -0,0 +1 @@ +#package Added: kukit/kss.demo/trunk/kss/demo/jscoverage/browser/__init__.py ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/jscoverage/browser/__init__.py Sun Apr 6 14:31:31 2008 @@ -0,0 +1 @@ +#package Added: kukit/kss.demo/trunk/kss/demo/jscoverage/browser/backToIndex.html ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/jscoverage/browser/backToIndex.html Sun Apr 6 14:31:31 2008 @@ -0,0 +1,23 @@ + + + +basic_commands + + +

basic_commands
Set production mode
open
+ + + + + + + + + + + + + +
Back to index
openindex.html
assertTextPresentKSS demos
+ + Added: kukit/kss.demo/trunk/kss/demo/jscoverage/browser/configure.zcml ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/jscoverage/browser/configure.zcml Sun Apr 6 14:31:31 2008 @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + Added: kukit/kss.demo/trunk/kss/demo/jscoverage/browser/coverage.py ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/jscoverage/browser/coverage.py Sun Apr 6 14:31:31 2008 @@ -0,0 +1,57 @@ + +try: + from Products.Five import BrowserView + BrowserView +except ImportError: + from zope.publisher.browser import BrowserView + +from zope.publisher.interfaces import NotFound + +COOKIE_JSCMODE = '__kss_jscoverage' + +class JscoverageView(BrowserView): + + # Zope3 requires the implementation of + # IBrowserPublisher, in order for the methods + # to be traversable. + # + # An alternative would be: + # + # + # + # + + def publishTraverse(self, request, name): + try: + return getattr(self, name) + except AttributeError: + raise NotFound(self.context, name, request) + + def browserDefault(self, request): + # make ui the default method + return self, ('isJscoverage', ) + + # -- + # Methods for jscoverage mode + # -- + + def setJscoverage(self): + 'Sets jscoverage mode cookie' + self.request.response.setCookie(COOKIE_JSCMODE, '1', path='/') + return 'jscoverage cookie on' + + def unsetJscoverage(self): + 'Unsets jscoverage mode cookie' + self.request.response.expireCookie(COOKIE_JSCMODE, path='/') + return 'jscoverage cookie off' + + def isJscoverage(self): + 'Queries jscoverage mode cookie' + return bool(COOKIE_JSCMODE in self.request.cookies) + + def getZuite(self, path): + """Redirects to the Zuite page, Zuite object is found from path.""" + zuite = self.context.aq_inner.aq_parent.restrictedTraverse(path) + html = "%s/core/TestRunner.html?test=%s/suite_jscoverage.html" % (zuite.absolute_url(), self.context.absolute_url()) + return self.request.response.redirect(html) + Added: kukit/kss.demo/trunk/kss/demo/jscoverage/browser/interfaces.py ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/jscoverage/browser/interfaces.py Sun Apr 6 14:31:31 2008 @@ -0,0 +1,14 @@ + +from zope.publisher.interfaces.browser import IBrowserPublisher + +class IJscoverageView(IBrowserPublisher): + + def setJscoverage(): + 'Sets jscoverage mode cookie' + + def unsetJscoverage(): + 'Unsets jscoverage mode cookie' + + def isJscoverage(): + 'Queries jscoverage mode cookie' + Added: kukit/kss.demo/trunk/kss/demo/jscoverage/browser/kss_demo_suite_jscoverage.pt ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/jscoverage/browser/kss_demo_suite_jscoverage.pt Sun Apr 6 14:31:31 2008 @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + +
Test Suite
+

+ Jscoverage mode +

+
Title
+

+ Development mode +

+
+

+ Back to all demos +

+
+ + Added: kukit/kss.demo/trunk/kss/demo/jscoverage/browser/setJscoverage.html ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/jscoverage/browser/setJscoverage.html Sun Apr 6 14:31:31 2008 @@ -0,0 +1,23 @@ + + + +basic_commands + + + + + + + + + + + + + + + + +
setJscoverage
opendemo/@@kss_jscoverage/setJscoverage
assertTextPresentjscoverage cookie on
+ + Added: kukit/kss.demo/trunk/kss/demo/jscoverage/browser/unsetJscoverage.html ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/jscoverage/browser/unsetJscoverage.html Sun Apr 6 14:31:31 2008 @@ -0,0 +1,23 @@ + + + +basic_commands + + + + + + + + + + + + + + + + +
unsetJscoverage
opendemo/@@kss_jscoverage/unsetJscoverage
assertTextPresentjscoverage cookie off
+ + Added: kukit/kss.demo/trunk/kss/demo/jscoverage/configure.zcml ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/jscoverage/configure.zcml Sun Apr 6 14:31:31 2008 @@ -0,0 +1,52 @@ + + + + + + + + + + + + + From gotcha at codespeak.net Sun Apr 6 14:32:42 2008 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 6 Apr 2008 14:32:42 +0200 (CEST) Subject: [KSS-checkins] r53443 - kukit/kss.core/trunk/kss/core Message-ID: <20080406123242.2259516A641@codespeak.net> Author: gotcha Date: Sun Apr 6 14:32:41 2008 New Revision: 53443 Modified: kukit/kss.core/trunk/kss/core/ (props changed) Log: fix externals From gotcha at codespeak.net Sun Apr 6 14:33:55 2008 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 6 Apr 2008 14:33:55 +0200 (CEST) Subject: [KSS-checkins] r53444 - kukit/kss.core/trunk/kss/core/plugins/core/demo/selenium_tests Message-ID: <20080406123355.5EDFD16A641@codespeak.net> Author: gotcha Date: Sun Apr 6 14:33:54 2008 New Revision: 53444 Added: kukit/kss.core/trunk/kss/core/plugins/core/demo/selenium_tests/log_level.html Log: add jscoverage support Added: kukit/kss.core/trunk/kss/core/plugins/core/demo/selenium_tests/log_level.html ============================================================================== --- (empty file) +++ kukit/kss.core/trunk/kss/core/plugins/core/demo/selenium_tests/log_level.html Sun Apr 6 14:33:54 2008 @@ -0,0 +1,134 @@ + + + +log_level + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
log_level
openhttp://localhost:8080/demo/basic_commands.html
open/demo/@@kss_devel_mode/ui
clickdocument.loglevel.loglevel[1]
clickAndWaitbutton_loglevel
assertTextloglevelINFO
openhttp://localhost:8080/demo/basic_commands.html
open/demo/@@kss_devel_mode/ui
assertTextloglevelINFO
clickdocument.loglevel.loglevel[2]
clickAndWaitbutton_loglevel
assertTextloglevelWARNING
openhttp://localhost:8080/demo/basic_commands.html
open/demo/@@kss_devel_mode/ui
assertTextloglevelWARNING
clickdocument.loglevel.loglevel[3]
clickAndWaitbutton_loglevel
assertTextloglevelERROR
openhttp://localhost:8080/demo/basic_commands.html
open/demo/@@kss_devel_mode/ui
assertTextloglevelERROR
clickdocument.loglevel.loglevel[0]
clickAndWaitbutton_loglevel
assertTextloglevelDEBUG
openhttp://localhost:8080/demo/basic_commands.html
+ + From gotcha at codespeak.net Sun Apr 6 14:39:52 2008 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 6 Apr 2008 14:39:52 +0200 (CEST) Subject: [KSS-checkins] r53446 - kukit/kss.buildout/branch/jscoverage Message-ID: <20080406123952.62EFA16A438@codespeak.net> Author: gotcha Date: Sun Apr 6 14:39:51 2008 New Revision: 53446 Modified: kukit/kss.buildout/branch/jscoverage/ (props changed) kukit/kss.buildout/branch/jscoverage/buildout.cfg kukit/kss.buildout/branch/jscoverage/mkbranch.sh Log: add jscoverage Modified: kukit/kss.buildout/branch/jscoverage/buildout.cfg ============================================================================== --- kukit/kss.buildout/branch/jscoverage/buildout.cfg (original) +++ kukit/kss.buildout/branch/jscoverage/buildout.cfg Sun Apr 6 14:39:51 2008 @@ -4,6 +4,7 @@ instance extraproducts ksspy + coverage develop = src/kss.core @@ -45,3 +46,7 @@ interpreter = ksspy extra-paths = ${zope2:location}/lib/python scripts = ksspy + +[coverage] +recipe = zc.recipe.cmmi +url = http://siliconforks.com/jscoverage/download/jscoverage-0.3.1.tar.bz2 Modified: kukit/kss.buildout/branch/jscoverage/mkbranch.sh ============================================================================== --- kukit/kss.buildout/branch/jscoverage/mkbranch.sh (original) +++ kukit/kss.buildout/branch/jscoverage/mkbranch.sh Sun Apr 6 14:39:51 2008 @@ -1,15 +1,15 @@ #!/bin/sh -NAME="jscoverage" -LOGMSG="jscoverage support" +NAME=$ARGV[1] +LOGMSG=$ARGV[2] -#svn cp http://codespeak.net/svn/kukit/kss.buildout/trunk http://codespeak.net/svn/kukit/kss.buildout/branch/$NAME -m "$LOGMSG" -#svn cp http://codespeak.net/svn/kukit/kss.core/trunk http://codespeak.net/svn/kukit/kss.core/branch/$NAME -m "$LOGMSG" -#svn cp http://codespeak.net/svn/kukit/kss.demo/trunk http://codespeak.net/svn/kukit/kss.demo/branch/$NAME -m "$LOGMSG" -#svn cp http://codespeak.net/svn/kukit/kukit.js/trunk http://codespeak.net/svn/kukit/kukit.js/branch/$NAME -m "$LOGMSG" -#svn sw http://codespeak.net/svn/kukit/kss.buildout/branch/$NAME . -#svn sw https://codespeak.net/svn/kukit/kss.core/branch/$NAME src/kss.core -#svn sw https://codespeak.net/svn/kukit/kss.demo/branch/$NAME src/kss.demo -#svn sw https://codespeak.net/svn/kukit/kukit.js/branch/$NAME src/kss.core/kss/core +svn cp http://codespeak.net/svn/kukit/kss.buildout/trunk http://codespeak.net/svn/kukit/kss.buildout/branch/$NAME -m "$LOGMSG" +svn cp http://codespeak.net/svn/kukit/kss.core/trunk http://codespeak.net/svn/kukit/kss.core/branch/$NAME -m "$LOGMSG" +svn cp http://codespeak.net/svn/kukit/kss.demo/trunk http://codespeak.net/svn/kukit/kss.demo/branch/$NAME -m "$LOGMSG" +svn cp http://codespeak.net/svn/kukit/kukit.js/trunk http://codespeak.net/svn/kukit/kukit.js/branch/$NAME -m "$LOGMSG" +svn sw http://codespeak.net/svn/kukit/kss.buildout/branch/$NAME . +svn sw https://codespeak.net/svn/kukit/kss.core/branch/$NAME src/kss.core +svn sw https://codespeak.net/svn/kukit/kss.demo/branch/$NAME src/kss.demo +svn sw https://codespeak.net/svn/kukit/kukit.js/branch/$NAME src/kss.core/kss/core EXTERNALS="src/EXTERNALS.txt" sed "s/trunk/branch\/$NAME/" $EXTERNALS >$EXTERNALS.out mv $EXTERNALS.out $EXTERNALS From gotcha at codespeak.net Sun Apr 6 14:45:44 2008 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 6 Apr 2008 14:45:44 +0200 (CEST) Subject: [KSS-checkins] r53447 - in kukit/kss.demo/branch/jscoverage/kss/demo: . browser jscoverage jscoverage/browser Message-ID: <20080406124544.C4B9C16A70A@codespeak.net> Author: gotcha Date: Sun Apr 6 14:45:44 2008 New Revision: 53447 Added: kukit/kss.demo/branch/jscoverage/kss/demo/jscoverage/ (props changed) - copied from r53442, kukit/kss.demo/trunk/kss/demo/jscoverage/ kukit/kss.demo/branch/jscoverage/kss/demo/jscoverage/IGNORE.txt - copied unchanged from r53442, kukit/kss.demo/trunk/kss/demo/jscoverage/IGNORE.txt kukit/kss.demo/branch/jscoverage/kss/demo/jscoverage/__init__.py - copied unchanged from r53442, kukit/kss.demo/trunk/kss/demo/jscoverage/__init__.py kukit/kss.demo/branch/jscoverage/kss/demo/jscoverage/browser/ - copied from r53442, kukit/kss.demo/trunk/kss/demo/jscoverage/browser/ kukit/kss.demo/branch/jscoverage/kss/demo/jscoverage/browser/__init__.py - copied unchanged from r53442, kukit/kss.demo/trunk/kss/demo/jscoverage/browser/__init__.py kukit/kss.demo/branch/jscoverage/kss/demo/jscoverage/browser/backToIndex.html - copied unchanged from r53442, kukit/kss.demo/trunk/kss/demo/jscoverage/browser/backToIndex.html kukit/kss.demo/branch/jscoverage/kss/demo/jscoverage/browser/configure.zcml - copied unchanged from r53442, kukit/kss.demo/trunk/kss/demo/jscoverage/browser/configure.zcml kukit/kss.demo/branch/jscoverage/kss/demo/jscoverage/browser/coverage.py - copied unchanged from r53442, kukit/kss.demo/trunk/kss/demo/jscoverage/browser/coverage.py kukit/kss.demo/branch/jscoverage/kss/demo/jscoverage/browser/interfaces.py - copied unchanged from r53442, kukit/kss.demo/trunk/kss/demo/jscoverage/browser/interfaces.py kukit/kss.demo/branch/jscoverage/kss/demo/jscoverage/browser/kss_demo_suite_jscoverage.pt - copied unchanged from r53442, kukit/kss.demo/trunk/kss/demo/jscoverage/browser/kss_demo_suite_jscoverage.pt kukit/kss.demo/branch/jscoverage/kss/demo/jscoverage/browser/setJscoverage.html - copied unchanged from r53442, kukit/kss.demo/trunk/kss/demo/jscoverage/browser/setJscoverage.html kukit/kss.demo/branch/jscoverage/kss/demo/jscoverage/browser/unsetJscoverage.html - copied unchanged from r53442, kukit/kss.demo/trunk/kss/demo/jscoverage/browser/unsetJscoverage.html kukit/kss.demo/branch/jscoverage/kss/demo/jscoverage/configure.zcml - copied unchanged from r53442, kukit/kss.demo/trunk/kss/demo/jscoverage/configure.zcml Modified: kukit/kss.demo/branch/jscoverage/kss/demo/browser/header_macros.pt kukit/kss.demo/branch/jscoverage/kss/demo/browser/kss_demo_index.pt kukit/kss.demo/branch/jscoverage/kss/demo/configure.zcml Log: add jscoverage support Modified: kukit/kss.demo/branch/jscoverage/kss/demo/browser/header_macros.pt ===========================================