seleniumbase 4.33.4__py3-none-any.whl → 4.34.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- seleniumbase/__version__.py +1 -1
- seleniumbase/behave/behave_sb.py +10 -2
- seleniumbase/console_scripts/run.py +6 -2
- seleniumbase/console_scripts/sb_commander.py +5 -5
- seleniumbase/console_scripts/sb_install.py +235 -6
- seleniumbase/console_scripts/sb_mkdir.py +1 -0
- seleniumbase/core/browser_launcher.py +358 -105
- seleniumbase/core/log_helper.py +33 -12
- seleniumbase/core/proxy_helper.py +35 -30
- seleniumbase/core/sb_cdp.py +277 -74
- seleniumbase/core/settings_parser.py +2 -0
- seleniumbase/core/style_sheet.py +10 -0
- seleniumbase/fixtures/base_case.py +216 -127
- seleniumbase/fixtures/constants.py +3 -0
- seleniumbase/fixtures/js_utils.py +2 -0
- seleniumbase/fixtures/page_actions.py +7 -2
- seleniumbase/fixtures/shared_utils.py +25 -0
- seleniumbase/plugins/driver_manager.py +28 -0
- seleniumbase/plugins/pytest_plugin.py +110 -0
- seleniumbase/plugins/sb_manager.py +41 -0
- seleniumbase/plugins/selenium_plugin.py +9 -0
- seleniumbase/undetected/cdp_driver/_contradict.py +3 -3
- seleniumbase/undetected/cdp_driver/browser.py +8 -6
- seleniumbase/undetected/cdp_driver/cdp_util.py +3 -0
- seleniumbase/undetected/cdp_driver/config.py +0 -1
- seleniumbase/undetected/cdp_driver/element.py +22 -20
- seleniumbase/undetected/patcher.py +20 -5
- {seleniumbase-4.33.4.dist-info → seleniumbase-4.34.2.dist-info}/LICENSE +1 -1
- {seleniumbase-4.33.4.dist-info → seleniumbase-4.34.2.dist-info}/METADATA +111 -86
- {seleniumbase-4.33.4.dist-info → seleniumbase-4.34.2.dist-info}/RECORD +33 -33
- {seleniumbase-4.33.4.dist-info → seleniumbase-4.34.2.dist-info}/WHEEL +1 -1
- {seleniumbase-4.33.4.dist-info → seleniumbase-4.34.2.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.33.4.dist-info → seleniumbase-4.34.2.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,7 @@
|
|
1
1
|
import fasteners
|
2
2
|
import logging
|
3
3
|
import os
|
4
|
+
import platform
|
4
5
|
import re
|
5
6
|
import shutil
|
6
7
|
import subprocess
|
@@ -64,6 +65,7 @@ LOCAL_EDGEDRIVER = None
|
|
64
65
|
LOCAL_IEDRIVER = None
|
65
66
|
LOCAL_HEADLESS_IEDRIVER = None
|
66
67
|
LOCAL_UC_DRIVER = None
|
68
|
+
ARCH = platform.architecture()[0]
|
67
69
|
IS_ARM_MAC = shared_utils.is_arm_mac()
|
68
70
|
IS_MAC = shared_utils.is_mac()
|
69
71
|
IS_LINUX = shared_utils.is_linux()
|
@@ -97,26 +99,12 @@ def log_d(message):
|
|
97
99
|
print(message)
|
98
100
|
|
99
101
|
|
100
|
-
def make_writable(file_path):
|
101
|
-
# Set permissions to: "If you can read it, you can write it."
|
102
|
-
mode = os.stat(file_path).st_mode
|
103
|
-
mode |= (mode & 0o444) >> 1 # copy R bits to W
|
104
|
-
os.chmod(file_path, mode)
|
105
|
-
|
106
|
-
|
107
|
-
def make_executable(file_path):
|
108
|
-
# Set permissions to: "If you can read it, you can execute it."
|
109
|
-
mode = os.stat(file_path).st_mode
|
110
|
-
mode |= (mode & 0o444) >> 2 # copy R bits to X
|
111
|
-
os.chmod(file_path, mode)
|
112
|
-
|
113
|
-
|
114
102
|
def make_driver_executable_if_not(driver_path):
|
115
103
|
# Verify driver has executable permissions. If not, add them.
|
116
104
|
permissions = oct(os.stat(driver_path)[0])[-3:]
|
117
105
|
if "4" in permissions or "6" in permissions:
|
118
106
|
# We want at least a '5' or '7' to make sure it's executable
|
119
|
-
make_executable(driver_path)
|
107
|
+
shared_utils.make_executable(driver_path)
|
120
108
|
|
121
109
|
|
122
110
|
def extend_driver(driver):
|
@@ -547,10 +535,26 @@ def uc_open_with_cdp_mode(driver, url=None):
|
|
547
535
|
if url_protocol not in ["about", "data", "chrome"]:
|
548
536
|
safe_url = False
|
549
537
|
|
538
|
+
headless = False
|
539
|
+
headed = None
|
540
|
+
xvfb = None
|
541
|
+
if hasattr(sb_config, "headless"):
|
542
|
+
headless = sb_config.headless
|
543
|
+
if hasattr(sb_config, "headed"):
|
544
|
+
headed = sb_config.headed
|
545
|
+
if hasattr(sb_config, "xvfb"):
|
546
|
+
xvfb = sb_config.xvfb
|
547
|
+
|
550
548
|
loop = asyncio.new_event_loop()
|
551
549
|
asyncio.set_event_loop(loop)
|
552
550
|
driver.cdp_base = loop.run_until_complete(
|
553
|
-
cdp_util.start(
|
551
|
+
cdp_util.start(
|
552
|
+
host=cdp_host,
|
553
|
+
port=cdp_port,
|
554
|
+
headless=headless,
|
555
|
+
headed=headed,
|
556
|
+
xvfb=xvfb,
|
557
|
+
)
|
554
558
|
)
|
555
559
|
loop.run_until_complete(driver.cdp_base.wait(0))
|
556
560
|
|
@@ -566,6 +570,10 @@ def uc_open_with_cdp_mode(driver, url=None):
|
|
566
570
|
for tab in driver.cdp_base.tabs[-1::-1]:
|
567
571
|
if "chrome-extension://" not in str(tab):
|
568
572
|
with gui_lock:
|
573
|
+
with suppress(Exception):
|
574
|
+
shared_utils.make_writable(
|
575
|
+
constants.MultiBrowser.PYAUTOGUILOCK
|
576
|
+
)
|
569
577
|
loop.run_until_complete(tab.activate())
|
570
578
|
break
|
571
579
|
|
@@ -580,11 +588,17 @@ def uc_open_with_cdp_mode(driver, url=None):
|
|
580
588
|
if page_tab:
|
581
589
|
loop.run_until_complete(page_tab.aopen())
|
582
590
|
with gui_lock:
|
591
|
+
with suppress(Exception):
|
592
|
+
shared_utils.make_writable(
|
593
|
+
constants.MultiBrowser.PYAUTOGUILOCK
|
594
|
+
)
|
583
595
|
loop.run_until_complete(page_tab.activate())
|
584
596
|
|
585
597
|
loop.run_until_complete(driver.cdp_base.update_targets())
|
586
598
|
page = loop.run_until_complete(driver.cdp_base.get(url))
|
587
599
|
with gui_lock:
|
600
|
+
with suppress(Exception):
|
601
|
+
shared_utils.make_writable(constants.MultiBrowser.PYAUTOGUILOCK)
|
588
602
|
loop.run_until_complete(page.activate())
|
589
603
|
loop.run_until_complete(page.wait())
|
590
604
|
if not safe_url:
|
@@ -604,6 +618,7 @@ def uc_open_with_cdp_mode(driver, url=None):
|
|
604
618
|
cdp.find_element = CDPM.find_element
|
605
619
|
cdp.find = CDPM.find_element
|
606
620
|
cdp.locator = CDPM.find_element
|
621
|
+
cdp.find_element_by_text = CDPM.find_element_by_text
|
607
622
|
cdp.find_all = CDPM.find_all
|
608
623
|
cdp.find_elements_by_text = CDPM.find_elements_by_text
|
609
624
|
cdp.select = CDPM.select
|
@@ -662,6 +677,7 @@ def uc_open_with_cdp_mode(driver, url=None):
|
|
662
677
|
cdp.get_window = CDPM.get_window
|
663
678
|
cdp.get_element_attributes = CDPM.get_element_attributes
|
664
679
|
cdp.get_element_attribute = CDPM.get_element_attribute
|
680
|
+
cdp.get_attribute = CDPM.get_attribute
|
665
681
|
cdp.get_element_html = CDPM.get_element_html
|
666
682
|
cdp.get_element_rect = CDPM.get_element_rect
|
667
683
|
cdp.get_element_size = CDPM.get_element_size
|
@@ -817,6 +833,72 @@ def verify_pyautogui_has_a_headed_browser(driver):
|
|
817
833
|
)
|
818
834
|
|
819
835
|
|
836
|
+
def __install_pyautogui_if_missing():
|
837
|
+
try:
|
838
|
+
import pyautogui
|
839
|
+
with suppress(Exception):
|
840
|
+
use_pyautogui_ver = constants.PyAutoGUI.VER
|
841
|
+
if pyautogui.__version__ != use_pyautogui_ver:
|
842
|
+
del pyautogui
|
843
|
+
shared_utils.pip_install(
|
844
|
+
"pyautogui", version=use_pyautogui_ver
|
845
|
+
)
|
846
|
+
import pyautogui
|
847
|
+
except Exception:
|
848
|
+
print("\nPyAutoGUI required! Installing now...")
|
849
|
+
shared_utils.pip_install(
|
850
|
+
"pyautogui", version=constants.PyAutoGUI.VER
|
851
|
+
)
|
852
|
+
try:
|
853
|
+
import pyautogui
|
854
|
+
except Exception:
|
855
|
+
if (
|
856
|
+
IS_LINUX
|
857
|
+
and hasattr(sb_config, "xvfb")
|
858
|
+
and hasattr(sb_config, "headed")
|
859
|
+
and hasattr(sb_config, "headless")
|
860
|
+
and hasattr(sb_config, "headless2")
|
861
|
+
and (not sb_config.headed or sb_config.xvfb)
|
862
|
+
and not (sb_config.headless or sb_config.headless2)
|
863
|
+
):
|
864
|
+
from sbvirtualdisplay import Display
|
865
|
+
xvfb_width = 1366
|
866
|
+
xvfb_height = 768
|
867
|
+
if (
|
868
|
+
hasattr(sb_config, "_xvfb_width")
|
869
|
+
and sb_config._xvfb_width
|
870
|
+
and isinstance(sb_config._xvfb_width, int)
|
871
|
+
and hasattr(sb_config, "_xvfb_height")
|
872
|
+
and sb_config._xvfb_height
|
873
|
+
and isinstance(sb_config._xvfb_height, int)
|
874
|
+
):
|
875
|
+
xvfb_width = sb_config._xvfb_width
|
876
|
+
xvfb_height = sb_config._xvfb_height
|
877
|
+
if xvfb_width < 1024:
|
878
|
+
xvfb_width = 1024
|
879
|
+
sb_config._xvfb_width = xvfb_width
|
880
|
+
if xvfb_height < 768:
|
881
|
+
xvfb_height = 768
|
882
|
+
sb_config._xvfb_height = xvfb_height
|
883
|
+
with suppress(Exception):
|
884
|
+
_xvfb_display = Display(
|
885
|
+
visible=True,
|
886
|
+
size=(xvfb_width, xvfb_height),
|
887
|
+
backend="xvfb",
|
888
|
+
use_xauth=True,
|
889
|
+
)
|
890
|
+
_xvfb_display.start()
|
891
|
+
sb_config._virtual_display = _xvfb_display
|
892
|
+
sb_config.headless_active = True
|
893
|
+
if (
|
894
|
+
hasattr(sb_config, "reuse_session")
|
895
|
+
and sb_config.reuse_session
|
896
|
+
and hasattr(sb_config, "_vd_list")
|
897
|
+
and isinstance(sb_config._vd_list, list)
|
898
|
+
):
|
899
|
+
sb_config._vd_list.append(_xvfb_display)
|
900
|
+
|
901
|
+
|
820
902
|
def install_pyautogui_if_missing(driver):
|
821
903
|
verify_pyautogui_has_a_headed_browser(driver)
|
822
904
|
pip_find_lock = fasteners.InterProcessLock(
|
@@ -826,64 +908,13 @@ def install_pyautogui_if_missing(driver):
|
|
826
908
|
with pip_find_lock:
|
827
909
|
pass
|
828
910
|
except Exception:
|
829
|
-
#
|
830
|
-
|
831
|
-
|
911
|
+
# Since missing permissions, skip the locks
|
912
|
+
__install_pyautogui_if_missing()
|
913
|
+
return
|
832
914
|
with pip_find_lock: # Prevent issues with multiple processes
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
use_pyautogui_ver = constants.PyAutoGUI.VER
|
837
|
-
if pyautogui.__version__ != use_pyautogui_ver:
|
838
|
-
del pyautogui
|
839
|
-
shared_utils.pip_install(
|
840
|
-
"pyautogui", version=use_pyautogui_ver
|
841
|
-
)
|
842
|
-
import pyautogui
|
843
|
-
except Exception:
|
844
|
-
print("\nPyAutoGUI required! Installing now...")
|
845
|
-
shared_utils.pip_install(
|
846
|
-
"pyautogui", version=constants.PyAutoGUI.VER
|
847
|
-
)
|
848
|
-
try:
|
849
|
-
import pyautogui
|
850
|
-
except Exception:
|
851
|
-
if (
|
852
|
-
IS_LINUX
|
853
|
-
and hasattr(sb_config, "xvfb")
|
854
|
-
and hasattr(sb_config, "headed")
|
855
|
-
and hasattr(sb_config, "headless")
|
856
|
-
and hasattr(sb_config, "headless2")
|
857
|
-
and (not sb_config.headed or sb_config.xvfb)
|
858
|
-
and not (sb_config.headless or sb_config.headless2)
|
859
|
-
):
|
860
|
-
from sbvirtualdisplay import Display
|
861
|
-
xvfb_width = 1366
|
862
|
-
xvfb_height = 768
|
863
|
-
if (
|
864
|
-
hasattr(sb_config, "_xvfb_width")
|
865
|
-
and sb_config._xvfb_width
|
866
|
-
and isinstance(sb_config._xvfb_width, int)
|
867
|
-
and hasattr(sb_config, "_xvfb_height")
|
868
|
-
and sb_config._xvfb_height
|
869
|
-
and isinstance(sb_config._xvfb_height, int)
|
870
|
-
):
|
871
|
-
xvfb_width = sb_config._xvfb_width
|
872
|
-
xvfb_height = sb_config._xvfb_height
|
873
|
-
if xvfb_width < 1024:
|
874
|
-
xvfb_width = 1024
|
875
|
-
sb_config._xvfb_width = xvfb_width
|
876
|
-
if xvfb_height < 768:
|
877
|
-
xvfb_height = 768
|
878
|
-
sb_config._xvfb_height = xvfb_height
|
879
|
-
with suppress(Exception):
|
880
|
-
xvfb_display = Display(
|
881
|
-
visible=True,
|
882
|
-
size=(xvfb_width, xvfb_height),
|
883
|
-
backend="xvfb",
|
884
|
-
use_xauth=True,
|
885
|
-
)
|
886
|
-
xvfb_display.start()
|
915
|
+
with suppress(Exception):
|
916
|
+
shared_utils.make_writable(constants.PipInstall.FINDLOCK)
|
917
|
+
__install_pyautogui_if_missing()
|
887
918
|
|
888
919
|
|
889
920
|
def get_configured_pyautogui(pyautogui_copy):
|
@@ -1195,6 +1226,13 @@ def _uc_gui_click_captcha(
|
|
1195
1226
|
and driver.is_element_present("#challenge-form div > div")
|
1196
1227
|
):
|
1197
1228
|
frame = "#challenge-form div > div"
|
1229
|
+
elif (
|
1230
|
+
driver.is_element_present('[name*="cf-turnstile-"]')
|
1231
|
+
and driver.is_element_present(
|
1232
|
+
'[style="display: grid;"] div div'
|
1233
|
+
)
|
1234
|
+
):
|
1235
|
+
frame = '[style="display: grid;"] div div'
|
1198
1236
|
elif (
|
1199
1237
|
driver.is_element_present('[name*="cf-turnstile-"]')
|
1200
1238
|
and driver.is_element_present("[class*=spacer] + div div")
|
@@ -1411,7 +1449,7 @@ def _uc_gui_handle_captcha_(driver, frame="iframe", ctype=None):
|
|
1411
1449
|
ctype = "cf_t"
|
1412
1450
|
else:
|
1413
1451
|
return
|
1414
|
-
if not driver.is_connected():
|
1452
|
+
if not driver.is_connected() and not __is_cdp_swap_needed(driver):
|
1415
1453
|
driver.connect()
|
1416
1454
|
time.sleep(2)
|
1417
1455
|
install_pyautogui_if_missing(driver)
|
@@ -1423,7 +1461,10 @@ def _uc_gui_handle_captcha_(driver, frame="iframe", ctype=None):
|
|
1423
1461
|
)
|
1424
1462
|
with gui_lock: # Prevent issues with multiple processes
|
1425
1463
|
needs_switch = False
|
1426
|
-
|
1464
|
+
if not __is_cdp_swap_needed(driver):
|
1465
|
+
is_in_frame = js_utils.is_in_frame(driver)
|
1466
|
+
else:
|
1467
|
+
is_in_frame = False
|
1427
1468
|
selector = "#challenge-stage"
|
1428
1469
|
if ctype == "g_rc":
|
1429
1470
|
selector = "#recaptcha-token"
|
@@ -1431,7 +1472,7 @@ def _uc_gui_handle_captcha_(driver, frame="iframe", ctype=None):
|
|
1431
1472
|
driver.switch_to.parent_frame()
|
1432
1473
|
needs_switch = True
|
1433
1474
|
is_in_frame = js_utils.is_in_frame(driver)
|
1434
|
-
if not is_in_frame:
|
1475
|
+
if not is_in_frame and not __is_cdp_swap_needed(driver):
|
1435
1476
|
# Make sure the window is on top
|
1436
1477
|
page_actions.switch_to_window(
|
1437
1478
|
driver, driver.current_window_handle, 2, uc_lock=False
|
@@ -1498,17 +1539,18 @@ def _uc_gui_handle_captcha_(driver, frame="iframe", ctype=None):
|
|
1498
1539
|
and frame == "iframe"
|
1499
1540
|
):
|
1500
1541
|
frame = 'iframe[title="reCAPTCHA"]'
|
1501
|
-
if not
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
if
|
1509
|
-
driver.
|
1510
|
-
|
1511
|
-
|
1542
|
+
if not __is_cdp_swap_needed(driver):
|
1543
|
+
if not is_in_frame or needs_switch:
|
1544
|
+
# Currently not in frame (or nested frame outside CF one)
|
1545
|
+
try:
|
1546
|
+
if visible_iframe or ctype == "g_rc":
|
1547
|
+
driver.switch_to_frame(frame)
|
1548
|
+
except Exception:
|
1549
|
+
if visible_iframe or ctype == "g_rc":
|
1550
|
+
if driver.is_element_present("iframe"):
|
1551
|
+
driver.switch_to_frame("iframe")
|
1552
|
+
else:
|
1553
|
+
return
|
1512
1554
|
try:
|
1513
1555
|
selector = "div.cf-turnstile"
|
1514
1556
|
if ctype == "g_rc":
|
@@ -1518,17 +1560,20 @@ def _uc_gui_handle_captcha_(driver, frame="iframe", ctype=None):
|
|
1518
1560
|
for i in range(10):
|
1519
1561
|
pyautogui.hotkey("shift", "tab")
|
1520
1562
|
time.sleep(0.027)
|
1563
|
+
if ctype == "g_rc":
|
1564
|
+
if js_utils.get_active_element_css(driver) == "body":
|
1565
|
+
break
|
1521
1566
|
tab_count = 0
|
1522
1567
|
for i in range(34):
|
1523
1568
|
pyautogui.press("\t")
|
1524
1569
|
tab_count += 1
|
1525
1570
|
time.sleep(0.027)
|
1526
1571
|
active_element_css = js_utils.get_active_element_css(driver)
|
1527
|
-
print(active_element_css)
|
1528
1572
|
if (
|
1529
1573
|
active_element_css.startswith(selector)
|
1530
1574
|
or active_element_css.endswith(" > div" * 2)
|
1531
1575
|
or (special_form and active_element_css.endswith(" div"))
|
1576
|
+
or (ctype == "g_rc" and "frame[name" in active_element_css)
|
1532
1577
|
):
|
1533
1578
|
found_checkbox = True
|
1534
1579
|
sb_config._saved_cf_tab_count = tab_count
|
@@ -1548,6 +1593,7 @@ def _uc_gui_handle_captcha_(driver, frame="iframe", ctype=None):
|
|
1548
1593
|
)
|
1549
1594
|
and hasattr(sb_config, "_saved_cf_tab_count")
|
1550
1595
|
and sb_config._saved_cf_tab_count
|
1596
|
+
and not __is_cdp_swap_needed(driver)
|
1551
1597
|
):
|
1552
1598
|
driver.uc_open_with_disconnect(driver.current_url, 3.8)
|
1553
1599
|
with suppress(Exception):
|
@@ -1762,22 +1808,34 @@ def _add_chrome_proxy_extension(
|
|
1762
1808
|
):
|
1763
1809
|
# Single-threaded
|
1764
1810
|
if zip_it:
|
1765
|
-
|
1766
|
-
|
1767
|
-
|
1768
|
-
|
1769
|
-
|
1811
|
+
proxy_zip_lock = fasteners.InterProcessLock(PROXY_ZIP_LOCK)
|
1812
|
+
with proxy_zip_lock:
|
1813
|
+
proxy_helper.create_proxy_ext(
|
1814
|
+
proxy_string, proxy_user, proxy_pass, bypass_list
|
1815
|
+
)
|
1816
|
+
proxy_zip = proxy_helper.PROXY_ZIP_PATH
|
1817
|
+
chrome_options.add_extension(proxy_zip)
|
1770
1818
|
else:
|
1771
|
-
|
1772
|
-
|
1773
|
-
|
1774
|
-
|
1775
|
-
|
1819
|
+
proxy_dir_lock = fasteners.InterProcessLock(PROXY_DIR_LOCK)
|
1820
|
+
with proxy_dir_lock:
|
1821
|
+
proxy_helper.create_proxy_ext(
|
1822
|
+
proxy_string,
|
1823
|
+
proxy_user,
|
1824
|
+
proxy_pass,
|
1825
|
+
bypass_list,
|
1826
|
+
zip_it=False,
|
1827
|
+
)
|
1828
|
+
proxy_dir_path = proxy_helper.PROXY_DIR_PATH
|
1829
|
+
chrome_options = add_chrome_ext_dir(
|
1830
|
+
chrome_options, proxy_dir_path
|
1831
|
+
)
|
1776
1832
|
else:
|
1777
1833
|
# Multi-threaded
|
1778
1834
|
if zip_it:
|
1779
1835
|
proxy_zip_lock = fasteners.InterProcessLock(PROXY_ZIP_LOCK)
|
1780
1836
|
with proxy_zip_lock:
|
1837
|
+
with suppress(Exception):
|
1838
|
+
shared_utils.make_writable(PROXY_ZIP_LOCK)
|
1781
1839
|
if multi_proxy:
|
1782
1840
|
_set_proxy_filenames()
|
1783
1841
|
if not os.path.exists(proxy_helper.PROXY_ZIP_PATH):
|
@@ -1789,6 +1847,8 @@ def _add_chrome_proxy_extension(
|
|
1789
1847
|
else:
|
1790
1848
|
proxy_dir_lock = fasteners.InterProcessLock(PROXY_DIR_LOCK)
|
1791
1849
|
with proxy_dir_lock:
|
1850
|
+
with suppress(Exception):
|
1851
|
+
shared_utils.make_writable(PROXY_DIR_LOCK)
|
1792
1852
|
if multi_proxy:
|
1793
1853
|
_set_proxy_filenames()
|
1794
1854
|
if not os.path.exists(proxy_helper.PROXY_DIR_PATH):
|
@@ -1797,7 +1857,7 @@ def _add_chrome_proxy_extension(
|
|
1797
1857
|
proxy_user,
|
1798
1858
|
proxy_pass,
|
1799
1859
|
bypass_list,
|
1800
|
-
False,
|
1860
|
+
zip_it=False,
|
1801
1861
|
)
|
1802
1862
|
chrome_options = add_chrome_ext_dir(
|
1803
1863
|
chrome_options, proxy_helper.PROXY_DIR_PATH
|
@@ -1814,6 +1874,8 @@ def is_using_uc(undetectable, browser_name):
|
|
1814
1874
|
def _unzip_to_new_folder(zip_file, folder):
|
1815
1875
|
proxy_dir_lock = fasteners.InterProcessLock(PROXY_DIR_LOCK)
|
1816
1876
|
with proxy_dir_lock:
|
1877
|
+
with suppress(Exception):
|
1878
|
+
shared_utils.make_writable(PROXY_DIR_LOCK)
|
1817
1879
|
if not os.path.exists(folder):
|
1818
1880
|
import zipfile
|
1819
1881
|
zip_ref = zipfile.ZipFile(zip_file, "r")
|
@@ -2298,7 +2360,6 @@ def _set_chrome_options(
|
|
2298
2360
|
chrome_options.add_argument("--disable-ipc-flooding-protection")
|
2299
2361
|
chrome_options.add_argument("--disable-password-generation")
|
2300
2362
|
chrome_options.add_argument("--disable-domain-reliability")
|
2301
|
-
chrome_options.add_argument("--disable-component-update")
|
2302
2363
|
chrome_options.add_argument("--disable-breakpad")
|
2303
2364
|
included_disabled_features = []
|
2304
2365
|
included_disabled_features.append("OptimizationHints")
|
@@ -2383,8 +2444,6 @@ def _set_firefox_options(
|
|
2383
2444
|
options.set_preference("dom.webnotifications.enabled", False)
|
2384
2445
|
options.set_preference("dom.disable_beforeunload", True)
|
2385
2446
|
options.set_preference("browser.contentblocking.database.enabled", True)
|
2386
|
-
options.set_preference("extensions.allowPrivateBrowsingByDefault", True)
|
2387
|
-
options.set_preference("extensions.PrivateBrowsing.notification", False)
|
2388
2447
|
options.set_preference("extensions.systemAddon.update.enabled", False)
|
2389
2448
|
options.set_preference("extensions.update.autoUpdateDefault", False)
|
2390
2449
|
options.set_preference("extensions.update.enabled", False)
|
@@ -2600,6 +2659,118 @@ def get_driver(
|
|
2600
2659
|
or browser_name == constants.Browser.EDGE
|
2601
2660
|
)
|
2602
2661
|
):
|
2662
|
+
if (
|
2663
|
+
binary_location.lower() == "cft"
|
2664
|
+
and browser_name == constants.Browser.GOOGLE_CHROME
|
2665
|
+
):
|
2666
|
+
binary_folder = None
|
2667
|
+
if IS_MAC:
|
2668
|
+
if IS_ARM_MAC:
|
2669
|
+
binary_folder = "chrome-mac-arm64"
|
2670
|
+
else:
|
2671
|
+
binary_folder = "chrome-mac-x64"
|
2672
|
+
elif IS_LINUX:
|
2673
|
+
binary_folder = "chrome-linux64"
|
2674
|
+
elif IS_WINDOWS:
|
2675
|
+
if "64" in ARCH:
|
2676
|
+
binary_folder = "chrome-win64"
|
2677
|
+
else:
|
2678
|
+
binary_folder = "chrome-win32"
|
2679
|
+
if binary_folder:
|
2680
|
+
binary_location = os.path.join(DRIVER_DIR, binary_folder)
|
2681
|
+
if not os.path.exists(binary_location):
|
2682
|
+
from seleniumbase.console_scripts import sb_install
|
2683
|
+
args = " ".join(sys.argv)
|
2684
|
+
if not (
|
2685
|
+
"-n" in sys.argv or " -n=" in args or args == "-c"
|
2686
|
+
):
|
2687
|
+
# (Not multithreaded)
|
2688
|
+
sys_args = sys.argv # Save a copy of current sys args
|
2689
|
+
log_d(
|
2690
|
+
"\nWarning: Chrome for Testing binary not found..."
|
2691
|
+
)
|
2692
|
+
try:
|
2693
|
+
sb_install.main(override="cft")
|
2694
|
+
except Exception as e:
|
2695
|
+
log_d("\nWarning: Chrome download failed: %s" % e)
|
2696
|
+
sys.argv = sys_args # Put back the original sys args
|
2697
|
+
else:
|
2698
|
+
chrome_fixing_lock = fasteners.InterProcessLock(
|
2699
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
2700
|
+
)
|
2701
|
+
with chrome_fixing_lock:
|
2702
|
+
with suppress(Exception):
|
2703
|
+
shared_utils.make_writable(
|
2704
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
2705
|
+
)
|
2706
|
+
if not os.path.exists(binary_location):
|
2707
|
+
sys_args = sys.argv # Save a copy of sys args
|
2708
|
+
log_d(
|
2709
|
+
"\nWarning: "
|
2710
|
+
"Chrome for Testing binary not found..."
|
2711
|
+
)
|
2712
|
+
sb_install.main(override="cft")
|
2713
|
+
sys.argv = sys_args # Put back original args
|
2714
|
+
else:
|
2715
|
+
binary_location = None
|
2716
|
+
if (
|
2717
|
+
binary_location.lower() == "chs"
|
2718
|
+
and browser_name == constants.Browser.GOOGLE_CHROME
|
2719
|
+
):
|
2720
|
+
binary_folder = None
|
2721
|
+
if IS_MAC:
|
2722
|
+
if IS_ARM_MAC:
|
2723
|
+
binary_folder = "chrome-headless-shell-mac-arm64"
|
2724
|
+
else:
|
2725
|
+
binary_folder = "chrome-headless-shell-mac-x64"
|
2726
|
+
elif IS_LINUX:
|
2727
|
+
binary_folder = "chrome-headless-shell-linux64"
|
2728
|
+
elif IS_WINDOWS:
|
2729
|
+
if "64" in ARCH:
|
2730
|
+
binary_folder = "chrome-headless-shell-win64"
|
2731
|
+
else:
|
2732
|
+
binary_folder = "chrome-headless-shell-win32"
|
2733
|
+
if binary_folder:
|
2734
|
+
binary_location = os.path.join(DRIVER_DIR, binary_folder)
|
2735
|
+
if not os.path.exists(binary_location):
|
2736
|
+
from seleniumbase.console_scripts import sb_install
|
2737
|
+
args = " ".join(sys.argv)
|
2738
|
+
if not (
|
2739
|
+
"-n" in sys.argv or " -n=" in args or args == "-c"
|
2740
|
+
):
|
2741
|
+
# (Not multithreaded)
|
2742
|
+
sys_args = sys.argv # Save a copy of current sys args
|
2743
|
+
log_d(
|
2744
|
+
"\nWarning: "
|
2745
|
+
"Chrome-Headless-Shell binary not found..."
|
2746
|
+
)
|
2747
|
+
try:
|
2748
|
+
sb_install.main(override="chs")
|
2749
|
+
except Exception as e:
|
2750
|
+
log_d(
|
2751
|
+
"\nWarning: "
|
2752
|
+
"Chrome-Headless-Shell download failed: %s" % e
|
2753
|
+
)
|
2754
|
+
sys.argv = sys_args # Put back the original sys args
|
2755
|
+
else:
|
2756
|
+
chrome_fixing_lock = fasteners.InterProcessLock(
|
2757
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
2758
|
+
)
|
2759
|
+
with chrome_fixing_lock:
|
2760
|
+
with suppress(Exception):
|
2761
|
+
shared_utils.make_writable(
|
2762
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
2763
|
+
)
|
2764
|
+
if not os.path.exists(binary_location):
|
2765
|
+
sys_args = sys.argv # Save a copy of sys args
|
2766
|
+
log_d(
|
2767
|
+
"\nWarning: "
|
2768
|
+
"Chrome-Headless-Shell binary not found..."
|
2769
|
+
)
|
2770
|
+
sb_install.main(override="chs")
|
2771
|
+
sys.argv = sys_args # Put back original args
|
2772
|
+
else:
|
2773
|
+
binary_location = None
|
2603
2774
|
if not os.path.exists(binary_location):
|
2604
2775
|
log_d(
|
2605
2776
|
"\nWarning: The Chromium binary specified (%s) was NOT found!"
|
@@ -2609,7 +2780,7 @@ def get_driver(
|
|
2609
2780
|
elif binary_location.endswith("/") or binary_location.endswith("\\"):
|
2610
2781
|
log_d(
|
2611
2782
|
"\nWarning: The Chromium binary path must be a full path "
|
2612
|
-
"that includes the
|
2783
|
+
"that includes the browser filename at the end of it!"
|
2613
2784
|
"\n(Will use default settings...)\n" % binary_location
|
2614
2785
|
)
|
2615
2786
|
# Example of a valid binary location path - MacOS:
|
@@ -2618,6 +2789,34 @@ def get_driver(
|
|
2618
2789
|
else:
|
2619
2790
|
binary_name = binary_location.split("/")[-1].split("\\")[-1]
|
2620
2791
|
valid_names = get_valid_binary_names_for_browser(browser_name)
|
2792
|
+
if binary_name == "Google Chrome for Testing.app":
|
2793
|
+
binary_name = "Google Chrome for Testing"
|
2794
|
+
binary_location += "/Contents/MacOS/Google Chrome for Testing"
|
2795
|
+
elif binary_name in ["chrome-mac-arm64", "chrome-mac-x64"]:
|
2796
|
+
binary_name = "Google Chrome for Testing"
|
2797
|
+
binary_location += "/Google Chrome for Testing.app"
|
2798
|
+
binary_location += "/Contents/MacOS/Google Chrome for Testing"
|
2799
|
+
elif binary_name == "chrome-linux64":
|
2800
|
+
binary_name = "chrome"
|
2801
|
+
binary_location += "/chrome"
|
2802
|
+
elif binary_name in ["chrome-win32", "chrome-win64"]:
|
2803
|
+
binary_name = "chrome.exe"
|
2804
|
+
binary_location += "\\chrome.exe"
|
2805
|
+
elif binary_name in [
|
2806
|
+
"chrome-headless-shell-mac-arm64",
|
2807
|
+
"chrome-headless-shell-mac-x64",
|
2808
|
+
]:
|
2809
|
+
binary_name = "chrome-headless-shell"
|
2810
|
+
binary_location += "/chrome-headless-shell"
|
2811
|
+
elif binary_name == "chrome-headless-shell-linux64":
|
2812
|
+
binary_name = "chrome-headless-shell"
|
2813
|
+
binary_location += "/chrome-headless-shell"
|
2814
|
+
elif binary_name in [
|
2815
|
+
"chrome-headless-shell-win32",
|
2816
|
+
"chrome-headless-shell-win64",
|
2817
|
+
]:
|
2818
|
+
binary_name = "chrome-headless-shell.exe"
|
2819
|
+
binary_location += "\\chrome-headless-shell.exe"
|
2621
2820
|
if binary_name not in valid_names:
|
2622
2821
|
log_d(
|
2623
2822
|
"\nWarning: The Chromium binary specified is NOT valid!"
|
@@ -2626,6 +2825,8 @@ def get_driver(
|
|
2626
2825
|
"" % (binary_name, valid_names)
|
2627
2826
|
)
|
2628
2827
|
binary_location = None
|
2828
|
+
elif binary_location.lower() == "chs":
|
2829
|
+
headless = True
|
2629
2830
|
if (uc_cdp_events or uc_subprocess) and not undetectable:
|
2630
2831
|
undetectable = True
|
2631
2832
|
if mobile_emulator and not user_agent:
|
@@ -2923,6 +3124,8 @@ def get_remote_driver(
|
|
2923
3124
|
constants.PipInstall.FINDLOCK
|
2924
3125
|
)
|
2925
3126
|
with pip_find_lock: # Prevent issues with multiple processes
|
3127
|
+
with suppress(Exception):
|
3128
|
+
shared_utils.make_writable(constants.PipInstall.FINDLOCK)
|
2926
3129
|
try:
|
2927
3130
|
from seleniumwire import webdriver
|
2928
3131
|
import blinker
|
@@ -3360,6 +3563,8 @@ def get_local_driver(
|
|
3360
3563
|
constants.PipInstall.FINDLOCK
|
3361
3564
|
)
|
3362
3565
|
with pip_find_lock: # Prevent issues with multiple processes
|
3566
|
+
with suppress(Exception):
|
3567
|
+
shared_utils.make_writable(constants.PipInstall.FINDLOCK)
|
3363
3568
|
try:
|
3364
3569
|
from seleniumwire import webdriver
|
3365
3570
|
import blinker
|
@@ -3423,6 +3628,10 @@ def get_local_driver(
|
|
3423
3628
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
3424
3629
|
)
|
3425
3630
|
with geckodriver_fixing_lock:
|
3631
|
+
with suppress(Exception):
|
3632
|
+
shared_utils.make_writable(
|
3633
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
3634
|
+
)
|
3426
3635
|
if not geckodriver_on_path():
|
3427
3636
|
sys_args = sys.argv # Save a copy of sys args
|
3428
3637
|
log_d(
|
@@ -3725,6 +3934,10 @@ def get_local_driver(
|
|
3725
3934
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
3726
3935
|
)
|
3727
3936
|
with edgedriver_fixing_lock:
|
3937
|
+
with suppress(Exception):
|
3938
|
+
shared_utils.make_writable(
|
3939
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
3940
|
+
)
|
3728
3941
|
msg = "Microsoft Edge Driver not found."
|
3729
3942
|
if edgedriver_upgrade_needed:
|
3730
3943
|
msg = "Microsoft Edge Driver update needed."
|
@@ -3783,6 +3996,12 @@ def get_local_driver(
|
|
3783
3996
|
edge_options.add_argument("--guest")
|
3784
3997
|
if dark_mode:
|
3785
3998
|
edge_options.add_argument("--enable-features=WebContentsForceDark")
|
3999
|
+
if headless1:
|
4000
|
+
# developer.chrome.com/blog/removing-headless-old-from-chrome
|
4001
|
+
with suppress(Exception):
|
4002
|
+
if int(str(use_version).split(".")[0]) >= 132:
|
4003
|
+
headless1 = False
|
4004
|
+
headless2 = True
|
3786
4005
|
if headless2:
|
3787
4006
|
try:
|
3788
4007
|
if use_version == "latest" or int(use_version) >= 109:
|
@@ -4036,7 +4255,6 @@ def get_local_driver(
|
|
4036
4255
|
edge_options.add_argument("--disable-ipc-flooding-protection")
|
4037
4256
|
edge_options.add_argument("--disable-password-generation")
|
4038
4257
|
edge_options.add_argument("--disable-domain-reliability")
|
4039
|
-
edge_options.add_argument("--disable-component-update")
|
4040
4258
|
edge_options.add_argument("--disable-breakpad")
|
4041
4259
|
included_disabled_features = []
|
4042
4260
|
included_disabled_features.append("OptimizationHints")
|
@@ -4108,6 +4326,10 @@ def get_local_driver(
|
|
4108
4326
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
4109
4327
|
)
|
4110
4328
|
with edgedriver_fixing_lock:
|
4329
|
+
with suppress(Exception):
|
4330
|
+
shared_utils.make_writable(
|
4331
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
4332
|
+
)
|
4111
4333
|
with suppress(Exception):
|
4112
4334
|
if not _was_driver_repaired():
|
4113
4335
|
_repair_edgedriver(edge_version)
|
@@ -4321,6 +4543,12 @@ def get_local_driver(
|
|
4321
4543
|
use_version = find_chromedriver_version_to_use(
|
4322
4544
|
use_version, driver_version
|
4323
4545
|
)
|
4546
|
+
if headless1:
|
4547
|
+
# developer.chrome.com/blog/removing-headless-old-from-chrome
|
4548
|
+
with suppress(Exception):
|
4549
|
+
if int(str(use_version).split(".")[0]) >= 132:
|
4550
|
+
headless1 = False
|
4551
|
+
headless2 = True
|
4324
4552
|
if headless2:
|
4325
4553
|
try:
|
4326
4554
|
if (
|
@@ -4490,6 +4718,10 @@ def get_local_driver(
|
|
4490
4718
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
4491
4719
|
)
|
4492
4720
|
with chromedriver_fixing_lock:
|
4721
|
+
with suppress(Exception):
|
4722
|
+
shared_utils.make_writable(
|
4723
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
4724
|
+
)
|
4493
4725
|
msg = "chromedriver update needed. Getting it now:"
|
4494
4726
|
if not path_chromedriver:
|
4495
4727
|
msg = "chromedriver not found. Getting it now:"
|
@@ -4581,6 +4813,10 @@ def get_local_driver(
|
|
4581
4813
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
4582
4814
|
)
|
4583
4815
|
with uc_lock: # Avoid multithreaded issues
|
4816
|
+
with suppress(Exception):
|
4817
|
+
shared_utils.make_writable(
|
4818
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
4819
|
+
)
|
4584
4820
|
if make_uc_driver_from_chromedriver:
|
4585
4821
|
if os.path.exists(LOCAL_CHROMEDRIVER):
|
4586
4822
|
with suppress(Exception):
|
@@ -4813,7 +5049,13 @@ def get_local_driver(
|
|
4813
5049
|
)
|
4814
5050
|
uc_activated = True
|
4815
5051
|
except URLError as e:
|
4816
|
-
if
|
5052
|
+
if (
|
5053
|
+
IS_MAC
|
5054
|
+
and hasattr(e, "args")
|
5055
|
+
and isinstance(e.args, (list, tuple))
|
5056
|
+
and len(e.args) > 0
|
5057
|
+
and cert in e.args[0]
|
5058
|
+
):
|
4817
5059
|
mac_certificate_error = True
|
4818
5060
|
else:
|
4819
5061
|
raise
|
@@ -4840,6 +5082,10 @@ def get_local_driver(
|
|
4840
5082
|
if not os.path.exists(cf_lock_path):
|
4841
5083
|
# Avoid multithreaded issues
|
4842
5084
|
with cf_lock:
|
5085
|
+
with suppress(Exception):
|
5086
|
+
shared_utils.make_writable(
|
5087
|
+
cf_lock_path
|
5088
|
+
)
|
4843
5089
|
# Install Python Certificates (MAC)
|
4844
5090
|
os.system(
|
4845
5091
|
r"bash /Applications/Python*/"
|
@@ -4983,6 +5229,10 @@ def get_local_driver(
|
|
4983
5229
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
4984
5230
|
)
|
4985
5231
|
with chromedriver_fixing_lock:
|
5232
|
+
with suppress(Exception):
|
5233
|
+
shared_utils.make_writable(
|
5234
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
5235
|
+
)
|
4986
5236
|
if not _was_driver_repaired():
|
4987
5237
|
_repair_chromedriver(
|
4988
5238
|
chrome_options, headless_options, mcv
|
@@ -5181,7 +5431,10 @@ def get_local_driver(
|
|
5181
5431
|
chromedr_fixing_lock = fasteners.InterProcessLock(
|
5182
5432
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
5183
5433
|
)
|
5434
|
+
D_F_L = constants.MultiBrowser.DRIVER_FIXING_LOCK
|
5184
5435
|
with chromedr_fixing_lock:
|
5436
|
+
with suppress(Exception):
|
5437
|
+
shared_utils.make_writable(D_F_L)
|
5185
5438
|
if not _was_driver_repaired():
|
5186
5439
|
with suppress(Exception):
|
5187
5440
|
_repair_chromedriver(
|