[Checkins] SVN: Zope3/branches/benji-testbrowser-with-real-browsers-take-2/src/zope/testbrowser/ more major refactoring, zope.testbrowser tests pass (at least)

Benji York benji at zope.com
Wed Aug 16 22:37:15 EDT 2006


Log message for revision 69578:
  more major refactoring, zope.testbrowser tests pass (at least)
  

Changed:
  U   Zope3/branches/benji-testbrowser-with-real-browsers-take-2/src/zope/testbrowser/browser.py
  U   Zope3/branches/benji-testbrowser-with-real-browsers-take-2/src/zope/testbrowser/forms.py
  U   Zope3/branches/benji-testbrowser-with-real-browsers-take-2/src/zope/testbrowser/real/real.py

-=-
Modified: Zope3/branches/benji-testbrowser-with-real-browsers-take-2/src/zope/testbrowser/browser.py
===================================================================
--- Zope3/branches/benji-testbrowser-with-real-browsers-take-2/src/zope/testbrowser/browser.py	2006-08-17 01:50:54 UTC (rev 69577)
+++ Zope3/branches/benji-testbrowser-with-real-browsers-take-2/src/zope/testbrowser/browser.py	2006-08-17 02:37:14 UTC (rev 69578)
@@ -16,18 +16,13 @@
 $Id$
 """
 __docformat__ = "reStructuredText"
-from cStringIO import StringIO
-from test import pystone
 from zope.testbrowser import interfaces
-from zope.testbrowser.forms import getControl, getForm, getAllControls
+from zope.testbrowser.forms import getControl, getForm, getAllControls, \
+    controlFactory, Form
 from zope.testbrowser.utilities import disambiguate, any, onlyOne, zeroOrOne, \
     SetattrErrorsMixin, PystoneTimer, compressText, RegexType
-import ClientForm
 import mechanize
-import operator
 import re
-import sys
-import time
 import urllib2
 
 try:
@@ -35,22 +30,6 @@
 except ImportError:
     from dummymodules import interface
 
-def controlFactory(control, form, browser):
-    if isinstance(control, ClientForm.Item):
-        # it is a subcontrol
-        return ItemControl(control, form, browser)
-    else:
-        t = control.type
-        if t in ('checkbox', 'select', 'radio'):
-            return ListControl(control, form, browser)
-        elif t in ('submit', 'submitbutton'):
-            return SubmitControl(control, form, browser)
-        elif t=='image':
-            return ImageControl(control, form, browser)
-        else:
-            return Control(control, form, browser)
-
-
 class Browser(SetattrErrorsMixin):
     """A web user agent."""
     interface.implements(interfaces.IBrowser)
@@ -258,302 +237,3 @@
     def __repr__(self):
         return "<%s text=%r url=%r>" % (
             self.__class__.__name__, self.text, self.url)
-
-
-class Control(SetattrErrorsMixin):
-    """A control of a form."""
-    interface.implements(interfaces.IControl)
-
-    _enable_setattr_errors = False
-
-    def __init__(self, control, form, browser):
-        self.mech_control = control
-        self.mech_form = form
-        self.browser = browser
-        self._browser_counter = self.browser._counter
-
-        if self.mech_control.type == 'file':
-            self.filename = None
-            self.content_type = None
-
-        # for some reason ClientForm thinks we shouldn't be able to modify
-        # hidden fields, but while testing it is sometimes very important
-        if self.mech_control.type == 'hidden':
-            self.mech_control.readonly = False
-
-        # disable addition of further attributes
-        self._enable_setattr_errors = True
-
-    @property
-    def disabled(self):
-        return bool(getattr(self.mech_control, 'disabled', False))
-
-    @property
-    def type(self):
-        return getattr(self.mech_control, 'type', None)
-
-    @property
-    def name(self):
-        return getattr(self.mech_control, 'name', None)
-
-    @property
-    def multiple(self):
-        return bool(getattr(self.mech_control, 'multiple', False))
-
-    @apply
-    def value():
-        """See zope.testbrowser.interfaces.IControl"""
-
-        def fget(self):
-            if (self.type == 'checkbox' and
-                len(self.mech_control.items) == 1 and
-                self.mech_control.items[0].name == 'on'):
-                return self.mech_control.items[0].selected
-            return self.mech_control.value
-
-        def fset(self, value):
-            if self._browser_counter != self.browser._counter:
-                raise interfaces.ExpiredError
-            if self.mech_control.type == 'file':
-                self.mech_control.add_file(value,
-                                           content_type=self.content_type,
-                                           filename=self.filename)
-            elif self.type == 'checkbox' and len(self.mech_control.items) == 1:
-                self.mech_control.items[0].selected = bool(value)
-            else:
-                self.mech_control.value = value
-        return property(fget, fset)
-
-    def add_file(self, file, content_type, filename):
-        if not self.mech_control.type == 'file':
-            raise TypeError("Can't call add_file on %s controls"
-                            % self.mech_control.type)
-        if isinstance(file, str):
-            file = StringIO(file)
-        self.mech_control.add_file(file, content_type, filename)
-
-    def clear(self):
-        if self._browser_counter != self.browser._counter:
-            raise interfaces.ExpiredError
-        self.mech_control.clear()
-
-    def __repr__(self):
-        return "<%s name=%r type=%r>" % (
-            self.__class__.__name__, self.name, self.type)
-
-
-class ListControl(Control):
-    interface.implements(interfaces.IListControl)
-
-    @apply
-    def displayValue():
-        """See zope.testbrowser.interfaces.IListControl"""
-        # not implemented for anything other than select;
-        # would be nice if ClientForm implemented for checkbox and radio.
-        # attribute error for all others.
-
-        def fget(self):
-            return self.mech_control.get_value_by_label()
-
-        def fset(self, value):
-            if self._browser_counter != self.browser._counter:
-                raise interfaces.ExpiredError
-            self.mech_control.set_value_by_label(value)
-
-        return property(fget, fset)
-
-    @property
-    def displayOptions(self):
-        """See zope.testbrowser.interfaces.IListControl"""
-        res = []
-        for item in self.mech_control.items:
-            if not item.disabled:
-                for label in item.get_labels():
-                    if label.text:
-                        res.append(label.text)
-                        break
-                else:
-                    res.append(None)
-        return res
-
-    @property
-    def options(self):
-        """See zope.testbrowser.interfaces.IListControl"""
-        if (self.type == 'checkbox' and len(self.mech_control.items) == 1 and
-            self.mech_control.items[0].name == 'on'):
-            return [True]
-        return [i.name for i in self.mech_control.items if not i.disabled]
-
-    @property
-    def disabled(self):
-        if self.type == 'checkbox' and len(self.mech_control.items) == 1:
-            return bool(getattr(self.mech_control.items[0], 'disabled', False))
-        return bool(getattr(self.mech_control, 'disabled', False))
-
-    @property
-    def controls(self):
-        if self._browser_counter != self.browser._counter:
-            raise interfaces.ExpiredError
-        res = [controlFactory(i, self.mech_form, self.browser) for i in
-                self.mech_control.items]
-        for s in res:
-            s.__dict__['control'] = self
-        return res
-
-    def getControl(self, label=None, value=None, index=None):
-        if self._browser_counter != self.browser._counter:
-            raise interfaces.ExpiredError
-
-        onlyOne([label, value], '"label" and "value"')
-
-        if label is not None:
-            options = self.mech_control.get_items(label=label)
-            msg = 'label %r' % label
-        elif value is not None:
-            options = self.mech_control.get_items(name=value)
-            msg = 'value %r' % value
-        res = controlFactory(
-            disambiguate(options, msg, index), self.mech_form, self.browser)
-        res.__dict__['control'] = self
-        return res
-
-
-class SubmitControl(Control):
-    interface.implements(interfaces.ISubmitControl)
-
-    def click(self):
-        if self._browser_counter != self.browser._counter:
-            raise interfaces.ExpiredError
-        self.browser._clickSubmit(self.mech_form, self.mech_control, (1,1))
-        self.browser._changed()
-
-
-class ImageControl(Control):
-    interface.implements(interfaces.IImageSubmitControl)
-
-    def click(self, coord=(1,1)):
-        if self._browser_counter != self.browser._counter:
-            raise interfaces.ExpiredError
-        self.browser._clickSubmit(self.mech_form, self.mech_control, coord)
-        self.browser._changed()
-
-
-class ItemControl(SetattrErrorsMixin):
-    interface.implements(interfaces.IItemControl)
-
-    def __init__(self, item, form, browser):
-        self.mech_item = item
-        self.mech_form = form
-        self.browser = browser
-        self._browser_counter = self.browser._counter
-        self._enable_setattr_errors = True
-
-    @property
-    def control(self):
-        if self._browser_counter != self.browser._counter:
-            raise interfaces.ExpiredError
-        res = controlFactory(
-            self.mech_item._control, self.mech_form, self.browser)
-        self.__dict__['control'] = res
-        return res
-
-    @property
-    def disabled(self):
-        return self.mech_item.disabled
-
-    @apply
-    def selected():
-        """See zope.testbrowser.interfaces.IControl"""
-
-        def fget(self):
-            return self.mech_item.selected
-
-        def fset(self, value):
-            if self._browser_counter != self.browser._counter:
-                raise interfaces.ExpiredError
-            self.mech_item.selected = value
-
-        return property(fget, fset)
-
-    @property
-    def optionValue(self):
-        return self.mech_item.attrs.get('value')
-
-    def click(self):
-        if self._browser_counter != self.browser._counter:
-            raise interfaces.ExpiredError
-        self.mech_item.selected = not self.mech_item.selected
-
-    def __repr__(self):
-        return "<%s name=%r type=%r optionValue=%r>" % (
-            self.__class__.__name__, self.mech_item._control.name,
-            self.mech_item._control.type, self.optionValue)
-
-
-class Form(SetattrErrorsMixin):
-    """HTML Form"""
-    interface.implements(interfaces.IForm)
-
-    def __init__(self, browser, form):
-        """Initialize the Form
-
-        browser - a Browser instance
-        form - a ClientForm instance
-        """
-        self.browser = browser
-        self.mech_form = form
-        self._browser_counter = self.browser._counter
-        self._enable_setattr_errors = True
-
-    @property
-    def action(self):
-        return self.mech_form.action
-
-    @property
-    def method(self):
-        return self.mech_form.method
-
-    @property
-    def enctype(self):
-        return self.mech_form.enctype
-
-    @property
-    def name(self):
-        return self.mech_form.name
-
-    @property
-    def id(self):
-        """See zope.testbrowser.interfaces.IForm"""
-        return self.mech_form.attrs.get('id')
-
-    def submit(self, label=None, name=None, index=None, coord=(1,1)):
-        """See zope.testbrowser.interfaces.IForm"""
-        if self._browser_counter != self.browser._counter:
-            raise interfaces.ExpiredError
-        form = self.mech_form
-        if label is not None or name is not None:
-            intermediate, msg = getAllControls([form], label, name)
-            intermediate = [
-                (control, form) for (control, form) in intermediate if
-                control.type in ('submit', 'submitbutton', 'image')]
-            control, form = disambiguate(intermediate, msg, index)
-            self.browser._clickSubmit(form, control, coord)
-        else: # JavaScript sort of submit
-            if index is not None or coord != (1,1):
-                raise ValueError(
-                    'May not use index or coord without a control')
-            request = self.mech_form._switch_click("request", urllib2.Request)
-            self.browser._start_timer()
-            self.browser.mech_browser.open(request)
-            self.browser._stop_timer()
-        self.browser._changed()
-
-    def getControl(self, label=None, name=None, index=None):
-        """See zope.testbrowser.interfaces.IBrowser"""
-        if self._browser_counter != self.browser._counter:
-            raise interfaces.ExpiredError
-        forms = [self.mech_form]
-        intermediate, msg = getAllControls(forms, label, name,
-                                           include_subcontrols=True)
-        control, form = disambiguate(intermediate, msg, index)
-        return controlFactory(control, form, self.browser)

Modified: Zope3/branches/benji-testbrowser-with-real-browsers-take-2/src/zope/testbrowser/forms.py
===================================================================
--- Zope3/branches/benji-testbrowser-with-real-browsers-take-2/src/zope/testbrowser/forms.py	2006-08-17 01:50:54 UTC (rev 69577)
+++ Zope3/branches/benji-testbrowser-with-real-browsers-take-2/src/zope/testbrowser/forms.py	2006-08-17 02:37:14 UTC (rev 69578)
@@ -1,6 +1,11 @@
+from cStringIO import StringIO
+from zope import interface
+from zope.testbrowser import interfaces
 from zope.testbrowser.utilities import disambiguate, any, onlyOne, zeroOrOne, \
-    compressText
+    compressText, SetattrErrorsMixin, compressText
+import ClientForm
 import re
+import urllib2
 
 def findByLabel(label, forms, include_subcontrols=False):
     # forms are iterable of mech_forms
@@ -66,3 +71,318 @@
             matching_forms.append(form)
 
     return disambiguate(matching_forms, '', index)
+
+
+class Control(SetattrErrorsMixin):
+    """A control of a form."""
+    interface.implements(interfaces.IControl)
+
+    _enable_setattr_errors = False
+
+    def __init__(self, control, form, browser):
+        self.mech_control = control
+        self.mech_form = form
+        self.browser = browser
+        self._browser_counter = self.browser._counter
+
+        if self.mech_control.type == 'file':
+            self.filename = None
+            self.content_type = None
+
+        # for some reason ClientForm thinks we shouldn't be able to modify
+        # hidden fields, but while testing it is sometimes very important
+        if self.mech_control.type == 'hidden':
+            self.mech_control.readonly = False
+
+        # disable addition of further attributes
+        self._enable_setattr_errors = True
+
+    @property
+    def disabled(self):
+        return bool(getattr(self.mech_control, 'disabled', False))
+
+    @property
+    def type(self):
+        return getattr(self.mech_control, 'type', None)
+
+    @property
+    def name(self):
+        return getattr(self.mech_control, 'name', None)
+
+    @property
+    def multiple(self):
+        return bool(getattr(self.mech_control, 'multiple', False))
+
+    @apply
+    def value():
+        """See zope.testbrowser.interfaces.IControl"""
+
+        def fget(self):
+            if (self.type == 'checkbox' and
+                len(self.mech_control.items) == 1 and
+                self.mech_control.items[0].name == 'on'):
+                return self.mech_control.items[0].selected
+            return self.mech_control.value
+
+        def fset(self, value):
+            if self._browser_counter != self.browser._counter:
+                raise interfaces.ExpiredError
+            if self.mech_control.type == 'file':
+                self.mech_control.add_file(value,
+                                           content_type=self.content_type,
+                                           filename=self.filename)
+            elif self.type == 'checkbox' and len(self.mech_control.items) == 1:
+                self.mech_control.items[0].selected = bool(value)
+            else:
+                self.mech_control.value = value
+        return property(fget, fset)
+
+    def add_file(self, file, content_type, filename):
+        if not self.mech_control.type == 'file':
+            raise TypeError("Can't call add_file on %s controls"
+                            % self.mech_control.type)
+        if isinstance(file, str):
+            file = StringIO(file)
+        self.mech_control.add_file(file, content_type, filename)
+
+    def clear(self):
+        if self._browser_counter != self.browser._counter:
+            raise interfaces.ExpiredError
+        self.mech_control.clear()
+
+    def __repr__(self):
+        return "<%s name=%r type=%r>" % (
+            self.__class__.__name__, self.name, self.type)
+
+
+class ListControl(Control):
+    interface.implements(interfaces.IListControl)
+
+    @apply
+    def displayValue():
+        """See zope.testbrowser.interfaces.IListControl"""
+        # not implemented for anything other than select;
+        # would be nice if ClientForm implemented for checkbox and radio.
+        # attribute error for all others.
+
+        def fget(self):
+            return self.mech_control.get_value_by_label()
+
+        def fset(self, value):
+            if self._browser_counter != self.browser._counter:
+                raise interfaces.ExpiredError
+            self.mech_control.set_value_by_label(value)
+
+        return property(fget, fset)
+
+    @property
+    def displayOptions(self):
+        """See zope.testbrowser.interfaces.IListControl"""
+        res = []
+        for item in self.mech_control.items:
+            if not item.disabled:
+                for label in item.get_labels():
+                    if label.text:
+                        res.append(label.text)
+                        break
+                else:
+                    res.append(None)
+        return res
+
+    @property
+    def options(self):
+        """See zope.testbrowser.interfaces.IListControl"""
+        if (self.type == 'checkbox' and len(self.mech_control.items) == 1 and
+            self.mech_control.items[0].name == 'on'):
+            return [True]
+        return [i.name for i in self.mech_control.items if not i.disabled]
+
+    @property
+    def disabled(self):
+        if self.type == 'checkbox' and len(self.mech_control.items) == 1:
+            return bool(getattr(self.mech_control.items[0], 'disabled', False))
+        return bool(getattr(self.mech_control, 'disabled', False))
+
+    @property
+    def controls(self):
+        if self._browser_counter != self.browser._counter:
+            raise interfaces.ExpiredError
+        res = [controlFactory(i, self.mech_form, self.browser) for i in
+                self.mech_control.items]
+        for s in res:
+            s.__dict__['control'] = self
+        return res
+
+    def getControl(self, label=None, value=None, index=None):
+        if self._browser_counter != self.browser._counter:
+            raise interfaces.ExpiredError
+
+        onlyOne([label, value], '"label" and "value"')
+
+        if label is not None:
+            options = self.mech_control.get_items(label=label)
+            msg = 'label %r' % label
+        elif value is not None:
+            options = self.mech_control.get_items(name=value)
+            msg = 'value %r' % value
+        res = controlFactory(
+            disambiguate(options, msg, index), self.mech_form, self.browser)
+        res.__dict__['control'] = self
+        return res
+
+
+class SubmitControl(Control):
+    interface.implements(interfaces.ISubmitControl)
+
+    def click(self):
+        if self._browser_counter != self.browser._counter:
+            raise interfaces.ExpiredError
+        self.browser._clickSubmit(self.mech_form, self.mech_control, (1,1))
+        self.browser._changed()
+
+
+class ImageControl(Control):
+    interface.implements(interfaces.IImageSubmitControl)
+
+    def click(self, coord=(1,1)):
+        if self._browser_counter != self.browser._counter:
+            raise interfaces.ExpiredError
+        self.browser._clickSubmit(self.mech_form, self.mech_control, coord)
+        self.browser._changed()
+
+
+class ItemControl(SetattrErrorsMixin):
+    interface.implements(interfaces.IItemControl)
+
+    def __init__(self, item, form, browser):
+        self.mech_item = item
+        self.mech_form = form
+        self.browser = browser
+        self._browser_counter = self.browser._counter
+        self._enable_setattr_errors = True
+
+    @property
+    def control(self):
+        if self._browser_counter != self.browser._counter:
+            raise interfaces.ExpiredError
+        res = controlFactory(
+            self.mech_item._control, self.mech_form, self.browser)
+        self.__dict__['control'] = res
+        return res
+
+    @property
+    def disabled(self):
+        return self.mech_item.disabled
+
+    @apply
+    def selected():
+        """See zope.testbrowser.interfaces.IControl"""
+
+        def fget(self):
+            return self.mech_item.selected
+
+        def fset(self, value):
+            if self._browser_counter != self.browser._counter:
+                raise interfaces.ExpiredError
+            self.mech_item.selected = value
+
+        return property(fget, fset)
+
+    @property
+    def optionValue(self):
+        return self.mech_item.attrs.get('value')
+
+    def click(self):
+        if self._browser_counter != self.browser._counter:
+            raise interfaces.ExpiredError
+        self.mech_item.selected = not self.mech_item.selected
+
+    def __repr__(self):
+        return "<%s name=%r type=%r optionValue=%r>" % (
+            self.__class__.__name__, self.mech_item._control.name,
+            self.mech_item._control.type, self.optionValue)
+
+
+class Form(SetattrErrorsMixin):
+    """HTML Form"""
+    interface.implements(interfaces.IForm)
+
+    def __init__(self, browser, form):
+        """Initialize the Form
+
+        browser - a Browser instance
+        form - a ClientForm instance
+        """
+        self.browser = browser
+        self.mech_form = form
+        self._browser_counter = self.browser._counter
+        self._enable_setattr_errors = True
+
+    @property
+    def action(self):
+        return self.mech_form.action
+
+    @property
+    def method(self):
+        return self.mech_form.method
+
+    @property
+    def enctype(self):
+        return self.mech_form.enctype
+
+    @property
+    def name(self):
+        return self.mech_form.name
+
+    @property
+    def id(self):
+        """See zope.testbrowser.interfaces.IForm"""
+        return self.mech_form.attrs.get('id')
+
+    def submit(self, label=None, name=None, index=None, coord=(1,1)):
+        """See zope.testbrowser.interfaces.IForm"""
+        if self._browser_counter != self.browser._counter:
+            raise interfaces.ExpiredError
+        form = self.mech_form
+        if label is not None or name is not None:
+            intermediate, msg = getAllControls([form], label, name)
+            intermediate = [
+                (control, form) for (control, form) in intermediate if
+                control.type in ('submit', 'submitbutton', 'image')]
+            control, form = disambiguate(intermediate, msg, index)
+            self.browser._clickSubmit(form, control, coord)
+        else: # JavaScript sort of submit
+            if index is not None or coord != (1,1):
+                raise ValueError(
+                    'May not use index or coord without a control')
+            request = self.mech_form._switch_click("request", urllib2.Request)
+            self.browser._start_timer()
+            self.browser.mech_browser.open(request)
+            self.browser._stop_timer()
+        self.browser._changed()
+
+    def getControl(self, label=None, name=None, index=None):
+        """See zope.testbrowser.interfaces.IBrowser"""
+        if self._browser_counter != self.browser._counter:
+            raise interfaces.ExpiredError
+        forms = [self.mech_form]
+        intermediate, msg = getAllControls(forms, label, name,
+                                           include_subcontrols=True)
+        control, form = disambiguate(intermediate, msg, index)
+        return controlFactory(control, form, self.browser)
+
+
+def controlFactory(control, form, browser):
+    if isinstance(control, ClientForm.Item):
+        # it is a subcontrol
+        return ItemControl(control, form, browser)
+    else:
+        t = control.type
+        if t in ('checkbox', 'select', 'radio'):
+            return ListControl(control, form, browser)
+        elif t in ('submit', 'submitbutton'):
+            return SubmitControl(control, form, browser)
+        elif t=='image':
+            return ImageControl(control, form, browser)
+        else:
+            return Control(control, form, browser)

Modified: Zope3/branches/benji-testbrowser-with-real-browsers-take-2/src/zope/testbrowser/real/real.py
===================================================================
--- Zope3/branches/benji-testbrowser-with-real-browsers-take-2/src/zope/testbrowser/real/real.py	2006-08-17 01:50:54 UTC (rev 69577)
+++ Zope3/branches/benji-testbrowser-with-real-browsers-take-2/src/zope/testbrowser/real/real.py	2006-08-17 02:37:14 UTC (rev 69578)
@@ -18,6 +18,8 @@
 __docformat__ = "reStructuredText"
 from BeautifulSoup import BeautifulSoup
 from zope.testbrowser import interfaces
+from zope.testbrowser.forms import getControl, getForm, getAllControls, \
+    controlFactory
 from zope.testbrowser.real.proxy import ServerManager, PROXY_PORT
 from zope.testbrowser.utilities import disambiguate, zeroOrOne, \
     SetattrErrorsMixin, PystoneTimer
@@ -182,8 +184,23 @@
 
     def getControl(self, label=None, name=None, index=None):
         """See zope.testbrowser.interfaces.IBrowser"""
-        raise NotImplementedError
+        import ClientForm
+        from StringIO import StringIO
+        class DummyResponse(object):
+            def __init__(self, contents, url):
+                self.stringIo = StringIO(contents)
+                self.url = url
+            def read(self, size):
+                return self.stringIo.read(size)
 
+            def geturl(self):
+                return self.url
+
+        dummy_response = DummyResponse(self.contents, self.url)
+        forms = ClientForm.ParseResponse(dummy_response)
+        control, form = getControl(forms, label, name, index)
+        return controlFactory(control, form, self)
+
     def getForm(self, id=None, name=None, action=None, index=None):
         """See zope.testbrowser.interfaces.IBrowser"""
         raise NotImplementedError



More information about the Checkins mailing list