seleniumbase 4.33.4__py3-none-any.whl → 4.34.2__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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(
|