Make multiple updates
This commit is contained in:
parent
bc9de47290
commit
d65c52cd18
|
@ -11,3 +11,4 @@ from seleniumbase import MasterQA # noqa
|
|||
from seleniumbase import page_actions # noqa
|
||||
from seleniumbase import page_utils # noqa
|
||||
from seleniumbase import SB # noqa
|
||||
from seleniumbase import translate # noqa
|
||||
|
|
|
@ -10,7 +10,7 @@ from selenium import webdriver
|
|||
from seleniumbase.__version__ import __version__
|
||||
from seleniumbase.common import decorators # noqa
|
||||
from seleniumbase.common import encryption # noqa
|
||||
from seleniumbase.core import colored_traceback
|
||||
from seleniumbase.core import colored_traceback # noqa
|
||||
from seleniumbase.core.browser_launcher import get_driver # noqa
|
||||
from seleniumbase.fixtures import js_utils # noqa
|
||||
from seleniumbase.fixtures import page_actions # noqa
|
||||
|
@ -36,8 +36,7 @@ if sys.version_info[0] < 3 and "pdbp" in locals():
|
|||
pdb.DefaultConfig.sticky_by_default = True
|
||||
colored_traceback.add_hook()
|
||||
os.environ["SE_AVOID_STATS"] = "true" # Disable Selenium Manager stats
|
||||
if sys.version_info >= (3, 7):
|
||||
webdriver.TouchActions = None # Lifeline for past selenium-wire versions
|
||||
webdriver.TouchActions = None # Lifeline for past selenium-wire versions
|
||||
if sys.version_info >= (3, 10):
|
||||
collections.Callable = collections.abc.Callable # Lifeline for nosetests
|
||||
del collections # Undo "import collections" / Simplify "dir(seleniumbase)"
|
||||
|
|
|
@ -48,6 +48,7 @@ behave -D agent="User Agent String" -D demo
|
|||
-D headless2 (Use the new headless mode, which supports extensions.)
|
||||
-D headed (Run tests in headed/GUI mode on Linux OS, where not default.)
|
||||
-D xvfb (Run tests using the Xvfb virtual display server on Linux OS.)
|
||||
-D xvfb-metrics=STRING (Set Xvfb display size on Linux: "Width,Height".)
|
||||
-D locale=LOCALE_CODE (Set the Language Locale Code for the web browser.)
|
||||
-D pdb (Activate Post Mortem Debug Mode if a test fails.)
|
||||
-D interval=SECONDS (The autoplay interval for presentations & tour steps)
|
||||
|
@ -90,6 +91,7 @@ behave -D agent="User Agent String" -D demo
|
|||
-D rcs | -D reuse-class-session (Reuse session for tests in class/feature)
|
||||
-D crumbs (Delete all cookies between tests reusing a session.)
|
||||
-D disable-beforeunload (Disable the "beforeunload" event on Chrome.)
|
||||
-D window-position=X,Y (Set the browser's starting window position.)
|
||||
-D window-size=WIDTH,HEIGHT (Set the browser's starting window size.)
|
||||
-D maximize (Start tests with the browser window maximized.)
|
||||
-D screenshot (Save a screenshot at the end of each test.)
|
||||
|
@ -104,6 +106,7 @@ import colorama
|
|||
import os
|
||||
import re
|
||||
import sys
|
||||
from contextlib import suppress
|
||||
from seleniumbase import config as sb_config
|
||||
from seleniumbase.config import settings
|
||||
from seleniumbase.core import download_helper
|
||||
|
@ -145,6 +148,7 @@ def get_configured_sb(context):
|
|||
sb.headless_active = False
|
||||
sb.headed = False
|
||||
sb.xvfb = False
|
||||
sb.xvfb_metrics = None
|
||||
sb.start_page = None
|
||||
sb.locale_code = None
|
||||
sb.pdb_option = False
|
||||
|
@ -193,6 +197,7 @@ def get_configured_sb(context):
|
|||
sb._disable_beforeunload = False
|
||||
sb.visual_baseline = False
|
||||
sb.use_wire = False
|
||||
sb.window_position = None
|
||||
sb.window_size = None
|
||||
sb.maximize_option = False
|
||||
sb.is_context_manager = False
|
||||
|
@ -302,6 +307,13 @@ def get_configured_sb(context):
|
|||
if low_key == "xvfb":
|
||||
sb.xvfb = True
|
||||
continue
|
||||
# Handle: -D xvfb-metrics=STR / xvfb_metrics=STR
|
||||
if low_key in ["xvfb-metrics", "xvfb_metrics"]:
|
||||
xvfb_metrics = userdata[key]
|
||||
if xvfb_metrics == "true":
|
||||
xvfb_metrics = sb.xvfb_metrics # revert to default
|
||||
sb.xvfb_metrics = xvfb_metrics
|
||||
continue
|
||||
# Handle: -D start-page=URL / start_page=URL / url=URL
|
||||
if low_key in ["start-page", "start_page", "url"]:
|
||||
start_page = userdata[key]
|
||||
|
@ -601,6 +613,13 @@ def get_configured_sb(context):
|
|||
if low_key == "wire":
|
||||
sb.use_wire = True
|
||||
continue
|
||||
# Handle: -D window-position=X,Y / window_position=X,Y
|
||||
if low_key in ["window-position", "window_position"]:
|
||||
window_position = userdata[key]
|
||||
if window_position == "true":
|
||||
window_position = sb.window_position # revert to default
|
||||
sb.window_position = window_position
|
||||
continue
|
||||
# Handle: -D window-size=Width,Height / window_size=Width,Height
|
||||
if low_key in ["window-size", "window_size"]:
|
||||
window_size = userdata[key]
|
||||
|
@ -904,6 +923,29 @@ def get_configured_sb(context):
|
|||
else:
|
||||
sb.enable_ws = False
|
||||
sb.disable_ws = True
|
||||
if sb.window_position:
|
||||
window_position = sb.window_position
|
||||
if window_position.count(",") != 1:
|
||||
message = (
|
||||
'\n\n window_position expects an "x,y" string!'
|
||||
'\n (Your input was: "%s")\n' % window_position
|
||||
)
|
||||
raise Exception(message)
|
||||
window_position = window_position.replace(" ", "")
|
||||
win_x = None
|
||||
win_y = None
|
||||
try:
|
||||
win_x = int(window_position.split(",")[0])
|
||||
win_y = int(window_position.split(",")[1])
|
||||
except Exception:
|
||||
message = (
|
||||
'\n\n Expecting integer values for "x,y"!'
|
||||
'\n (window_position input was: "%s")\n'
|
||||
% window_position
|
||||
)
|
||||
raise Exception(message)
|
||||
settings.WINDOW_START_X = win_x
|
||||
settings.WINDOW_START_Y = win_y
|
||||
if sb.window_size:
|
||||
window_size = sb.window_size
|
||||
if window_size.count(",") != 1:
|
||||
|
@ -938,9 +980,11 @@ def get_configured_sb(context):
|
|||
sb_config.is_pytest = False
|
||||
sb_config.is_nosetest = False
|
||||
sb_config.is_context_manager = False
|
||||
sb_config.window_position = sb.window_position
|
||||
sb_config.window_size = sb.window_size
|
||||
sb_config.maximize_option = sb.maximize_option
|
||||
sb_config.xvfb = sb.xvfb
|
||||
sb_config.xvfb_metrics = sb.xvfb_metrics
|
||||
sb_config.reuse_class_session = sb._reuse_class_session
|
||||
sb_config.save_screenshot = sb.save_screenshot_after_test
|
||||
sb_config.no_screenshot = sb.no_screenshot_after_test
|
||||
|
@ -1162,12 +1206,10 @@ def behave_dashboard_prepare():
|
|||
sb_config.item_count_untested = sb_config.item_count
|
||||
dash_path = os.path.join(os.getcwd(), "dashboard.html")
|
||||
star_len = len("Dashboard: ") + len(dash_path)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
terminal_size = os.get_terminal_size().columns
|
||||
if terminal_size > 30 and star_len > terminal_size:
|
||||
star_len = terminal_size
|
||||
except Exception:
|
||||
pass
|
||||
stars = "*" * star_len
|
||||
c1 = ""
|
||||
cr = ""
|
||||
|
@ -1263,7 +1305,7 @@ def _perform_behave_unconfigure_():
|
|||
|
||||
|
||||
def do_final_driver_cleanup_as_needed():
|
||||
try:
|
||||
with suppress(Exception):
|
||||
if hasattr(sb_config, "last_driver") and sb_config.last_driver:
|
||||
if (
|
||||
not is_windows
|
||||
|
@ -1271,8 +1313,6 @@ def do_final_driver_cleanup_as_needed():
|
|||
or sb_config.last_driver.service.process
|
||||
):
|
||||
sb_config.last_driver.quit()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def _perform_behave_terminal_summary_():
|
||||
|
@ -1281,12 +1321,10 @@ def _perform_behave_terminal_summary_():
|
|||
)
|
||||
dash_path = os.path.join(os.getcwd(), "dashboard.html")
|
||||
equals_len = len("Dashboard: ") + len(dash_path)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
terminal_size = os.get_terminal_size().columns
|
||||
if terminal_size > 30 and equals_len > terminal_size:
|
||||
equals_len = terminal_size
|
||||
except Exception:
|
||||
pass
|
||||
equals = "=" * (equals_len + 2)
|
||||
c2 = ""
|
||||
cr = ""
|
||||
|
|
|
@ -110,6 +110,10 @@ DISABLE_CSP_ON_CHROME = False
|
|||
# (This applies when using --proxy=[PROXY_STRING] for using a proxy server.)
|
||||
RAISE_INVALID_PROXY_STRING_EXCEPTION = True
|
||||
|
||||
# Default browser coordinates when opening new windows for tests.
|
||||
WINDOW_START_X = 20
|
||||
WINDOW_START_Y = 54
|
||||
|
||||
# Default browser resolutions when opening new windows for tests.
|
||||
# (Headless resolutions take priority, and include all browsers.)
|
||||
# (Firefox starts maximized by default when running in GUI Mode.)
|
||||
|
|
|
@ -16,16 +16,16 @@ Output:
|
|||
import colorama
|
||||
import subprocess
|
||||
import sys
|
||||
import tkinter as tk
|
||||
from seleniumbase.fixtures import shared_utils
|
||||
from tkinter.scrolledtext import ScrolledText
|
||||
|
||||
if sys.version_info <= (3, 7):
|
||||
if sys.version_info <= (3, 8):
|
||||
current_version = ".".join(str(ver) for ver in sys.version_info[:3])
|
||||
raise Exception(
|
||||
"\n* SBase Commander requires Python 3.7 or newer!"
|
||||
"\n* SBase Commander requires Python 3.8 or newer!"
|
||||
"\n** You are currently using Python %s" % current_version
|
||||
)
|
||||
from seleniumbase.fixtures import shared_utils
|
||||
import tkinter as tk # noqa: E402
|
||||
from tkinter.scrolledtext import ScrolledText # noqa: E402
|
||||
|
||||
|
||||
def set_colors(use_colors):
|
||||
|
|
|
@ -20,17 +20,17 @@ import colorama
|
|||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tkinter as tk
|
||||
from seleniumbase.fixtures import shared_utils
|
||||
from tkinter import messagebox
|
||||
from tkinter.scrolledtext import ScrolledText
|
||||
|
||||
if sys.version_info <= (3, 7):
|
||||
if sys.version_info <= (3, 8):
|
||||
current_version = ".".join(str(ver) for ver in sys.version_info[:3])
|
||||
raise Exception(
|
||||
"\n* SBase Case Plans Generator requires Python 3.7 or newer!"
|
||||
"\n* SBase Case Plans Generator requires Python 3.8 or newer!"
|
||||
"\n** You are currently using Python %s" % current_version
|
||||
)
|
||||
from seleniumbase.fixtures import shared_utils
|
||||
import tkinter as tk # noqa: E402
|
||||
from tkinter import messagebox # noqa: E402
|
||||
from tkinter.scrolledtext import ScrolledText # noqa: E402
|
||||
|
||||
|
||||
def set_colors(use_colors):
|
||||
|
|
|
@ -21,16 +21,16 @@ import colorama
|
|||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tkinter as tk
|
||||
from seleniumbase.fixtures import shared_utils
|
||||
from tkinter.scrolledtext import ScrolledText
|
||||
|
||||
if sys.version_info <= (3, 7):
|
||||
if sys.version_info <= (3, 8):
|
||||
current_version = ".".join(str(ver) for ver in sys.version_info[:3])
|
||||
raise Exception(
|
||||
"\n* SBase Commander requires Python 3.7 or newer!"
|
||||
"\n* SBase Commander requires Python 3.8 or newer!"
|
||||
"\n** You are currently using Python %s" % current_version
|
||||
)
|
||||
from seleniumbase.fixtures import shared_utils
|
||||
import tkinter as tk # noqa: E402
|
||||
from tkinter.scrolledtext import ScrolledText # noqa: E402
|
||||
|
||||
|
||||
def set_colors(use_colors):
|
||||
|
|
|
@ -18,23 +18,23 @@ import colorama
|
|||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tkinter as tk
|
||||
from seleniumbase import config as sb_config
|
||||
from seleniumbase.fixtures import page_utils
|
||||
from seleniumbase.fixtures import shared_utils
|
||||
from tkinter import messagebox
|
||||
|
||||
sb_config.rec_subprocess_p = None
|
||||
sb_config.rec_subprocess_used = False
|
||||
sys_executable = sys.executable
|
||||
if " " in sys_executable:
|
||||
sys_executable = "python"
|
||||
if sys.version_info <= (3, 7):
|
||||
if sys.version_info <= (3, 8):
|
||||
current_version = ".".join(str(ver) for ver in sys.version_info[:3])
|
||||
raise Exception(
|
||||
"\n* Recorder Desktop requires Python 3.7 or newer!"
|
||||
"\n* Recorder Desktop requires Python 3.8 or newer!"
|
||||
"\n*** You are currently using Python %s" % current_version
|
||||
)
|
||||
import tkinter as tk # noqa: E402
|
||||
from tkinter import messagebox # noqa: E402
|
||||
|
||||
|
||||
def set_colors(use_colors):
|
||||
|
|
|
@ -9,6 +9,7 @@ import time
|
|||
import types
|
||||
import urllib3
|
||||
import warnings
|
||||
from contextlib import suppress
|
||||
from selenium import webdriver
|
||||
from selenium.common.exceptions import ElementClickInterceptedException
|
||||
from selenium.common.exceptions import InvalidSessionIdException
|
||||
|
@ -277,7 +278,7 @@ def chromedriver_on_path():
|
|||
def get_uc_driver_version(full=False):
|
||||
uc_driver_version = None
|
||||
if os.path.exists(LOCAL_UC_DRIVER):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
output = subprocess.check_output(
|
||||
'"%s" --version' % LOCAL_UC_DRIVER, shell=True
|
||||
)
|
||||
|
@ -292,8 +293,6 @@ def get_uc_driver_version(full=False):
|
|||
uc_driver_version = full_version
|
||||
else:
|
||||
uc_driver_version = output
|
||||
except Exception:
|
||||
pass
|
||||
return uc_driver_version
|
||||
|
||||
|
||||
|
@ -372,7 +371,7 @@ def uc_special_open_if_cf(
|
|||
):
|
||||
if url.startswith("http:") or url.startswith("https:"):
|
||||
special = False
|
||||
try:
|
||||
with suppress(Exception):
|
||||
req_get = requests_get(url, proxy_string)
|
||||
status_str = str(req_get.status_code)
|
||||
if (
|
||||
|
@ -384,8 +383,6 @@ def uc_special_open_if_cf(
|
|||
special = True
|
||||
if status_str == "403" or status_str == "429":
|
||||
time.sleep(0.06) # Forbidden / Blocked! (Wait first!)
|
||||
except Exception:
|
||||
pass
|
||||
if special:
|
||||
time.sleep(0.05)
|
||||
with driver:
|
||||
|
@ -416,13 +413,11 @@ def uc_special_open_if_cf(
|
|||
"mobile": True
|
||||
}
|
||||
)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
driver.execute_cdp_cmd(
|
||||
'Emulation.setDeviceMetricsOverride',
|
||||
set_device_metrics_override
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
if not mobile_emulator:
|
||||
page_actions.switch_to_window(
|
||||
driver, driver.window_handles[-1], 2
|
||||
|
@ -529,13 +524,11 @@ def uc_click(
|
|||
timeout=settings.SMALL_TIMEOUT,
|
||||
reconnect_time=None,
|
||||
):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
rct = float(by) # Add shortcut: driver.uc_click(selector, RCT)
|
||||
if not reconnect_time:
|
||||
reconnect_time = rct
|
||||
by = "css selector"
|
||||
except Exception:
|
||||
pass
|
||||
element = driver.wait_for_selector(selector, by=by, timeout=timeout)
|
||||
tag_name = element.tag_name
|
||||
if not tag_name == "span" and not tag_name == "input": # Must be "visible"
|
||||
|
@ -574,7 +567,7 @@ def install_pyautogui_if_missing(driver):
|
|||
with pip_find_lock: # Prevent issues with multiple processes
|
||||
try:
|
||||
import pyautogui
|
||||
try:
|
||||
with suppress(Exception):
|
||||
use_pyautogui_ver = constants.PyAutoGUI.VER
|
||||
if pyautogui.__version__ != use_pyautogui_ver:
|
||||
del pyautogui
|
||||
|
@ -582,8 +575,6 @@ def install_pyautogui_if_missing(driver):
|
|||
"pyautogui", version=use_pyautogui_ver
|
||||
)
|
||||
import pyautogui
|
||||
except Exception:
|
||||
pass
|
||||
except Exception:
|
||||
print("\nPyAutoGUI required! Installing now...")
|
||||
shared_utils.pip_install(
|
||||
|
@ -794,12 +785,10 @@ def uc_gui_click_x_y(driver, x, y, timeframe=0.25):
|
|||
y = y * width_ratio
|
||||
_uc_gui_click_x_y(driver, x, y, timeframe=timeframe, uc_lock=False)
|
||||
return
|
||||
try:
|
||||
with suppress(Exception):
|
||||
page_actions.switch_to_window(
|
||||
driver, driver.current_window_handle, 2, uc_lock=False
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
_uc_gui_click_x_y(driver, x, y, timeframe=timeframe, uc_lock=False)
|
||||
|
||||
|
||||
|
@ -1002,10 +991,8 @@ def _uc_gui_click_captcha(
|
|||
driver.uc_open_with_disconnect(driver.current_url, 3.8)
|
||||
else:
|
||||
driver.disconnect()
|
||||
try:
|
||||
_uc_gui_click_x_y(driver, x, y, timeframe=0.54321)
|
||||
except Exception:
|
||||
pass
|
||||
with suppress(Exception):
|
||||
_uc_gui_click_x_y(driver, x, y, timeframe=0.32)
|
||||
reconnect_time = (float(constants.UC.RECONNECT_TIME) / 2.0) + 0.6
|
||||
if IS_LINUX:
|
||||
reconnect_time = constants.UC.RECONNECT_TIME + 0.2
|
||||
|
@ -1047,12 +1034,12 @@ def _uc_gui_click_captcha(
|
|||
return
|
||||
if blind:
|
||||
driver.uc_open_with_disconnect(driver.current_url, 3.8)
|
||||
_uc_gui_click_x_y(driver, x, y, timeframe=1.05)
|
||||
_uc_gui_click_x_y(driver, x, y, timeframe=0.32)
|
||||
else:
|
||||
driver.uc_open_with_reconnect(driver.current_url, 3.8)
|
||||
if _on_a_captcha_page(driver):
|
||||
driver.disconnect()
|
||||
_uc_gui_click_x_y(driver, x, y, timeframe=1.05)
|
||||
_uc_gui_click_x_y(driver, x, y, timeframe=0.32)
|
||||
driver.reconnect(reconnect_time)
|
||||
|
||||
|
||||
|
@ -1232,13 +1219,11 @@ def _uc_gui_handle_captcha_(driver, frame="iframe", ctype=None):
|
|||
and sb_config._saved_cf_tab_count
|
||||
):
|
||||
driver.uc_open_with_disconnect(driver.current_url, 3.8)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
for i in range(sb_config._saved_cf_tab_count):
|
||||
pyautogui.press("\t")
|
||||
time.sleep(0.027)
|
||||
pyautogui.press(" ")
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
driver.disconnect()
|
||||
pyautogui.press(" ")
|
||||
|
@ -1919,13 +1904,11 @@ def _set_chrome_options(
|
|||
else:
|
||||
chromium_arg_item = "--" + chromium_arg_item
|
||||
if "remote-debugging-port=" in chromium_arg_item:
|
||||
try:
|
||||
with suppress(Exception):
|
||||
# Extra processing for UC Mode
|
||||
chrome_options._remote_debugging_port = int(
|
||||
chromium_arg_item.split("remote-debugging-port=")[1]
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
if "set-binary" in chromium_arg_item and not binary_location:
|
||||
br_app = "google-chrome"
|
||||
binary_loc = detect_b_ver.get_binary_location(
|
||||
|
@ -2577,14 +2560,12 @@ def get_remote_driver(
|
|||
try:
|
||||
from seleniumwire import webdriver
|
||||
import blinker
|
||||
try:
|
||||
with suppress(Exception):
|
||||
use_blinker_ver = constants.SeleniumWire.BLINKER_VER
|
||||
if blinker.__version__ != use_blinker_ver:
|
||||
shared_utils.pip_install(
|
||||
"blinker", version=use_blinker_ver
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
del blinker
|
||||
except Exception:
|
||||
shared_utils.pip_install(
|
||||
|
@ -3008,14 +2989,12 @@ def get_local_driver(
|
|||
try:
|
||||
from seleniumwire import webdriver
|
||||
import blinker
|
||||
try:
|
||||
with suppress(Exception):
|
||||
use_blinker_ver = constants.SeleniumWire.BLINKER_VER
|
||||
if blinker.__version__ != use_blinker_ver:
|
||||
shared_utils.pip_install(
|
||||
"blinker", version=use_blinker_ver
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
del blinker
|
||||
except Exception:
|
||||
shared_utils.pip_install(
|
||||
|
@ -3306,7 +3285,7 @@ def get_local_driver(
|
|||
edge_driver_version = None
|
||||
edgedriver_upgrade_needed = False
|
||||
if os.path.exists(LOCAL_EDGEDRIVER):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
output = subprocess.check_output(
|
||||
'"%s" --version' % LOCAL_EDGEDRIVER, shell=True
|
||||
)
|
||||
|
@ -3332,8 +3311,6 @@ def get_local_driver(
|
|||
edge_driver_version = output
|
||||
if driver_version == "keep":
|
||||
driver_version = edge_driver_version
|
||||
except Exception:
|
||||
pass
|
||||
use_version = find_edgedriver_version_to_use(
|
||||
use_version, driver_version
|
||||
)
|
||||
|
@ -3437,7 +3414,7 @@ def get_local_driver(
|
|||
edge_options.add_argument("--headless=new")
|
||||
elif headless and undetectable:
|
||||
# (For later: UC Mode doesn't support Edge now)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
if int(use_version) >= 109:
|
||||
edge_options.add_argument("--headless=new")
|
||||
elif (
|
||||
|
@ -3447,8 +3424,6 @@ def get_local_driver(
|
|||
edge_options.add_argument("--headless=chrome")
|
||||
else:
|
||||
pass # Will need Xvfb on Linux
|
||||
except Exception:
|
||||
pass
|
||||
elif headless:
|
||||
if "--headless" not in edge_options.arguments:
|
||||
edge_options.add_argument("--headless")
|
||||
|
@ -3748,19 +3723,15 @@ def get_local_driver(
|
|||
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
||||
)
|
||||
with edgedriver_fixing_lock:
|
||||
try:
|
||||
with suppress(Exception):
|
||||
if not _was_driver_repaired():
|
||||
_repair_edgedriver(edge_version)
|
||||
_mark_driver_repaired()
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
with suppress(Exception):
|
||||
if not _was_driver_repaired():
|
||||
_repair_edgedriver(edge_version)
|
||||
_mark_driver_repaired()
|
||||
except Exception:
|
||||
pass
|
||||
driver = Edge(service=service, options=edge_options)
|
||||
return extend_driver(driver)
|
||||
elif browser_name == constants.Browser.SAFARI:
|
||||
|
@ -3912,7 +3883,7 @@ def get_local_driver(
|
|||
ch_driver_version = None
|
||||
path_chromedriver = chromedriver_on_path()
|
||||
if os.path.exists(LOCAL_CHROMEDRIVER):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
output = subprocess.check_output(
|
||||
'"%s" --version' % LOCAL_CHROMEDRIVER, shell=True
|
||||
)
|
||||
|
@ -3926,8 +3897,6 @@ def get_local_driver(
|
|||
ch_driver_version = output
|
||||
if driver_version == "keep":
|
||||
driver_version = ch_driver_version
|
||||
except Exception:
|
||||
pass
|
||||
elif path_chromedriver:
|
||||
try:
|
||||
make_driver_executable_if_not(path_chromedriver)
|
||||
|
@ -3936,7 +3905,7 @@ def get_local_driver(
|
|||
"\nWarning: Could not make chromedriver"
|
||||
" executable: %s" % e
|
||||
)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
output = subprocess.check_output(
|
||||
'"%s" --version' % path_chromedriver, shell=True
|
||||
)
|
||||
|
@ -3950,8 +3919,6 @@ def get_local_driver(
|
|||
ch_driver_version = output
|
||||
if driver_version == "keep":
|
||||
use_version = ch_driver_version
|
||||
except Exception:
|
||||
pass
|
||||
disable_build_check = True
|
||||
uc_driver_version = None
|
||||
if is_using_uc(undetectable, browser_name):
|
||||
|
@ -4144,7 +4111,7 @@ def get_local_driver(
|
|||
if IS_ARM_MAC and use_uc:
|
||||
intel_for_uc = True # Use Intel driver for UC Mode
|
||||
if os.path.exists(LOCAL_CHROMEDRIVER):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
output = subprocess.check_output(
|
||||
'"%s" --version' % LOCAL_CHROMEDRIVER,
|
||||
shell=True,
|
||||
|
@ -4157,8 +4124,6 @@ def get_local_driver(
|
|||
output = full_ch_driver_version.split(".")[0]
|
||||
if int(output) >= 2:
|
||||
ch_driver_version = output
|
||||
except Exception:
|
||||
pass
|
||||
if (
|
||||
(
|
||||
not use_uc
|
||||
|
@ -4296,7 +4261,7 @@ def get_local_driver(
|
|||
chrome_options.add_argument(
|
||||
"--user-agent=%s" % user_agent
|
||||
)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
if (
|
||||
(
|
||||
not user_agent
|
||||
|
@ -4402,7 +4367,7 @@ def get_local_driver(
|
|||
service=service,
|
||||
options=headless_options,
|
||||
)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
user_agent = driver.execute_script(
|
||||
"return navigator.userAgent;"
|
||||
)
|
||||
|
@ -4424,11 +4389,7 @@ def get_local_driver(
|
|||
"--user-agent=%s" % user_agent
|
||||
)
|
||||
sb_config.uc_agent_cache = user_agent
|
||||
except Exception:
|
||||
pass
|
||||
driver.quit()
|
||||
except Exception:
|
||||
pass
|
||||
uc_path = None
|
||||
if os.path.exists(LOCAL_UC_DRIVER):
|
||||
uc_path = LOCAL_UC_DRIVER
|
||||
|
@ -4751,13 +4712,11 @@ def get_local_driver(
|
|||
"mobile": True
|
||||
}
|
||||
)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
driver.execute_cdp_cmd(
|
||||
'Emulation.setDeviceMetricsOverride',
|
||||
set_device_metrics_override
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
return extend_driver(driver)
|
||||
else: # Running headless on Linux (and not using --uc)
|
||||
try:
|
||||
|
@ -4803,23 +4762,19 @@ def get_local_driver(
|
|||
)
|
||||
with chromedr_fixing_lock:
|
||||
if not _was_driver_repaired():
|
||||
try:
|
||||
with suppress(Exception):
|
||||
_repair_chromedriver(
|
||||
chrome_options, chrome_options, mcv
|
||||
)
|
||||
_mark_driver_repaired()
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
if not _was_driver_repaired():
|
||||
try:
|
||||
with suppress(Exception):
|
||||
_repair_chromedriver(
|
||||
chrome_options, chrome_options, mcv
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
_mark_driver_repaired()
|
||||
try:
|
||||
with suppress(Exception):
|
||||
service = ChromeService(
|
||||
log_output=os.devnull,
|
||||
service_args=["--disable-build-check"],
|
||||
|
@ -4829,8 +4784,6 @@ def get_local_driver(
|
|||
options=chrome_options,
|
||||
)
|
||||
return extend_driver(driver)
|
||||
except Exception:
|
||||
pass
|
||||
# Use the virtual display on Linux during headless errors
|
||||
logging.debug(
|
||||
"\nWarning: Chrome failed to launch in"
|
||||
|
@ -4851,14 +4804,12 @@ def get_local_driver(
|
|||
if is_using_uc(undetectable, browser_name):
|
||||
raise
|
||||
# Try again if Chrome didn't launch
|
||||
try:
|
||||
with suppress(Exception):
|
||||
service = ChromeService(service_args=["--disable-build-check"])
|
||||
driver = webdriver.Chrome(
|
||||
service=service, options=chrome_options
|
||||
)
|
||||
return extend_driver(driver)
|
||||
except Exception:
|
||||
pass
|
||||
if user_data_dir:
|
||||
print("\nUnable to set user_data_dir while starting Chrome!\n")
|
||||
raise
|
||||
|
|
|
@ -35,10 +35,7 @@ class DatabaseManager:
|
|||
import cryptography # noqa: F401
|
||||
import pymysql
|
||||
except Exception:
|
||||
if sys.version_info < (3, 7):
|
||||
shared_utils.pip_install("PyMySQL[rsa]", version="1.0.2")
|
||||
else:
|
||||
shared_utils.pip_install("PyMySQL[rsa]", version="1.1.0")
|
||||
shared_utils.pip_install("PyMySQL[rsa]", version="1.1.1")
|
||||
import pymysql
|
||||
db_server = settings.DB_HOST
|
||||
db_port = settings.DB_PORT
|
||||
|
|
|
@ -422,9 +422,14 @@ def generate_sbase_code(srt_actions):
|
|||
):
|
||||
import unicodedata
|
||||
|
||||
action[1][0] = unicodedata.normalize("NFKC", action[1][0])
|
||||
action[1][0] = action[1][0].replace("\n", "\\n")
|
||||
action[1][0] = action[1][0].replace("\u00B6", "")
|
||||
text_list = False
|
||||
try:
|
||||
action[1][0] = unicodedata.normalize("NFKC", action[1][0])
|
||||
action[1][0] = action[1][0].replace("\n", "\\n")
|
||||
action[1][0] = action[1][0].replace("\u00B6", "")
|
||||
except Exception:
|
||||
text_list = True
|
||||
|
||||
method = "assert_text"
|
||||
if action[0] == "as_et":
|
||||
method = "assert_exact_text"
|
||||
|
@ -437,7 +442,17 @@ def generate_sbase_code(srt_actions):
|
|||
elif action[0] == "da_et":
|
||||
method = "deferred_assert_exact_text"
|
||||
if action[1][1] != "html":
|
||||
if '"' not in action[1][0] and '"' not in action[1][1]:
|
||||
if text_list and '"' not in action[1][1]:
|
||||
sb_actions.append(
|
||||
'self.%s(%s, "%s")'
|
||||
% (method, action[1][0], action[1][1])
|
||||
)
|
||||
elif text_list and "'" not in action[1][1]:
|
||||
sb_actions.append(
|
||||
"self.%s(%s, '%s')"
|
||||
% (method, action[1][0], action[1][1])
|
||||
)
|
||||
elif '"' not in action[1][0] and '"' not in action[1][1]:
|
||||
sb_actions.append(
|
||||
'self.%s("%s", "%s")'
|
||||
% (method, action[1][0], action[1][1])
|
||||
|
@ -458,7 +473,11 @@ def generate_sbase_code(srt_actions):
|
|||
% (method, action[1][0], action[1][1])
|
||||
)
|
||||
else:
|
||||
if '"' not in action[1][0]:
|
||||
if text_list:
|
||||
sb_actions.append(
|
||||
'self.%s(%s)' % (method, action[1][0])
|
||||
)
|
||||
elif '"' not in action[1][0]:
|
||||
sb_actions.append(
|
||||
'self.%s("%s")' % (method, action[1][0])
|
||||
)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
"""Add new methods to extend the driver"""
|
||||
from contextlib import suppress
|
||||
from selenium.webdriver.remote.webelement import WebElement
|
||||
from seleniumbase.fixtures import js_utils
|
||||
from seleniumbase.fixtures import page_actions
|
||||
|
@ -36,10 +37,8 @@ class DriverMethods():
|
|||
selector, by = page_utils.swap_selector_and_by_if_reversed(
|
||||
selector, by
|
||||
)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
return self.driver.default_find_element(by=by, value=selector)
|
||||
except Exception:
|
||||
pass
|
||||
raise Exception('No such Element: {%s} (by="%s")!' % (selector, by))
|
||||
|
||||
def get_attribute(self, selector, attribute, by="css selector"):
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,6 +2,7 @@
|
|||
import re
|
||||
import requests
|
||||
import time
|
||||
from contextlib import suppress
|
||||
from selenium.common.exceptions import NoSuchElementException
|
||||
from selenium.common.exceptions import WebDriverException
|
||||
from selenium.webdriver.common.by import By
|
||||
|
@ -56,11 +57,9 @@ def execute_async_script(driver, script, timeout=settings.LARGE_TIMEOUT):
|
|||
def wait_for_angularjs(driver, timeout=settings.LARGE_TIMEOUT, **kwargs):
|
||||
if hasattr(settings, "SKIP_JS_WAITS") and settings.SKIP_JS_WAITS:
|
||||
return
|
||||
try:
|
||||
with suppress(Exception):
|
||||
# This closes pop-up alerts
|
||||
driver.execute_script("")
|
||||
except Exception:
|
||||
pass
|
||||
if (
|
||||
(hasattr(driver, "_is_using_uc") and driver._is_using_uc)
|
||||
or not settings.WAIT_FOR_ANGULARJS
|
||||
|
@ -92,10 +91,8 @@ def wait_for_angularjs(driver, timeout=settings.LARGE_TIMEOUT, **kwargs):
|
|||
"handler": handler,
|
||||
"suffix": suffix,
|
||||
}
|
||||
try:
|
||||
with suppress(Exception):
|
||||
execute_async_script(driver, script, timeout=timeout)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def convert_to_css_selector(selector, by=By.CSS_SELECTOR):
|
||||
|
@ -191,14 +188,12 @@ def raise_unable_to_load_jquery_exception(driver):
|
|||
def activate_jquery(driver):
|
||||
# If "jQuery is not defined" on a website, use this method to activate it.
|
||||
# This method is needed because jQuery is not always defined on web sites.
|
||||
try:
|
||||
with suppress(Exception):
|
||||
# Let's first find out if jQuery is already defined.
|
||||
driver.execute_script("jQuery('html');")
|
||||
# Since that command worked, jQuery is defined. Let's return.
|
||||
return
|
||||
except Exception:
|
||||
# jQuery is not currently defined. Let's proceed by defining it.
|
||||
pass
|
||||
# jQuery is not defined. It will be loaded in the next part.
|
||||
jquery_js = constants.JQuery.MIN_JS
|
||||
add_js_link(driver, jquery_js)
|
||||
for x in range(36):
|
||||
|
@ -390,11 +385,9 @@ def highlight(driver, selector, by="css selector", loops=4):
|
|||
|
||||
|
||||
def highlight_with_js(driver, selector, loops=4, o_bs=""):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
# This closes any pop-up alerts
|
||||
driver.execute_script("")
|
||||
except Exception:
|
||||
pass
|
||||
if selector == "html":
|
||||
selector = "body"
|
||||
selector_no_spaces = selector.replace(" ", "")
|
||||
|
@ -490,11 +483,9 @@ def highlight_with_js(driver, selector, loops=4, o_bs=""):
|
|||
|
||||
|
||||
def highlight_element_with_js(driver, element, loops=4, o_bs=""):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
# This closes any pop-up alerts
|
||||
driver.execute_script("")
|
||||
except Exception:
|
||||
pass
|
||||
script = (
|
||||
"""arguments[0].style.boxShadow =
|
||||
'0px 0px 6px 6px rgba(128, 128, 128, 0.5)';"""
|
||||
|
@ -566,11 +557,9 @@ def highlight_element_with_js(driver, element, loops=4, o_bs=""):
|
|||
|
||||
|
||||
def highlight_with_jquery(driver, selector, loops=4, o_bs=""):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
# This closes any pop-up alerts
|
||||
driver.execute_script("")
|
||||
except Exception:
|
||||
pass
|
||||
if selector == "html":
|
||||
selector = "body"
|
||||
selector_no_spaces = selector.replace(" ", "")
|
||||
|
@ -908,11 +897,9 @@ def set_messenger_theme(
|
|||
time.sleep(0.03)
|
||||
activate_messenger(driver)
|
||||
time.sleep(0.15)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
driver.execute_script(msg_style)
|
||||
time.sleep(0.02)
|
||||
except Exception:
|
||||
pass
|
||||
time.sleep(0.05)
|
||||
|
||||
|
||||
|
@ -949,7 +936,7 @@ def post_messenger_success_message(driver, message, msg_dur=None):
|
|||
if not msg_dur:
|
||||
msg_dur = settings.DEFAULT_MESSAGE_DURATION
|
||||
msg_dur = float(msg_dur)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
theme = "future"
|
||||
location = "bottom_right"
|
||||
if hasattr(sb_config, "mobile_emulator") and sb_config.mobile_emulator:
|
||||
|
@ -957,28 +944,22 @@ def post_messenger_success_message(driver, message, msg_dur=None):
|
|||
set_messenger_theme(driver, theme=theme, location=location)
|
||||
post_message(driver, message, msg_dur, style="success")
|
||||
time.sleep(msg_dur + 0.07)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def post_messenger_error_message(driver, message, msg_dur=None):
|
||||
if not msg_dur:
|
||||
msg_dur = settings.DEFAULT_MESSAGE_DURATION
|
||||
msg_dur = float(msg_dur)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
set_messenger_theme(driver, theme="block", location="top_center")
|
||||
post_message(driver, message, msg_dur, style="error")
|
||||
time.sleep(msg_dur + 0.07)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def highlight_with_js_2(driver, message, selector, o_bs, msg_dur):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
# This closes any pop-up alerts
|
||||
driver.execute_script("")
|
||||
except Exception:
|
||||
pass
|
||||
if selector == "html":
|
||||
selector = "body"
|
||||
selector_no_spaces = selector.replace(" ", "")
|
||||
|
@ -991,11 +972,9 @@ def highlight_with_js_2(driver, message, selector, o_bs, msg_dur):
|
|||
else:
|
||||
early_exit = True # Changing the box-shadow changes the selector
|
||||
if early_exit:
|
||||
try:
|
||||
with suppress(Exception):
|
||||
activate_jquery(driver)
|
||||
post_messenger_success_message(driver, message, msg_dur)
|
||||
except Exception:
|
||||
pass
|
||||
return
|
||||
script = (
|
||||
"""document.querySelector('%s').style.boxShadow =
|
||||
|
@ -1047,11 +1026,9 @@ def highlight_with_js_2(driver, message, selector, o_bs, msg_dur):
|
|||
except Exception:
|
||||
return
|
||||
time.sleep(0.0181)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
activate_jquery(driver)
|
||||
post_messenger_success_message(driver, message, msg_dur)
|
||||
except Exception:
|
||||
pass
|
||||
script = """document.querySelector('%s').style.boxShadow = '%s';""" % (
|
||||
selector,
|
||||
o_bs,
|
||||
|
@ -1063,11 +1040,9 @@ def highlight_with_js_2(driver, message, selector, o_bs, msg_dur):
|
|||
|
||||
|
||||
def highlight_element_with_js_2(driver, message, element, o_bs, msg_dur):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
# This closes any pop-up alerts
|
||||
driver.execute_script("")
|
||||
except Exception:
|
||||
pass
|
||||
script = (
|
||||
"""arguments[0].style.boxShadow =
|
||||
'0px 0px 6px 6px rgba(128, 128, 128, 0.5)';"""
|
||||
|
@ -1113,11 +1088,9 @@ def highlight_element_with_js_2(driver, message, element, o_bs, msg_dur):
|
|||
except Exception:
|
||||
return
|
||||
time.sleep(0.0181)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
activate_jquery(driver)
|
||||
post_messenger_success_message(driver, message, msg_dur)
|
||||
except Exception:
|
||||
pass
|
||||
script = """arguments[0].style.boxShadow = '%s';""" % (o_bs)
|
||||
try:
|
||||
driver.execute_script(script, element)
|
||||
|
@ -1138,11 +1111,9 @@ def highlight_with_jquery_2(driver, message, selector, o_bs, msg_dur):
|
|||
else:
|
||||
early_exit = True # Changing the box-shadow changes the selector
|
||||
if early_exit:
|
||||
try:
|
||||
with suppress(Exception):
|
||||
activate_jquery(driver)
|
||||
post_messenger_success_message(driver, message, msg_dur)
|
||||
except Exception:
|
||||
pass
|
||||
return
|
||||
script = (
|
||||
"""jQuery('%s').css('box-shadow',
|
||||
|
@ -1195,11 +1166,9 @@ def highlight_with_jquery_2(driver, message, selector, o_bs, msg_dur):
|
|||
return
|
||||
time.sleep(0.0181)
|
||||
|
||||
try:
|
||||
with suppress(Exception):
|
||||
activate_jquery(driver)
|
||||
post_messenger_success_message(driver, message, msg_dur)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
script = """jQuery('%s').css('box-shadow', '%s');""" % (selector, o_bs)
|
||||
try:
|
||||
|
@ -1484,12 +1453,10 @@ def get_drag_and_drop_with_offset_script(selector, x, y):
|
|||
|
||||
|
||||
def clear_out_console_logs(driver):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
# Clear out the current page log before navigating to a new page
|
||||
# (To make sure that assert_no_js_errors() uses current results)
|
||||
driver.get_log("browser")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def _jq_format(code):
|
||||
|
|
|
@ -21,6 +21,7 @@ import codecs
|
|||
import fasteners
|
||||
import os
|
||||
import time
|
||||
from contextlib import suppress
|
||||
from selenium.common.exceptions import ElementNotInteractableException
|
||||
from selenium.common.exceptions import ElementNotVisibleException
|
||||
from selenium.common.exceptions import NoAlertPresentException
|
||||
|
@ -1409,12 +1410,10 @@ def switch_to_frame(driver, frame, timeout=settings.SMALL_TIMEOUT):
|
|||
else:
|
||||
by = "css selector"
|
||||
if is_element_visible(driver, frame, by=by):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
element = driver.find_element(by=by, value=frame)
|
||||
driver.switch_to.frame(element)
|
||||
return True
|
||||
except Exception:
|
||||
pass
|
||||
now_ms = time.time() * 1000.0
|
||||
if now_ms >= stop_ms:
|
||||
break
|
||||
|
@ -1548,12 +1547,10 @@ def click_if_visible(
|
|||
if is_element_visible(driver, selector, by=by):
|
||||
click(driver, selector, by=by, timeout=1)
|
||||
elif timeout > 0:
|
||||
try:
|
||||
with suppress(Exception):
|
||||
wait_for_element_visible(
|
||||
driver, selector, by=by, timeout=timeout
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
if is_element_visible(driver, selector, by=by):
|
||||
click(driver, selector, by=by, timeout=1)
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ def get_domain_url(url):
|
|||
Into this:
|
||||
https://blog.xkcd.com
|
||||
"""
|
||||
if not url.startswith("http://") and not url.startswith("https://"):
|
||||
if not url.startswith(("http://", "https://")):
|
||||
return url
|
||||
url_header = url.split("://")[0]
|
||||
simple_url = url.split("://")[1]
|
||||
|
@ -40,45 +40,25 @@ def swap_selector_and_by_if_reversed(selector, by):
|
|||
|
||||
def is_xpath_selector(selector):
|
||||
"""Determine if a selector is an xpath selector."""
|
||||
if (
|
||||
selector.startswith("/")
|
||||
or selector.startswith("./")
|
||||
or selector.startswith("(")
|
||||
):
|
||||
return True
|
||||
return False
|
||||
return selector.startswith(("/", "./", "("))
|
||||
|
||||
|
||||
def is_link_text_selector(selector):
|
||||
"""Determine if a selector is a link text selector."""
|
||||
if (
|
||||
selector.startswith("link=")
|
||||
or selector.startswith("link_text=")
|
||||
or selector.startswith("text=")
|
||||
):
|
||||
return True
|
||||
return False
|
||||
return selector.startswith(("link=", "link_text=", "text="))
|
||||
|
||||
|
||||
def is_partial_link_text_selector(selector):
|
||||
"""Determine if a selector is a partial link text selector."""
|
||||
if (
|
||||
selector.startswith("partial_link=")
|
||||
or selector.startswith("partial_link_text=")
|
||||
or selector.startswith("partial_text=")
|
||||
or selector.startswith("p_link=")
|
||||
or selector.startswith("p_link_text=")
|
||||
or selector.startswith("p_text=")
|
||||
):
|
||||
return True
|
||||
return False
|
||||
return selector.startswith((
|
||||
"partial_link=", "partial_link_text=", "partial_text=",
|
||||
"p_link=", "p_link_text=", "p_text="
|
||||
))
|
||||
|
||||
|
||||
def is_name_selector(selector):
|
||||
"""Determine if a selector is a name selector."""
|
||||
if selector.startswith("name=") or selector.startswith("&"):
|
||||
return True
|
||||
return False
|
||||
return selector.startswith(("name=", "&"))
|
||||
|
||||
|
||||
def recalculate_selector(selector, by, xp_ok=True):
|
||||
|
@ -108,10 +88,9 @@ def recalculate_selector(selector, by, xp_ok=True):
|
|||
name = get_name_from_selector(selector)
|
||||
selector = '[name="%s"]' % name
|
||||
by = By.CSS_SELECTOR
|
||||
if xp_ok:
|
||||
if ":contains(" in selector and by == By.CSS_SELECTOR:
|
||||
selector = css_to_xpath.convert_css_to_xpath(selector)
|
||||
by = By.XPATH
|
||||
if xp_ok and ":contains(" in selector and by == By.CSS_SELECTOR:
|
||||
selector = css_to_xpath.convert_css_to_xpath(selector)
|
||||
by = By.XPATH
|
||||
if by == "":
|
||||
by = By.CSS_SELECTOR
|
||||
if not is_valid_by(by):
|
||||
|
@ -130,21 +109,10 @@ def looks_like_a_page_url(url):
|
|||
possible typos when calling self.get(url), which will try to
|
||||
navigate to the page if a URL is detected, but will instead call
|
||||
self.get_element(URL_AS_A_SELECTOR) if the input is not a URL."""
|
||||
if (
|
||||
url.startswith("http:")
|
||||
or url.startswith("https:")
|
||||
or url.startswith("://")
|
||||
or url.startswith("about:")
|
||||
or url.startswith("blob:")
|
||||
or url.startswith("chrome:")
|
||||
or url.startswith("data:")
|
||||
or url.startswith("edge:")
|
||||
or url.startswith("file:")
|
||||
or url.startswith("view-source:")
|
||||
):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
return url.startswith((
|
||||
"http:", "https:", "://", "about:", "blob:", "chrome:",
|
||||
"data:", "edge:", "file:", "view-source:"
|
||||
))
|
||||
|
||||
|
||||
def get_link_text_from_selector(selector):
|
||||
|
@ -195,18 +163,12 @@ def is_valid_url(url):
|
|||
r"(?:/?|[/?]\S+)$",
|
||||
re.IGNORECASE,
|
||||
)
|
||||
if (
|
||||
return (
|
||||
regex.match(url)
|
||||
or url.startswith("about:")
|
||||
or url.startswith("blob:")
|
||||
or url.startswith("chrome:")
|
||||
or url.startswith("data:")
|
||||
or url.startswith("edge:")
|
||||
or url.startswith("file:")
|
||||
):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
or url.startswith((
|
||||
"about:", "blob:", "chrome:", "data:", "edge:", "file:"
|
||||
))
|
||||
)
|
||||
|
||||
|
||||
def _get_unique_links(page_url, soup):
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import ast
|
||||
import sys
|
||||
import time
|
||||
from contextlib import suppress
|
||||
from nose.plugins import Plugin
|
||||
from seleniumbase import config as sb_config
|
||||
from seleniumbase.config import settings
|
||||
|
@ -305,14 +306,12 @@ class Base(Plugin):
|
|||
if python3_11_or_newer and py311_patch2:
|
||||
# Handle a bug on Python 3.11 where exceptions aren't seen
|
||||
sb_config._browser_version = None
|
||||
try:
|
||||
with suppress(Exception):
|
||||
test._BaseCase__set_last_page_screenshot()
|
||||
test._BaseCase__set_last_page_url()
|
||||
test._BaseCase__set_last_page_source()
|
||||
sb_config._browser_version = test._get_browser_version()
|
||||
test._log_fail_data()
|
||||
except Exception:
|
||||
pass
|
||||
sb_config._excinfo_tb = err
|
||||
log_path = None
|
||||
if hasattr(sb_config, "_test_logpath"):
|
||||
|
|
|
@ -7,7 +7,7 @@ Usage --> ``with DriverContext() as driver:``
|
|||
|
||||
Example -->
|
||||
|
||||
```
|
||||
```python
|
||||
from seleniumbase import DriverContext
|
||||
|
||||
with DriverContext() as driver:
|
||||
|
@ -27,7 +27,7 @@ Usage --> ``driver = Driver()``
|
|||
|
||||
Example -->
|
||||
|
||||
```
|
||||
```python
|
||||
from seleniumbase import Driver
|
||||
|
||||
driver = Driver()
|
||||
|
@ -75,7 +75,7 @@ def Driver(
|
|||
proxy=None, # Use proxy. Format: "SERVER:PORT" or "USER:PASS@SERVER:PORT".
|
||||
proxy_bypass_list=None, # Skip proxy when using the listed domains.
|
||||
proxy_pac_url=None, # Use PAC file. (Format: URL or USERNAME:PASSWORD@URL)
|
||||
multi_proxy=False, # Allow multiple proxies with auth when multi-threaded.
|
||||
multi_proxy=None, # Allow multiple proxies with auth when multi-threaded.
|
||||
agent=None, # Modify the web browser's User-Agent string.
|
||||
cap_file=None, # The desired capabilities to use with a Selenium Grid.
|
||||
cap_string=None, # The desired capabilities to use with a Selenium Grid.
|
||||
|
@ -133,7 +133,98 @@ def Driver(
|
|||
wire=None, # Shortcut / Duplicate of "use_wire".
|
||||
pls=None, # Shortcut / Duplicate of "page_load_strategy".
|
||||
):
|
||||
"""
|
||||
* SeleniumBase Driver as a Python Context Manager or a returnable object. *
|
||||
|
||||
Example 1: (context manager format)
|
||||
-----------------------------------
|
||||
.. code-block:: python
|
||||
from seleniumbase import DriverContext
|
||||
|
||||
with DriverContext() as driver:
|
||||
driver.get("https://google.com/ncr")
|
||||
|
||||
Example 2: (as a Python returnable)
|
||||
-----------------------------------
|
||||
.. code-block:: python
|
||||
from seleniumbase import Driver
|
||||
|
||||
driver = Driver()
|
||||
driver.get("https://google.com/ncr")
|
||||
|
||||
Optional Parameters:
|
||||
--------------------
|
||||
browser: # Choose from "chrome", "edge", "firefox", or "safari".
|
||||
headless: # The original headless mode for Chromium and Firefox.
|
||||
headless2: # Chromium's new headless mode. (Has more features)
|
||||
headed: # Run tests in headed/GUI mode on Linux, where not default.
|
||||
locale_code: # Set the Language Locale Code for the web browser.
|
||||
protocol: # The Selenium Grid protocol: "http" or "https".
|
||||
servername: # The Selenium Grid server/IP used for tests.
|
||||
port: # The Selenium Grid port used by the test server.
|
||||
proxy: # Use proxy. Format: "SERVER:PORT" or "USER:PASS@SERVER:PORT".
|
||||
proxy_bypass_list: # Skip proxy when using the listed domains.
|
||||
proxy_pac_url: # Use PAC file. (Format: URL or USERNAME:PASSWORD@URL)
|
||||
multi_proxy: # Allow multiple proxies with auth when multi-threaded.
|
||||
agent: # Modify the web browser's User-Agent string.
|
||||
cap_file: # The desired capabilities to use with a Selenium Grid.
|
||||
cap_string: # The desired capabilities to use with a Selenium Grid.
|
||||
recorder_ext: # Enables the SeleniumBase Recorder Chromium extension.
|
||||
disable_js: # Disable JavaScript on websites. Pages might break!
|
||||
disable_csp: # Disable the Content Security Policy of websites.
|
||||
enable_ws: # Enable Web Security on Chromium-based browsers.
|
||||
disable_ws: # Reverse of "enable_ws". (None and False are different)
|
||||
enable_sync: # Enable "Chrome Sync" on websites.
|
||||
use_auto_ext: # Use Chrome's automation extension.
|
||||
undetectable: # Use undetected-chromedriver to evade bot-detection.
|
||||
uc_cdp_events: # Capture CDP events in undetected-chromedriver mode.
|
||||
uc_subprocess: # Use undetected-chromedriver as a subprocess.
|
||||
log_cdp_events: # Capture {"performance": "ALL", "browser": "ALL"}
|
||||
no_sandbox: # (DEPRECATED) - "--no-sandbox" is always used now.
|
||||
disable_gpu: # (DEPRECATED) - GPU is disabled if not "swiftshader".
|
||||
incognito: # Enable Chromium's Incognito mode.
|
||||
guest_mode: # Enable Chromium's Guest mode.
|
||||
dark_mode: # Enable Chromium's Dark mode.
|
||||
devtools: # Open Chromium's DevTools when the browser opens.
|
||||
remote_debug: # Enable Chrome's Debugger on "http://localhost:9222".
|
||||
enable_3d_apis: # Enable WebGL and 3D APIs.
|
||||
swiftshader: # Chrome: --use-gl=angle / --use-angle=swiftshader-webgl
|
||||
ad_block_on: # Block some types of display ads from loading.
|
||||
host_resolver_rules: # Set host-resolver-rules, comma-separated.
|
||||
block_images: # Block images from loading during tests.
|
||||
do_not_track: # Tell websites that you don't want to be tracked.
|
||||
chromium_arg: # "ARG=N,ARG2" (Set Chromium args, ","-separated.)
|
||||
firefox_arg: # "ARG=N,ARG2" (Set Firefox args, comma-separated.)
|
||||
firefox_pref: # SET (Set Firefox PREFERENCE:VALUE set, ","-separated)
|
||||
user_data_dir: # Set the Chrome user data directory to use.
|
||||
extension_zip: # Load a Chrome Extension .zip|.crx, comma-separated.
|
||||
extension_dir: # Load a Chrome Extension directory, comma-separated.
|
||||
disable_features: # "F1,F2" (Disable Chrome features, ","-separated.)
|
||||
binary_location: # Set path of the Chromium browser binary to use.
|
||||
driver_version: # Set the chromedriver or uc_driver version to use.
|
||||
page_load_strategy: # Set Chrome PLS to "normal", "eager", or "none".
|
||||
use_wire: # Use selenium-wire's webdriver over selenium webdriver.
|
||||
external_pdf: # Set Chrome "plugins.always_open_pdf_externally":True.
|
||||
window_position: # Set the browser's starting window position: "X,Y"
|
||||
window_size: # Set the browser's starting window size: "Width,Height"
|
||||
is_mobile: # Use the mobile device emulator while running tests.
|
||||
mobile: # Shortcut / Duplicate of "is_mobile".
|
||||
d_width: # Set device width
|
||||
d_height: # Set device height
|
||||
d_p_r: # Set device pixel ratio
|
||||
uc: # Shortcut / Duplicate of "undetectable".
|
||||
undetected: # Shortcut / Duplicate of "undetectable".
|
||||
uc_cdp: # Shortcut / Duplicate of "uc_cdp_events".
|
||||
uc_sub: # Shortcut / Duplicate of "uc_subprocess".
|
||||
log_cdp: # Shortcut / Duplicate of "log_cdp_events".
|
||||
ad_block: # Shortcut / Duplicate of "ad_block_on".
|
||||
server: # Shortcut / Duplicate of "servername".
|
||||
guest: # Shortcut / Duplicate of "guest_mode".
|
||||
wire: # Shortcut / Duplicate of "use_wire".
|
||||
pls: # Shortcut / Duplicate of "page_load_strategy".
|
||||
"""
|
||||
from seleniumbase import config as sb_config
|
||||
from seleniumbase.config import settings
|
||||
from seleniumbase.fixtures import constants
|
||||
from seleniumbase.fixtures import shared_utils
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import os
|
|||
import pytest
|
||||
import sys
|
||||
import time
|
||||
from contextlib import suppress
|
||||
from seleniumbase import config as sb_config
|
||||
from seleniumbase.config import settings
|
||||
from seleniumbase.core import log_helper
|
||||
|
@ -1848,10 +1849,8 @@ def _create_dashboard_assets_():
|
|||
abs_path = os.path.abspath(".")
|
||||
assets_folder = os.path.join(abs_path, "assets")
|
||||
if not os.path.exists(assets_folder):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
os.makedirs(assets_folder, exist_ok=True)
|
||||
except Exception:
|
||||
pass
|
||||
pytest_style_css = os.path.join(assets_folder, "pytest_style.css")
|
||||
add_pytest_style_css = True
|
||||
if os.path.exists(pytest_style_css):
|
||||
|
@ -1923,12 +1922,10 @@ def pytest_collection_finish(session):
|
|||
dash_path = os.path.join(os.getcwd(), "dashboard.html")
|
||||
dash_url = "file://" + dash_path.replace("\\", "/")
|
||||
star_len = len("Dashboard: ") + len(dash_url)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
terminal_size = os.get_terminal_size().columns
|
||||
if terminal_size > 30 and star_len > terminal_size:
|
||||
star_len = terminal_size
|
||||
except Exception:
|
||||
pass
|
||||
stars = "*" * star_len
|
||||
c1 = ""
|
||||
cr = ""
|
||||
|
@ -1970,11 +1967,11 @@ def pytest_runtest_teardown(item):
|
|||
(Has zero effect on tests using --reuse-session / --rs)"""
|
||||
if "--co" in sys_argv or "--collect-only" in sys_argv:
|
||||
return
|
||||
try:
|
||||
with suppress(Exception):
|
||||
if hasattr(item, "_testcase") or hasattr(sb_config, "_sb_pdb_driver"):
|
||||
if hasattr(item, "_testcase"):
|
||||
self = item._testcase
|
||||
try:
|
||||
with suppress(Exception):
|
||||
if (
|
||||
hasattr(self, "driver")
|
||||
and self.driver
|
||||
|
@ -1982,22 +1979,18 @@ def pytest_runtest_teardown(item):
|
|||
):
|
||||
if not (is_windows or self.driver.service.process):
|
||||
self.driver.quit()
|
||||
except Exception:
|
||||
pass
|
||||
elif (
|
||||
hasattr(sb_config, "_sb_pdb_driver")
|
||||
and sb_config._sb_pdb_driver
|
||||
):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
if (
|
||||
not is_windows
|
||||
or sb_config._sb_pdb_driver.service.process
|
||||
):
|
||||
sb_config._sb_pdb_driver.quit()
|
||||
sb_config._sb_pdb_driver = None
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
with suppress(Exception):
|
||||
if (
|
||||
hasattr(self, "_xvfb_display")
|
||||
and self._xvfb_display
|
||||
|
@ -2014,10 +2007,6 @@ def pytest_runtest_teardown(item):
|
|||
):
|
||||
sb_config._virtual_display.stop()
|
||||
sb_config._virtual_display = None
|
||||
except Exception:
|
||||
pass
|
||||
except Exception:
|
||||
pass
|
||||
if (
|
||||
(
|
||||
sb_config._has_exception
|
||||
|
@ -2398,7 +2387,7 @@ def pytest_runtest_makereport(item, call):
|
|||
)
|
||||
if log_path:
|
||||
sb_config._log_fail_data()
|
||||
try:
|
||||
with suppress(Exception):
|
||||
extra_report = None
|
||||
if hasattr(item, "_testcase"):
|
||||
extra_report = item._testcase._html_report_extra
|
||||
|
@ -2443,5 +2432,3 @@ def pytest_runtest_makereport(item, call):
|
|||
"</script>" % constants.Dashboard.LIVE_JS
|
||||
)
|
||||
report.extra.append(pytest_html.extras.html(refresh_updates))
|
||||
except Exception:
|
||||
pass
|
||||
|
|
|
@ -7,7 +7,7 @@ Usage --> ``with SB() as sb:``
|
|||
|
||||
Example -->
|
||||
|
||||
```
|
||||
```python
|
||||
from seleniumbase import SB
|
||||
|
||||
with SB() as sb: # Many args! Eg. SB(browser="edge")
|
||||
|
@ -41,7 +41,7 @@ def SB(
|
|||
proxy=None, # Use proxy. Format: "SERVER:PORT" or "USER:PASS@SERVER:PORT".
|
||||
proxy_bypass_list=None, # Skip proxy when using the listed domains.
|
||||
proxy_pac_url=None, # Use PAC file. (Format: URL or USERNAME:PASSWORD@URL)
|
||||
multi_proxy=False, # Allow multiple proxies with auth when multi-threaded.
|
||||
multi_proxy=None, # Allow multiple proxies with auth when multi-threaded.
|
||||
agent=None, # Modify the web browser's User-Agent string.
|
||||
cap_file=None, # The desired capabilities to use with a Selenium Grid.
|
||||
cap_string=None, # The desired capabilities to use with a Selenium Grid.
|
||||
|
@ -127,6 +127,124 @@ def SB(
|
|||
interval=None, # SECONDS (Autoplay interval for SB Slides & Tour steps.)
|
||||
time_limit=None, # SECONDS (Safely fail tests that exceed the time limit.)
|
||||
):
|
||||
"""
|
||||
* SeleniumBase as a Python Context Manager *
|
||||
|
||||
Example:
|
||||
--------
|
||||
.. code-block:: python
|
||||
from seleniumbase import SB
|
||||
|
||||
with SB() as sb: # Many args! Eg. SB(browser="edge")
|
||||
sb.open("https://google.com/ncr")
|
||||
sb.type('[name="q"]', "SeleniumBase on GitHub")
|
||||
sb.submit('[name="q"]')
|
||||
sb.click('a[href*="github.com/seleniumbase"]')
|
||||
sb.highlight("div.Layout-main")
|
||||
sb.highlight("div.Layout-sidebar")
|
||||
sb.sleep(0.5)
|
||||
|
||||
Optional Parameters:
|
||||
--------------------
|
||||
test: Test Mode: Output, Logging, Continue on failure unless "rtf".
|
||||
rtf: Shortcut / Duplicate of "raise_test_failure".
|
||||
raise_test_failure: If "test" mode, raise Exception on 1st failure.
|
||||
browser: Choose from "chrome", "edge", "firefox", or "safari".
|
||||
headless: The original headless mode for Chromium and Firefox.
|
||||
headless2: Chromium's new headless mode. (Has more features)
|
||||
locale_code: Set the Language Locale Code for the web browser.
|
||||
protocol: The Selenium Grid protocol: "http" or "https".
|
||||
servername: The Selenium Grid server/IP used for tests.
|
||||
port: The Selenium Grid port used by the test server.
|
||||
proxy: Use proxy. Format: "SERVER:PORT" or "USER:PASS@SERVER:PORT".
|
||||
proxy_bypass_list: Skip proxy when using the listed domains.
|
||||
proxy_pac_url: Use PAC file. (Format: URL or USERNAME:PASSWORD@URL)
|
||||
multi_proxy: # Allow multiple proxies with auth when multi-threaded.
|
||||
agent: Modify the web browser's User-Agent string.
|
||||
cap_file: The desired capabilities to use with a Selenium Grid.
|
||||
cap_string: The desired capabilities to use with a Selenium Grid.
|
||||
recorder_ext: Enables the SeleniumBase Recorder Chromium extension.
|
||||
disable_js: Disable JavaScript on websites. Pages might break!
|
||||
disable_csp: Disable the Content Security Policy of websites.
|
||||
enable_ws: Enable Web Security on Chromium-based browsers.
|
||||
enable_sync: Enable "Chrome Sync" on websites.
|
||||
use_auto_ext: Use Chrome's automation extension.
|
||||
undetectable: Use undetected-chromedriver to evade bot-detection.
|
||||
uc_cdp_events: Capture CDP events in undetected-chromedriver mode.
|
||||
uc_subprocess: Use undetected-chromedriver as a subprocess.
|
||||
log_cdp_events: Capture {"performance": "ALL", "browser": "ALL"}
|
||||
incognito: Enable Chromium's Incognito mode.
|
||||
guest_mode: Enable Chromium's Guest mode.
|
||||
dark_mode: Enable Chromium's Dark mode.
|
||||
devtools: Open Chromium's DevTools when the browser opens.
|
||||
remote_debug: Enable Chrome's Debugger on "http://localhost:9222".
|
||||
enable_3d_apis: Enable WebGL and 3D APIs.
|
||||
swiftshader: Chrome: --use-gl=angle / --use-angle=swiftshader-webgl
|
||||
ad_block_on: Block some types of display ads from loading.
|
||||
host_resolver_rules: Set host-resolver-rules, comma-separated.
|
||||
block_images: Block images from loading during tests.
|
||||
do_not_track: Tell websites that you don't want to be tracked.
|
||||
chromium_arg: "ARG=N,ARG2" (Set Chromium args, ","-separated.)
|
||||
firefox_arg: "ARG=N,ARG2" (Set Firefox args, comma-separated.)
|
||||
firefox_pref: SET (Set Firefox PREFERENCE:VALUE set, ","-separated)
|
||||
user_data_dir: Set the Chrome user data directory to use.
|
||||
extension_zip: Load a Chrome Extension .zip|.crx, comma-separated.
|
||||
extension_dir: Load a Chrome Extension directory, comma-separated.
|
||||
disable_features: "F1,F2" (Disable Chrome features, ","-separated.)
|
||||
binary_location: Set path of the Chromium browser binary to use.
|
||||
driver_version: Set the chromedriver or uc_driver version to use.
|
||||
skip_js_waits: Skip JS Waits (readyState=="complete" and Angular).
|
||||
wait_for_angularjs: Wait for AngularJS to load after some actions.
|
||||
use_wire: Use selenium-wire's webdriver over selenium webdriver.
|
||||
external_pdf: Set Chrome "plugins.always_open_pdf_externally":True.
|
||||
window_position: Set the browser's starting window position: "X,Y"
|
||||
window_size: Set the browser's starting window size: "Width,Height"
|
||||
is_mobile: Use the mobile device emulator while running tests.
|
||||
mobile: Shortcut / Duplicate of "is_mobile".
|
||||
device_metrics: Set mobile metrics: "CSSWidth,CSSHeight,PixelRatio"
|
||||
xvfb: Run tests using the Xvfb virtual display server on Linux OS.
|
||||
xvfb_metrics: Set Xvfb display size on Linux: "Width,Height".
|
||||
start_page: The starting URL for the web browser when tests begin.
|
||||
rec_print: If Recorder is enabled, prints output after tests end.
|
||||
rec_behave: Like Recorder Mode, but also generates behave-gherkin.
|
||||
record_sleep: If Recorder enabled, also records self.sleep calls.
|
||||
data: Extra test data. Access with "self.data" in tests.
|
||||
var1: Extra test data. Access with "self.var1" in tests.
|
||||
var2: Extra test data. Access with "self.var2" in tests.
|
||||
var3: Extra test data. Access with "self.var3" in tests.
|
||||
variables: DICT (Extra test data. Access with "self.variables")
|
||||
account: Set account. Access with "self.account" in tests.
|
||||
environment: Set the test env. Access with "self.env" in tests.
|
||||
headed: Run tests in headed/GUI mode on Linux, where not default.
|
||||
maximize: Start tests with the browser window maximized.
|
||||
disable_ws: Reverse of "enable_ws". (None and False are different)
|
||||
disable_beforeunload: Disable the "beforeunload" event on Chromium.
|
||||
settings_file: A file for overriding default SeleniumBase settings.
|
||||
uc: Shortcut / Duplicate of "undetectable".
|
||||
undetected: Shortcut / Duplicate of "undetectable".
|
||||
uc_cdp: Shortcut / Duplicate of "uc_cdp_events".
|
||||
uc_sub: Shortcut / Duplicate of "uc_subprocess".
|
||||
log_cdp: Shortcut / Duplicate of "log_cdp_events".
|
||||
ad_block: Shortcut / Duplicate of "ad_block_on".
|
||||
server: Shortcut / Duplicate of "servername".
|
||||
guest: Shortcut / Duplicate of "guest_mode".
|
||||
wire: Shortcut / Duplicate of "use_wire".
|
||||
pls: Shortcut / Duplicate of "page_load_strategy".
|
||||
sjw: Shortcut / Duplicate of "skip_js_waits".
|
||||
wfa: Shortcut / Duplicate of "wait_for_angularjs".
|
||||
save_screenshot: Save a screenshot at the end of each test.
|
||||
no_screenshot: No screenshots saved unless tests directly ask it.
|
||||
page_load_strategy: Set Chrome PLS to "normal", "eager", or "none".
|
||||
timeout_multiplier: Multiplies the default timeout values.
|
||||
js_checking_on: Check for JavaScript errors after page loads.
|
||||
slow: Slow down the automation. Faster than using Demo Mode.
|
||||
demo: Slow down and visually see test actions as they occur.
|
||||
demo_sleep: SECONDS (Set wait time after Slow & Demo Mode actions.)
|
||||
message_duration: SECONDS (The time length for Messenger alerts.)
|
||||
highlights: Number of highlight animations for Demo Mode actions.
|
||||
interval: SECONDS (Autoplay interval for SB Slides & Tour steps.)
|
||||
time_limit: SECONDS (Safely fail tests that exceed the time limit.)
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
"""Selenium Plugin for SeleniumBase tests that run with pynose / nosetests"""
|
||||
import sys
|
||||
from contextlib import suppress
|
||||
from nose.plugins import Plugin
|
||||
from seleniumbase import config as sb_config
|
||||
from seleniumbase.config import settings
|
||||
|
@ -1308,7 +1309,7 @@ class SeleniumBrowser(Plugin):
|
|||
):
|
||||
width = settings.HEADLESS_START_WIDTH
|
||||
height = settings.HEADLESS_START_HEIGHT
|
||||
try:
|
||||
with suppress(Exception):
|
||||
from sbvirtualdisplay import Display
|
||||
|
||||
self._xvfb_display = Display(visible=0, size=(width, height))
|
||||
|
@ -1316,8 +1317,6 @@ class SeleniumBrowser(Plugin):
|
|||
sb_config._virtual_display = self._xvfb_display
|
||||
self.headless_active = True
|
||||
sb_config.headless_active = True
|
||||
except Exception:
|
||||
pass
|
||||
sb_config._is_timeout_changed = False
|
||||
sb_config._SMALL_TIMEOUT = settings.SMALL_TIMEOUT
|
||||
sb_config._LARGE_TIMEOUT = settings.LARGE_TIMEOUT
|
||||
|
@ -1350,7 +1349,7 @@ class SeleniumBrowser(Plugin):
|
|||
pass
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
with suppress(Exception):
|
||||
if (
|
||||
hasattr(self, "_xvfb_display")
|
||||
and self._xvfb_display
|
||||
|
@ -1367,5 +1366,3 @@ class SeleniumBrowser(Plugin):
|
|||
):
|
||||
sb_config._virtual_display.stop()
|
||||
sb_config._virtual_display = None
|
||||
except Exception:
|
||||
pass
|
||||
|
|
|
@ -10,6 +10,7 @@ import selenium.webdriver.chrome.service
|
|||
import selenium.webdriver.chrome.webdriver
|
||||
import selenium.webdriver.common.service
|
||||
import selenium.webdriver.remote.command
|
||||
from contextlib import suppress
|
||||
from .cdp import CDP
|
||||
from .cdp import PageElement
|
||||
from .dprocess import start_detached
|
||||
|
@ -201,11 +202,9 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
|||
# Create a temporary folder for the user-data profile.
|
||||
options.add_argument(arg)
|
||||
if not language:
|
||||
try:
|
||||
with suppress(Exception):
|
||||
import locale
|
||||
language = locale.getlocale()[0].replace("_", "-")
|
||||
except Exception:
|
||||
pass
|
||||
if (
|
||||
not language
|
||||
or "English" in language
|
||||
|
@ -242,7 +241,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
|||
)
|
||||
if hasattr(options, 'handle_prefs'):
|
||||
options.handle_prefs(user_data_dir)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
import json
|
||||
with open(
|
||||
os.path.join(
|
||||
|
@ -263,8 +262,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
|||
fs.seek(0, 0)
|
||||
fs.truncate()
|
||||
json.dump(config, fs)
|
||||
except Exception:
|
||||
pass
|
||||
creationflags = 0
|
||||
if "win32" in sys.platform:
|
||||
creationflags = subprocess.CREATE_NO_WINDOW
|
||||
|
@ -293,8 +290,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
|||
self.browser_pid = browser.pid
|
||||
service_ = None
|
||||
log_output = subprocess.PIPE
|
||||
if sys.version_info < (3, 8):
|
||||
log_output = os.devnull
|
||||
if patch_driver:
|
||||
service_ = selenium.webdriver.chrome.service.Service(
|
||||
executable_path=self.patcher.executable_path,
|
||||
|
@ -342,7 +337,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
|||
|
||||
def _get_cdc_props(self):
|
||||
cdc_props = []
|
||||
try:
|
||||
with suppress(Exception):
|
||||
cdc_props = self.execute_script(
|
||||
"""
|
||||
let objectToInspect = window,
|
||||
|
@ -355,8 +350,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
|||
return result.filter(i => i.match(/^[a-z]{3}_[a-z]{22}_.*/i))
|
||||
"""
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
return cdc_props
|
||||
|
||||
def _hook_remove_cdc_props(self, cdc_props):
|
||||
|
@ -427,50 +420,38 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
|||
- Starts the chromedriver service that runs in the background.
|
||||
- Recreates the session."""
|
||||
if hasattr(self, "service"):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
self.service.stop()
|
||||
except Exception:
|
||||
pass
|
||||
if isinstance(timeout, str):
|
||||
if timeout.lower() == "breakpoint":
|
||||
breakpoint() # To continue:
|
||||
pass # Type "c" & press ENTER!
|
||||
else:
|
||||
time.sleep(timeout)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
self.service.start()
|
||||
except Exception:
|
||||
pass
|
||||
time.sleep(0.012)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
self.start_session()
|
||||
except Exception:
|
||||
pass
|
||||
time.sleep(0.012)
|
||||
|
||||
def disconnect(self):
|
||||
"""Stops the chromedriver service that runs in the background.
|
||||
To use driver methods again, you MUST call driver.connect()"""
|
||||
if hasattr(self, "service"):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
self.service.stop()
|
||||
except Exception:
|
||||
pass
|
||||
time.sleep(0.012)
|
||||
|
||||
def connect(self):
|
||||
"""Starts the chromedriver service that runs in the background
|
||||
and recreates the session."""
|
||||
if hasattr(self, "service"):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
self.service.start()
|
||||
except Exception:
|
||||
pass
|
||||
time.sleep(0.012)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
self.start_session()
|
||||
except Exception:
|
||||
pass
|
||||
time.sleep(0.012)
|
||||
|
||||
def start_session(self, capabilities=None):
|
||||
|
@ -496,12 +477,10 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
|||
if hasattr(self, "service") and getattr(self.service, "process", None):
|
||||
logger.debug("Stopping webdriver service")
|
||||
self.service.stop()
|
||||
try:
|
||||
with suppress(Exception):
|
||||
if self.reactor and isinstance(self.reactor, Reactor):
|
||||
logger.debug("Shutting down Reactor")
|
||||
self.reactor.event.set()
|
||||
except Exception:
|
||||
pass
|
||||
if (
|
||||
hasattr(self, "keep_user_data_dir")
|
||||
and hasattr(self, "user_data_dir")
|
||||
|
@ -530,18 +509,14 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
|||
self.patcher = None
|
||||
|
||||
def __del__(self):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
if "win32" in sys.platform:
|
||||
self.stop_client()
|
||||
self.command_executor.close()
|
||||
else:
|
||||
super().quit()
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
with suppress(Exception):
|
||||
self.quit()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
|
|
@ -3,7 +3,10 @@ import os
|
|||
import sys
|
||||
import atexit
|
||||
import logging
|
||||
import platform
|
||||
from contextlib import suppress
|
||||
from subprocess import PIPE
|
||||
from subprocess import Popen
|
||||
|
||||
CREATE_NEW_PROCESS_GROUP = 0x00000200
|
||||
DETACHED_PROCESS = 0x00000008
|
||||
|
@ -37,9 +40,6 @@ def start_detached(executable, *args):
|
|||
def _start_detached(executable, *args, writer=None):
|
||||
# Configure Launch
|
||||
kwargs = {}
|
||||
import platform
|
||||
from subprocess import Popen
|
||||
|
||||
if platform.system() == "Windows":
|
||||
kwargs.update(
|
||||
creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP
|
||||
|
@ -58,11 +58,9 @@ def _cleanup():
|
|||
import signal
|
||||
|
||||
for pid in REGISTERED:
|
||||
try:
|
||||
with suppress(Exception):
|
||||
logging.getLogger(__name__).debug("cleaning up pid %d " % pid)
|
||||
os.kill(pid, signal.SIGTERM)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
atexit.register(_cleanup)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
import json
|
||||
import os
|
||||
from contextlib import suppress
|
||||
from selenium.webdriver.chromium.options import ChromiumOptions
|
||||
|
||||
|
||||
|
@ -49,7 +50,7 @@ class ChromeOptions(ChromiumOptions):
|
|||
undot_prefs, self._undot_key(key, value)
|
||||
)
|
||||
prefs_file = os.path.join(default_path, "Preferences")
|
||||
try:
|
||||
with suppress(Exception):
|
||||
if os.path.exists(prefs_file):
|
||||
with open(
|
||||
prefs_file, encoding="utf-8", mode="r", errors="ignore"
|
||||
|
@ -57,13 +58,9 @@ class ChromeOptions(ChromiumOptions):
|
|||
undot_prefs = self._merge_nested(
|
||||
json.load(f), undot_prefs
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
with suppress(Exception):
|
||||
with open(prefs_file, encoding="utf-8", mode="w") as f:
|
||||
json.dump(undot_prefs, f)
|
||||
except Exception:
|
||||
pass
|
||||
# Remove experimental_options to avoid errors
|
||||
del self._experimental_options["prefs"]
|
||||
exclude_switches = self.experimental_options.get("excludeSwitches")
|
||||
|
|
|
@ -8,6 +8,7 @@ import string
|
|||
import sys
|
||||
import time
|
||||
import zipfile
|
||||
from contextlib import suppress
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
IS_POSIX = sys.platform.startswith(("darwin", "cygwin", "linux"))
|
||||
|
@ -53,10 +54,8 @@ class Patcher(object):
|
|||
self.executable_path = None
|
||||
prefix = "undetected"
|
||||
if not os.path.exists(self.data_path):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
os.makedirs(self.data_path, exist_ok=True)
|
||||
except Exception:
|
||||
pass
|
||||
if not executable_path:
|
||||
self.executable_path = os.path.join(
|
||||
self.data_path, "_".join([prefix, self.exe_name])
|
||||
|
|
9
setup.py
9
setup.py
|
@ -1,5 +1,5 @@
|
|||
"""Setup steps for installing SeleniumBase dependencies and plugins.
|
||||
(Uses selenium 4.x and is compatible with Python 3.7+)"""
|
||||
(Uses selenium 4.x and is compatible with Python 3.8+)"""
|
||||
from setuptools import setup, find_packages # noqa: F401
|
||||
import os
|
||||
import sys
|
||||
|
@ -47,7 +47,7 @@ if sys.argv[-1] == "publish":
|
|||
print("\n*** Installing build: *** (Required for PyPI uploads)\n")
|
||||
os.system("python -m pip install --upgrade 'build'")
|
||||
print("\n*** Installing pkginfo: *** (Required for PyPI uploads)\n")
|
||||
os.system("python -m pip install --upgrade 'pkginfo'")
|
||||
os.system("python -m pip install 'pkginfo'")
|
||||
print("\n*** Installing readme-renderer: *** (For PyPI uploads)\n")
|
||||
os.system("python -m pip install --upgrade 'readme-renderer'")
|
||||
print("\n*** Installing jaraco.classes: *** (For PyPI uploads)\n")
|
||||
|
@ -79,12 +79,14 @@ setup(
|
|||
long_description_content_type="text/markdown",
|
||||
url="https://github.com/seleniumbase/SeleniumBase",
|
||||
project_urls={
|
||||
"Homepage": "https://github.com/seleniumbase/SeleniumBase",
|
||||
"Changelog": "https://github.com/seleniumbase/SeleniumBase/releases",
|
||||
"Download": "https://pypi.org/project/seleniumbase/#files",
|
||||
"Gitter": "https://gitter.im/seleniumbase/SeleniumBase",
|
||||
"Blog": "https://seleniumbase.com/",
|
||||
"Discord": "https://discord.gg/EdhQTn3EyE",
|
||||
"PyPI": "https://pypi.org/project/seleniumbase/",
|
||||
"Source": "https://github.com/seleniumbase/SeleniumBase",
|
||||
"Repository": "https://github.com/seleniumbase/SeleniumBase",
|
||||
"Documentation": "https://seleniumbase.io/",
|
||||
},
|
||||
platforms=["Windows", "Linux", "Mac OS-X"],
|
||||
|
@ -120,7 +122,6 @@ setup(
|
|||
"Operating System :: POSIX :: Linux",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
|
|
Loading…
Reference in New Issue