new_tab()改回返回tab_id;增加tab.set.activate();Tab对象能获取自己的窗口矩形信息;修复浏览器最小化时模拟操作不响应

This commit is contained in:
g1879 2023-10-20 17:15:36 +08:00
parent f2b522b25e
commit 2d5f1687c8
13 changed files with 148 additions and 136 deletions

View File

@ -127,9 +127,12 @@ class Browser(object):
"""
self._driver.get(f'http://{self.address}/json/activate/{tab_id}')
def get_window_bounds(self):
"""返回浏览器窗口位置和大小信息"""
return self.run_cdp('Browser.getWindowForTarget', targetId=self.id)['bounds']
def get_window_bounds(self, tab_id=None):
"""返回浏览器窗口位置和大小信息
:param tab_id: 标签页id
:return: 窗口大小字典
"""
return self.run_cdp('Browser.getWindowForTarget', targetId=tab_id or self.id)['bounds']
def quit(self):
"""关闭浏览器"""

View File

@ -46,7 +46,7 @@ class Browser(object):
def activate_tab(self, tab_id: str) -> None: ...
def get_window_bounds(self) -> dict: ...
def get_window_bounds(self, tab_id: str = None) -> dict: ...
def connect_to_page(self) -> None: ...

View File

@ -105,6 +105,7 @@ class ChromiumBase(BasePage):
self._driver.call_method('DOM.enable')
self._driver.call_method('Page.enable')
self._driver.call_method('Emulation.setFocusEmulationEnabled', enabled=True)
self._driver.set_listener('Page.frameStoppedLoading', self._onFrameStoppedLoading)
self._driver.set_listener('Page.frameStartedLoading', self._onFrameStartedLoading)

View File

@ -15,6 +15,7 @@ from .._configs.chromium_options import ChromiumOptions
from .._pages.chromium_base import ChromiumBase, Timeout
from .._pages.chromium_tab import ChromiumTab
from .._units.setter import ChromiumPageSetter
from .._units.tab_rect import ChromiumTabRect
from .._units.waiter import ChromiumPageWaiter
@ -155,7 +156,7 @@ class ChromiumPage(ChromiumBase):
"""
return self._browser.find_tabs(title, url, tab_type, single)
def _new_tab(self, url=None, switch_to=False):
def new_tab(self, url=None, switch_to=False):
"""新建一个标签页,该标签页在最后面
:param url: 新标签页跳转到的网址
:param switch_to: 新建标签页后是否把焦点移过去
@ -184,14 +185,6 @@ class ChromiumPage(ChromiumBase):
return tid
def new_tab(self, url=None, switch_to=False):
"""新建一个标签页,该标签页在最后面
:param url: 新标签页跳转到的网址
:param switch_to: 新建标签页后是否把焦点移过去
:return: 新标签页对象
"""
return ChromiumTab(self, self._new_tab(url, switch_to))
def to_main_tab(self):
"""跳转到主标签页"""
self.to_tab(self._main_tab)
@ -326,77 +319,6 @@ class ChromiumPage(ChromiumBase):
self._driver.has_alert = True
class ChromiumTabRect(object):
def __init__(self, page):
self._page = page
@property
def window_state(self):
"""返回窗口状态normal、fullscreen、maximized、 minimized"""
return self._get_browser_rect()['windowState']
@property
def browser_location(self):
"""返回浏览器在屏幕上的坐标,左上角为(0, 0)"""
r = self._get_browser_rect()
if r['windowState'] in ('maximized', 'fullscreen'):
return 0, 0
return r['left'] + 7, r['top']
@property
def page_location(self):
"""返回页面左上角在屏幕中坐标,左上角为(0, 0)"""
w, h = self.viewport_location
r = self._get_page_rect()['layoutViewport']
return w - r['pageX'], h - r['pageY']
@property
def viewport_location(self):
"""返回视口在屏幕中坐标,左上角为(0, 0)"""
w_bl, h_bl = self.browser_location
w_bs, h_bs = self.browser_size
w_vs, h_vs = self.viewport_size_with_scrollbar
return w_bl + w_bs - w_vs, h_bl + h_bs - h_vs
@property
def browser_size(self):
"""返回浏览器大小"""
r = self._get_browser_rect()
if r['windowState'] == 'fullscreen':
return r['width'], r['height']
elif r['windowState'] == 'maximized':
return r['width'] - 16, r['height'] - 16
else:
return r['width'] - 16, r['height'] - 7
@property
def page_size(self):
"""返回页面总宽高,格式:(宽, 高)"""
r = self._get_page_rect()['contentSize']
return r['width'], r['height']
@property
def viewport_size(self):
"""返回视口宽高,不包括滚动条,格式:(宽, 高)"""
r = self._get_page_rect()['visualViewport']
return r['clientWidth'], r['clientHeight']
@property
def viewport_size_with_scrollbar(self):
"""返回视口宽高,包括滚动条,格式:(宽, 高)"""
r = self._page.run_js('return window.innerWidth.toString() + " " + window.innerHeight.toString();')
w, h = r.split(' ')
return int(w), int(h)
def _get_page_rect(self):
"""获取页面范围信息"""
return self._page.run_cdp_loaded('Page.getLayoutMetrics')
def _get_browser_rect(self):
"""获取浏览器范围信息"""
return self._page.browser.get_window_bounds()
class Alert(object):
"""用于保存alert信息的类"""

View File

@ -6,11 +6,12 @@
from typing import Union, Tuple, List, Optional
from .._base.browser import Browser
from .._pages.chromium_base import ChromiumBase
from .._base.chromium_driver import ChromiumDriver
from .._pages.chromium_tab import ChromiumTab
from .._configs.chromium_options import ChromiumOptions
from .._pages.chromium_base import ChromiumBase
from .._pages.chromium_tab import ChromiumTab
from .._units.setter import ChromiumPageSetter
from .._units.tab_rect import ChromiumTabRect
from .._units.waiter import ChromiumPageWaiter
@ -24,7 +25,7 @@ class ChromiumPage(ChromiumBase):
self._main_tab: str = ...
self._alert: Alert = ...
self._browser: Browser = ...
self._rect: ChromiumTabRect = ...
self._rect: Optional[ChromiumTabRect] = ...
def _handle_options(self, addr_driver_opts: Union[str, ChromiumDriver, ChromiumOptions]) -> str: ...
@ -64,9 +65,7 @@ class ChromiumPage(ChromiumBase):
def find_tabs(self, title: str = None, url: str = None,
tab_type: Union[str, list, tuple] = None, single: bool = True) -> Union[str, List[str]]: ...
def _new_tab(self, url: str = None, switch_to: bool = False) -> str: ...
def new_tab(self, url: str = None, switch_to: bool = False) -> ChromiumTab: ...
def new_tab(self, url: str = None, switch_to: bool = False) -> str: ...
def to_main_tab(self) -> None: ...
@ -91,39 +90,6 @@ class ChromiumPage(ChromiumBase):
def _on_alert_open(self, **kwargs): ...
class ChromiumTabRect(object):
def __init__(self, page: ChromiumPage):
self._page: ChromiumPage = ...
@property
def window_state(self) -> str: ...
@property
def browser_location(self) -> Tuple[int, int]: ...
@property
def page_location(self) -> Tuple[int, int]: ...
@property
def viewport_location(self) -> Tuple[int, int]: ...
@property
def browser_size(self) -> Tuple[int, int]: ...
@property
def page_size(self) -> Tuple[int, int]: ...
@property
def viewport_size(self) -> Tuple[int, int]: ...
@property
def viewport_size_with_scrollbar(self) -> Tuple[int, int]: ...
def _get_page_rect(self) -> dict: ...
def _get_browser_rect(self) -> dict: ...
class Alert(object):
def __init__(self):

View File

@ -10,6 +10,7 @@ from .._commons.web import set_session_cookies, set_browser_cookies
from .._pages.chromium_base import ChromiumBase
from .._pages.session_page import SessionPage
from .._units.setter import TabSetter, WebPageTabSetter
from .._units.tab_rect import ChromiumTabRect
from .._units.waiter import ChromiumTabWaiter
@ -24,6 +25,7 @@ class ChromiumTab(ChromiumBase):
self._page = page
self._browser = page.browser
super().__init__(page.address, tab_id, page.timeout)
self._rect = None
def _d_set_runtime_settings(self):
"""重写设置浏览器运行参数方法"""
@ -45,7 +47,9 @@ class ChromiumTab(ChromiumBase):
@property
def rect(self):
"""返回获取窗口坐标和大小的对象"""
return self.page.rect
if self._rect is None:
self._rect = ChromiumTabRect(self)
return self._rect
@property
def set(self):

View File

@ -3,13 +3,14 @@
@Author : g1879
@Contact : g1879@qq.com
"""
from typing import Union, Tuple, Any, List
from typing import Union, Tuple, Any, List, Optional
from requests import Session, Response
from .._units.tab_rect import ChromiumTabRect
from .chromium_base import ChromiumBase
from .chromium_frame import ChromiumFrame
from .chromium_page import ChromiumPage, ChromiumTabRect
from .chromium_page import ChromiumPage
from .session_page import SessionPage
from .web_page import WebPage
from .._base.browser import Browser
@ -24,6 +25,7 @@ class ChromiumTab(ChromiumBase):
def __init__(self, page: ChromiumPage, tab_id: str = None):
self._page: ChromiumPage = ...
self._browser: Browser = ...
self._rect: Optional[ChromiumTabRect] = ...
def _d_set_runtime_settings(self) -> None: ...

