@@ -719,9 +719,12 @@ def double_click(self, selector, by="css selector", timeout=None):
719
719
self.execute_script(double_click_script)
720
720
else:
721
721
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);"""
723
726
)
724
- self.safe_execute_script (double_click_script)
727
+ self.execute_script (double_click_script, element )
725
728
if settings.WAIT_FOR_RSC_ON_CLICKS:
726
729
self.wait_for_ready_state_complete()
727
730
else:
@@ -797,9 +800,12 @@ def context_click(self, selector, by="css selector", timeout=None):
797
800
self.execute_script(right_click_script)
798
801
else:
799
802
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);"""
801
807
)
802
- self.safe_execute_script (right_click_script)
808
+ self.execute_script (right_click_script, element )
803
809
if settings.WAIT_FOR_RSC_ON_CLICKS:
804
810
self.wait_for_ready_state_complete()
805
811
else:
@@ -1971,25 +1977,28 @@ def get_property_value(
1971
1977
timeout = self.__get_new_timeout(timeout)
1972
1978
selector, by = self.__recalculate_selector(selector, by)
1973
1979
self.wait_for_ready_state_complete()
1974
- page_actions.wait_for_element_present(
1980
+ element = page_actions.wait_for_element_present(
1975
1981
self.driver, selector, by, timeout
1976
1982
)
1977
1983
try:
1978
1984
selector = self.convert_to_css_selector(selector, by=by)
1979
1985
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
1984
1991
)
1992
+ value = self.execute_script(script, element)
1993
+ if value is not None:
1994
+ return value
1995
+ else:
1996
+ return ""
1985
1997
selector = re.escape(selector)
1986
1998
selector = self.__escape_quotes_if_needed(selector)
1987
1999
script = """var $elm = document.querySelector('%s');
1988
2000
$val = window.getComputedStyle($elm).getPropertyValue('%s');
1989
- return $val;""" % (
1990
- selector,
1991
- property,
1992
- )
2001
+ return $val;""" % (selector, property)
1993
2002
value = self.execute_script(script)
1994
2003
if value is not None:
1995
2004
return value
@@ -5350,13 +5359,15 @@ def bring_to_front(self, selector, by="css selector"):
5350
5359
Other element would receive the click: ... }"""
5351
5360
self.__check_scope()
5352
5361
selector, by = self.__recalculate_selector(selector, by)
5353
- self.wait_for_element_visible(
5362
+ element = self.wait_for_element_visible(
5354
5363
selector, by=by, timeout=settings.SMALL_TIMEOUT
5355
5364
)
5356
5365
try:
5357
5366
selector = self.convert_to_css_selector(selector, by=by)
5358
5367
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)
5360
5371
return
5361
5372
selector = re.escape(selector)
5362
5373
selector = self.__escape_quotes_if_needed(selector)
@@ -5425,11 +5436,12 @@ def __highlight(
5425
5436
selector, by=by, timeout=settings.SMALL_TIMEOUT
5426
5437
)
5427
5438
self.__slow_scroll_to_element(element)
5439
+ use_element_directly = False
5428
5440
try:
5429
5441
selector = self.convert_to_css_selector(selector, by=by)
5430
5442
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
5433
5445
if self.highlights:
5434
5446
loops = self.highlights
5435
5447
if self.browser == "ie":
@@ -5455,7 +5467,9 @@ def __highlight(
5455
5467
box_end = style.find(";", box_start) + 1
5456
5468
original_box_shadow = style[box_start:box_end]
5457
5469
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:
5459
5473
selector = re.escape(selector)
5460
5474
selector = self.__escape_quotes_if_needed(selector)
5461
5475
self.__highlight_with_js(selector, loops, o_bs)
@@ -5765,9 +5779,8 @@ def js_click(
5765
5779
if ":contains\\(" not in css_selector:
5766
5780
self.__js_click(selector, by=by)
5767
5781
else:
5768
- click_script = """jQuery('%s')[0].click();""" % css_selector
5769
5782
try:
5770
- self.safe_execute_script(click_script )
5783
+ self.__js_click_element(element )
5771
5784
except Exception:
5772
5785
self.wait_for_ready_state_complete()
5773
5786
element = self.wait_for_element_present(
@@ -5777,7 +5790,7 @@ def js_click(
5777
5790
if self.is_element_clickable(selector):
5778
5791
self.__element_click(element)
5779
5792
else:
5780
- self.safe_execute_script(click_script )
5793
+ self.__js_click_element(element )
5781
5794
else:
5782
5795
if ":contains\\(" not in css_selector:
5783
5796
self.__js_click_all(selector, by=by)
@@ -5929,14 +5942,23 @@ def jquery_click_all(self, selector, by="css selector", timeout=None):
5929
5942
def hide_element(self, selector, by="css selector"):
5930
5943
"""Hide the first element on the page that matches the selector."""
5931
5944
self.__check_scope()
5945
+ element = None
5932
5946
try:
5933
5947
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
+ )
5935
5951
except Exception:
5936
5952
pass
5937
5953
selector, by = self.__recalculate_selector(selector, by)
5938
5954
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:
5940
5962
selector = self.__make_css_match_first_element_only(css_selector)
5941
5963
script = """jQuery('%s').hide();""" % selector
5942
5964
self.safe_execute_script(script)
@@ -5946,7 +5968,8 @@ def hide_element(self, selector, by="css selector"):
5946
5968
script = (
5947
5969
'const e = document.querySelector("%s");'
5948
5970
'e.style.display="none";e.style.visibility="hidden";'
5949
- % css_selector)
5971
+ % css_selector
5972
+ )
5950
5973
self.execute_script(script)
5951
5974
5952
5975
def hide_elements(self, selector, by="css selector"):
@@ -5977,14 +6000,21 @@ def hide_elements(self, selector, by="css selector"):
5977
6000
def show_element(self, selector, by="css selector"):
5978
6001
"""Show the first element on the page that matches the selector."""
5979
6002
self.__check_scope()
6003
+ element = None
5980
6004
try:
5981
6005
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)
5983
6007
except Exception:
5984
6008
pass
5985
6009
selector, by = self.__recalculate_selector(selector, by)
5986
6010
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:
5988
6018
selector = self.__make_css_match_first_element_only(css_selector)
5989
6019
script = """jQuery('%s').show(0);""" % selector
5990
6020
self.safe_execute_script(script)
@@ -6026,14 +6056,23 @@ def show_elements(self, selector, by="css selector"):
6026
6056
def remove_element(self, selector, by="css selector"):
6027
6057
"""Remove the first element on the page that matches the selector."""
6028
6058
self.__check_scope()
6059
+ element = None
6029
6060
try:
6030
6061
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
+ )
6032
6065
except Exception:
6033
6066
pass
6034
6067
selector, by = self.__recalculate_selector(selector, by)
6035
6068
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:
6037
6076
selector = self.__make_css_match_first_element_only(css_selector)
6038
6077
script = """jQuery('%s').remove();""" % selector
6039
6078
self.safe_execute_script(script)
@@ -7547,8 +7586,11 @@ def set_value(
7547
7586
)
7548
7587
self.execute_script(script)
7549
7588
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)
7552
7594
if text.endswith("\n"):
7553
7595
element = self.wait_for_element_present(
7554
7596
original_selector, by=by, timeout=timeout
@@ -7568,6 +7610,19 @@ def set_value(
7568
7610
self.execute_script(mouse_move_script)
7569
7611
except Exception:
7570
7612
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
7571
7626
self.__demo_mode_pause_if_active()
7572
7627
7573
7628
def js_update_text(self, selector, text, by="css selector", timeout=None):
@@ -7664,11 +7719,8 @@ def set_text_content(
7664
7719
)
7665
7720
self.execute_script(script)
7666
7721
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)
7672
7724
self.__demo_mode_pause_if_active()
7673
7725
7674
7726
def jquery_update_text(
@@ -7759,8 +7811,9 @@ def get_value(self, selector, by="css selector", timeout=None):
7759
7811
)
7760
7812
value = self.execute_script(script)
7761
7813
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)
7764
7817
return value
7765
7818
7766
7819
def set_time_limit(self, time_limit):
@@ -12536,6 +12589,40 @@ def __js_click(self, selector, by="css selector"):
12536
12589
)
12537
12590
self.execute_script(script)
12538
12591
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
+
12539
12626
def __js_click_all(self, selector, by="css selector"):
12540
12627
"""Clicks all matching elements using pure JS. (No jQuery)"""
12541
12628
selector, by = self.__recalculate_selector(selector, by)
@@ -12977,6 +13064,10 @@ def __highlight_with_js(self, selector, loops, o_bs):
12977
13064
self.wait_for_ready_state_complete()
12978
13065
js_utils.highlight_with_js(self.driver, selector, loops, o_bs)
12979
13066
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
+
12980
13071
def __highlight_with_jquery(self, selector, loops, o_bs):
12981
13072
self.wait_for_ready_state_complete()
12982
13073
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):
12994
13085
self.driver, message, selector, o_bs, duration
12995
13086
)
12996
13087
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
+
12997
13101
def __highlight_with_jquery_2(self, message, selector, o_bs):
12998
13102
duration = self.message_duration
12999
13103
if not duration:
@@ -13032,11 +13136,12 @@ def __highlight_with_assert_success(
13032
13136
selector, by=by, timeout=settings.SMALL_TIMEOUT
13033
13137
)
13034
13138
self.__slow_scroll_to_element(element)
13139
+ use_element_directly = False
13035
13140
try:
13036
13141
selector = self.convert_to_css_selector(selector, by=by)
13037
13142
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
13040
13145
13041
13146
o_bs = "" # original_box_shadow
13042
13147
try:
@@ -13055,7 +13160,9 @@ def __highlight_with_assert_success(
13055
13160
original_box_shadow = style[box_start:box_end]
13056
13161
o_bs = original_box_shadow
13057
13162
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:
13059
13166
selector = re.escape(selector)
13060
13167
selector = self.__escape_quotes_if_needed(selector)
13061
13168
self.__highlight_with_js_2(message, selector, o_bs)
0 commit comments