[twill] Named and unnamed forms problem and ugly workaround

Renato Borges renato.oferenda at gmail.com
Fri Nov 9 11:37:41 PST 2007


Hello everyone!

First of all, I'd like to thank everyone involved with the twill project for
creating and maintaining a very useful tool!

To time-deprived readers, I'll explain it briefly:

My problem is that unnamed forms that sit on a page that have a named form
that has the unnamed form's number as part of its name cannot be accessed
through regular fv's. For instance, if form #1 is named "Form-123" then
unnamed forms #2 and #3 cannot be accessed by fv (2, , ) or fv ( "3", , )
because the numbers 2 and 3 and the strings "2" and "3" are matched to the
"Form-123" form.

I suppose that a pretty solution would be to subclass the twill browser and
add a matching process that prioritizes number matching. But I cannot do so
right now.

So I made an ugly workaround: I set the unnamed form to a certain name and
use it normally onwards, through the set name.

To those who need more info, I'll explain in length:

We at http://stoa.usp.br/ are beginning to use twill to monitor our site for
any "system breaks" that might follow one of the developers submitting poor
code.

Recently, we started using a Google-provided form that makes searches in our
site. With this, our main page has the following forms:

>>> showforms()

Form name=searchform (#1)
## ## __Name__________________ __Type___ __ID________
__Value__________________
1     tag                      text      (None)
2     user_type                select    (None)       [''] of ['', 'person',
'community',  ...
3  1  None                     submit    (None)       Ok


Form name=searchbox_006456382451512069951:41lst14sjem (#2)
## ## __Name__________________ __Type___ __ID________
__Value__________________
1     cx                       hidden    (None)
006456382451512069951:41lst14sjem
2     cof                      hidden    (None)       FORID:0
3     q                        text      (None)
4  1  sa                       submit    (None)       Search


Form #3
## ## __Name__________________ __Type___ __ID________
__Value__________________
1     username                 text      username
2     password                 password  password
3     passthru_url             hidden    (None)       http://stoa.usp.br/
4     action                   hidden    (None)       log_on
5  1  submit                   submit    (None)       Ok
6     remember                 checkbox  (None)       ['on'] of ['on']

As you can see, form #2 is the Google-provided form, with a long string as
its name, and this string contains numbers, note specially that it contains
the numbers 1 and 3.

Now, I need to fv the unnamed form #3, but if I try it directly I get an
error:

>>> fv (3, "username", "test")
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/usr/lib/python2.4/site-packages/twill-0.9b1-py2.4.egg/twill/commands.py",
line 428, in formvalue
    control = browser.get_form_field(form, fieldname)
  File "/usr/lib/python2.4/site-packages/twill-0.9b1-py2.4.egg/twill/browser.py",
line 366, in get_form_field
    raise Exception('no field matches "%s"' % (fieldname,))
Exception: no field matches "username"
>>> fv ("3", "username", "test")
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/usr/lib/python2.4/site-packages/twill-0.9b1-py2.4.egg/twill/commands.py",
line 428, in formvalue
    control = browser.get_form_field(form, fieldname)
  File "/usr/lib/python2.4/site-packages/twill-0.9b1-py2.4.egg/twill/browser.py",
line 366, in get_form_field
    raise Exception('no field matches "%s"' % (fieldname,))
Exception: no field matches "username"

The reason is that twill matches 3 or "3" first to the Google-provided form,
because it has the number 3 as part of it's string name! I get the "no field
matches" error because there is no "username" at the Google-provided form!

Now I hope there is a better way to solve this issue (other than rewriting
the site), but I came up with this ugly solution:

I retrieve a forms list with a call to a browser object's get_all_forms()
method;
I name the third form as "login";
I use the string "login" to use such form, instead of using the number 3.

It works, check it out:

>>> b = get_browser()
>>> b.get_all_forms()[2].name = "login"
>>> fv ("login", "username", "test")
>>> showforms()

Form name=searchform (#1)
## ## __Name__________________ __Type___ __ID________
__Value__________________
1     tag                      text      (None)
2     user_type                select    (None)       [''] of ['', 'person',
'community',  ...
3  1  None                     submit    (None)       Ok


Form name=searchbox_006456382451512069951:41lst14sjem (#2)
## ## __Name__________________ __Type___ __ID________
__Value__________________
1     cx                       hidden    (None)
006456382451512069951:41lst14sjem
2     cof                      hidden    (None)       FORID:0
3     q                        text      (None)
4  1  sa                       submit    (None)       Search


Form name=login (#3)
## ## __Name__________________ __Type___ __ID________
__Value__________________
1     username                 text      username     test
2     password                 password  password
3     passthru_url             hidden    (None)       http://stoa.usp.br/
4     action                   hidden    (None)       log_on
5  1  submit                   submit    (None)       Ok
6     remember                 checkbox  (None)       ['on'] of ['on']

Well, I know it ain't pretty, but it works. At least until the developers
change the front page again. I thought this would be of interest to anyone
having problems with named and unnamed forms on the same page: the problem
is, possibly due to a form that has numbers as part of its name.

Again, I'd like to thank Titus and the rest of the crew. Great work!

See ya!
Renato.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.idyll.org/pipermail/twill/attachments/20071109/86e9c5f9/attachment.htm 


More information about the twill mailing list