动作链删除db_click();各点击方法增加times参数;Tab对象增加rect.scrollbar_position属性;优化点击

This commit is contained in:
g1879 2024-07-05 11:27:15 +08:00
parent c6e3e0b71f
commit 8456f7ad39
8 changed files with 44 additions and 44 deletions

View File

@ -192,7 +192,7 @@ class Driver(object):
if 'result' not in result and 'error' in result:
kwargs['_timeout'] = timeout
return {'error': result['error']['message'], 'type': result.get('type', 'call_method_error'),
'method': _method, 'args': kwargs, 'data': result['error']['data']}
'method': _method, 'args': kwargs, 'data': result['error'].get('data')}
else:
return result['result']

View File

@ -19,7 +19,7 @@ from .._base.base import DrissionElement, BaseElement
from .._functions.elements import ChromiumElementsList
from .._functions.keys import input_text_or_keys
from .._functions.locator import get_loc, locator_to_tuple
from .._functions.web import make_absolute_link, get_ele_txt, format_html, is_js_func, offset_scroll, get_blob
from .._functions.web import make_absolute_link, get_ele_txt, format_html, is_js_func, get_blob
from .._units.clicker import Clicker
from .._units.rect import ElementRect
from .._units.scroller import ElementScroller
@ -787,9 +787,7 @@ class ChromiumElement(DrissionElement):
:param offset_y: 相对元素左上角坐标的y轴偏移量
:return: None
"""
self.owner.scroll.to_see(self)
x, y = offset_scroll(self, offset_x, offset_y)
self.owner._run_cdp('Input.dispatchMouseEvent', type='mouseMoved', x=x, y=y, _ignore=AlertExistsError)
self.owner.actions.move_to(self, offset_x=offset_x, offset_y=offset_y, duration=.1)
def drag(self, offset_x=0, offset_y=0, duration=.5):
"""拖拽当前元素到相对位置

View File

