Skip to content

Commit ea0ee86

Browse files
authored
Merge pull request #270 from JohaJung/html5_form_attr
bugfix: form input discovery
2 parents addc1d1 + ac3f855 commit ea0ee86

File tree

4 files changed

+18
-5
lines changed

4 files changed

+18
-5
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ News
44
3.0.6 (unreleased)
55
------------------
66

7-
- Nothing changed yet.
7+
- Fix a bug that inputs outside of a ``<form>`` tag were considered
8+
belonging to that form because they had a HTML representation identical
9+
to some input inside that ``<form>``.
810

911

1012
3.0.5 (2025-06-04)

tests/html/form_inputs.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,9 @@
6363
</form>
6464
<input name="button" type="submit" value="text" form="outer_inputs_form">
6565

66+
<!-- this input is equal (in the sense beautifulSoup checks equality)
67+
to that in outer_inputs_form -->
68+
<input name="bar" type="text" value="bar">
69+
6670
</body>
6771
</html>

tests/test_forms.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ def test_button_submit_by_value_and_index(self):
143143
def test_outer_inputs(self):
144144
form = self.callFUT(formid='outer_inputs_form')
145145
self.assertEqual(('foo', 'bar', 'button'), tuple(form.fields))
146+
# check that identical input is not considered belonging to this form
147+
self.assertTrue(all(len(itm) == 1 for itm in form.fields.values()))
146148

147149
class TestResponseFormAttribute(unittest.TestCase):
148150

webtest/forms.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -433,10 +433,15 @@ def _parse_fields(self):
433433
field_order = []
434434
tags = ('input', 'select', 'textarea', 'button')
435435
inner_elts = self.html.find_all(tags)
436-
def _form_elt_filter(tag):
437-
return tag in inner_elts or (
438-
tag.attrs.get('form') == self.id and tag.name in tags)
439-
elements = self.response.html.find_all(_form_elt_filter)
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
440445
for pos, node in enumerate(elements):
441446
attrs = dict(node.attrs)
442447
tag = node.name

0 commit comments

Comments
 (0)