diff --git a/common/src/web/formPage.html b/common/src/web/formPage.html index 70a31da55cae6..571e9bce1d9cc 100644 --- a/common/src/web/formPage.html +++ b/common/src/web/formPage.html @@ -82,8 +82,9 @@ Apples - Oranges - Lemons + Pears + Oranges + Lemons diff --git a/py/selenium/webdriver/support/select.py b/py/selenium/webdriver/support/select.py index 5b833124c1475..31f68825682d7 100644 --- a/py/selenium/webdriver/support/select.py +++ b/py/selenium/webdriver/support/select.py @@ -114,6 +114,8 @@ def select_by_visible_text(self, text: str) -> None: opts = self._el.find_elements(By.XPATH, xpath) matched = False for opt in opts: + if not self._has_css_property_and_visible(opt): + raise NoSuchElementException(f"Invisible option with text: {text}") self._set_selected(opt) if not self.is_multiple: return @@ -128,6 +130,8 @@ def select_by_visible_text(self, text: str) -> None: candidates = self._el.find_elements(By.XPATH, xpath) for candidate in candidates: if text == candidate.text: + if not self._has_css_property_and_visible(candidate): + raise NoSuchElementException(f"Invisible option with text: {text}") self._set_selected(candidate) if not self.is_multiple: return @@ -202,6 +206,8 @@ def deselect_by_visible_text(self, text: str) -> None: xpath = f".//option[normalize-space(.) = {self._escape_string(text)}]" opts = self._el.find_elements(By.XPATH, xpath) for opt in opts: + if not self._has_css_property_and_visible(opt): + raise NoSuchElementException(f"Invisible option with text: {text}") self._unset_selected(opt) matched = True if not matched: @@ -241,3 +247,13 @@ def _get_longest_token(self, value: str) -> str: if len(item) > len(longest): longest = item return longest + + def _has_css_property_and_visible(self, option) -> bool: + css_value_candidates = ["hidden", "none", "0", "0.0"] + css_property_candidates = ["visibility", "display", "opacity"] + + for property in css_property_candidates: + css_value = option.value_of_css_property(property) + if css_value in css_value_candidates: + return False + return True diff --git a/py/test/selenium/webdriver/common/select_class_tests.py b/py/test/selenium/webdriver/common/select_class_tests.py index 06b601555c01e..4374b68e90292 100644 --- a/py/test/selenium/webdriver/common/select_class_tests.py +++ b/py/test/selenium/webdriver/common/select_class_tests.py @@ -25,6 +25,7 @@ disabledSelect = {"name": "no-select", "values": ["Foo"]} disabledSingleSelect = {"name": "single_disabled", "values": ["Enabled", "Disabled"]} disabledMultiSelect = {"name": "multi_disabled", "values": ["Enabled", "Disabled"]} +invisibleMultiSelect = {"id": "invisible_multi_select", "values": ["Apples", "Pears", "Oranges", "Lemons"]} singleSelectValues1 = { "name": "selectomatic", "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): sel.select_by_visible_text(disabledMultiSelect["values"][1]) +def test_raises_exception_select_by_text_multiple_hidden(driver, pages): + pages.load("formPage.html") + + sel = Select(driver.find_element(By.ID, invisibleMultiSelect["id"])) + for option in invisibleMultiSelect["values"]: + with pytest.raises(NoSuchElementException): + sel.select_by_visible_text(option) + + def test_deselect_all_single(driver, pages): pages.load("formPage.html") for select in [singleSelectValues1, singleSelectValues2]: