From 43d118391f79894953c92a915f151a0c748a1967 Mon Sep 17 00:00:00 2001 From: g1879 Date: Sat, 25 Feb 2023 19:51:08 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=83=E7=B4=A0=E5=A2=9E=E5=8A=A0is=5Fcovere?= =?UTF-8?q?d=E3=80=81wait.covered=E3=80=81wait.not=5Fcovered?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DrissionPage/chromium_base.py | 8 +---- DrissionPage/chromium_element.py | 56 ++++++++++++++++++++++++++++--- DrissionPage/chromium_element.pyi | 9 +++++ DrissionPage/chromium_tab.py | 3 ++ 4 files changed, 64 insertions(+), 12 deletions(-) diff --git a/DrissionPage/chromium_base.py b/DrissionPage/chromium_base.py index 23902b1..8e82e94 100644 --- a/DrissionPage/chromium_base.py +++ b/DrissionPage/chromium_base.py @@ -974,16 +974,10 @@ class ChromiumPageScroll(ChromiumScroll): :param loc_or_ele: 元素的定位信息,可以是loc元组,或查询字符串 :return: None """ - ID = None ele = self._driver._ele(loc_or_ele) ele.run_js('this.scrollIntoView({behavior: "auto", block: "nearest", inline: "nearest"});') - x, y = ele.location - try: - ID = ele.page.run_cdp('DOM.getNodeForLocation', x=x, y=y).get('backendNodeId', None) - except Exception: - pass - if ID != ele.ids.backend_id: + if ele.states.is_covered: ele.run_js('this.scrollIntoView({behavior: "auto", block: "center", inline: "center"});') diff --git a/DrissionPage/chromium_element.py b/DrissionPage/chromium_element.py index 08c3628..7b9afb1 100644 --- a/DrissionPage/chromium_element.py +++ b/DrissionPage/chromium_element.py @@ -1457,6 +1457,20 @@ class ChromiumElementStates(object): x, y = self._ele.locations.click_point return location_in_viewport(self._ele.page, x, y) if x else False + @property + def is_covered(self): + """返回元素是否被覆盖,与是否在视口中无关""" + lx, ly = self._ele.locations.click_point + try: + r = self._ele.page.run_cdp('DOM.getNodeForLocation', x=lx, y=ly) + except CallMethodError: + return False + + if r.get('backendNodeId') != self._ele.ids.backend_id: + return True + + return False + class ShadowRootStates(object): def __init__(self, ele): @@ -1626,10 +1640,10 @@ class Click(object): """无遮挡返回True,有遮挡返回False,无元素返回None""" try: r = self._ele.page.run_cdp('DOM.getNodeForLocation', x=lx, y=ly) - except Exception: + except CallMethodError: return None - if retry and r.get('nodeId') != self._ele.ids.node_id: + if retry and r.get('backendNodeId') != self._ele.ids.backend_id: return False self._click(cx, cy) @@ -1981,7 +1995,7 @@ class ChromiumElementWaiter(object): def delete(self, timeout=None): """等待元素从dom删除 - :param timeout: 超时时间 + :param timeout: 超时时间,为None使用元素所在页面timeout属性 :return: 是否等待成功 """ if timeout is None: @@ -2006,18 +2020,48 @@ class ChromiumElementWaiter(object): def display(self, timeout=None): """等待元素从dom显示 - :param timeout: 超时时间 + :param timeout: 超时时间,为None使用元素所在页面timeout属性 :return: 是否等待成功 """ return self._wait_ele('display', timeout) def hidden(self, timeout=None): """等待元素从dom隐藏 - :param timeout: 超时时间 + :param timeout: 超时时间,为None使用元素所在页面timeout属性 :return: 是否等待成功 """ return self._wait_ele('hidden', timeout) + def covered(self, timeout=None): + """等待当前元素被遮盖 + :param timeout:超时时间,为None使用元素所在页面timeout属性 + :return: 是否等待成功 + """ + return self._covered(True, timeout) + + def not_covered(self, timeout=None): + """等待当前元素被遮盖 + :param timeout:超时时间,为None使用元素所在页面timeout属性 + :return: 是否等待成功 + """ + return self._covered(False, timeout) + + def _covered(self, mode=False, timeout=None): + """等待当前元素被遮盖 + :param mode: True表示被遮盖,False表示不被遮盖 + :param timeout: 超时时间,为None使用元素所在页面timeout属性 + :return: 是否等待成功 + """ + if timeout is None: + timeout = self._driver.page.timeout if isinstance(self._driver, ChromiumElement) else self._driver.timeout + end_time = perf_counter() + timeout + while perf_counter() < end_time: + if self._loc_or_ele.states.is_covered == mode: + return True + sleep(.05) + + return False + def _wait_ele(self, mode, timeout=None): """执行等待 :param mode: 等待模式 @@ -2039,6 +2083,8 @@ class ChromiumElementWaiter(object): elif mode == 'hidden' and not target.states.is_displayed: return True + sleep(.05) + return False diff --git a/DrissionPage/chromium_element.pyi b/DrissionPage/chromium_element.pyi index d828dde..925ca48 100644 --- a/DrissionPage/chromium_element.pyi +++ b/DrissionPage/chromium_element.pyi @@ -215,6 +215,9 @@ class ChromiumElementStates(object): @property def is_in_viewport(self) -> bool: ... + @property + def is_covered(self) -> bool: ... + class ChromiumShadowRoot(BaseElement): @@ -534,6 +537,12 @@ class ChromiumElementWaiter(object): def hidden(self, timeout: Union[int, float] = None) -> bool: ... + def _covered(self, mode: bool = False, timeout: Union[int, float] = None) -> bool: ... + + def covered(self, timeout: Union[int, float] = None) -> bool: ... + + def not_covered(self, timeout: Union[int, float] = None) -> bool: ... + def _wait_ele(self, mode: str, timeout: Union[int, float] = None) -> Union[None, bool]: ... diff --git a/DrissionPage/chromium_tab.py b/DrissionPage/chromium_tab.py index b072d0e..deada18 100644 --- a/DrissionPage/chromium_tab.py +++ b/DrissionPage/chromium_tab.py @@ -21,3 +21,6 @@ class ChromiumTab(ChromiumBase): """重写设置浏览器运行参数方法""" self._timeouts = self.page.timeouts self._page_load_strategy = self.page.page_load_strategy + +# class WebPageTab(SessionPage, ChromiumTab, BasePage): +# pass