Skip to content

Commit 39a3696

Browse files
committed
Improve Shadow-DOM compatibility
1 parent 2c92555 commit 39a3696

File tree

1 file changed

+40
-13
lines changed

1 file changed

+40
-13
lines changed

seleniumbase/fixtures/base_case.py

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5895,7 +5895,9 @@ def skip(self, reason=""):
58955895

58965896
# Shadow DOM / Shadow-root methods
58975897

5898-
def __get_shadow_element(self, selector, timeout=None):
5898+
def __get_shadow_element(
5899+
self, selector, timeout=None, must_be_visible=False
5900+
):
58995901
self.wait_for_ready_state_complete()
59005902
if timeout is None:
59015903
timeout = settings.SMALL_TIMEOUT
@@ -5911,6 +5913,7 @@ def __get_shadow_element(self, selector, timeout=None):
59115913
selectors = selector.split("::shadow ")
59125914
element = self.get_element(selectors[0])
59135915
selector_chain = selectors[0]
5916+
is_present = False
59145917
for selector_part in selectors[1:]:
59155918
shadow_root = None
59165919
if (
@@ -5997,6 +6000,11 @@ def __get_shadow_element(self, selector, timeout=None):
59976000
try:
59986001
element = shadow_root.find_element(
59996002
By.CSS_SELECTOR, value=selector_part)
6003+
is_present = True
6004+
if must_be_visible:
6005+
if not element.is_displayed():
6006+
raise Exception(
6007+
"Shadow Root element not visible!")
60006008
found = True
60016009
break
60026010
except Exception:
@@ -6005,6 +6013,10 @@ def __get_shadow_element(self, selector, timeout=None):
60056013
if not found:
60066014
element = shadow_root.find_element(
60076015
By.CSS_SELECTOR, value=selector_part)
6016+
is_present = True
6017+
if must_be_visible and not element.is_displayed():
6018+
raise Exception(
6019+
"Shadow Root element not visible!")
60086020
else:
60096021
element = page_actions.wait_for_element_present(
60106022
shadow_root,
@@ -6013,11 +6025,16 @@ def __get_shadow_element(self, selector, timeout=None):
60136025
timeout=timeout,
60146026
)
60156027
except Exception:
6028+
error = "not present"
6029+
the_exception = "NoSuchElementException"
6030+
if must_be_visible and is_present:
6031+
error = "not visible"
6032+
the_exception = "ElementNotVisibleException"
60166033
msg = (
6017-
"Shadow DOM Element {%s} was not present after %s seconds!"
6018-
% (selector_chain, timeout)
6034+
"Shadow DOM Element {%s} was %s after %s seconds!"
6035+
% (selector_chain, error, timeout)
60196036
)
6020-
page_actions.timeout_exception("NoSuchElementException", msg)
6037+
page_actions.timeout_exception(the_exception, msg)
60216038
return element
60226039

60236040
def __fail_if_invalid_shadow_selector_usage(self, selector):
@@ -6035,11 +6052,15 @@ def __is_shadow_selector(self, selector):
60356052
return False
60366053

60376054
def __shadow_click(self, selector, timeout):
6038-
element = self.__get_shadow_element(selector, timeout=timeout)
6055+
element = self.__get_shadow_element(
6056+
selector, timeout=timeout, must_be_visible=True
6057+
)
60396058
element.click()
60406059

60416060
def __shadow_type(self, selector, text, timeout, clear_first=True):
6042-
element = self.__get_shadow_element(selector, timeout=timeout)
6061+
element = self.__get_shadow_element(
6062+
selector, timeout=timeout, must_be_visible=True
6063+
)
60436064
if clear_first:
60446065
try:
60456066
element.clear()
@@ -6060,7 +6081,9 @@ def __shadow_type(self, selector, text, timeout, clear_first=True):
60606081
self.wait_for_ready_state_complete()
60616082

60626083
def __shadow_clear(self, selector, timeout):
6063-
element = self.__get_shadow_element(selector, timeout=timeout)
6084+
element = self.__get_shadow_element(
6085+
selector, timeout=timeout, must_be_visible=True
6086+
)
60646087
try:
60656088
element.clear()
60666089
backspaces = Keys.BACK_SPACE * 42 # Autofill Defense
@@ -6069,8 +6092,13 @@ def __shadow_clear(self, selector, timeout):
60696092
pass
60706093

60716094
def __get_shadow_text(self, selector, timeout):
6072-
element = self.__get_shadow_element(selector, timeout=timeout)
6073-
return element.text
6095+
element = self.__get_shadow_element(
6096+
selector, timeout=timeout, must_be_visible=True
6097+
)
6098+
element_text = element.text
6099+
if self.browser == "safari":
6100+
element_text = element.get_attribute("innerText")
6101+
return element_text
60746102

60756103
def __get_shadow_attribute(self, selector, attribute, timeout):
60766104
element = self.__get_shadow_element(selector, timeout=timeout)
@@ -6248,10 +6276,9 @@ def __wait_for_shadow_element_present(self, selector, timeout):
62486276
return element
62496277

62506278
def __wait_for_shadow_element_visible(self, selector, timeout):
6251-
element = self.__get_shadow_element(selector, timeout=timeout)
6252-
if not element.is_displayed():
6253-
msg = "Shadow DOM Element {%s} was not visible!" % selector
6254-
page_actions.timeout_exception("NoSuchElementException", msg)
6279+
element = self.__get_shadow_element(
6280+
selector, timeout=timeout, must_be_visible=True
6281+
)
62556282
return element
62566283

62576284
def __wait_for_shadow_attribute_present(

0 commit comments

Comments
 (0)