View File

@ -294,14 +294,6 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
"""
return tab_id if isinstance(tab_id, WebPageTab) else WebPageTab(self, tab_id or self.tab_id)
def new_tab(self, url=None, switch_to=False):
"""新建一个标签页,该标签页在最后面
:param url: 新标签页跳转到的网址
:param switch_to: 新建标签页后是否把焦点移过去
:return: 新标签页对象
"""
return WebPageTab(self, self._new_tab(url, switch_to))
def close_driver(self):
"""关闭driver及浏览器"""
if self._has_driver:

View File

@ -121,8 +121,6 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
def get_tab(self, tab_id: Union[str, WebPageTab] = None) -> WebPageTab: ...
def new_tab(self, url: str = None, switch_to: bool = False) -> WebPageTab: ...
def close_driver(self) -> None: ...
def close_session(self) -> None: ...

View File

@ -152,6 +152,10 @@ class TabSetter(ChromiumBaseSetter):
self._page.browser._dl_mgr.set_file_exists(self._page.tab_id, mode)
def activate(self):
"""使标签页处于最前面"""
self._page.browser.activate_tab(self._page.tab_id)
class ChromiumPageSetter(TabSetter):
def main_tab(self, tab_id=None):

View File

@ -62,6 +62,8 @@ class TabSetter(ChromiumBaseSetter):
def when_download_file_exists(self, mode: FILE_EXISTS) -> None: ...
def activate(self) -> None: ...
class ChromiumPageSetter(TabSetter):
_page: ChromiumPage = ...

View File

@ -0,0 +1,76 @@
# -*- coding:utf-8 -*-
"""
@Author : g1879
@Contact : g1879@qq.com
"""
class ChromiumTabRect(object):
def __init__(self, page):
self._page = page
@property
def window_state(self):
"""返回窗口状态normal、fullscreen、maximized、 minimized"""
return self._get_browser_rect()['windowState']
@property
def browser_location(self):
"""返回浏览器在屏幕上的坐标,左上角为(0, 0)"""
r = self._get_browser_rect()
if r['windowState'] in ('maximized', 'fullscreen'):
return 0, 0
return r['left'] + 7, r['top']
@property
def page_location(self):
"""返回页面左上角在屏幕中坐标,左上角为(0, 0)"""
w, h = self.viewport_location
r = self._get_page_rect()['layoutViewport']
return w - r['pageX'], h - r['pageY']
@property
def viewport_location(self):
"""返回视口在屏幕中坐标,左上角为(0, 0)"""
w_bl, h_bl = self.browser_location
w_bs, h_bs = self.browser_size
w_vs, h_vs = self.viewport_size_with_scrollbar
return w_bl + w_bs - w_vs, h_bl + h_bs - h_vs
@property
def browser_size(self):
"""返回浏览器大小"""
r = self._get_browser_rect()
if r['windowState'] == 'fullscreen':
return r['width'], r['height']
elif r['windowState'] == 'maximized':
return r['width'] - 16, r['height'] - 16
else:
return r['width'] - 16, r['height'] - 7
@property
def page_size(self):
"""返回页面总宽高,格式:(宽, 高)"""
r = self._get_page_rect()['contentSize']
return r['width'], r['height']
@property
def viewport_size(self):
"""返回视口宽高,不包括滚动条,格式:(宽, 高)"""
r = self._get_page_rect()['visualViewport']
return r['clientWidth'], r['clientHeight']
@property
def viewport_size_with_scrollbar(self):
"""返回视口宽高,包括滚动条,格式:(宽, 高)"""
r = self._page.run_js('return window.innerWidth.toString() + " " + window.innerHeight.toString();')
w, h = r.split(' ')
return int(w), int(h)
def _get_page_rect(self):
"""获取页面范围信息"""
return self._page.run_cdp_loaded('Page.getLayoutMetrics')
def _get_browser_rect(self):
"""获取浏览器范围信息"""
return self._page.browser.get_window_bounds(self._page.tab_id)

View File

@ -0,0 +1,42 @@
# -*- coding:utf-8 -*-
"""
@Author : g1879
@Contact : g1879@qq.com
"""
from typing import Tuple, Union
from .._pages.chromium_page import ChromiumPage
from .._pages.chromium_tab import ChromiumTab
class ChromiumTabRect(object):
def __init__(self, page: Union[ChromiumPage, ChromiumTab]):
self._page: Union[ChromiumPage, ChromiumTab] = ...
@property
def window_state(self) -> str: ...
@property
def browser_location(self) -> Tuple[int, int]: ...
@property
def page_location(self) -> Tuple[int, int]: ...
@property
def viewport_location(self) -> Tuple[int, int]: ...
@property
def browser_size(self) -> Tuple[int, int]: ...
@property
def page_size(self) -> Tuple[int, int]: ...
@property
def viewport_size(self) -> Tuple[int, int]: ...
@property
def viewport_size_with_scrollbar(self) -> Tuple[int, int]: ...
def _get_page_rect(self) -> dict: ...
def _get_browser_rect(self) -> dict: ...