Skip to content

Commit a187e3c

Browse files
FFederishbenzer
andauthored
[py] Fix select being able to select options hidden by css rules (#15135)
* [py] Fix select being able to select options hidden by css rules * corrected formatting with format.sh * Fix select_by_visible_test to raise an exception on hidden options even if the argument text has spaces Fix error messages to be the same as java's one * [py] adding check to all instances of invisible properties to test_raises_exception_select_by_text_multiple_hidden - adding "opacity: 0.0", "display: none", "visibility: hidden" to formPage.html#invisible_multi_select - checking all the options of formPage.html#invisible_multi_select in test_raises_exception_select_by_text_multiple_hidden() --------- Co-authored-by: Simon Benzer <[email protected]>
1 parent f629044 commit a187e3c

File tree

3 files changed

+29
-2
lines changed

3 files changed

+29
-2
lines changed

common/src/web/formPage.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,9 @@
8282

8383
<select id="invisible_multi_select" multiple>
8484
<option selected="selected" value="apples" style="opacity: 0;">Apples</option>
85-
<option value="oranges">Oranges</option>
86-
<option selected="selected" value="lemons">Lemons</option>
85+
<option value="pears" style="opacity: 0.0;">Pears</option>
86+
<option value="oranges" style="display: none;">Oranges</option>
87+
<option selected="selected" value="lemons" style="visibility: hidden;">Lemons</option>
8788
</select>
8889

8990
<select name="select-default">

py/selenium/webdriver/support/select.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ def select_by_visible_text(self, text: str) -> None:
114114
opts = self._el.find_elements(By.XPATH, xpath)
115115
matched = False
116116
for opt in opts:
117+
if not self._has_css_property_and_visible(opt):
118+
raise NoSuchElementException(f"Invisible option with text: {text}")
117119
self._set_selected(opt)
118120
if not self.is_multiple:
119121
return
@@ -128,6 +130,8 @@ def select_by_visible_text(self, text: str) -> None:
128130
candidates = self._el.find_elements(By.XPATH, xpath)
129131
for candidate in candidates:
130132
if text == candidate.text:
133+
if not self._has_css_property_and_visible(candidate):
134+
raise NoSuchElementException(f"Invisible option with text: {text}")
131135
self._set_selected(candidate)
132136
if not self.is_multiple:
133137
return
@@ -202,6 +206,8 @@ def deselect_by_visible_text(self, text: str) -> None:
202206
xpath = f".//option[normalize-space(.) = {self._escape_string(text)}]"
203207
opts = self._el.find_elements(By.XPATH, xpath)
204208
for opt in opts:
209+
if not self._has_css_property_and_visible(opt):
210+
raise NoSuchElementException(f"Invisible option with text: {text}")
205211
self._unset_selected(opt)
206212
matched = True
207213
if not matched:
@@ -241,3 +247,13 @@ def _get_longest_token(self, value: str) -> str:
241247
if len(item) > len(longest):
242248
longest = item
243249
return longest
250+
251+
def _has_css_property_and_visible(self, option) -> bool:
252+
css_value_candidates = ["hidden", "none", "0", "0.0"]
253+
css_property_candidates = ["visibility", "display", "opacity"]
254+
255+
for property in css_property_candidates:
256+
css_value = option.value_of_css_property(property)
257+
if css_value in css_value_candidates:
258+
return False
259+
return True

py/test/selenium/webdriver/common/select_class_tests.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
disabledSelect = {"name": "no-select", "values": ["Foo"]}
2626
disabledSingleSelect = {"name": "single_disabled", "values": ["Enabled", "Disabled"]}
2727
disabledMultiSelect = {"name": "multi_disabled", "values": ["Enabled", "Disabled"]}
28+
invisibleMultiSelect = {"id": "invisible_multi_select", "values": ["Apples", "Pears", "Oranges", "Lemons"]}
2829
singleSelectValues1 = {
2930
"name": "selectomatic",
3031
"values": ["One", "Two", "Four", "Still learning how to count, apparently"],
@@ -161,6 +162,15 @@ def test_raises_exception_select_by_text_multiple_disabled(driver, pages):
161162
sel.select_by_visible_text(disabledMultiSelect["values"][1])
162163

163164

165+
def test_raises_exception_select_by_text_multiple_hidden(driver, pages):
166+
pages.load("formPage.html")
167+
168+
sel = Select(driver.find_element(By.ID, invisibleMultiSelect["id"]))
169+
for option in invisibleMultiSelect["values"]:
170+
with pytest.raises(NoSuchElementException):
171+
sel.select_by_visible_text(option)
172+
173+
164174
def test_deselect_all_single(driver, pages):
165175
pages.load("formPage.html")
166176
for select in [singleSelectValues1, singleSelectValues2]:

0 commit comments

Comments
 (0)