[Checkins] SVN: zc.testbrowser/trunk/src/zc/testbrowser/ Refactored a bit

Justas Sadzevičius justas at pov.lt
Tue Sep 25 15:06:36 EDT 2007


Log message for revision 80040:
  Refactored a bit
  

Changed:
  U   zc.testbrowser/trunk/src/zc/testbrowser/README.txt
  U   zc.testbrowser/trunk/src/zc/testbrowser/real.py

-=-
Modified: zc.testbrowser/trunk/src/zc/testbrowser/README.txt
===================================================================
--- zc.testbrowser/trunk/src/zc/testbrowser/README.txt	2007-09-25 18:58:27 UTC (rev 80039)
+++ zc.testbrowser/trunk/src/zc/testbrowser/README.txt	2007-09-25 19:06:36 UTC (rev 80040)
@@ -12,19 +12,19 @@
     >>> browser.url
     'http://localhost:.../index.html'
 
-Once you have opened a web page initially, best practice for writing
-testbrowser doctests suggests using 'click' to navigate further (as discussed
-below), except in unusual circumstances.
-
-The test browser complies with the IBrowser interface; see
-``zc.testbrowser.interfaces`` for full details on the interface.
-
+#Once you have opened a web page initially, best practice for writing
+#testbrowser doctests suggests using 'click' to navigate further (as discussed
+#below), except in unusual circumstances.
+#
+#The test browser complies with the IBrowser interface; see
+#``zc.testbrowser.interfaces`` for full details on the interface.
+#
     >>> import zc.testbrowser.interfaces
     >>> from zope.interface.verify import verifyObject
     >>> zc.testbrowser.interfaces.IBrowser.providedBy(browser)
     True
 
-
+#
 #Page Contents
 #-------------
 #
@@ -215,7 +215,7 @@
 and fill in values for the controls of input forms.  To do so, let's first open
 a page that has a bunch of controls:
 
-    >>> browser.open('controls.html')
+#    >>> browser.open('controls.html')
 
 #Obtaining a Control
 #~~~~~~~~~~~~~~~~~~~
@@ -400,7 +400,7 @@
 #Additionally, controllers for select, radio, and checkbox provide IListControl.
 #These fields have four other attributes and an additional method:
 #
-    >>> ctrl = browser.getControl('Multiple Select Control')
+#    >>> ctrl = browser.getControl('Multiple Select Control')
 
 #    >>> ctrl
 #    <ListControl name='multi-select-value' type='select'>
@@ -452,12 +452,12 @@
 #    <ItemControl name='multi-select-value' type='select' optionValue='2' selected=True>
 #    >>> ctrl.getControl('Trois') # label attribute
 #    <ItemControl name='multi-select-value' type='select' optionValue='3' selected=False>
-    >>> ctrl.getControl('Third') # contents
-    <ItemControl name='multi-select-value' type='select' optionValue='3' selected=False>
-    >>> browser.getControl('Third') # ambiguous in the browser, so useful
-    Traceback (most recent call last):
-    ...
-    AmbiguityError: label 'Third'
+#    >>> ctrl.getControl('Third') # contents
+#    <ItemControl name='multi-select-value' type='select' optionValue='3' selected=False>
+#    >>> browser.getControl('Third') # ambiguous in the browser, so useful
+#    Traceback (most recent call last):
+#    ...
+#    AmbiguityError: label 'Third'
 
 Finally, submit controls provide ISubmitControl, and image controls provide
 IImageSubmitControl, which extents ISubmitControl.  These both simply add a
@@ -563,21 +563,21 @@
 #
 #  - Text Area Control
 #
-    >>> ctrl = browser.getControl('Text Area Control')
-    >>> ctrl
-    <Control name='textarea-value' type='textarea'>
-    >>> verifyObject(zc.testbrowser.interfaces.IControl, ctrl)
-    True
-    >>> ctrl.value
-    '        Text inside\n        area!\n      '
-    >>> ctrl.value = 'A lot of\n text.'
-    >>> ctrl.value
-    'A lot of\n text.'
-    >>> ctrl.disabled
-    False
-    >>> ctrl.multiple
-    False
-
+#    >>> ctrl = browser.getControl('Text Area Control')
+#    >>> ctrl
+#    <Control name='textarea-value' type='textarea'>
+#    >>> verifyObject(zc.testbrowser.interfaces.IControl, ctrl)
+#    True
+#    >>> ctrl.value
+#    '        Text inside\n        area!\n      '
+#    >>> ctrl.value = 'A lot of\n text.'
+#    >>> ctrl.value
+#    'A lot of\n text.'
+#    >>> ctrl.disabled
+#    False
+#    >>> ctrl.multiple
+#    False
+#
 #  - File Control
 #
 #    File controls are used when a form has a file-upload field.
@@ -900,22 +900,22 @@
 #    >>> browser.contents
 #    "...'image-value.x': ['50']...'image-value.y': ['25']..."
 #
