[Zope3-checkins] SVN: Zope3/branches/testbrowser-integration/src/zope/testbrowser/ Work on zope.testbrowser:

Benji York benji at zope.com
Sat Jul 30 10:33:40 EDT 2005


Log message for revision 37597:
  Work on zope.testbrowser:
   - make hidden fields writable (ClientForm thinks they shouldn't be, but while
     testing pages that would otherwise use Javascript to fill in hidden fields
     this will be neccesary)
   - remove the readonly attribute of controls, all controls are now writable
   - rework __repr__ of Control to better match prevailing style (it did look
     like a constructor, but no user code constructs Controls, and the style
     shown wouldn't work anyway)
   - simplify some of the test cases (remove unnecessary "prints", extra verbiage
     in expected output, remove unnecessary and distracting <BLANKLINE>s)
   - fix minor typos and grammar
   - make control.multiple return a boolean (as the interface claims)
  

Changed:
  U   Zope3/branches/testbrowser-integration/src/zope/testbrowser/README.txt
  U   Zope3/branches/testbrowser-integration/src/zope/testbrowser/browser.py

-=-
Modified: Zope3/branches/testbrowser-integration/src/zope/testbrowser/README.txt
===================================================================
--- Zope3/branches/testbrowser-integration/src/zope/testbrowser/README.txt	2005-07-30 14:19:01 UTC (rev 37596)
+++ Zope3/branches/testbrowser-integration/src/zope/testbrowser/README.txt	2005-07-30 14:33:39 UTC (rev 37597)
@@ -30,20 +30,16 @@
         <h1>Simple Page</h1>
       </body>
     </html>
-    <BLANKLINE>
 
 Making assertions about page contents is easy.
 
-    >>> 'Simple Page' in browser.contents
+    >>> '<h1>Simple Page</h1>' in browser.contents
     True
 
-Utilizing the doctest facilities, it is better to do:
+Utilizing the doctest facilities, it also possible to do:
 
-    >>> print browser.contents
-    <html>
-    ...
-        <h1>Simple Page</h1>
-    ...
+    >>> browser.contents
+    '...<h1>Simple Page</h1>...'
 
 Note: Unfortunately, ellipsis (...) cannot be used at the beginning of the
 output.
@@ -108,7 +104,6 @@
     Content-Type: text/html;charset=utf-8
     X-Content-Type-Warning: guessed from content
     X-Powered-By: Zope (www.zope.org), Python (www.python.org)
-    <BLANKLINE>
 
 Or as a mapping:
 
@@ -120,7 +115,7 @@
 ----------
 
 If you want to simulate clicking on a link, there is a `click` method. In the
-`navigate.html` file there are several links setup to demonstrate the
+`navigate.html` file there are several links set up to demonstrate the
 capabilities of the `click` method. 
 
     >>> browser.open('http://localhost/@@/testbrowser/navigate.html')
@@ -128,76 +123,53 @@
 The simplest is to access the link by the text value that is linked, in other
 words the linked text you would see in a browser:
 
-    >>> print browser.contents
-    <html>
-    ...
-    <a href="navigate.html?message=By+Link+Text">Link Text</a>
-    ...
+    >>> browser.contents
+    '...<a href="navigate.html?message=By+Link+Text">Link Text</a>...'
 
     >>> browser.click('Link Text')
     >>> browser.url
     'http://localhost/@@/testbrowser/navigate.html?message=By+Link+Text'
-    >>> print browser.contents
-    <html>
-    ...
-    Message: <em>By Link Text</em>
-    ...
+    >>> browser.contents
+    '...Message: <em>By Link Text</em>...'
 
 You can also find the link by (1) its URL,
 
     >>> browser.open('http://localhost/@@/testbrowser/navigate.html')
-    >>> print browser.contents
-    <html>
-    ...
-    <a href="navigate.html?message=By+URL">Using the URL</a>
-    ...
+    >>> browser.contents
+    '...<a href="navigate.html?message=By+URL">Using the URL</a>...'
 
     >>> browser.click(url='\?message=By\+URL')
     >>> browser.url
     'http://localhost/@@/testbrowser/navigate.html?message=By+URL'
-    >>> print browser.contents
-    <html>
-    ...
-    Message: <em>By URL</em>
-    ...
+    >>> browser.contents
+    '...Message: <em>By URL</em>...'
 
-and (2) its id:
+or (2) its id:
 
     >>> browser.open('http://localhost/@@/testbrowser/navigate.html')
-    >>> print browser.contents
-    <html>
-    ...
-    <a href="navigate.html?message=By+Id" id="anchorid">By Anchor Id</a>
-    ...
+    >>> browser.contents
+    '...<a href="navigate.html?message=By+Id" 
+    id="anchorid">By Anchor Id</a>...'
 
     >>> browser.click(id='anchorid')
     >>> browser.url
     'http://localhost/@@/testbrowser/navigate.html?message=By+Id'
-    >>> print browser.contents
-    <html>
-    ...
-    Message: <em>By Id</em>
-    ...
+    >>> browser.contents
+    '...Message: <em>By Id</em>...'
 
 But there are more interesting cases. You can also use the `click` method to
 submit forms. You can either use the submit button's value by simply
 specifying the text:
 
     >>> browser.open('http://localhost/@@/testbrowser/navigate.html')
-    >>> print browser.contents
-    <html>
-    ...
-    <input type="submit" name="submit-form" value="Submit" />
-    ...
+    >>> browser.contents
+    '...<input type="submit" name="submit-form" value="Submit" />...'
 
     >>> browser.click('Submit')
     >>> browser.url
     'http://localhost/@@/testbrowser/navigate.html'
-    >>> print browser.contents
-    <html>
-    ...
-    Message: <em>By Form Submit</em>
-    ...
+    >>> browser.contents
+    '...Message: <em>By Form Submit</em>...'
 
 Alternatively, you can specify the name of the control:
 
@@ -205,11 +177,8 @@
     >>> browser.click(name='submit-form')
     >>> browser.url
     'http://localhost/@@/testbrowser/navigate.html'
-    >>> print browser.contents
-    <html>
-    ...
-    Message: <em>By Form Submit</em>
-    ...
+    >>> browser.contents
+    '...Message: <em>By Form Submit</em>...'
 
 You thought we were done here? Not so quickly. The `click` method also
 supports image maps, though not by specifying the coordinates, but using the
@@ -219,11 +188,8 @@
     >>> browser.click(id='zope3')
     >>> browser.url
     'http://localhost/@@/testbrowser/navigate.html?message=Zope+3+Name'
-    >>> print browser.contents
-    <html>
-    ...
-    Message: <em>Zope 3 Name</em>
-    ...
+    >>> browser.contents
+    '...Message: <em>Zope 3 Name</em>...'
 
 
 Other Navigation
@@ -267,15 +233,8 @@
     'Some Text'
 
 The key is matched against the value, id and name of the control. The
-`controls` mapping provides oterh functions too:
+`controls` mapping provides other functions too:
 
-  - Getting the value with a default option:
-
-      >>> browser.controls.get('text-value')
-      'Some Text'
-      >>> browser.controls.get('foo-value', 42)
-      42
-
   - Asking for existence:
 
       >>> 'text-value' in browser.controls
@@ -283,6 +242,13 @@
       >>> 'foo-value' in browser.controls
       False
 
+  - Getting the value with a default option:
+
+      >>> browser.controls.get('text-value')
+      'Some Text'
+      >>> browser.controls.get('foo-value', 42)
+      42
+
   - Setting an item to a new value:
 
     >>> browser.controls['text-value'] = 'Some other Text'
@@ -314,14 +280,15 @@
 ~~~~~~~~~~~~~~~
 
 But the value of a control is not always everything that there is to know or
-interesting. In those cases, one can access the control object:
+that is interesting. In those cases, one can access the control object:
 
     >>> ctrl = browser.getControl('text-value')
     >>> ctrl
-    Control(name='text-value', type='text')
+    <Control name='text-value' type='text'>
 
 The string passed into the function will be matched against the value, id and
-name of the control. The control has several useful attributes:
+name of the control, just as when using the controll mapping. The control has
+several useful attributes:
 
   - the name as which the control is known to the form:
 
@@ -344,15 +311,10 @@
     >>> ctrl.disabled
     False
 
-  - another flag describing whether the value can be changed; this might seem
-    strange, but for example hidden field values cannot be modified:
-
-    >>> ctrl.readonly
-    False
-
   - there is a flag to tell us whether the control can have multiple values:
 
     >>> ctrl.multiple
+    False
 
   - and finally there is an attribute that provides all available value
     options. This is of course not sensible for a text input control and thus
@@ -377,15 +339,14 @@
 
     >>> ctrl = browser.getControl('password-value')
     >>> ctrl
-    Control(name='password-value', type='password')
+    <Control name='password-value' type='password'>
     >>> ctrl.value
     'pass now'
     >>> ctrl.value = 'Password'
     >>> ctrl.disabled
     False
-    >>> ctrl.readonly
-    False
     >>> ctrl.multiple
+    False
     >>> ctrl.options
     Traceback (most recent call last):
     ...    
@@ -395,18 +356,14 @@
 
     >>> ctrl = browser.getControl('hidden-value')
     >>> ctrl
-    Control(name='hidden-value', type='hidden')
+    <Control name='hidden-value' type='hidden'>
     >>> ctrl.value
     'Hidden'
     >>> ctrl.value = 'More Hidden'
-    Traceback (most recent call last):
-    ...    
-    AttributeError: control 'hidden-value' is readonly
     >>> ctrl.disabled
     False
-    >>> ctrl.readonly
-    True
     >>> ctrl.multiple
+    False
     >>> ctrl.options
     Traceback (most recent call last):
     ...    
@@ -416,15 +373,14 @@
 
     >>> ctrl = browser.getControl('textarea-value')
     >>> ctrl
-    Control(name='textarea-value', type='textarea')
+    <Control name='textarea-value' type='textarea'>
     >>> ctrl.value
     '\n        Text inside\n        area!\n      '
     >>> ctrl.value = 'A lot of\n text.'
     >>> ctrl.disabled
     False
-    >>> ctrl.readonly
-    False
     >>> ctrl.multiple
+    False
     >>> ctrl.options
     Traceback (most recent call last):
     ...    
@@ -434,15 +390,14 @@
 
     >>> ctrl = browser.getControl('file-value')
     >>> ctrl
-    Control(name='file-value', type='file')
+    <Control name='file-value' type='file'>
     >>> ctrl.value
     >>> import cStringIO
     >>> ctrl.value = cStringIO.StringIO('File contents')
     >>> ctrl.disabled
     False
-    >>> ctrl.readonly
-    False
     >>> ctrl.multiple
+    False
     >>> ctrl.options
     Traceback (most recent call last):
     ...    
@@ -452,14 +407,12 @@
 
     >>> ctrl = browser.getControl('single-select-value')
     >>> ctrl
-    Control(name='single-select-value', type='select')
+    <Control name='single-select-value' type='select'>
     >>> ctrl.value
     ['1']
     >>> ctrl.value = ['2']
     >>> ctrl.disabled
     False
-    >>> ctrl.readonly
-    False
     >>> ctrl.multiple
     False
     >>> ctrl.options
@@ -469,14 +422,12 @@
 
     >>> ctrl = browser.getControl('multi-select-value')
     >>> ctrl
-    Control(name='multi-select-value', type='select')
+    <Control name='multi-select-value' type='select'>
     >>> ctrl.value
     []
     >>> ctrl.value = ['1', '2']
     >>> ctrl.disabled
     False
-    >>> ctrl.readonly
-    False
     >>> ctrl.multiple
     True
     >>> ctrl.options
@@ -486,14 +437,12 @@
 
     >>> ctrl = browser.getControl('single-unvalued-checkbox-value')
     >>> ctrl
-    Control(name='single-unvalued-checkbox-value', type='checkbox')
+    <Control name='single-unvalued-checkbox-value' type='checkbox'>
     >>> ctrl.value
     True
     >>> ctrl.value = False
     >>> ctrl.disabled
     False
-    >>> ctrl.readonly
-    False
     >>> ctrl.multiple
     True
     >>> ctrl.options
@@ -503,14 +452,12 @@
 
     >>> ctrl = browser.getControl('single-valued-checkbox-value')
     >>> ctrl
-    Control(name='single-valued-checkbox-value', type='checkbox')
+    <Control name='single-valued-checkbox-value' type='checkbox'>
     >>> ctrl.value
     ['1']
     >>> ctrl.value = []
     >>> ctrl.disabled
     False
-    >>> ctrl.readonly
-    False
     >>> ctrl.multiple
     True
     >>> ctrl.options
@@ -520,14 +467,12 @@
 
     >>> ctrl = browser.getControl('multi-checkbox-value')
     >>> ctrl
-    Control(name='multi-checkbox-value', type='checkbox')
+    <Control name='multi-checkbox-value' type='checkbox'>
     >>> ctrl.value
     ['1', '3']
     >>> ctrl.value = ['1', '2']
     >>> ctrl.disabled
     False
-    >>> ctrl.readonly
-    False
     >>> ctrl.multiple
     True
     >>> ctrl.options
@@ -537,14 +482,13 @@
 
     >>> ctrl = browser.getControl('image-value')
     >>> ctrl
-    Control(name='image-value', type='image')
+    <Control name='image-value' type='image'>
     >>> ctrl.value
     ''
     >>> ctrl.disabled
     False
-    >>> ctrl.readonly
-    False
     >>> ctrl.multiple
+    False
     >>> ctrl.options
     Traceback (most recent call last):
     ...    
@@ -554,14 +498,13 @@
 
     >>> ctrl = browser.getControl('submit-value')
     >>> ctrl
-    Control(name='submit-value', type='submit')
+    <Control name='submit-value' type='submit'>
     >>> ctrl.value
     'Submit'
     >>> ctrl.disabled
     False
-    >>> ctrl.readonly
-    True
     >>> ctrl.multiple
+    False
     >>> ctrl.options
     Traceback (most recent call last):
     ...    
@@ -666,7 +609,7 @@
 browser, you can get control objects
 
     >>> form.getControl('text-value')
-    Control(name='text-value', type='text')
+    <Control name='text-value' type='text'>
 
 and submit the form:
 
@@ -700,12 +643,8 @@
     >>> form.controls['text-value']
     'Second Text'
     >>> form.submit('Submit')
-    >>> print browser.contents
-    <html>
-    ...
-    <em>Second Text</em>
-    ...
-    </html>
+    >>> browser.contents
+    '...<em>Second Text</em>...'
 
 The `forms` mapping also supports the check for containment
 

Modified: Zope3/branches/testbrowser-integration/src/zope/testbrowser/browser.py
===================================================================
--- Zope3/branches/testbrowser-integration/src/zope/testbrowser/browser.py	2005-07-30 14:19:01 UTC (rev 37596)
+++ Zope3/branches/testbrowser-integration/src/zope/testbrowser/browser.py	2005-07-30 14:33:39 UTC (rev 37597)
@@ -203,14 +203,25 @@
     def __init__(self, control):
         self.mech_control = control
 
+        # 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
+
     def __getattr__(self, name):
         # See zope.testbrowser.interfaces.IControl
-        names = ['disabled', 'type', 'name', 'readonly', 'multiple']
+        names = ['disabled', 'type', 'name', 'multiple']
+        booleans = ['disabled', 'multiple']
         if name in names:
-            return getattr(self.mech_control, name, None)
+            result = getattr(self.mech_control, name, None)
         else:
             raise AttributeError(name)
 
+        if name in booleans:
+            result = bool(result)
+
+        return result
+
     @apply
     def value():
         """See zope.testbrowser.interfaces.IControl"""
@@ -248,7 +259,7 @@
             raise AttributeError('options')
 
     def __repr__(self):
-        return "Control(name='%s', type='%s')" %(self.name, self.type)
+        return "<Control name=%r type=%r>" %(self.name, self.type)
 
 
 class FormsMapping(object):



More information about the Zope3-Checkins mailing list