@@ -1753,63 +1753,22 @@ def click_with_offset(
17531753 If mark==True, will draw a dot at location. (Useful for debugging)
17541754 In Demo Mode, mark becomes True unless set to False. (Default: None)
17551755 """
1756- from selenium.webdriver.common.action_chains import ActionChains
1756+ self.__check_scope()
1757+ self.__click_with_offset(
1758+ selector, x, y, by=by, double=False, mark=mark, timeout=timeout)
17571759
1760+ def double_click_with_offset(
1761+ self, selector, x, y, by=By.CSS_SELECTOR, mark=None, timeout=None
1762+ ):
1763+ """
1764+ Double click an element at an {X,Y}-offset location.
1765+ {0,0} is the top-left corner of the element.
1766+ If mark==True, will draw a dot at location. (Useful for debugging)
1767+ In Demo Mode, mark becomes True unless set to False. (Default: None)
1768+ """
17581769 self.__check_scope()
1759- if not timeout:
1760- timeout = settings.SMALL_TIMEOUT
1761- if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
1762- timeout = self.__get_new_timeout(timeout)
1763- selector, by = self.__recalculate_selector(selector, by)
1764- element = page_actions.wait_for_element_visible(
1765- self.driver, selector, by, timeout
1766- )
1767- if self.demo_mode:
1768- self.highlight(selector, by=by, loops=1)
1769- elif self.slow_mode:
1770- self.__slow_scroll_to_element(element)
1771- if self.demo_mode and mark is None:
1772- mark = True
1773- if mark:
1774- selector = self.convert_to_css_selector(selector, by=by)
1775- selector = re.escape(selector)
1776- selector = self.__escape_quotes_if_needed(selector)
1777- px = x - 3
1778- py = y - 3
1779- script = (
1780- "var canvas = document.querySelector('%s');"
1781- "var ctx = canvas.getContext('2d');"
1782- "ctx.fillStyle = '#F8F808';"
1783- "ctx.fillRect(%s, %s, 7, 7);"
1784- "ctx.fillStyle = '#F80808';"
1785- "ctx.fillRect(%s+1, %s+1, 5, 5);"
1786- % (selector, px, py, px, py)
1787- )
1788- self.execute_script(script)
1789- try:
1790- element_location = element.location["y"]
1791- element_location = element_location - 130 + y
1792- if element_location < 0:
1793- element_location = 0
1794- scroll_script = "window.scrollTo(0, %s);" % element_location
1795- self.driver.execute_script(scroll_script)
1796- self.sleep(0.1)
1797- except Exception:
1798- pass
1799- try:
1800- action_chains = ActionChains(self.driver)
1801- action_chains.move_to_element_with_offset(element, x, y)
1802- action_chains.click().perform()
1803- except MoveTargetOutOfBoundsException:
1804- message = (
1805- "Target coordinates for click are out-of-bounds!\n"
1806- "The offset must stay inside the target element!"
1807- )
1808- raise Exception(message)
1809- if self.demo_mode:
1810- self.__demo_mode_pause_if_active()
1811- elif self.slow_mode:
1812- self.__slow_mode_pause_if_active()
1770+ self.__click_with_offset(
1771+ selector, x, y, by=by, double=True, mark=mark, timeout=timeout)
18131772
18141773 def is_checked(self, selector, by=By.CSS_SELECTOR, timeout=None):
18151774 """Determines if a checkbox or a radio button element is checked.
@@ -10717,6 +10676,77 @@ def __js_click_all(self, selector, by=By.CSS_SELECTOR):
1071710676 )
1071810677 self.execute_script(script)
1071910678
10679+ def __click_with_offset(
10680+ self,
10681+ selector,
10682+ x,
10683+ y,
10684+ by=By.CSS_SELECTOR,
10685+ double=False,
10686+ mark=None,
10687+ timeout=None,
10688+ ):
10689+ from selenium.webdriver.common.action_chains import ActionChains
10690+
10691+ self.__check_scope()
10692+ if not timeout:
10693+ timeout = settings.SMALL_TIMEOUT
10694+ if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
10695+ timeout = self.__get_new_timeout(timeout)
10696+ selector, by = self.__recalculate_selector(selector, by)
10697+ element = page_actions.wait_for_element_visible(
10698+ self.driver, selector, by, timeout
10699+ )
10700+ if self.demo_mode:
10701+ self.highlight(selector, by=by, loops=1)
10702+ elif self.slow_mode:
10703+ self.__slow_scroll_to_element(element)
10704+ if self.demo_mode and mark is None:
10705+ mark = True
10706+ if mark:
10707+ selector = self.convert_to_css_selector(selector, by=by)
10708+ selector = re.escape(selector)
10709+ selector = self.__escape_quotes_if_needed(selector)
10710+ px = x - 3
10711+ py = y - 3
10712+ script = (
10713+ "var canvas = document.querySelector('%s');"
10714+ "var ctx = canvas.getContext('2d');"
10715+ "ctx.fillStyle = '#F8F808';"
10716+ "ctx.fillRect(%s, %s, 7, 7);"
10717+ "ctx.fillStyle = '#F80808';"
10718+ "ctx.fillRect(%s+1, %s+1, 5, 5);"
10719+ % (selector, px, py, px, py)
10720+ )
10721+ self.execute_script(script)
10722+ try:
10723+ element_location = element.location["y"]
10724+ element_location = element_location - 130 + y
10725+ if element_location < 0:
10726+ element_location = 0
10727+ scroll_script = "window.scrollTo(0, %s);" % element_location
10728+ self.driver.execute_script(scroll_script)
10729+ self.sleep(0.1)
10730+ except Exception:
10731+ pass
10732+ try:
10733+ action_chains = ActionChains(self.driver)
10734+ action_chains.move_to_element_with_offset(element, x, y)
10735+ if not double:
10736+ action_chains.click().perform()
10737+ else:
10738+ action_chains.double_click().perform()
10739+ except MoveTargetOutOfBoundsException:
10740+ message = (
10741+ "Target coordinates for click are out-of-bounds!\n"
10742+ "The offset must stay inside the target element!"
10743+ )
10744+ raise Exception(message)
10745+ if self.demo_mode:
10746+ self.__demo_mode_pause_if_active()
10747+ elif self.slow_mode:
10748+ self.__slow_mode_pause_if_active()
10749+
1072010750 def __jquery_slow_scroll_to(self, selector, by=By.CSS_SELECTOR):
1072110751 selector, by = self.__recalculate_selector(selector, by)
1072210752 element = self.wait_for_element_present(
0 commit comments