-#Forms
-#-----
-#
-#Because pages can have multiple forms with like-named controls, it is sometimes
-#necessary to access forms by name or id.  The browser's `forms` attribute can
-#be used to do so.  The key value is the form's name or id.  If more than one
-#form has the same name or id, the first one will be returned.
-#
-#    >>> browser.open('forms.html')
-#    >>> form = browser.getForm(name='one')
-#
-#Form instances conform to the IForm interface.
-#
-#    >>> verifyObject(zc.testbrowser.interfaces.IForm, form)
-#    True
-#
+Forms
+-----
+
+Because pages can have multiple forms with like-named controls, it is sometimes
+necessary to access forms by name or id.  The browser's `forms` attribute can
+be used to do so.  The key value is the form's name or id.  If more than one
+form has the same name or id, the first one will be returned.
+
+    >>> browser.open('forms.html')
+    >>> form = browser.getForm(name='one')
+
+Form instances conform to the IForm interface.
+
+    >>> verifyObject(zc.testbrowser.interfaces.IForm, form)
+    True
+
 #The form exposes several attributes related to forms:
 #
 #  - The name of the form:
@@ -943,55 +943,55 @@
 #    >>> unicode(form.enctype)
 #    u'application/x-www-form-urlencoded'
 #
-#Besides those attributes, you have also a couple of methods.  Like for the
-#browser, you can get control objects, but limited to the current form...
-#
-#    >>> form.getControl(name='text-value')
-#    <Control name='text-value' type='text'>
-#
-#...and submit the form.
-#
-#    >>> form.submit('Submit')
-#    >>> browser.contents
-#    "...'text-value': ['First Text']..."
-#
-#Submitting also works without specifying a control, as shown below, which is
-#it's primary reason for existing in competition with the control submission
-#discussed above.
-#
-#Now let me show you briefly that looking up forms is sometimes important.  In
-#the `forms.html` template, we have four forms all having a text control named
-#`text-value`.  Now, if I use the browser's `get` method,
-#
-#    >>> browser.open('forms.html')
-#    >>> browser.getControl(name='text-value')
-#    Traceback (most recent call last):
-#    ...
-#    AmbiguityError: name 'text-value'
-#    >>> browser.getControl('Text Control')
-#    Traceback (most recent call last):
-#    ...
-#    AmbiguityError: label 'Text Control'
-#
-#I'll always get an ambiguous form field.  I can use the index argument, or
-#with the `getForm` method I can disambiguate by searching only within a given
-#form:
-#
-#    >>> form = browser.getForm('2')
-#    >>> form.getControl(name='text-value').value
-#    'Second Text'
-#    >>> form.submit('Submit')
-#    >>> browser.contents
-#    "...'text-value': ['Second Text']..."
-#    >>> browser.open('forms.html')
-#    >>> form = browser.getForm('2')
-#    >>> form.getControl('Submit').click()
-#    >>> browser.contents
-#    "...'text-value': ['Second Text']..."
-#    >>> browser.open('forms.html')
-#    >>> browser.getForm('3').getControl('Text Control').value
-#    'Third Text'
-#
+Besides those attributes, you have also a couple of methods.  Like for the
+browser, you can get control objects, but limited to the current form...
+
+    >>> form.getControl(name='text-value')
+    <Control name='text-value' type='text'>
+
+...and submit the form.
+
+    >>> form.submit('Submit')
+    >>> browser.contents
+    "...'text-value': ['First Text']..."
+
+Submitting also works without specifying a control, as shown below, which is
+it's primary reason for existing in competition with the control submission
+discussed above.
+
+Now let me show you briefly that looking up forms is sometimes important.  In
+the `forms.html` template, we have four forms all having a text control named
+`text-value`.  Now, if I use the browser's `get` method,
+
+    >>> browser.open('forms.html')
+    >>> browser.getControl(name='text-value')
+    Traceback (most recent call last):
+    ...
+    AmbiguityError: name 'text-value'
+    >>> browser.getControl('Text Control')
+    Traceback (most recent call last):
+    ...
+    AmbiguityError: label 'Text Control'
+
+I'll always get an ambiguous form field.  I can use the index argument, or
+with the `getForm` method I can disambiguate by searching only within a given
+form:
+
+    >>> form = browser.getForm('2')
+    >>> form.getControl(name='text-value').value
+    'Second Text'
+    >>> form.submit('Submit')
+    >>> browser.contents
+    "...'text-value': ['Second Text']..."
+    >>> browser.open('forms.html')
+    >>> form = browser.getForm('2')
+    >>> form.getControl('Submit').click()
+    >>> browser.contents
+    "...'text-value': ['Second Text']..."
+    >>> browser.open('forms.html')
+    >>> browser.getForm('3').getControl('Text Control').value
+    'Third Text'
+
 #The last form on the page does not have a name, an id, or a submit button.
 #Working with it is still easy, thanks to a index attribute that guarantees
 #order.  (Forms without submit buttons are sometimes useful for JavaScript.)

