@@ -719,9 +719,12 @@ def double_click(self, selector, by="css selector", timeout=None):
719719 self.execute_script(double_click_script)
720720 else:
721721 double_click_script = (
722- """jQuery('%s').dblclick();""" % css_selector
722+ """var targetElement1 = arguments[0];
723+ var clickEvent1 = document.createEvent('MouseEvents');
724+ clickEvent1.initEvent('dblclick', true, true);
725+ targetElement1.dispatchEvent(clickEvent1);"""
723726 )
724- self.safe_execute_script (double_click_script)
727+ self.execute_script (double_click_script, element )
725728 if settings.WAIT_FOR_RSC_ON_CLICKS:
726729 self.wait_for_ready_state_complete()
727730 else:
@@ -797,9 +800,12 @@ def context_click(self, selector, by="css selector", timeout=None):
797800 self.execute_script(right_click_script)
798801 else:
799802 right_click_script = (
800- """jQuery('%s').contextmenu();""" % css_selector
803+ """var targetElement1 = arguments[0];
804+ var clickEvent1 = document.createEvent('MouseEvents');
805+ clickEvent1.initEvent('contextmenu', true, true);
806+ targetElement1.dispatchEvent(clickEvent1);"""
801807 )
802- self.safe_execute_script (right_click_script)
808+ self.execute_script (right_click_script, element )
803809 if settings.WAIT_FOR_RSC_ON_CLICKS:
804810 self.wait_for_ready_state_complete()
805811 else:
@@ -1971,25 +1977,28 @@ def get_property_value(
19711977 timeout = self.__get_new_timeout(timeout)
19721978 selector, by = self.__recalculate_selector(selector, by)
19731979 self.wait_for_ready_state_complete()
1974- page_actions.wait_for_element_present(
1980+ element = page_actions.wait_for_element_present(
19751981 self.driver, selector, by, timeout
19761982 )
19771983 try:
19781984 selector = self.convert_to_css_selector(selector, by=by)
19791985 except Exception:
1980- # Don't run action if can't convert to CSS_Selector for JavaScript
1981- raise Exception(
1982- "Exception: Could not convert {%s}(by=%s) to CSS_SELECTOR!"
1983- % (selector, by)
1986+ # If can't convert to CSS_Selector for JS, use element directly
1987+ script = (
1988+ """var $elm = arguments[0];
1989+ $val = window.getComputedStyle($elm).getPropertyValue('%s');
1990+ return $val;""" % property
19841991 )
1992+ value = self.execute_script(script, element)
1993+ if value is not None:
1994+ return value
1995+ else:
1996+ return ""
19851997 selector = re.escape(selector)
19861998 selector = self.__escape_quotes_if_needed(selector)
19871999 script = """var $elm = document.querySelector('%s');
19882000 $val = window.getComputedStyle($elm).getPropertyValue('%s');
1989- return $val;""" % (
1990- selector,
1991- property,
1992- )
2001+ return $val;""" % (selector, property)
19932002 value = self.execute_script(script)
19942003 if value is not None:
19952004 return value
@@ -5350,13 +5359,15 @@ def bring_to_front(self, selector, by="css selector"):
53505359 Other element would receive the click: ... }"""
53515360 self.__check_scope()
53525361 selector, by = self.__recalculate_selector(selector, by)
5353- self.wait_for_element_visible(
5362+ element = self.wait_for_element_visible(
53545363 selector, by=by, timeout=settings.SMALL_TIMEOUT
53555364 )
53565365 try:
53575366 selector = self.convert_to_css_selector(selector, by=by)
53585367 except Exception:
5359- # Don't run action if can't convert to CSS_Selector for JavaScript
5368+ # If can't convert to CSS_Selector for JS, use element directly
5369+ script = ("""arguments[0].style.zIndex = '999999';""")
5370+ self.execute_script(script, element)
53605371 return
53615372 selector = re.escape(selector)
53625373 selector = self.__escape_quotes_if_needed(selector)
@@ -5425,11 +5436,12 @@ def __highlight(
54255436 selector, by=by, timeout=settings.SMALL_TIMEOUT
54265437 )
54275438 self.__slow_scroll_to_element(element)
5439+ use_element_directly = False
54285440 try:
54295441 selector = self.convert_to_css_selector(selector, by=by)
54305442 except Exception:
5431- # Don't highlight if can't convert to CSS_SELECTOR
5432- return
5443+ # If can't convert to CSS_Selector for JS, use element directly
5444+ use_element_directly = True
54335445 if self.highlights:
54345446 loops = self.highlights
54355447 if self.browser == "ie":
@@ -5455,7 +5467,9 @@ def __highlight(
54555467 box_end = style.find(";", box_start) + 1
54565468 original_box_shadow = style[box_start:box_end]
54575469 o_bs = original_box_shadow
5458- if ":contains" not in selector and ":first" not in selector:
5470+ if use_element_directly:
5471+ self.__highlight_element_with_js(element, loops, o_bs)
5472+ elif ":contains" not in selector and ":first" not in selector:
54595473 selector = re.escape(selector)
54605474 selector = self.__escape_quotes_if_needed(selector)
54615475 self.__highlight_with_js(selector, loops, o_bs)
@@ -5765,9 +5779,8 @@ def js_click(
57655779 if ":contains\\(" not in css_selector:
57665780 self.__js_click(selector, by=by)
57675781 else:
5768- click_script = """jQuery('%s')[0].click();""" % css_selector
57695782 try:
5770- self.safe_execute_script(click_script )
5783+ self.__js_click_element(element )
57715784 except Exception:
57725785 self.wait_for_ready_state_complete()
57735786 element = self.wait_for_element_present(
@@ -5777,7 +5790,7 @@ def js_click(
57775790 if self.is_element_clickable(selector):
57785791 self.__element_click(element)
57795792 else:
5780- self.safe_execute_script(click_script )
5793+ self.__js_click_element(element )
57815794 else:
57825795 if ":contains\\(" not in css_selector:
57835796 self.__js_click_all(selector, by=by)
@@ -5929,14 +5942,23 @@ def jquery_click_all(self, selector, by="css selector", timeout=None):
59295942 def hide_element(self, selector, by="css selector"):
59305943 """Hide the first element on the page that matches the selector."""
59315944 self.__check_scope()
5945+ element = None
59325946 try:
59335947 self.wait_for_element_visible("body", timeout=1.5)
5934- self.wait_for_element_present(selector, by=by, timeout=0.5)
5948+ element = self.wait_for_element_present(
5949+ selector, by=by, timeout=0.5
5950+ )
59355951 except Exception:
59365952 pass
59375953 selector, by = self.__recalculate_selector(selector, by)
59385954 css_selector = self.convert_to_css_selector(selector, by=by)
5939- if ":contains(" in css_selector:
5955+ if ":contains(" in css_selector and element:
5956+ script = (
5957+ 'const e = arguments[0];'
5958+ 'e.style.display="none";e.style.visibility="hidden";'
5959+ )
5960+ self.execute_script(script, element)
5961+ elif ":contains(" in css_selector and not element:
59405962 selector = self.__make_css_match_first_element_only(css_selector)
59415963 script = """jQuery('%s').hide();""" % selector
59425964 self.safe_execute_script(script)
@@ -5946,7 +5968,8 @@ def hide_element(self, selector, by="css selector"):
59465968 script = (
59475969 'const e = document.querySelector("%s");'
59485970 'e.style.display="none";e.style.visibility="hidden";'
5949- % css_selector)
5971+ % css_selector
5972+ )
59505973 self.execute_script(script)
59515974
59525975 def hide_elements(self, selector, by="css selector"):
@@ -5977,14 +6000,21 @@ def hide_elements(self, selector, by="css selector"):
59776000 def show_element(self, selector, by="css selector"):
59786001 """Show the first element on the page that matches the selector."""
59796002 self.__check_scope()
6003+ element = None
59806004 try:
59816005 self.wait_for_element_visible("body", timeout=1.5)
5982- self.wait_for_element_present(selector, by=by, timeout=1)
6006+ element = self.wait_for_element_present(selector, by=by, timeout=1)
59836007 except Exception:
59846008 pass
59856009 selector, by = self.__recalculate_selector(selector, by)
59866010 css_selector = self.convert_to_css_selector(selector, by=by)
5987- if ":contains(" in css_selector:
6011+ if ":contains(" in css_selector and element:
6012+ script = (
6013+ 'const e = arguments[0];'
6014+ 'e.style.display="";e.style.visibility="visible";'
6015+ )
6016+ self.execute_script(script, element)
6017+ elif ":contains(" in css_selector and not element:
59886018 selector = self.__make_css_match_first_element_only(css_selector)
59896019 script = """jQuery('%s').show(0);""" % selector
59906020 self.safe_execute_script(script)
@@ -6026,14 +6056,23 @@ def show_elements(self, selector, by="css selector"):
60266056 def remove_element(self, selector, by="css selector"):
60276057 """Remove the first element on the page that matches the selector."""
60286058 self.__check_scope()
6059+ element = None
60296060 try:
60306061 self.wait_for_element_visible("body", timeout=1.5)
6031- self.wait_for_element_present(selector, by=by, timeout=0.5)
6062+ element = self.wait_for_element_present(
6063+ selector, by=by, timeout=0.5
6064+ )
60326065 except Exception:
60336066 pass
60346067 selector, by = self.__recalculate_selector(selector, by)
60356068 css_selector = self.convert_to_css_selector(selector, by=by)
6036- if ":contains(" in css_selector:
6069+ if ":contains(" in css_selector and element:
6070+ script = (
6071+ 'const e = arguments[0];'
6072+ 'e.parentElement.removeChild(e);'
6073+ )
6074+ self.execute_script(script, element)
6075+ elif ":contains(" in css_selector and not element:
60376076 selector = self.__make_css_match_first_element_only(css_selector)
60386077 script = """jQuery('%s').remove();""" % selector
60396078 self.safe_execute_script(script)
@@ -7547,8 +7586,11 @@ def set_value(
75477586 )
75487587 self.execute_script(script)
75497588 else:
7550- script = """jQuery('%s')[0].value='%s';""" % (css_selector, value)
7551- self.safe_execute_script(script)
7589+ element = self.wait_for_element_present(
7590+ original_selector, by=by, timeout=timeout
7591+ )
7592+ script = """arguments[0].value='%s';""" % value
7593+ self.execute_script(script, element)
75527594 if text.endswith("\n"):
75537595 element = self.wait_for_element_present(
75547596 original_selector, by=by, timeout=timeout
@@ -7568,6 +7610,19 @@ def set_value(
75687610 self.execute_script(mouse_move_script)
75697611 except Exception:
75707612 pass
7613+ elif the_type == "range" and ":contains\\(" in css_selector:
7614+ try:
7615+ element = self.wait_for_element_present(
7616+ original_selector, by=by, timeout=1
7617+ )
7618+ mouse_move_script = (
7619+ """m_elm = arguments[0];"""
7620+ """m_evt = new Event('mousemove');"""
7621+ """m_elm.dispatchEvent(m_evt);"""
7622+ )
7623+ self.execute_script(mouse_move_script, element)
7624+ except Exception:
7625+ pass
75717626 self.__demo_mode_pause_if_active()
75727627
75737628 def js_update_text(self, selector, text, by="css selector", timeout=None):
@@ -7664,11 +7719,8 @@ def set_text_content(
76647719 )
76657720 self.execute_script(script)
76667721 else:
7667- script = """jQuery('%s')[0].textContent='%s';""" % (
7668- css_selector,
7669- value,
7670- )
7671- self.safe_execute_script(script)
7722+ script = """arguments[0].textContent='%s';""" % value
7723+ self.execute_script(script, element)
76727724 self.__demo_mode_pause_if_active()
76737725
76747726 def jquery_update_text(
@@ -7759,8 +7811,9 @@ def get_value(self, selector, by="css selector", timeout=None):
77597811 )
77607812 value = self.execute_script(script)
77617813 else:
7762- script = """return jQuery('%s')[0].value;""" % css_selector
7763- value = self.safe_execute_script(script)
7814+ element = self.wait_for_element_present(selector, by=by, timeout=1)
7815+ script = """return arguments[0].value;"""
7816+ value = self.execute_script(script, element)
77647817 return value
77657818
77667819 def set_time_limit(self, time_limit):
@@ -12536,6 +12589,40 @@ def __js_click(self, selector, by="css selector"):
1253612589 )
1253712590 self.execute_script(script)
1253812591
12592+ def __js_click_element(self, element):
12593+ """Clicks an element using pure JS. Does not use jQuery."""
12594+ is_visible = element.is_displayed()
12595+ current_url = self.get_current_url()
12596+ script = (
12597+ """var simulateClick = function (elem) {
12598+ var evt = new MouseEvent('click', {
12599+ bubbles: true,
12600+ cancelable: true,
12601+ view: window
12602+ });
12603+ var canceled = !elem.dispatchEvent(evt);
12604+ };
12605+ var someLink = arguments[0];
12606+ simulateClick(someLink);"""
12607+ )
12608+ if hasattr(self, "recorder_mode") and self.recorder_mode:
12609+ self.save_recorded_actions()
12610+ try:
12611+ self.execute_script(script, element)
12612+ except Exception:
12613+ # If element was visible but no longer, or on a different page now,
12614+ # assume that the click actually worked and continue with the test.
12615+ if (
12616+ (is_visible and not element.is_displayed())
12617+ or current_url != self.get_current_url()
12618+ ):
12619+ return # The click worked, but threw an Exception. Keep going.
12620+ # It appears the first click didn't work. Make another attempt.
12621+ self.wait_for_ready_state_complete()
12622+ # If the regular mouse-simulated click fails, do a basic JS click
12623+ script = ("""arguments[0].click();""")
12624+ self.execute_script(script, element)
12625+
1253912626 def __js_click_all(self, selector, by="css selector"):
1254012627 """Clicks all matching elements using pure JS. (No jQuery)"""
1254112628 selector, by = self.__recalculate_selector(selector, by)
@@ -12977,6 +13064,10 @@ def __highlight_with_js(self, selector, loops, o_bs):
1297713064 self.wait_for_ready_state_complete()
1297813065 js_utils.highlight_with_js(self.driver, selector, loops, o_bs)
1297913066
13067+ def __highlight_element_with_js(self, element, loops, o_bs):
13068+ self.wait_for_ready_state_complete()
13069+ js_utils.highlight_element_with_js(self.driver, element, loops, o_bs)
13070+
1298013071 def __highlight_with_jquery(self, selector, loops, o_bs):
1298113072 self.wait_for_ready_state_complete()
1298213073 js_utils.highlight_with_jquery(self.driver, selector, loops, o_bs)
@@ -12994,6 +13085,19 @@ def __highlight_with_js_2(self, message, selector, o_bs):
1299413085 self.driver, message, selector, o_bs, duration
1299513086 )
1299613087
13088+ def __highlight_element_with_js_2(self, message, element, o_bs):
13089+ duration = self.message_duration
13090+ if not duration:
13091+ duration = settings.DEFAULT_MESSAGE_DURATION
13092+ if (
13093+ (self.headless or self.headless2 or self.xvfb)
13094+ and float(duration) > 0.75
13095+ ):
13096+ duration = 0.75
13097+ js_utils.highlight_element_with_js_2(
13098+ self.driver, message, element, o_bs, duration
13099+ )
13100+
1299713101 def __highlight_with_jquery_2(self, message, selector, o_bs):
1299813102 duration = self.message_duration
1299913103 if not duration:
@@ -13032,11 +13136,12 @@ def __highlight_with_assert_success(
1303213136 selector, by=by, timeout=settings.SMALL_TIMEOUT
1303313137 )
1303413138 self.__slow_scroll_to_element(element)
13139+ use_element_directly = False
1303513140 try:
1303613141 selector = self.convert_to_css_selector(selector, by=by)
1303713142 except Exception:
13038- # Don't highlight if can't convert to CSS_SELECTOR
13039- return
13143+ # If can't convert to CSS_Selector for JS, use element directly
13144+ use_element_directly = True
1304013145
1304113146 o_bs = "" # original_box_shadow
1304213147 try:
@@ -13055,7 +13160,9 @@ def __highlight_with_assert_success(
1305513160 original_box_shadow = style[box_start:box_end]
1305613161 o_bs = original_box_shadow
1305713162
13058- if ":contains" not in selector and ":first" not in selector:
13163+ if use_element_directly:
13164+ self.__highlight_element_with_js_2(message, element, o_bs)
13165+ elif ":contains" not in selector and ":first" not in selector:
1305913166 selector = re.escape(selector)
1306013167 selector = self.__escape_quotes_if_needed(selector)
1306113168 self.__highlight_with_js_2(message, selector, o_bs)
0 commit comments