[Zope3-checkins] SVN: Zope3/branches/testbrowser-integration/src/zope/app/testing/testbrowser/ - Developed forms mapping and form tests.

Stephan Richter srichter at cosmos.phy.tufts.edu
Wed Jul 27 21:18:32 EDT 2005


Log message for revision 37517:
  - Developed forms mapping and form tests.
  
  - Fixed several bugs that surfaced while writing tests.
  
  - Added ``getControl()`` to the ``Form`` class.
  
  

Changed:
  U   Zope3/branches/testbrowser-integration/src/zope/app/testing/testbrowser/README.txt
  U   Zope3/branches/testbrowser-integration/src/zope/app/testing/testbrowser/browser.py
  A   Zope3/branches/testbrowser-integration/src/zope/app/testing/testbrowser/ftests/forms.html
  U   Zope3/branches/testbrowser-integration/src/zope/app/testing/testbrowser/interfaces.py

-=-
Modified: Zope3/branches/testbrowser-integration/src/zope/app/testing/testbrowser/README.txt
===================================================================
--- Zope3/branches/testbrowser-integration/src/zope/app/testing/testbrowser/README.txt	2005-07-28 00:05:56 UTC (rev 37516)
+++ Zope3/branches/testbrowser-integration/src/zope/app/testing/testbrowser/README.txt	2005-07-28 01:18:31 UTC (rev 37517)
@@ -620,34 +620,106 @@
 Forms
 -----
 
-
-
 Because pages can have multiple forms with like-named controls, it is sometimes
 neccesary 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.
 
-XXX these need to be re-targeted to pages registered just for this test
-##    >>> # zope form and use that instead
-##    >>> form = browser.forms['portlet_form']
+    >>> browser.open('http://localhost/@@/testbrowser/forms.html')
+    >>> form = browser.forms['one']
 
-The form exposes several attributes:
+The form exposes several attributes related to forms:
 
-##    >>> form.name
-##    'portlet_form'
-##    >>> form.action
-##    'http://localhost/++etc++site/default/...'
-##    >>> form.method
-##    'POST'
-##    >>> form.id is None
-##    True
+  - The name of the form:
 
-The form's controls can also be accessed with the `controls` mapping.
+    >>> form.name
+    'one'
 
-##    >>> form.controls['portlet_action']
-##    '...'
+  - The id of the form:
 
+    >>> form.id
+    '1'
+    
+  - The action (target URL) when the form is submitted:
 
+    >>> form.action
+    'http://localhost/@@/testbrowser/forms.html'
+
+  - The method (HTTP verb) used to transmit the form data:
+
+    >>> form.method
+    'POST'
+
+  - The encoding type of the form data:
+
+    >>> form.enctype
+    'multipart/form-data'
+
+  - The controls for this specific form are also available:
+
+    >>> form.controls
+    <zope.app.testing.testbrowser.browser.ControlsMapping object at ...>
+    >>> form.controls['text-value']
+    'First Text'
+
+Besides those attributes, you have also a couple of methods. Like for the
+browser, you can get control objects
+
+    >>> form.getControl('text-value')
+    Control(name='text-value', type='text')
+
+and submit the form:
+
+    >>> form.submit('Submit')
+    >>> print browser.contents
+    <html>
+    ...
+    <em>First Text</em>
+    ...
+    </html>
+
+Okay, that's it about forms. Now let me show you briefly that looking up forms
+is sometimes important. In the `forms.html` template, we have three forms all
+having a text control named `text-value`. Now, if I use the browser's
+`controls` attribute and `click` method,
+
+    >>> browser.controls['text-value']
+    'First Text'
+    >>> browser.click('Submit')
+    >>> print browser.contents
+    <html>
+    ...
+    <em>First Text</em>
+    ...
+    </html>
+
+I can every only get to the first form, making the others unreachable. But
+with the `forms` mapping I can get to the second and third form as well:
+
+    >>> form = browser.forms['2']
+    >>> form.controls['text-value']
+    'Second Text'
+    >>> form.submit('Submit')
+    >>> print browser.contents
+    <html>
+    ...
+    <em>Second Text</em>
+    ...
+    </html>
+
+The `forms` mapping also supports the check for containment
+
+    >>> 'three' in browser.forms
+    True
+
+and retrievel with optional default value:
+
+    >>> browser.forms.get('2')
+    <zope.app.testing.testbrowser.browser.Form object at ...>
+    >>> browser.forms.get('invalid', 42)
+    42
+
+
 Handling Errors
 ---------------
 