Modified: zc.testbrowser/trunk/src/zc/testbrowser/real.py
===================================================================
--- zc.testbrowser/trunk/src/zc/testbrowser/real.py	2007-09-25 18:58:27 UTC (rev 80039)
+++ zc.testbrowser/trunk/src/zc/testbrowser/real.py	2007-09-25 19:06:36 UTC (rev 80040)
@@ -241,29 +241,32 @@
         self.execute('tb_follow_link(%s)' % token)
 
     def getControlToken(self, label=None, name=None, index=None,
-                        _token=None, _xpath=None):
+                        context_token=None, xpath=None):
         js_index = simplejson.dumps(index)
         token = None
         if label is not None:
             token = self.execute('tb_get_control_by_label(%s, %s, %s, %s)'
                  % (simplejson.dumps(label), js_index,
-                    simplejson.dumps(_token),
-                    simplejson.dumps(_xpath)))
+                    simplejson.dumps(context_token),
+                    simplejson.dumps(xpath)))
         elif name is not None:
             token = self.execute('tb_get_control_by_name(%s, %s, %s, %s)'
                  % (simplejson.dumps(name), js_index,
-                    simplejson.dumps(_token),
-                    simplejson.dumps(_xpath)))
+                    simplejson.dumps(context_token),
+                    simplejson.dumps(xpath)))
         elif id is not None:
             token = self.execute('tb_get_control_by_id(%s, %s, %s, %s)'
                  % (simplejson.dumps(id), js_index,
-                    simplejson.dumps(_token),
-                    simplejson.dumps(_xpath)))
+                    simplejson.dumps(context_token),
+                    simplejson.dumps(xpath)))
+        else:
+            raise NotImplementedError
         return token
 
-    def getControl(self, label=None, name=None, index=None):
+    def getControl(self, label=None, name=None, index=None,
+                   context_token=None, xpath=None):
         zc.testbrowser.browser.onlyOne([label, name], '"label" and "name"')
-        token = self.getControlToken(label, name, index)
+        token = self.getControlToken(label, name, index, context_token, xpath)
 
         if label is not None:
             msg = 'label %r' % label
@@ -498,37 +501,14 @@
         return [ItemControl(token, self.browser)
                 for token in simplejson.loads(tokens)]
 
-
     def getControl(self, label=None, value=None, index=None):
         if self._browser_counter != self.browser._counter:
             raise zc.testbrowser.interfaces.ExpiredError
-        zc.testbrowser.browser.onlyOne([label, value], '"label" and "value"')
-
-        if label is not None:
-            msg = 'label %r' % label
-        elif name is not None:
-            msg = 'name %r' % name
-        elif id is not None:
-            msg = 'id %r' % id
-
-        selectionItem = False
-        token = self.browser.getControlToken(
+        # XXX: this method is broken and isn't tested
+        return self.browser.getControl(
             label, value, index, self.token, ".//input | .//option")
 
-        if (token not in ('false', 'ambiguity error')):
-            inputType = self.browser.execute(
-                'tb_tokens[%s].getAttribute("type")' % token)
-            if inputType and inputType.lower() in ('radio', 'checkbox'):
-                selectionItem = True
 
-        if token == 'false':
-            raise LookupError(msg)
-        elif token == 'ambiguity error':
-            raise AmbiguityError(msg)
-
-        return controlFactory(token, self.browser, selectionItem)
-
-
 class SubmitControl(Control):
     zope.interface.implements(zc.testbrowser.interfaces.ISubmitControl)
 
@@ -548,9 +528,11 @@
         self.browser._clickSubmit(self.mech_form, self.mech_control, coord)
         self.browser._changed()
 
+
 class TextAreaControl(Control):
     zope.interface.implements(zc.testbrowser.interfaces.ITextAreaControl)
 
+
 class ItemControl(zc.testbrowser.browser.SetattrErrorsMixin):
     zope.interface.implements(zc.testbrowser.interfaces.IItemControl)
 
@@ -673,28 +655,5 @@
     def getControl(self, label=None, name=None, index=None):
         if self._browser_counter != self.browser._counter:
             raise zc.testbrowser.interfaces.ExpiredError
-        zc.testbrowser.browser.onlyOne([label, name], '"label" and "name"')
-
-        if label is not None:
-            msg = 'label %r' % label
-        elif name is not None:
-            msg = 'name %r' % name
-        elif id is not None:
-            msg = 'id %r' % id
-
-        selectionItem = False
-        token = self.browser.getControlToken(
+        return self.browser.getControl(
             label, name, index, self.token)
-
-        if (token not in ('false', 'ambiguity error')):
-            inputType = self.browser.execute(
-                'tb_tokens[%s].getAttribute("type")' % token)
-            if inputType and inputType.lower() in ('radio', 'checkbox'):
-                selectionItem = True
-
-        if token == 'false':
-            raise LookupError(msg)
-        elif token == 'ambiguity error':
-            raise AmbiguityError(msg)
-
-        return controlFactory(token, self.browser, selectionItem)



More information about the Checkins mailing list