@ -107,12 +107,12 @@ def location_in_viewport(page, loc_x, loc_y):
def offset_scroll(ele, offset_x, offset_y):
"""接收元素及偏移坐标,把坐标滚动到页面中间,返回该点在视口中的坐标
"""接收元素及偏移坐标,把坐标滚动到页面中间,返回该点绝对坐标
有偏移量时以元素左上角坐标为基准没有时以click_point为基准
:param ele: 元素对象
:param offset_x: 偏移量x
:param offset_y: 偏移量y
:return: 视口中的坐标
:return: 绝对坐标
"""
loc_x, loc_y = ele.rect.location
cp_x, cp_y = ele.rect.click_point
@ -122,11 +122,7 @@ def offset_scroll(ele, offset_x, offset_y):
clientWidth = ele.owner._run_js('return document.body.clientWidth;')
clientHeight = ele.owner._run_js('return document.body.clientHeight;')
ele.owner.scroll.to_location(lx - clientWidth // 2, ly - clientHeight // 2)
cl_x, cl_y = ele.rect.viewport_location
ccp_x, ccp_y = ele.rect.viewport_click_point
cx = cl_x + offset_x if offset_x else ccp_x
cy = cl_y + offset_y if offset_y else ccp_y
return cx, cy
return lx, ly
def make_absolute_link(link, baseURI=None):

View File

@ -94,36 +94,31 @@ class Actions:
return self
def click(self, on_ele=None):
def click(self, on_ele=None, times=1):
"""点击鼠标左键,可先移动到元素上
:param on_ele: ChromiumElement元素或文本定位符
:param times: 点击次数
:return: self
"""
self._hold(on_ele, 'left').wait(.05)._release('left')
self._hold(on_ele, 'left', times).wait(.05)._release('left')
return self
def r_click(self, on_ele=None):
def r_click(self, on_ele=None, times=1):
"""点击鼠标右键,可先移动到元素上
:param on_ele: ChromiumElement元素或文本定位符
:param times: 点击次数
:return: self
"""
self._hold(on_ele, 'right').wait(.05)._release('right')
self._hold(on_ele, 'right', times).wait(.05)._release('right')
return self
def m_click(self, on_ele=None):
def m_click(self, on_ele=None, times=1):
"""点击鼠标中键,可先移动到元素上
:param on_ele: ChromiumElement元素或文本定位符
:param times: 点击次数
:return: self
"""
self._hold(on_ele, 'middle').wait(.05)._release('middle')
return self
def db_click(self, on_ele=None):
"""双击鼠标左键,可先移动到元素上
:param on_ele: ChromiumElement元素或文本定位符
:return: self
"""
self._hold(on_ele, 'left', 2).wait(.05)._release('left')
self._hold(on_ele, 'middle', times).wait(.05)._release('middle')
return self
def hold(self, on_ele=None):

View File

@ -57,13 +57,11 @@ class Actions:
def move(self, offset_x: float = 0, offset_y: float = 0, duration: float = .5) -> Actions: ...
def click(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
def click(self, on_ele: Union[ChromiumElement, str] = None, times: int = 1) -> Actions: ...
def r_click(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
def r_click(self, on_ele: Union[ChromiumElement, str] = None, times: int = 1) -> Actions: ...
def m_click(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
def db_click(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
def m_click(self, on_ele: Union[ChromiumElement, str] = None, times: int = 1) -> Actions: ...
def hold(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...

View File

@ -53,7 +53,7 @@ class Clicker(object):
try:
self._ele.scroll.to_see()
if self._ele.states.is_enabled and self._ele.states.is_displayed:
rect = self._ele.rect.viewport_corners
rect = self._ele.rect.corners
can_click = True
except NoRectError:
if by_js is False:
@ -90,12 +90,12 @@ class Clicker(object):
r = self._ele.owner._run_cdp('DOM.getNodeForLocation', x=int(x), y=int(y),
includeUserAgentShadowDOM=True, ignorePointerEventsNone=True)
if r['backendNodeId'] != self._ele._backend_id:
vx, vy = self._ele.rect.viewport_midpoint
vx, vy = self._ele.rect.midpoint
else:
vx, vy = self._ele.rect.viewport_click_point
vx, vy = self._ele.rect.click_point
except CDPError:
vx, vy = self._ele.rect.viewport_midpoint
vx, vy = self._ele.rect.midpoint
self._click(vx, vy)
return True
@ -110,7 +110,7 @@ class Clicker(object):
def right(self):
"""右键单击"""
self._ele.owner.scroll.to_see(self._ele)
x, y = self._ele.rect.viewport_click_point
x, y = self._ele.rect.click_point
self._click(x, y, 'right')
def middle(self, get_tab=True):
@ -119,7 +119,7 @@ class Clicker(object):
:return: Tab对象或None
"""
self._ele.owner.scroll.to_see(self._ele)
x, y = self._ele.rect.viewport_click_point
x, y = self._ele.rect.click_point
curr_tid = self._ele.tab.browser.tab_ids[0]
self._click(x, y, 'middle')
if get_tab:
@ -198,15 +198,19 @@ class Clicker(object):
return (self._ele.tab.browser.get_mix_tab(tid) if self._ele.tab._type == 'MixTab'
else self._ele.tab.browser.get_tab(tid))
def _click(self, client_x, client_y, button='left', count=1):
def _click(self, loc_x, loc_y, button='left', count=1):
"""实施点击
:param client_x: 视口中的x坐标
:param client_y: 视口中的y坐标
:param loc_x: 绝对x坐标
:param loc_y: 绝对y坐标
:param button: 'left' 'right' 'middle' 'back' 'forward'
:param count: 点击次数
:return: None
"""
self._ele.owner._run_cdp('Input.dispatchMouseEvent', type='mousePressed', x=client_x,
y=client_y, button=button, clickCount=count, _ignore=AlertExistsError)
self._ele.owner._run_cdp('Input.dispatchMouseEvent', type='mouseReleased', x=client_x,
y=client_y, button=button, _ignore=AlertExistsError)
self._ele.owner.actions.move_to((loc_x, loc_y), duration=.1)
sx, sy = self._ele.owner.rect.scrollbar_position
x = loc_x - sx
y = loc_y - sy
self._ele.owner._run_cdp('Input.dispatchMouseEvent', type='mousePressed', x=x,
y=y, button=button, clickCount=count, _ignore=AlertExistsError)
self._ele.owner._run_cdp('Input.dispatchMouseEvent', type='mouseReleased', x=x,
y=y, button=button, _ignore=AlertExistsError)

View File

@ -176,6 +176,12 @@ class TabRect(object):
w, h = r.split(' ')
return int(w), int(h)
@property
def scrollbar_position(self):
"""返回滚动条位置,格式:(x, y)"""
r = self._get_page_rect()['visualViewport']
return r['pageX'], r['pageY']
def _get_page_rect(self):
"""获取页面范围信息"""
return self._owner._run_cdp_loaded('Page.getLayoutMetrics')

View File

@ -89,6 +89,9 @@ class TabRect(object):
@property
def viewport_size_with_scrollbar(self) -> Tuple[int, int]: ...
@property
def scrollbar_position(self) -> Tuple[int, int]: ...
def _get_page_rect(self) -> dict: ...
def _get_window_rect(self) -> dict: ...