[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