Update CDP Mode
This commit is contained in:
parent
d0625e8a8f
commit
f242c8df5c
|
@ -231,6 +231,7 @@ sb.cdp.find_all(selector)
|
||||||
sb.cdp.find_elements_by_text(text, tag_name=None)
|
sb.cdp.find_elements_by_text(text, tag_name=None)
|
||||||
sb.cdp.select(selector)
|
sb.cdp.select(selector)
|
||||||
sb.cdp.select_all(selector)
|
sb.cdp.select_all(selector)
|
||||||
|
sb.cdp.find_elements(selector)
|
||||||
sb.cdp.click_link(link_text)
|
sb.cdp.click_link(link_text)
|
||||||
sb.cdp.tile_windows(windows=None, max_columns=0)
|
sb.cdp.tile_windows(windows=None, max_columns=0)
|
||||||
sb.cdp.get_all_cookies(*args, **kwargs)
|
sb.cdp.get_all_cookies(*args, **kwargs)
|
||||||
|
@ -290,6 +291,8 @@ sb.cdp.get_element_attributes(selector)
|
||||||
sb.cdp.get_element_html(selector)
|
sb.cdp.get_element_html(selector)
|
||||||
sb.cdp.set_locale(locale)
|
sb.cdp.set_locale(locale)
|
||||||
sb.cdp.set_attributes(selector, attribute, value)
|
sb.cdp.set_attributes(selector, attribute, value)
|
||||||
|
sb.cdp.gui_click_x_y(x, y)
|
||||||
|
sb.cdp.gui_click_element(selector)
|
||||||
sb.cdp.internalize_links()
|
sb.cdp.internalize_links()
|
||||||
sb.cdp.is_element_present(selector)
|
sb.cdp.is_element_present(selector)
|
||||||
sb.cdp.is_element_visible(selector)
|
sb.cdp.is_element_visible(selector)
|
||||||
|
@ -297,6 +300,8 @@ sb.cdp.assert_element(selector)
|
||||||
sb.cdp.assert_element_present(selector)
|
sb.cdp.assert_element_present(selector)
|
||||||
sb.cdp.assert_text(text, selector="html")
|
sb.cdp.assert_text(text, selector="html")
|
||||||
sb.cdp.assert_exact_text(text, selector="html")
|
sb.cdp.assert_exact_text(text, selector="html")
|
||||||
|
sb.cdp.scroll_down(amount=25)
|
||||||
|
sb.cdp.scroll_up(amount=25)
|
||||||
sb.cdp.save_screenshot(name, folder=None, selector=None)
|
sb.cdp.save_screenshot(name, folder=None, selector=None)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -588,6 +588,7 @@ def uc_open_with_cdp_mode(driver, url=None):
|
||||||
cdp.find_elements_by_text = CDPM.find_elements_by_text
|
cdp.find_elements_by_text = CDPM.find_elements_by_text
|
||||||
cdp.select = CDPM.select
|
cdp.select = CDPM.select
|
||||||
cdp.select_all = CDPM.select_all
|
cdp.select_all = CDPM.select_all
|
||||||
|
cdp.find_elements = CDPM.find_elements
|
||||||
cdp.click_link = CDPM.click_link
|
cdp.click_link = CDPM.click_link
|
||||||
cdp.tile_windows = CDPM.tile_windows
|
cdp.tile_windows = CDPM.tile_windows
|
||||||
cdp.get_all_cookies = CDPM.get_all_cookies
|
cdp.get_all_cookies = CDPM.get_all_cookies
|
||||||
|
@ -619,6 +620,8 @@ def uc_open_with_cdp_mode(driver, url=None):
|
||||||
cdp.reset_window_size = CDPM.reset_window_size
|
cdp.reset_window_size = CDPM.reset_window_size
|
||||||
cdp.set_locale = CDPM.set_locale
|
cdp.set_locale = CDPM.set_locale
|
||||||
cdp.set_attributes = CDPM.set_attributes
|
cdp.set_attributes = CDPM.set_attributes
|
||||||
|
cdp.gui_click_x_y = CDPM.gui_click_x_y
|
||||||
|
cdp.gui_click_element = CDPM.gui_click_element
|
||||||
cdp.internalize_links = CDPM.internalize_links
|
cdp.internalize_links = CDPM.internalize_links
|
||||||
cdp.get_window = CDPM.get_window
|
cdp.get_window = CDPM.get_window
|
||||||
cdp.get_element_attributes = CDPM.get_element_attributes
|
cdp.get_element_attributes = CDPM.get_element_attributes
|
||||||
|
@ -655,6 +658,8 @@ def uc_open_with_cdp_mode(driver, url=None):
|
||||||
cdp.assert_element_visible = CDPM.assert_element
|
cdp.assert_element_visible = CDPM.assert_element
|
||||||
cdp.assert_text = CDPM.assert_text
|
cdp.assert_text = CDPM.assert_text
|
||||||
cdp.assert_exact_text = CDPM.assert_exact_text
|
cdp.assert_exact_text = CDPM.assert_exact_text
|
||||||
|
cdp.scroll_down = CDPM.scroll_down
|
||||||
|
cdp.scroll_up = CDPM.scroll_up
|
||||||
cdp.save_screenshot = CDPM.save_screenshot
|
cdp.save_screenshot = CDPM.save_screenshot
|
||||||
cdp.page = page # async world
|
cdp.page = page # async world
|
||||||
cdp.driver = driver.cdp_base # async world
|
cdp.driver = driver.cdp_base # async world
|
||||||
|
@ -2218,7 +2223,6 @@ def _set_chrome_options(
|
||||||
)
|
)
|
||||||
):
|
):
|
||||||
chrome_options.add_argument("--no-pings")
|
chrome_options.add_argument("--no-pings")
|
||||||
chrome_options.add_argument("--disable-popup-blocking")
|
|
||||||
chrome_options.add_argument("--homepage=chrome://version/")
|
chrome_options.add_argument("--homepage=chrome://version/")
|
||||||
chrome_options.add_argument("--animation-duration-scale=0")
|
chrome_options.add_argument("--animation-duration-scale=0")
|
||||||
chrome_options.add_argument("--wm-window-animations-disabled")
|
chrome_options.add_argument("--wm-window-animations-disabled")
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
"""Add CDP methods to extend the driver"""
|
"""Add CDP methods to extend the driver"""
|
||||||
|
import fasteners
|
||||||
import math
|
import math
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
import time
|
import time
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
from seleniumbase import config as sb_config
|
from seleniumbase import config as sb_config
|
||||||
|
@ -239,6 +241,9 @@ class CDPMethods():
|
||||||
self.__slow_mode_pause_if_set()
|
self.__slow_mode_pause_if_set()
|
||||||
return updated_elements
|
return updated_elements
|
||||||
|
|
||||||
|
def find_elements(self, selector, timeout=settings.SMALL_TIMEOUT):
|
||||||
|
return self.select_all(selector, timeout=timeout)
|
||||||
|
|
||||||
def click_link(self, link_text):
|
def click_link(self, link_text):
|
||||||
self.find_elements_by_text(link_text, "a")[0].click()
|
self.find_elements_by_text(link_text, "a")[0].click()
|
||||||
|
|
||||||
|
@ -835,6 +840,194 @@ class CDPMethods():
|
||||||
with suppress(Exception):
|
with suppress(Exception):
|
||||||
self.loop.run_until_complete(self.page.evaluate(js_code))
|
self.loop.run_until_complete(self.page.evaluate(js_code))
|
||||||
|
|
||||||
|
def __verify_pyautogui_has_a_headed_browser(self):
|
||||||
|
"""PyAutoGUI requires a headed browser so that it can
|
||||||
|
focus on the correct element when performing actions."""
|
||||||
|
driver = self.driver
|
||||||
|
if hasattr(driver, "cdp_base"):
|
||||||
|
driver = driver.cdp_base
|
||||||
|
if driver.config.headless:
|
||||||
|
raise Exception(
|
||||||
|
"PyAutoGUI can't be used in headless mode!"
|
||||||
|
)
|
||||||
|
|
||||||
|
def __install_pyautogui_if_missing(self):
|
||||||
|
self.__verify_pyautogui_has_a_headed_browser()
|
||||||
|
driver = self.driver
|
||||||
|
if hasattr(driver, "cdp_base"):
|
||||||
|
driver = driver.cdp_base
|
||||||
|
pip_find_lock = fasteners.InterProcessLock(
|
||||||
|
constants.PipInstall.FINDLOCK
|
||||||
|
)
|
||||||
|
with pip_find_lock: # Prevent issues with multiple processes
|
||||||
|
try:
|
||||||
|
import pyautogui
|
||||||
|
with suppress(Exception):
|
||||||
|
use_pyautogui_ver = constants.PyAutoGUI.VER
|
||||||
|
if pyautogui.__version__ != use_pyautogui_ver:
|
||||||
|
del pyautogui
|
||||||
|
shared_utils.pip_install(
|
||||||
|
"pyautogui", version=use_pyautogui_ver
|
||||||
|
)
|
||||||
|
import pyautogui
|
||||||
|
except Exception:
|
||||||
|
print("\nPyAutoGUI required! Installing now...")
|
||||||
|
shared_utils.pip_install(
|
||||||
|
"pyautogui", version=constants.PyAutoGUI.VER
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
import pyautogui
|
||||||
|
except Exception:
|
||||||
|
if (
|
||||||
|
shared_utils.is_linux()
|
||||||
|
and (not sb_config.headed or sb_config.xvfb)
|
||||||
|
and not driver.config.headless
|
||||||
|
):
|
||||||
|
from sbvirtualdisplay import Display
|
||||||
|
xvfb_width = 1366
|
||||||
|
xvfb_height = 768
|
||||||
|
if (
|
||||||
|
hasattr(sb_config, "_xvfb_width")
|
||||||
|
and sb_config._xvfb_width
|
||||||
|
and isinstance(sb_config._xvfb_width, int)
|
||||||
|
and hasattr(sb_config, "_xvfb_height")
|
||||||
|
and sb_config._xvfb_height
|
||||||
|
and isinstance(sb_config._xvfb_height, int)
|
||||||
|
):
|
||||||
|
xvfb_width = sb_config._xvfb_width
|
||||||
|
xvfb_height = sb_config._xvfb_height
|
||||||
|
if xvfb_width < 1024:
|
||||||
|
xvfb_width = 1024
|
||||||
|
sb_config._xvfb_width = xvfb_width
|
||||||
|
if xvfb_height < 768:
|
||||||
|
xvfb_height = 768
|
||||||
|
sb_config._xvfb_height = xvfb_height
|
||||||
|
with suppress(Exception):
|
||||||
|
xvfb_display = Display(
|
||||||
|
visible=True,
|
||||||
|
size=(xvfb_width, xvfb_height),
|
||||||
|
backend="xvfb",
|
||||||
|
use_xauth=True,
|
||||||
|
)
|
||||||
|
xvfb_display.start()
|
||||||
|
|
||||||
|
def __get_configured_pyautogui(self, pyautogui_copy):
|
||||||
|
if (
|
||||||
|
shared_utils.is_linux()
|
||||||
|
and hasattr(pyautogui_copy, "_pyautogui_x11")
|
||||||
|
and "DISPLAY" in os.environ.keys()
|
||||||
|
):
|
||||||
|
if (
|
||||||
|
hasattr(sb_config, "_pyautogui_x11_display")
|
||||||
|
and sb_config._pyautogui_x11_display
|
||||||
|
and hasattr(pyautogui_copy._pyautogui_x11, "_display")
|
||||||
|
and (
|
||||||
|
sb_config._pyautogui_x11_display
|
||||||
|
== pyautogui_copy._pyautogui_x11._display
|
||||||
|
)
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
import Xlib.display
|
||||||
|
pyautogui_copy._pyautogui_x11._display = (
|
||||||
|
Xlib.display.Display(os.environ['DISPLAY'])
|
||||||
|
)
|
||||||
|
sb_config._pyautogui_x11_display = (
|
||||||
|
pyautogui_copy._pyautogui_x11._display
|
||||||
|
)
|
||||||
|
return pyautogui_copy
|
||||||
|
|
||||||
|
def __gui_click_x_y(self, x, y, timeframe=0.25, uc_lock=False):
|
||||||
|
self.__install_pyautogui_if_missing()
|
||||||
|
import pyautogui
|
||||||
|
pyautogui = self.__get_configured_pyautogui(pyautogui)
|
||||||
|
screen_width, screen_height = pyautogui.size()
|
||||||
|
if x < 0 or y < 0 or x > screen_width or y > screen_height:
|
||||||
|
raise Exception(
|
||||||
|
"PyAutoGUI cannot click on point (%s, %s)"
|
||||||
|
" outside screen. (Width: %s, Height: %s)"
|
||||||
|
% (x, y, screen_width, screen_height)
|
||||||
|
)
|
||||||
|
if uc_lock:
|
||||||
|
gui_lock = fasteners.InterProcessLock(
|
||||||
|
constants.MultiBrowser.PYAUTOGUILOCK
|
||||||
|
)
|
||||||
|
with gui_lock: # Prevent issues with multiple processes
|
||||||
|
pyautogui.moveTo(x, y, timeframe, pyautogui.easeOutQuad)
|
||||||
|
if timeframe >= 0.25:
|
||||||
|
time.sleep(0.056) # Wait if moving at human-speed
|
||||||
|
if "--debug" in sys.argv:
|
||||||
|
print(" <DEBUG> pyautogui.click(%s, %s)" % (x, y))
|
||||||
|
pyautogui.click(x=x, y=y)
|
||||||
|
else:
|
||||||
|
# Called from a method where the gui_lock is already active
|
||||||
|
pyautogui.moveTo(x, y, timeframe, pyautogui.easeOutQuad)
|
||||||
|
if timeframe >= 0.25:
|
||||||
|
time.sleep(0.056) # Wait if moving at human-speed
|
||||||
|
if "--debug" in sys.argv:
|
||||||
|
print(" <DEBUG> pyautogui.click(%s, %s)" % (x, y))
|
||||||
|
pyautogui.click(x=x, y=y)
|
||||||
|
|
||||||
|
def gui_click_x_y(self, x, y, timeframe=0.25):
|
||||||
|
gui_lock = fasteners.InterProcessLock(
|
||||||
|
constants.MultiBrowser.PYAUTOGUILOCK
|
||||||
|
)
|
||||||
|
with gui_lock: # Prevent issues with multiple processes
|
||||||
|
self.__install_pyautogui_if_missing()
|
||||||
|
import pyautogui
|
||||||
|
pyautogui = self.__get_configured_pyautogui(pyautogui)
|
||||||
|
width_ratio = 1.0
|
||||||
|
if (
|
||||||
|
shared_utils.is_windows()
|
||||||
|
and (
|
||||||
|
not hasattr(sb_config, "_saved_width_ratio")
|
||||||
|
or not sb_config._saved_width_ratio
|
||||||
|
)
|
||||||
|
):
|
||||||
|
window_rect = self.get_window_rect()
|
||||||
|
width = window_rect["width"]
|
||||||
|
height = window_rect["height"]
|
||||||
|
win_x = window_rect["x"]
|
||||||
|
win_y = window_rect["y"]
|
||||||
|
if (
|
||||||
|
hasattr(sb_config, "_saved_width_ratio")
|
||||||
|
and sb_config._saved_width_ratio
|
||||||
|
):
|
||||||
|
width_ratio = sb_config._saved_width_ratio
|
||||||
|
else:
|
||||||
|
scr_width = pyautogui.size().width
|
||||||
|
self.maximize()
|
||||||
|
win_width = self.get_window_size()["width"]
|
||||||
|
width_ratio = round(float(scr_width) / float(win_width), 2)
|
||||||
|
width_ratio += 0.01
|
||||||
|
if width_ratio < 0.45 or width_ratio > 2.55:
|
||||||
|
width_ratio = 1.01
|
||||||
|
sb_config._saved_width_ratio = width_ratio
|
||||||
|
self.set_window_rect(win_x, win_y, width, height)
|
||||||
|
self.bring_active_window_to_front()
|
||||||
|
elif (
|
||||||
|
shared_utils.is_windows()
|
||||||
|
and hasattr(sb_config, "_saved_width_ratio")
|
||||||
|
and sb_config._saved_width_ratio
|
||||||
|
):
|
||||||
|
width_ratio = sb_config._saved_width_ratio
|
||||||
|
self.bring_active_window_to_front()
|
||||||
|
if shared_utils.is_windows():
|
||||||
|
x = x * width_ratio
|
||||||
|
y = y * width_ratio
|
||||||
|
self.__gui_click_x_y(x, y, timeframe=timeframe, uc_lock=False)
|
||||||
|
return
|
||||||
|
self.bring_active_window_to_front()
|
||||||
|
self.__gui_click_x_y(x, y, timeframe=timeframe, uc_lock=False)
|
||||||
|
|
||||||
|
def gui_click_element(self, selector, timeframe=0.25):
|
||||||
|
self.__slow_mode_pause_if_set()
|
||||||
|
x, y = self.get_gui_element_center(selector)
|
||||||
|
self.__add_light_pause()
|
||||||
|
self.gui_click_x_y(x, y, timeframe=timeframe)
|
||||||
|
self.__slow_mode_pause_if_set()
|
||||||
|
self.loop.run_until_complete(self.page.wait())
|
||||||
|
|
||||||
def internalize_links(self):
|
def internalize_links(self):
|
||||||
"""All `target="_blank"` links become `target="_self"`.
|
"""All `target="_blank"` links become `target="_self"`.
|
||||||
This prevents those links from opening in a new tab."""
|
This prevents those links from opening in a new tab."""
|
||||||
|
@ -938,6 +1131,16 @@ class CDPMethods():
|
||||||
% (text, element.text_all, selector)
|
% (text, element.text_all, selector)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def scroll_down(self, amount=25):
|
||||||
|
self.loop.run_until_complete(
|
||||||
|
self.page.scroll_down(amount)
|
||||||
|
)
|
||||||
|
|
||||||
|
def scroll_up(self, amount=25):
|
||||||
|
self.loop.run_until_complete(
|
||||||
|
self.page.scroll_up(amount)
|
||||||
|
)
|
||||||
|
|
||||||
def save_screenshot(self, name, folder=None, selector=None):
|
def save_screenshot(self, name, folder=None, selector=None):
|
||||||
filename = name
|
filename = name
|
||||||
if folder:
|
if folder:
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
"""CDP-Driver is based on NoDriver"""
|
"""CDP-Driver is based on NoDriver"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import fasteners
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
import time
|
import time
|
||||||
import types
|
import types
|
||||||
import typing
|
import typing
|
||||||
|
from contextlib import suppress
|
||||||
|
from seleniumbase import config as sb_config
|
||||||
|
from seleniumbase.config import settings
|
||||||
|
from seleniumbase.fixtures import constants
|
||||||
from seleniumbase.fixtures import shared_utils
|
from seleniumbase.fixtures import shared_utils
|
||||||
from typing import Optional, List, Union, Callable
|
from typing import Optional, List, Union, Callable
|
||||||
from .element import Element
|
from .element import Element
|
||||||
|
@ -15,9 +21,120 @@ from .tab import Tab
|
||||||
import mycdp as cdp
|
import mycdp as cdp
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
IS_LINUX = shared_utils.is_linux()
|
||||||
T = typing.TypeVar("T")
|
T = typing.TypeVar("T")
|
||||||
|
|
||||||
|
|
||||||
|
def __activate_standard_virtual_display():
|
||||||
|
from sbvirtualdisplay import Display
|
||||||
|
width = settings.HEADLESS_START_WIDTH
|
||||||
|
height = settings.HEADLESS_START_HEIGHT
|
||||||
|
with suppress(Exception):
|
||||||
|
_xvfb_display = Display(
|
||||||
|
visible=0, size=(width, height)
|
||||||
|
)
|
||||||
|
_xvfb_display.start()
|
||||||
|
sb_config._virtual_display = _xvfb_display
|
||||||
|
sb_config.headless_active = True
|
||||||
|
|
||||||
|
|
||||||
|
def __activate_virtual_display_as_needed(
|
||||||
|
headless, headed, xvfb, xvfb_metrics
|
||||||
|
):
|
||||||
|
"""This is only needed on Linux."""
|
||||||
|
if IS_LINUX and (not headed or xvfb):
|
||||||
|
from sbvirtualdisplay import Display
|
||||||
|
pip_find_lock = fasteners.InterProcessLock(
|
||||||
|
constants.PipInstall.FINDLOCK
|
||||||
|
)
|
||||||
|
with pip_find_lock: # Prevent issues with multiple processes
|
||||||
|
if not headless:
|
||||||
|
import Xlib.display
|
||||||
|
try:
|
||||||
|
_xvfb_width = None
|
||||||
|
_xvfb_height = None
|
||||||
|
if xvfb_metrics:
|
||||||
|
with suppress(Exception):
|
||||||
|
metrics_string = xvfb_metrics
|
||||||
|
metrics_string = metrics_string.replace(" ", "")
|
||||||
|
metrics_list = metrics_string.split(",")[0:2]
|
||||||
|
_xvfb_width = int(metrics_list[0])
|
||||||
|
_xvfb_height = int(metrics_list[1])
|
||||||
|
# The minimum width,height is: 1024,768
|
||||||
|
if _xvfb_width < 1024:
|
||||||
|
_xvfb_width = 1024
|
||||||
|
sb_config._xvfb_width = _xvfb_width
|
||||||
|
if _xvfb_height < 768:
|
||||||
|
_xvfb_height = 768
|
||||||
|
sb_config._xvfb_height = _xvfb_height
|
||||||
|
xvfb = True
|
||||||
|
if not _xvfb_width:
|
||||||
|
_xvfb_width = 1366
|
||||||
|
if not _xvfb_height:
|
||||||
|
_xvfb_height = 768
|
||||||
|
_xvfb_display = Display(
|
||||||
|
visible=True,
|
||||||
|
size=(_xvfb_width, _xvfb_height),
|
||||||
|
backend="xvfb",
|
||||||
|
use_xauth=True,
|
||||||
|
)
|
||||||
|
_xvfb_display.start()
|
||||||
|
if "DISPLAY" not in os.environ.keys():
|
||||||
|
print(
|
||||||
|
"\nX11 display failed! Will use regular xvfb!"
|
||||||
|
)
|
||||||
|
__activate_standard_virtual_display()
|
||||||
|
except Exception as e:
|
||||||
|
if hasattr(e, "msg"):
|
||||||
|
print("\n" + str(e.msg))
|
||||||
|
else:
|
||||||
|
print(e)
|
||||||
|
print("\nX11 display failed! Will use regular xvfb!")
|
||||||
|
__activate_standard_virtual_display()
|
||||||
|
return
|
||||||
|
pyautogui_is_installed = False
|
||||||
|
try:
|
||||||
|
import pyautogui
|
||||||
|
with suppress(Exception):
|
||||||
|
use_pyautogui_ver = constants.PyAutoGUI.VER
|
||||||
|
if pyautogui.__version__ != use_pyautogui_ver:
|
||||||
|
del pyautogui # To get newer ver
|
||||||
|
shared_utils.pip_install(
|
||||||
|
"pyautogui", version=use_pyautogui_ver
|
||||||
|
)
|
||||||
|
import pyautogui
|
||||||
|
pyautogui_is_installed = True
|
||||||
|
except Exception:
|
||||||
|
message = (
|
||||||
|
"PyAutoGUI is required for UC Mode on Linux! "
|
||||||
|
"Installing now..."
|
||||||
|
)
|
||||||
|
print("\n" + message)
|
||||||
|
shared_utils.pip_install(
|
||||||
|
"pyautogui", version=constants.PyAutoGUI.VER
|
||||||
|
)
|
||||||
|
import pyautogui
|
||||||
|
pyautogui_is_installed = True
|
||||||
|
if (
|
||||||
|
pyautogui_is_installed
|
||||||
|
and hasattr(pyautogui, "_pyautogui_x11")
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
pyautogui._pyautogui_x11._display = (
|
||||||
|
Xlib.display.Display(os.environ['DISPLAY'])
|
||||||
|
)
|
||||||
|
sb_config._pyautogui_x11_display = (
|
||||||
|
pyautogui._pyautogui_x11._display
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
if hasattr(e, "msg"):
|
||||||
|
print("\n" + str(e.msg))
|
||||||
|
else:
|
||||||
|
print(e)
|
||||||
|
else:
|
||||||
|
__activate_standard_virtual_display()
|
||||||
|
|
||||||
|
|
||||||
async def start(
|
async def start(
|
||||||
config: Optional[Config] = None,
|
config: Optional[Config] = None,
|
||||||
*,
|
*,
|
||||||
|
@ -27,11 +144,14 @@ async def start(
|
||||||
guest: Optional[bool] = False,
|
guest: Optional[bool] = False,
|
||||||
browser_executable_path: Optional[PathLike] = None,
|
browser_executable_path: Optional[PathLike] = None,
|
||||||
browser_args: Optional[List[str]] = None,
|
browser_args: Optional[List[str]] = None,
|
||||||
|
xvfb_metrics: Optional[List[str]] = None, # "Width,Height" for Linux
|
||||||
sandbox: Optional[bool] = True,
|
sandbox: Optional[bool] = True,
|
||||||
lang: Optional[str] = None,
|
lang: Optional[str] = None,
|
||||||
host: Optional[str] = None,
|
host: Optional[str] = None,
|
||||||
port: Optional[int] = None,
|
port: Optional[int] = None,
|
||||||
expert: Optional[bool] = None,
|
xvfb: Optional[int] = None, # Use a special virtual display on Linux
|
||||||
|
headed: Optional[bool] = None, # Override default Xvfb mode on Linux
|
||||||
|
expert: Optional[bool] = None, # Open up closed Shadow-root elements
|
||||||
**kwargs: Optional[dict],
|
**kwargs: Optional[dict],
|
||||||
) -> Browser:
|
) -> Browser:
|
||||||
"""
|
"""
|
||||||
|
@ -73,6 +193,9 @@ async def start(
|
||||||
(For example, ensuring shadow-root is always in "open" mode.)
|
(For example, ensuring shadow-root is always in "open" mode.)
|
||||||
:type expert: bool
|
:type expert: bool
|
||||||
"""
|
"""
|
||||||
|
if IS_LINUX and not headless and not headed and not xvfb:
|
||||||
|
xvfb = True # The default setting on Linux
|
||||||
|
__activate_virtual_display_as_needed(headless, headed, xvfb, xvfb_metrics)
|
||||||
if not config:
|
if not config:
|
||||||
config = Config(
|
config = Config(
|
||||||
user_data_dir,
|
user_data_dir,
|
||||||
|
|
Loading…
Reference in New Issue