[Checkins] SVN: zc.testbrowser/trunk/src/zc/testbrowser/ Partial implementation of the Form control

Justas Sadzevičius justas at pov.lt
Tue Sep 25 10:37:57 EDT 2007


Log message for revision 80011:
  Partial implementation of the Form control
  

Changed:
  U   zc.testbrowser/trunk/src/zc/testbrowser/README.txt
  U   zc.testbrowser/trunk/src/zc/testbrowser/real.js
  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 14:35:13 UTC (rev 80010)
+++ zc.testbrowser/trunk/src/zc/testbrowser/README.txt	2007-09-25 14:37:57 UTC (rev 80011)
@@ -920,28 +920,28 @@
 #
 #  - The name of the form:
 #
-#    >>> form.name
-#    'one'
+#    >>> unicode(form.name)
+#    u'one'
 #
 #  - The id of the form:
 #
-#    >>> form.id
-#    '1'
+#    >>> unicode(form.id)
+#    u'1'
 #
 #  - The action (target URL) when the form is submitted:
 #
-#    >>> form.action
-#    'http://localhost:.../forms.html'
+#    >>> unicode(form.action)
+#    u'http://localhost:.../forms.html'
 #
 #  - The method (HTTP verb) used to transmit the form data:
 #
-#    >>> form.method
-#    'POST'
+#    >>> unicode(form.method)
+#    u'POST'
 #
 #  - The encoding type of the form data:
 #
-#    >>> form.enctype
-#    'application/x-www-form-urlencoded'
+#    >>> 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...

Modified: zc.testbrowser/trunk/src/zc/testbrowser/real.js
===================================================================
--- zc.testbrowser/trunk/src/zc/testbrowser/real.js	2007-09-25 14:35:13 UTC (rev 80010)
+++ zc.testbrowser/trunk/src/zc/testbrowser/real.js	2007-09-25 14:37:57 UTC (rev 80011)
@@ -12,6 +12,24 @@
         pattern, context, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
 }
 
+function tb_xpath_tokens(pattern, context) {
+    var tokens = new Array();
+    var result = tb_xpath(pattern, context)
+    for (var c = 0; c < result.snapshotLength; c++) {
+        tb_tokens[tb_next_token] = result.snapshotItem(c);
+        tokens.push(tb_next_token++);
+    }
+    return tokens.toSource();
+}
+
+function tb_extract_token_attrs(tokens, attr) {
+    var attrs = new Array();
+    for (var i in tokens) {
+        attrs.push(tb_tokens[tokens[i]].getAttribute(attr));
+    }
+    return attrs.toSource()
+}
+
 function tb_get_link_by_predicate(predicate, index) {
     var anchors = content.document.getElementsByTagName('a');
     var i=0;

Modified: zc.testbrowser/trunk/src/zc/testbrowser/real.py
===================================================================
--- zc.testbrowser/trunk/src/zc/testbrowser/real.py	2007-09-25 14:35:13 UTC (rev 80010)
+++ zc.testbrowser/trunk/src/zc/testbrowser/real.py	2007-09-25 14:37:57 UTC (rev 80011)
@@ -20,6 +20,21 @@
     pass
 
 
+def disambiguate(intermediate, msg, index):
+    if intermediate:
+        if index is None:
+            if len(intermediate) > 1:
+                raise AmbiguityError(msg)
+            else:
+                return intermediate[0]
+        else:
+            try:
+                return intermediate[index]
+            except KeyError:
+                msg = '%s index %d' % (msg, index)
+    raise LookupError(msg)
+
+
 def controlFactory(token, browser, selectionItem=False):
     tagName = browser.execute('tb_tokens[%s].tagName' % token).lower()
     if tagName == 'select':
@@ -91,6 +106,14 @@
         for line in lines:
             self.execute(line)
 
+    def getAttribute(self, token, attr_name):
+        return self.getAttributes([token], attr_name)[0]
+
+    def getAttributes(self, tokens, attr_name):
+        return simplejson.loads(self.execute(
+            'tb_extract_token_attrs(%s, %s)' % (
+                simplejson.dumps(tokens), simplejson.dumps(attr_name))))
+
     def expect(self):
         i, match, text = self.telnet.expect([PROMPT], self.timeout)
         if match is None:
@@ -247,9 +270,26 @@
         return controlFactory(token, self, selectionItem)
 
     def getForm(self, id=None, name=None, action=None, index=None):
-        raise NotImplementedError
+        xpath = '//form'
+        if id is not None:
+            xpath += '[@id=%s]' % repr(id)
+        if name is not None:
+            xpath += '[@name=%s]' % repr(name)
 
+        matching_tokens = simplejson.loads(self.execute(
+            'tb_xpath_tokens(%s)' % simplejson.dumps(xpath)))
 
+        if action is not None:
+            form_actions = self.getAttributes(matching_tokens, 'action')
+            matching_tokens = [tok for tok, form_act in zip(matching_tokens,
+                                                            form_actions)
+                               if re.search(action, form_act)]
+
+        form_token = disambiguate(matching_tokens, '', index)
+
+        return Form(self, form_token)
+
+
 class Link(zc.testbrowser.browser.SetattrErrorsMixin):
     zope.interface.implements(zc.testbrowser.interfaces.ILink)
 
@@ -558,3 +598,54 @@
         return "<%s name=%r type=%r optionValue=%r selected=%r>" % (
             self.__class__.__name__, name, type, self.optionValue,
             self.selected)
+
+
+class Form(zc.testbrowser.browser.SetattrErrorsMixin):
+    """HTML Form"""
+    zope.interface.implements(zc.testbrowser.interfaces.IForm)
+
+    def __init__(self, browser, token):
+        self.token = token
+        self.browser = browser
+        self._browser_counter = self.browser._counter
+        self._enable_setattr_errors = True
+
+    @property
+    def action(self):
+        if self._browser_counter != self.browser._counter:
+            raise zc.testbrowser.interfaces.ExpiredError
+        action = self.browser.getAttribute(self.token, 'action')
+        if action:
+            return urlparse.urljoin(self.browser.base, action)
+        return self.browser.url
+
+    @property
+    def method(self):
+        if self._browser_counter != self.browser._counter:
+            raise zc.testbrowser.interfaces.ExpiredError
+        return self.browser.getAttribute(self.token, 'method').upper()
+
+    @property
+    def enctype(self):
+        if self._browser_counter != self.browser._counter:
+            raise zc.testbrowser.interfaces.ExpiredError
+        enc = self.browser.execute('tb_tokens[%s].encoding' % self.token)
+        return enc or 'application/x-www-form-urlencoded'
+
+    @property
+    def name(self):
+        if self._browser_counter != self.browser._counter:
+            raise zc.testbrowser.interfaces.ExpiredError
+        return self.browser.getAttribute(self.token, 'name')
+
+    @property
+    def id(self):
+        if self._browser_counter != self.browser._counter:
+            raise zc.testbrowser.interfaces.ExpiredError
+        return self.browser.getAttribute(self.token, 'id')
+
+    def submit(self, label=None, name=None, index=None, coord=(1,1)):
+        raise NotImplementedError
+
+    def getControl(self, label=None, name=None, index=None):
+        raise NotImplementedError



More information about the Checkins mailing list