| 429 | self._parse_fields() |
| 430 | |
| 431 | def _parse_fields(self): |
| 432 | fields = OrderedDict() |
| 433 | field_order = [] |
| 434 | tags = ('input', 'select', 'textarea', 'button') |
| 435 | inner_elts = self.html.find_all(tags) |
| 436 | if self.id: |
| 437 | def _form_elt_filter(tag): |
| 438 | return tag.name in tags and any( |
| 439 | prt.name == 'form' and prt.attrs.get('id') == self.id |
| 440 | for prt in tag.parents |
| 441 | ) or tag.attrs.get('form') == self.id |
| 442 | elements = self.response.html.find_all(_form_elt_filter) |
| 443 | else: |
| 444 | elements = inner_elts |
| 445 | for pos, node in enumerate(elements): |
| 446 | attrs = dict(node.attrs) |
| 447 | tag = node.name |
| 448 | name = None |
| 449 | if 'name' in attrs: |
| 450 | name = attrs.pop('name') |
| 451 | |
| 452 | if tag == 'textarea': |
| 453 | if node.text.startswith('\r\n'): # pragma: no cover |
| 454 | text = node.text[2:] |
| 455 | elif node.text.startswith('\n'): |
| 456 | text = node.text[1:] |
| 457 | else: |
| 458 | text = node.text |
| 459 | attrs['value'] = text |
| 460 | |
| 461 | tag_type = attrs.get('type', 'text').lower() |
| 462 | if tag == 'select': |
| 463 | tag_type = 'select' |
| 464 | if tag_type == "select" and "multiple" in attrs: |
| 465 | tag_type = "multiple_select" |
| 466 | if tag == 'button': |
| 467 | tag_type = 'submit' |
| 468 | |
| 469 | FieldClass = self.FieldClass.classes.get(tag_type, |
| 470 | self.FieldClass) |
| 471 | |
| 472 | # https://github.com/Pylons/webtest/issues/131 |
| 473 | reserved_attributes = ('form', 'tag', 'pos') |
| 474 | for attr in reserved_attributes: |
| 475 | if attr in attrs: |
| 476 | del attrs[attr] |
| 477 | |
| 478 | if tag == 'input': |
| 479 | if tag_type == 'radio': |
| 480 | field = fields.get(name) |
| 481 | if not field: |
| 482 | field = FieldClass(self, tag, name, pos, **attrs) |
| 483 | fields.setdefault(name, []).append(field) |
| 484 | field_order.append((name, field)) |
| 485 | else: |
| 486 | field = field[0] |
| 487 | assert isinstance(field, |
| 488 | self.FieldClass.classes['radio']) |