Modified: Zope3/branches/testbrowser-integration/src/zope/app/testing/testbrowser/browser.py
===================================================================
--- Zope3/branches/testbrowser-integration/src/zope/app/testing/testbrowser/browser.py	2005-07-28 00:05:56 UTC (rev 37516)
+++ Zope3/branches/testbrowser-integration/src/zope/app/testing/testbrowser/browser.py	2005-07-28 01:18:31 UTC (rev 37517)
@@ -260,9 +260,8 @@
 
     def __getitem__(self, key):
         """See zope.interface.common.mapping.IItemMapping"""
-        try:
-            form = self.browser._findForm(key, key, None)
-        except ValueError:
+        form = self.browser._findForm(key, key, None)
+        if form is None:
             raise KeyError(key)
         return Form(self.browser, form)
 
@@ -273,7 +272,7 @@
         except KeyError:
             return default
 
-    def __contains__(self, item):
+    def __contains__(self, key):
         """See zope.interface.common.mapping.IReadMapping"""
         return self.browser._findForm(key, key, None) is not None
 
@@ -293,11 +292,10 @@
 
     def __getitem__(self, key):
         """See zope.app.testing.testbrowser.interfaces.IControlsMapping"""
-        form, control = self.browser._findControl(key, key, key)
+        form, control = self.browser._findControl(key, key, key,
+                                                  form=self.mech_form)
         if control is None:
             raise KeyError(key)
-        if self.mech_form is not None and self.mech_form != form:
-            raise KeyError(key)
         return Control(control).value
 
     def get(self, key, default=None):
@@ -344,7 +342,7 @@
     @property
     def id(self):
         """See zope.app.testing.testbrowser.interfaces.IForm"""
-        return self.mech_form.attrs.get(id)
+        return self.mech_form.attrs.get('id')
 
     @property
     def controls(self):
@@ -355,7 +353,19 @@
         """See zope.app.testing.testbrowser.interfaces.IForm"""
         form, control = self.browser._findControl(
             text, id, name, type='submit', form=self.mech_form)
+
+        if control is None:
+            form, control = self.browser._findControl(
+                text, id, name, type='image', form=self.mech_form)
+
         if control is not None:
             self.browser._clickSubmit(form, control, coord)
             self.browser._changed()
-            return
+
+    def getControl(self, text):
+        """See zope.app.testing.testbrowser.interfaces.IForm"""
+        form, control = self.browser._findControl(text, text, text,
+                                                  form=self.mech_form)
+        if control is None:
+            raise ValueError('could not locate control: ' + text)
+        return Control(control)

Added: Zope3/branches/testbrowser-integration/src/zope/app/testing/testbrowser/ftests/forms.html
===================================================================
--- Zope3/branches/testbrowser-integration/src/zope/app/testing/testbrowser/ftests/forms.html	2005-07-28 00:05:56 UTC (rev 37516)
+++ Zope3/branches/testbrowser-integration/src/zope/app/testing/testbrowser/ftests/forms.html	2005-07-28 01:18:31 UTC (rev 37517)
@@ -0,0 +1,27 @@
+<html>
+  <body>
+
+    <h1>Forms Tests</h1>
+
+    <em tal:condition="request/text-value|nothing"
+        tal:content="request/text-value" />
+
+    <form id="1" name="one" action="forms.html"
+          enctype="multipart/form-data" method="post">
+      <input type="text" name="text-value" value="First Text" />
+      <input type="image" name="image-1" src="zope3logo.gif" />
+      <input type="submit" name="submit-1" value="Submit" />
+    </form>
+
+    <form id="2" name="two" action="forms.html">
+      <input type="text" name="text-value" value="Second Text" />
+      <input type="submit" name="submit-2" value="Submit" />
+    </form>
+
+    <form id="3" name="three" action="forms.html">
+      <input type="text" name="text-value" value="Third Text" />
+      <input type="submit" name="submit-3" value="Submit" />
+    </form>
+
+  </body>
+</html>
\ No newline at end of file

Modified: Zope3/branches/testbrowser-integration/src/zope/app/testing/testbrowser/interfaces.py
===================================================================
--- Zope3/branches/testbrowser-integration/src/zope/app/testing/testbrowser/interfaces.py	2005-07-28 00:05:56 UTC (rev 37516)
+++ Zope3/branches/testbrowser-integration/src/zope/app/testing/testbrowser/interfaces.py	2005-07-28 01:18:31 UTC (rev 37517)
@@ -128,6 +128,9 @@
         schema=IControlsMapping,
         required=True)
 
+    def getControl(self, text):
+        """Get a control of the form."""
+
     def submit(text=None, id=None, name=None, coord=(1,1)):
         """Submit this form.
 



More information about the Zope3-Checkins mailing list