seleniumbase 4.34.14__py3-none-any.whl → 4.34.16__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/core/browser_launcher.py +33 -36
- seleniumbase/core/proxy_helper.py +7 -5
- seleniumbase/core/sb_cdp.py +105 -35
- seleniumbase/fixtures/base_case.py +14 -3
- seleniumbase/fixtures/js_utils.py +31 -9
- seleniumbase/undetected/cdp_driver/browser.py +2 -0
- seleniumbase/undetected/cdp_driver/cdp_util.py +104 -2
- seleniumbase/undetected/cdp_driver/config.py +10 -0
- {seleniumbase-4.34.14.dist-info → seleniumbase-4.34.16.dist-info}/METADATA +5 -5
- {seleniumbase-4.34.14.dist-info → seleniumbase-4.34.16.dist-info}/RECORD +15 -15
- {seleniumbase-4.34.14.dist-info → seleniumbase-4.34.16.dist-info}/LICENSE +0 -0
- {seleniumbase-4.34.14.dist-info → seleniumbase-4.34.16.dist-info}/WHEEL +0 -0
- {seleniumbase-4.34.14.dist-info → seleniumbase-4.34.16.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.34.14.dist-info → seleniumbase-4.34.16.dist-info}/top_level.txt +0 -0
seleniumbase/__version__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# seleniumbase package
|
2
|
-
__version__ = "4.34.
|
2
|
+
__version__ = "4.34.16"
|
@@ -107,7 +107,7 @@ def make_driver_executable_if_not(driver_path):
|
|
107
107
|
shared_utils.make_executable(driver_path)
|
108
108
|
|
109
109
|
|
110
|
-
def extend_driver(driver):
|
110
|
+
def extend_driver(driver, proxy_auth=False, use_uc=True):
|
111
111
|
# Extend the driver with new methods
|
112
112
|
driver.default_find_element = driver.find_element
|
113
113
|
driver.default_find_elements = driver.find_elements
|
@@ -235,6 +235,8 @@ def extend_driver(driver):
|
|
235
235
|
driver.reset_window_size = DM.reset_window_size
|
236
236
|
if hasattr(driver, "proxy"):
|
237
237
|
driver.set_wire_proxy = DM.set_wire_proxy
|
238
|
+
if proxy_auth and not use_uc:
|
239
|
+
time.sleep(0.11) # Proxy needs moment to load in Manifest V3
|
238
240
|
return driver
|
239
241
|
|
240
242
|
|
@@ -716,6 +718,10 @@ def uc_open_with_cdp_mode(driver, url=None):
|
|
716
718
|
cdp.is_selected = CDPM.is_selected
|
717
719
|
cdp.is_element_present = CDPM.is_element_present
|
718
720
|
cdp.is_element_visible = CDPM.is_element_visible
|
721
|
+
cdp.is_text_visible = CDPM.is_text_visible
|
722
|
+
cdp.is_exact_text_visible = CDPM.is_exact_text_visible
|
723
|
+
cdp.wait_for_text = CDPM.wait_for_text
|
724
|
+
cdp.wait_for_text_not_visible = CDPM.wait_for_text_not_visible
|
719
725
|
cdp.wait_for_element_visible = CDPM.wait_for_element_visible
|
720
726
|
cdp.assert_element = CDPM.assert_element
|
721
727
|
cdp.assert_element_visible = CDPM.assert_element_visible
|
@@ -729,6 +735,7 @@ def uc_open_with_cdp_mode(driver, url=None):
|
|
729
735
|
cdp.assert_url_contains = CDPM.assert_url_contains
|
730
736
|
cdp.assert_text = CDPM.assert_text
|
731
737
|
cdp.assert_exact_text = CDPM.assert_exact_text
|
738
|
+
cdp.assert_text_not_visible = CDPM.assert_text_not_visible
|
732
739
|
cdp.assert_true = CDPM.assert_true
|
733
740
|
cdp.assert_false = CDPM.assert_false
|
734
741
|
cdp.assert_equal = CDPM.assert_equal
|
@@ -2278,6 +2285,7 @@ def _set_chrome_options(
|
|
2278
2285
|
or proxy_string
|
2279
2286
|
):
|
2280
2287
|
chrome_options.add_argument("--ignore-certificate-errors")
|
2288
|
+
chrome_options.add_argument("--ignore-ssl-errors=yes")
|
2281
2289
|
if not enable_ws:
|
2282
2290
|
chrome_options.add_argument("--disable-web-security")
|
2283
2291
|
if (
|
@@ -3591,6 +3599,7 @@ def get_local_driver(
|
|
3591
3599
|
Can also be used to spin up additional browsers for the same test."""
|
3592
3600
|
downloads_path = DOWNLOADS_FOLDER
|
3593
3601
|
b_path = binary_location
|
3602
|
+
use_uc = is_using_uc(undetectable, browser_name)
|
3594
3603
|
if use_wire:
|
3595
3604
|
pip_find_lock = fasteners.InterProcessLock(
|
3596
3605
|
constants.PipInstall.FINDLOCK
|
@@ -4064,7 +4073,7 @@ def get_local_driver(
|
|
4064
4073
|
edge_options.add_argument("--headless=old")
|
4065
4074
|
else:
|
4066
4075
|
edge_options.add_argument("--headless")
|
4067
|
-
if mobile_emulator and not
|
4076
|
+
if mobile_emulator and not use_uc:
|
4068
4077
|
emulator_settings = {}
|
4069
4078
|
device_metrics = {}
|
4070
4079
|
if (
|
@@ -4128,7 +4137,7 @@ def get_local_driver(
|
|
4128
4137
|
settings.CHROME_START_HEIGHT,
|
4129
4138
|
)
|
4130
4139
|
)
|
4131
|
-
if user_data_dir and not
|
4140
|
+
if user_data_dir and not use_uc:
|
4132
4141
|
abs_path = os.path.abspath(user_data_dir)
|
4133
4142
|
edge_options.add_argument("--user-data-dir=%s" % abs_path)
|
4134
4143
|
if extension_zip:
|
@@ -4163,7 +4172,7 @@ def get_local_driver(
|
|
4163
4172
|
edge_options.add_argument("--disable-prompt-on-repost")
|
4164
4173
|
if not enable_3d_apis:
|
4165
4174
|
edge_options.add_argument("--disable-3d-apis")
|
4166
|
-
if headless or headless2 or
|
4175
|
+
if headless or headless2 or use_uc:
|
4167
4176
|
edge_options.add_argument("--disable-renderer-backgrounding")
|
4168
4177
|
edge_options.add_argument("--disable-backgrounding-occluded-windows")
|
4169
4178
|
edge_options.add_argument("--disable-client-side-phishing-detection")
|
@@ -4228,6 +4237,7 @@ def get_local_driver(
|
|
4228
4237
|
edge_options.add_argument("--log-level=3")
|
4229
4238
|
edge_options.add_argument("--no-first-run")
|
4230
4239
|
edge_options.add_argument("--ignore-certificate-errors")
|
4240
|
+
edge_options.add_argument("--ignore-ssl-errors=yes")
|
4231
4241
|
if devtools and not headless:
|
4232
4242
|
edge_options.add_argument("--auto-open-devtools-for-tabs")
|
4233
4243
|
edge_options.add_argument("--allow-file-access-from-files")
|
@@ -4235,10 +4245,7 @@ def get_local_driver(
|
|
4235
4245
|
edge_options.add_argument("--allow-running-insecure-content")
|
4236
4246
|
if user_agent:
|
4237
4247
|
edge_options.add_argument("--user-agent=%s" % user_agent)
|
4238
|
-
if (
|
4239
|
-
IS_LINUX
|
4240
|
-
or (IS_MAC and not is_using_uc(undetectable, browser_name))
|
4241
|
-
):
|
4248
|
+
if IS_LINUX or (IS_MAC and not use_uc):
|
4242
4249
|
edge_options.add_argument("--no-sandbox")
|
4243
4250
|
if remote_debug:
|
4244
4251
|
# To access the Debugger, go to: edge://inspect/#devices
|
@@ -4252,10 +4259,7 @@ def get_local_driver(
|
|
4252
4259
|
if swiftshader:
|
4253
4260
|
edge_options.add_argument("--use-gl=angle")
|
4254
4261
|
edge_options.add_argument("--use-angle=swiftshader-webgl")
|
4255
|
-
elif
|
4256
|
-
not is_using_uc(undetectable, browser_name)
|
4257
|
-
and not enable_3d_apis
|
4258
|
-
):
|
4262
|
+
elif not use_uc and not enable_3d_apis:
|
4259
4263
|
edge_options.add_argument("--disable-gpu")
|
4260
4264
|
if IS_LINUX:
|
4261
4265
|
edge_options.add_argument("--disable-dev-shm-usage")
|
@@ -4502,14 +4506,14 @@ def get_local_driver(
|
|
4502
4506
|
and len(saved_mcv.split(".")) == 4
|
4503
4507
|
):
|
4504
4508
|
driver_version = saved_mcv
|
4505
|
-
if
|
4509
|
+
if use_uc:
|
4506
4510
|
use_br_version_for_uc = True
|
4507
4511
|
if (
|
4508
4512
|
(headless or headless2)
|
4509
4513
|
and IS_WINDOWS
|
4510
4514
|
and major_chrome_version
|
4511
4515
|
and int(major_chrome_version) >= 117
|
4512
|
-
and not
|
4516
|
+
and not use_uc
|
4513
4517
|
and not (remote_debug or devtools or use_wire)
|
4514
4518
|
and not (proxy_string or multi_proxy or proxy_pac_url)
|
4515
4519
|
and (not chromium_arg or "debug" not in chromium_arg)
|
@@ -4565,7 +4569,7 @@ def get_local_driver(
|
|
4565
4569
|
use_version = ch_driver_version
|
4566
4570
|
disable_build_check = True
|
4567
4571
|
uc_driver_version = None
|
4568
|
-
if
|
4572
|
+
if use_uc:
|
4569
4573
|
if use_br_version_for_uc or driver_version == "mlatest":
|
4570
4574
|
uc_driver_version = get_uc_driver_version(full=True)
|
4571
4575
|
full_ch_driver_version = uc_driver_version
|
@@ -4626,7 +4630,6 @@ def get_local_driver(
|
|
4626
4630
|
"\nWarning: Could not make chromedriver"
|
4627
4631
|
" executable: %s" % e
|
4628
4632
|
)
|
4629
|
-
use_uc = is_using_uc(undetectable, browser_name)
|
4630
4633
|
make_uc_driver_from_chromedriver = False
|
4631
4634
|
local_ch_exists = (
|
4632
4635
|
LOCAL_CHROMEDRIVER and os.path.exists(LOCAL_CHROMEDRIVER)
|
@@ -4843,7 +4846,7 @@ def get_local_driver(
|
|
4843
4846
|
service_args = []
|
4844
4847
|
if disable_build_check:
|
4845
4848
|
service_args = ["--disable-build-check"]
|
4846
|
-
if
|
4849
|
+
if use_uc:
|
4847
4850
|
uc_lock = fasteners.InterProcessLock(
|
4848
4851
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
4849
4852
|
)
|
@@ -4872,20 +4875,14 @@ def get_local_driver(
|
|
4872
4875
|
"\nWarning: Could not make uc_driver"
|
4873
4876
|
" executable: %s" % e
|
4874
4877
|
)
|
4875
|
-
if
|
4876
|
-
not headless
|
4877
|
-
or not IS_LINUX
|
4878
|
-
or is_using_uc(undetectable, browser_name)
|
4879
|
-
):
|
4878
|
+
if not headless or not IS_LINUX or use_uc:
|
4880
4879
|
uc_activated = False
|
4881
4880
|
try:
|
4882
|
-
if (
|
4883
|
-
os.path.exists(LOCAL_CHROMEDRIVER)
|
4884
|
-
or is_using_uc(undetectable, browser_name)
|
4885
|
-
):
|
4881
|
+
if os.path.exists(LOCAL_CHROMEDRIVER) or use_uc:
|
4886
4882
|
if headless and not IS_LINUX:
|
4887
4883
|
undetectable = False # No support for headless
|
4888
|
-
|
4884
|
+
use_uc = is_using_uc(undetectable, browser_name)
|
4885
|
+
if use_uc:
|
4889
4886
|
from seleniumbase import undetected
|
4890
4887
|
from urllib.error import URLError
|
4891
4888
|
if IS_LINUX:
|
@@ -5185,7 +5182,7 @@ def get_local_driver(
|
|
5185
5182
|
driver = webdriver.Chrome(
|
5186
5183
|
service=service, options=chrome_options
|
5187
5184
|
)
|
5188
|
-
return extend_driver(driver)
|
5185
|
+
return extend_driver(driver, proxy_auth, use_uc)
|
5189
5186
|
if not auto_upgrade_chromedriver:
|
5190
5187
|
raise # Not an obvious fix.
|
5191
5188
|
else:
|
@@ -5436,11 +5433,11 @@ def get_local_driver(
|
|
5436
5433
|
'Emulation.setDeviceMetricsOverride',
|
5437
5434
|
set_device_metrics_override
|
5438
5435
|
)
|
5439
|
-
return extend_driver(driver)
|
5436
|
+
return extend_driver(driver, proxy_auth, use_uc)
|
5440
5437
|
else: # Running headless on Linux (and not using --uc)
|
5441
5438
|
try:
|
5442
5439
|
driver = webdriver.Chrome(options=chrome_options)
|
5443
|
-
return extend_driver(driver)
|
5440
|
+
return extend_driver(driver, proxy_auth, use_uc)
|
5444
5441
|
except Exception as e:
|
5445
5442
|
if not hasattr(e, "msg"):
|
5446
5443
|
raise
|
@@ -5462,7 +5459,7 @@ def get_local_driver(
|
|
5462
5459
|
driver = webdriver.Chrome(
|
5463
5460
|
service=service, options=chrome_options
|
5464
5461
|
)
|
5465
|
-
return extend_driver(driver)
|
5462
|
+
return extend_driver(driver, proxy_auth, use_uc)
|
5466
5463
|
mcv = None # Major Chrome Version
|
5467
5464
|
if "Current browser version is " in e.msg:
|
5468
5465
|
line = e.msg.split("Current browser version is ")[1]
|
@@ -5505,7 +5502,7 @@ def get_local_driver(
|
|
5505
5502
|
service=service,
|
5506
5503
|
options=chrome_options,
|
5507
5504
|
)
|
5508
|
-
return extend_driver(driver)
|
5505
|
+
return extend_driver(driver, proxy_auth, use_uc)
|
5509
5506
|
# Use the virtual display on Linux during headless errors
|
5510
5507
|
logging.debug(
|
5511
5508
|
"\nWarning: Chrome failed to launch in"
|
@@ -5523,9 +5520,9 @@ def get_local_driver(
|
|
5523
5520
|
driver = webdriver.Chrome(
|
5524
5521
|
service=service, options=chrome_options
|
5525
5522
|
)
|
5526
|
-
return extend_driver(driver)
|
5523
|
+
return extend_driver(driver, proxy_auth, use_uc)
|
5527
5524
|
except Exception as original_exception:
|
5528
|
-
if
|
5525
|
+
if use_uc:
|
5529
5526
|
raise
|
5530
5527
|
# Try again if Chrome didn't launch
|
5531
5528
|
with suppress(Exception):
|
@@ -5533,7 +5530,7 @@ def get_local_driver(
|
|
5533
5530
|
driver = webdriver.Chrome(
|
5534
5531
|
service=service, options=chrome_options
|
5535
5532
|
)
|
5536
|
-
return extend_driver(driver)
|
5533
|
+
return extend_driver(driver, proxy_auth, use_uc)
|
5537
5534
|
if user_data_dir:
|
5538
5535
|
print("\nUnable to set user_data_dir while starting Chrome!\n")
|
5539
5536
|
raise
|
@@ -5560,7 +5557,7 @@ def get_local_driver(
|
|
5560
5557
|
)
|
5561
5558
|
try:
|
5562
5559
|
driver = webdriver.Chrome(service=service)
|
5563
|
-
return extend_driver(driver)
|
5560
|
+
return extend_driver(driver, proxy_auth, use_uc)
|
5564
5561
|
except Exception:
|
5565
5562
|
raise original_exception
|
5566
5563
|
else:
|
@@ -94,21 +94,23 @@ def create_proxy_ext(
|
|
94
94
|
manifest_json = (
|
95
95
|
"""{\n"""
|
96
96
|
""""version": "1.0.0",\n"""
|
97
|
-
""""manifest_version":
|
97
|
+
""""manifest_version": 3,\n"""
|
98
98
|
""""name": "Chrome Proxy",\n"""
|
99
99
|
""""permissions": [\n"""
|
100
100
|
""" "proxy",\n"""
|
101
101
|
""" "tabs",\n"""
|
102
102
|
""" "unlimitedStorage",\n"""
|
103
103
|
""" "storage",\n"""
|
104
|
-
""" "<all_urls>",\n"""
|
105
104
|
""" "webRequest",\n"""
|
106
|
-
""" "
|
105
|
+
""" "webRequestAuthProvider"\n"""
|
106
|
+
"""],\n"""
|
107
|
+
""""host_permissions": [\n"""
|
108
|
+
""" "<all_urls>"\n"""
|
107
109
|
"""],\n"""
|
108
110
|
""""background": {\n"""
|
109
|
-
""" "
|
111
|
+
""" "service_worker": "background.js"\n"""
|
110
112
|
"""},\n"""
|
111
|
-
""""minimum_chrome_version":"
|
113
|
+
""""minimum_chrome_version":"88.0.0"\n"""
|
112
114
|
"""}"""
|
113
115
|
)
|
114
116
|
abs_path = os.path.abspath(".")
|
seleniumbase/core/sb_cdp.py
CHANGED
@@ -62,6 +62,7 @@ class CDPMethods():
|
|
62
62
|
lambda destination: self.__mouse_drag(element, destination)
|
63
63
|
)
|
64
64
|
element.mouse_move = lambda: self.__mouse_move(element)
|
65
|
+
element.press_keys = lambda text: self.__press_keys(element, text)
|
65
66
|
element.query_selector = (
|
66
67
|
lambda selector: self.__query_selector(element, selector)
|
67
68
|
)
|
@@ -211,7 +212,8 @@ class CDPMethods():
|
|
211
212
|
element = self.__add_sync_methods(element.parent)
|
212
213
|
return self.__add_sync_methods(element)
|
213
214
|
elif (
|
214
|
-
element.parent
|
215
|
+
element.parent
|
216
|
+
and element.parent.parent
|
215
217
|
and tag_name in element.parent.parent.tag_name.lower()
|
216
218
|
and text.strip() in element.parent.parent.text
|
217
219
|
):
|
@@ -272,7 +274,8 @@ class CDPMethods():
|
|
272
274
|
if element not in updated_elements:
|
273
275
|
updated_elements.append(element)
|
274
276
|
elif (
|
275
|
-
element.parent
|
277
|
+
element.parent
|
278
|
+
and element.parent.parent
|
276
279
|
and tag_name in element.parent.parent.tag_name.lower()
|
277
280
|
and text.strip() in element.parent.parent.text
|
278
281
|
):
|
@@ -445,6 +448,23 @@ class CDPMethods():
|
|
445
448
|
self.loop.run_until_complete(element.mouse_move_async())
|
446
449
|
)
|
447
450
|
|
451
|
+
def __press_keys(self, element, text):
|
452
|
+
element.scroll_into_view()
|
453
|
+
submit = False
|
454
|
+
if text.endswith("\n") or text.endswith("\r"):
|
455
|
+
submit = True
|
456
|
+
text = text[:-1]
|
457
|
+
for key in text:
|
458
|
+
element.send_keys(key)
|
459
|
+
time.sleep(0.044)
|
460
|
+
if submit:
|
461
|
+
element.send_keys("\r\n")
|
462
|
+
time.sleep(0.044)
|
463
|
+
self.__slow_mode_pause_if_set()
|
464
|
+
return (
|
465
|
+
self.loop.run_until_complete(self.page.wait())
|
466
|
+
)
|
467
|
+
|
448
468
|
def __query_selector(self, element, selector):
|
449
469
|
selector = self.__convert_to_css_if_xpath(selector)
|
450
470
|
element2 = self.loop.run_until_complete(
|
@@ -1681,21 +1701,79 @@ class CDPMethods():
|
|
1681
1701
|
return True
|
1682
1702
|
return False
|
1683
1703
|
|
1684
|
-
def
|
1704
|
+
def is_text_visible(self, text, selector="body"):
|
1705
|
+
selector = self.__convert_to_css_if_xpath(selector)
|
1706
|
+
text = text.strip()
|
1707
|
+
element = None
|
1708
|
+
try:
|
1709
|
+
element = self.find_element(selector, timeout=0.1)
|
1710
|
+
except Exception:
|
1711
|
+
return False
|
1712
|
+
with suppress(Exception):
|
1713
|
+
if text in element.text_all:
|
1714
|
+
return True
|
1715
|
+
return False
|
1716
|
+
|
1717
|
+
def is_exact_text_visible(self, text, selector="body"):
|
1718
|
+
selector = self.__convert_to_css_if_xpath(selector)
|
1719
|
+
text = text.strip()
|
1720
|
+
element = None
|
1721
|
+
try:
|
1722
|
+
element = self.find_element(selector, timeout=0.1)
|
1723
|
+
except Exception:
|
1724
|
+
return False
|
1725
|
+
with suppress(Exception):
|
1726
|
+
if text == element.text_all.strip():
|
1727
|
+
return True
|
1728
|
+
return False
|
1729
|
+
|
1730
|
+
def wait_for_text(self, text, selector="body", timeout=None):
|
1685
1731
|
if not timeout:
|
1686
1732
|
timeout = settings.SMALL_TIMEOUT
|
1733
|
+
start_ms = time.time() * 1000.0
|
1734
|
+
stop_ms = start_ms + (timeout * 1000.0)
|
1735
|
+
text = text.strip()
|
1736
|
+
element = None
|
1687
1737
|
try:
|
1688
|
-
self.
|
1738
|
+
element = self.find_element(selector, timeout=timeout)
|
1689
1739
|
except Exception:
|
1690
|
-
raise Exception("Element {%s}
|
1691
|
-
for i in range(
|
1692
|
-
|
1693
|
-
|
1740
|
+
raise Exception("Element {%s} not found!" % selector)
|
1741
|
+
for i in range(int(timeout * 10)):
|
1742
|
+
with suppress(Exception):
|
1743
|
+
element = self.find_element(selector, timeout=0.1)
|
1744
|
+
if text in element.text_all:
|
1745
|
+
return True
|
1746
|
+
now_ms = time.time() * 1000.0
|
1747
|
+
if now_ms >= stop_ms:
|
1748
|
+
break
|
1694
1749
|
time.sleep(0.1)
|
1695
|
-
raise Exception(
|
1750
|
+
raise Exception(
|
1751
|
+
"Text {%s} not found in {%s}! Actual text: {%s}"
|
1752
|
+
% (text, selector, element.text_all)
|
1753
|
+
)
|
1696
1754
|
|
1697
|
-
def
|
1698
|
-
|
1755
|
+
def wait_for_text_not_visible(self, text, selector="body", timeout=None):
|
1756
|
+
if not timeout:
|
1757
|
+
timeout = settings.SMALL_TIMEOUT
|
1758
|
+
text = text.strip()
|
1759
|
+
start_ms = time.time() * 1000.0
|
1760
|
+
stop_ms = start_ms + (timeout * 1000.0)
|
1761
|
+
for i in range(int(timeout * 10)):
|
1762
|
+
if not self.is_text_visible(text, selector):
|
1763
|
+
return True
|
1764
|
+
now_ms = time.time() * 1000.0
|
1765
|
+
if now_ms >= stop_ms:
|
1766
|
+
break
|
1767
|
+
time.sleep(0.1)
|
1768
|
+
plural = "s"
|
1769
|
+
if timeout == 1:
|
1770
|
+
plural = ""
|
1771
|
+
raise Exception(
|
1772
|
+
"Text {%s} in {%s} was still visible after %s second%s!"
|
1773
|
+
% (text, selector, timeout, plural)
|
1774
|
+
)
|
1775
|
+
|
1776
|
+
def wait_for_element_visible(self, selector, timeout=None):
|
1699
1777
|
if not timeout:
|
1700
1778
|
timeout = settings.SMALL_TIMEOUT
|
1701
1779
|
try:
|
@@ -1704,10 +1782,15 @@ class CDPMethods():
|
|
1704
1782
|
raise Exception("Element {%s} was not found!" % selector)
|
1705
1783
|
for i in range(30):
|
1706
1784
|
if self.is_element_visible(selector):
|
1707
|
-
return
|
1785
|
+
return self.select(selector)
|
1708
1786
|
time.sleep(0.1)
|
1709
1787
|
raise Exception("Element {%s} was not visible!" % selector)
|
1710
1788
|
|
1789
|
+
def assert_element(self, selector, timeout=None):
|
1790
|
+
"""Same as assert_element_visible()"""
|
1791
|
+
self.assert_element_visible(selector, timeout=timeout)
|
1792
|
+
return True
|
1793
|
+
|
1711
1794
|
def assert_element_visible(self, selector, timeout=None):
|
1712
1795
|
"""Same as assert_element()"""
|
1713
1796
|
if not timeout:
|
@@ -1852,29 +1935,9 @@ class CDPMethods():
|
|
1852
1935
|
raise Exception(error % (expected, actual))
|
1853
1936
|
|
1854
1937
|
def assert_text(self, text, selector="body", timeout=None):
|
1855
|
-
|
1856
|
-
|
1857
|
-
|
1858
|
-
stop_ms = start_ms + (timeout * 1000.0)
|
1859
|
-
text = text.strip()
|
1860
|
-
element = None
|
1861
|
-
try:
|
1862
|
-
element = self.find_element(selector, timeout=timeout)
|
1863
|
-
except Exception:
|
1864
|
-
raise Exception("Element {%s} not found!" % selector)
|
1865
|
-
for i in range(int(timeout * 10)):
|
1866
|
-
with suppress(Exception):
|
1867
|
-
element = self.find_element(selector, timeout=0.1)
|
1868
|
-
if text in element.text_all:
|
1869
|
-
return True
|
1870
|
-
now_ms = time.time() * 1000.0
|
1871
|
-
if now_ms >= stop_ms:
|
1872
|
-
break
|
1873
|
-
time.sleep(0.1)
|
1874
|
-
raise Exception(
|
1875
|
-
"Text {%s} not found in {%s}! Actual text: {%s}"
|
1876
|
-
% (text, selector, element.text_all)
|
1877
|
-
)
|
1938
|
+
"""Same as wait_for_text()"""
|
1939
|
+
self.wait_for_text(text, selector=selector, timeout=timeout)
|
1940
|
+
return True
|
1878
1941
|
|
1879
1942
|
def assert_exact_text(self, text, selector="body", timeout=None):
|
1880
1943
|
if not timeout:
|
@@ -1904,6 +1967,13 @@ class CDPMethods():
|
|
1904
1967
|
% (text, element.text_all, selector)
|
1905
1968
|
)
|
1906
1969
|
|
1970
|
+
def assert_text_not_visible(self, text, selector="body", timeout=None):
|
1971
|
+
"""Raises an exception if the text is still visible after timeout."""
|
1972
|
+
self.wait_for_text_not_visible(
|
1973
|
+
text, selector=selector, timeout=timeout
|
1974
|
+
)
|
1975
|
+
return True
|
1976
|
+
|
1907
1977
|
def assert_true(self, expression):
|
1908
1978
|
if not expression:
|
1909
1979
|
raise AssertionError("%s is not true" % expression)
|
@@ -1454,6 +1454,8 @@ class BaseCase(unittest.TestCase):
|
|
1454
1454
|
|
1455
1455
|
def is_text_visible(self, text, selector="body", by="css selector"):
|
1456
1456
|
"""Returns whether the text substring is visible in the element."""
|
1457
|
+
if self.__is_cdp_swap_needed():
|
1458
|
+
return self.cdp.is_text_visible(text, selector)
|
1457
1459
|
self.wait_for_ready_state_complete()
|
1458
1460
|
time.sleep(0.01)
|
1459
1461
|
selector, by = self.__recalculate_selector(selector, by)
|
@@ -1464,6 +1466,8 @@ class BaseCase(unittest.TestCase):
|
|
1464
1466
|
def is_exact_text_visible(self, text, selector="body", by="css selector"):
|
1465
1467
|
"""Returns whether the text is exactly equal to the element text.
|
1466
1468
|
(Leading and trailing whitespace is ignored in the verification.)"""
|
1469
|
+
if self.__is_cdp_swap_needed():
|
1470
|
+
return self.cdp.is_exact_text_visible(text, selector)
|
1467
1471
|
self.wait_for_ready_state_complete()
|
1468
1472
|
time.sleep(0.01)
|
1469
1473
|
selector, by = self.__recalculate_selector(selector, by)
|
@@ -9281,7 +9285,8 @@ class BaseCase(unittest.TestCase):
|
|
9281
9285
|
"bottom_left", "bottom_center", "bottom_right"]
|
9282
9286
|
max_messages: The limit of concurrent messages to display."""
|
9283
9287
|
self.__check_scope()
|
9284
|
-
self.
|
9288
|
+
if not self.__is_cdp_swap_needed():
|
9289
|
+
self._check_browser()
|
9285
9290
|
if not theme:
|
9286
9291
|
theme = "default" # "flat"
|
9287
9292
|
if not location:
|
@@ -9308,7 +9313,8 @@ class BaseCase(unittest.TestCase):
|
|
9308
9313
|
You can also post messages by using =>
|
9309
9314
|
self.execute_script('Messenger().post("My Message")') """
|
9310
9315
|
self.__check_scope()
|
9311
|
-
self.
|
9316
|
+
if not self.__is_cdp_swap_needed():
|
9317
|
+
self._check_browser()
|
9312
9318
|
if style not in ["info", "success", "error"]:
|
9313
9319
|
style = "info"
|
9314
9320
|
if not duration:
|
@@ -10326,6 +10332,10 @@ class BaseCase(unittest.TestCase):
|
|
10326
10332
|
if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT:
|
10327
10333
|
timeout = self.__get_new_timeout(timeout)
|
10328
10334
|
selector, by = self.__recalculate_selector(selector, by)
|
10335
|
+
if self.__is_cdp_swap_needed():
|
10336
|
+
return self.cdp.wait_for_text(
|
10337
|
+
text, selector=selector, timeout=timeout
|
10338
|
+
)
|
10329
10339
|
return page_actions.wait_for_text_not_visible(
|
10330
10340
|
self.driver, text, selector, by, timeout
|
10331
10341
|
)
|
@@ -13909,7 +13919,8 @@ class BaseCase(unittest.TestCase):
|
|
13909
13919
|
js_utils.highlight_element_with_js(self.driver, element, loops, o_bs)
|
13910
13920
|
|
13911
13921
|
def __highlight_with_jquery(self, selector, loops, o_bs):
|
13912
|
-
self.
|
13922
|
+
if not self.__is_cdp_swap_needed():
|
13923
|
+
self.wait_for_ready_state_complete()
|
13913
13924
|
js_utils.highlight_with_jquery(self.driver, selector, loops, o_bs)
|
13914
13925
|
|
13915
13926
|
def __highlight_with_js_2(self, message, selector, o_bs):
|
@@ -585,52 +585,60 @@ def highlight_with_jquery(driver, selector, loops=4, o_bs=""):
|
|
585
585
|
'0px 0px 6px 6px rgba(128, 128, 128, 0.5)');"""
|
586
586
|
% selector
|
587
587
|
)
|
588
|
-
|
588
|
+
with suppress(Exception):
|
589
|
+
safe_execute_script(driver, script)
|
589
590
|
for n in range(loops):
|
590
591
|
script = (
|
591
592
|
"""jQuery('%s').css('box-shadow',
|
592
593
|
'0px 0px 6px 6px rgba(255, 0, 0, 1)');"""
|
593
594
|
% selector
|
594
595
|
)
|
595
|
-
|
596
|
+
with suppress(Exception):
|
597
|
+
execute_script(driver, script)
|
596
598
|
time.sleep(0.0181)
|
597
599
|
script = (
|
598
600
|
"""jQuery('%s').css('box-shadow',
|
599
601
|
'0px 0px 6px 6px rgba(128, 0, 128, 1)');"""
|
600
602
|
% selector
|
601
603
|
)
|
602
|
-
|
604
|
+
with suppress(Exception):
|
605
|
+
execute_script(driver, script)
|
603
606
|
time.sleep(0.0181)
|
604
607
|
script = (
|
605
608
|
"""jQuery('%s').css('box-shadow',
|
606
609
|
'0px 0px 6px 6px rgba(0, 0, 255, 1)');"""
|
607
610
|
% selector
|
608
611
|
)
|
609
|
-
|
612
|
+
with suppress(Exception):
|
613
|
+
execute_script(driver, script)
|
610
614
|
time.sleep(0.0181)
|
611
615
|
script = (
|
612
616
|
"""jQuery('%s').css('box-shadow',
|
613
617
|
'0px 0px 6px 6px rgba(0, 255, 0, 1)');"""
|
614
618
|
% selector
|
615
619
|
)
|
616
|
-
|
620
|
+
with suppress(Exception):
|
621
|
+
execute_script(driver, script)
|
617
622
|
time.sleep(0.0181)
|
618
623
|
script = (
|
619
624
|
"""jQuery('%s').css('box-shadow',
|
620
625
|
'0px 0px 6px 6px rgba(128, 128, 0, 1)');"""
|
621
626
|
% selector
|
622
627
|
)
|
623
|
-
|
628
|
+
with suppress(Exception):
|
629
|
+
execute_script(driver, script)
|
624
630
|
time.sleep(0.0181)
|
625
631
|
script = (
|
626
632
|
"""jQuery('%s').css('box-shadow',
|
627
633
|
'0px 0px 6px 6px rgba(128, 0, 128, 1)');"""
|
628
634
|
% selector
|
629
635
|
)
|
630
|
-
|
636
|
+
with suppress(Exception):
|
637
|
+
execute_script(driver, script)
|
631
638
|
time.sleep(0.0181)
|
632
639
|
script = """jQuery('%s').css('box-shadow', '%s');""" % (selector, o_bs)
|
633
|
-
|
640
|
+
with suppress(Exception):
|
641
|
+
execute_script(driver, script)
|
634
642
|
|
635
643
|
|
636
644
|
def add_css_link(driver, css_link):
|
@@ -924,9 +932,20 @@ def post_message(driver, message, msg_dur=None, style="info"):
|
|
924
932
|
"""hideAfter: %s, hideOnNavigate: true});"""
|
925
933
|
% (message, style, msg_dur)
|
926
934
|
)
|
935
|
+
retry = False
|
927
936
|
try:
|
928
937
|
execute_script(driver, messenger_script)
|
938
|
+
except TypeError as e:
|
939
|
+
if (
|
940
|
+
shared_utils.is_cdp_swap_needed(driver)
|
941
|
+
and "cannot unpack non-iterable" in str(e)
|
942
|
+
):
|
943
|
+
pass
|
944
|
+
else:
|
945
|
+
retry = True
|
929
946
|
except Exception:
|
947
|
+
retry = True
|
948
|
+
if retry:
|
930
949
|
activate_messenger(driver)
|
931
950
|
set_messenger_theme(driver)
|
932
951
|
try:
|
@@ -1273,7 +1292,10 @@ def slow_scroll_to_element(driver, element, *args, **kwargs):
|
|
1273
1292
|
scroll_position = execute_script(driver, "return window.scrollY;")
|
1274
1293
|
element_location_y = None
|
1275
1294
|
try:
|
1276
|
-
|
1295
|
+
if shared_utils.is_cdp_swap_needed(driver):
|
1296
|
+
element.get_position().y
|
1297
|
+
else:
|
1298
|
+
element_location_y = element.location["y"]
|
1277
1299
|
except Exception:
|
1278
1300
|
element.location_once_scrolled_into_view
|
1279
1301
|
return
|
@@ -265,6 +265,8 @@ class Browser:
|
|
265
265
|
:param new_window: Open new window
|
266
266
|
:return: Page
|
267
267
|
"""
|
268
|
+
if url and ":" not in url:
|
269
|
+
url = "https://" + url
|
268
270
|
if new_tab or new_window:
|
269
271
|
# Create new target using the browser session.
|
270
272
|
target_id = await self.connection.send(
|
@@ -4,6 +4,7 @@ import asyncio
|
|
4
4
|
import fasteners
|
5
5
|
import logging
|
6
6
|
import os
|
7
|
+
import sys
|
7
8
|
import time
|
8
9
|
import types
|
9
10
|
import typing
|
@@ -11,6 +12,7 @@ from contextlib import suppress
|
|
11
12
|
from seleniumbase import config as sb_config
|
12
13
|
from seleniumbase.config import settings
|
13
14
|
from seleniumbase.core import detect_b_ver
|
15
|
+
from seleniumbase.core import proxy_helper
|
14
16
|
from seleniumbase.fixtures import constants
|
15
17
|
from seleniumbase.fixtures import shared_utils
|
16
18
|
from typing import Optional, List, Union, Callable
|
@@ -23,6 +25,7 @@ import mycdp as cdp
|
|
23
25
|
|
24
26
|
logger = logging.getLogger(__name__)
|
25
27
|
IS_LINUX = shared_utils.is_linux()
|
28
|
+
PROXY_DIR_LOCK = proxy_helper.PROXY_DIR_LOCK
|
26
29
|
T = typing.TypeVar("T")
|
27
30
|
|
28
31
|
|
@@ -139,6 +142,85 @@ def __activate_virtual_display_as_needed(
|
|
139
142
|
__activate_standard_virtual_display()
|
140
143
|
|
141
144
|
|
145
|
+
def __set_proxy_filenames():
|
146
|
+
DOWNLOADS_DIR = constants.Files.DOWNLOADS_FOLDER
|
147
|
+
for num in range(1000):
|
148
|
+
PROXY_DIR_PATH = os.path.join(DOWNLOADS_DIR, "proxy_ext_dir_%s" % num)
|
149
|
+
if os.path.exists(PROXY_DIR_PATH):
|
150
|
+
continue
|
151
|
+
proxy_helper.PROXY_DIR_PATH = PROXY_DIR_PATH
|
152
|
+
return
|
153
|
+
# Exceeded upper bound. Use Defaults:
|
154
|
+
PROXY_DIR_PATH = os.path.join(DOWNLOADS_DIR, "proxy_ext_dir")
|
155
|
+
proxy_helper.PROXY_DIR_PATH = PROXY_DIR_PATH
|
156
|
+
|
157
|
+
|
158
|
+
def __add_chrome_ext_dir(extension_dir, dir_path):
|
159
|
+
# Add dir_path to the existing extension_dir
|
160
|
+
option_exists = False
|
161
|
+
if extension_dir:
|
162
|
+
option_exists = True
|
163
|
+
extension_dir = "%s,%s" % (
|
164
|
+
extension_dir, os.path.realpath(dir_path)
|
165
|
+
)
|
166
|
+
if not option_exists:
|
167
|
+
extension_dir = os.path.realpath(dir_path)
|
168
|
+
return extension_dir
|
169
|
+
|
170
|
+
|
171
|
+
def __add_chrome_proxy_extension(
|
172
|
+
extension_dir,
|
173
|
+
proxy_string,
|
174
|
+
proxy_user,
|
175
|
+
proxy_pass,
|
176
|
+
proxy_bypass_list=None,
|
177
|
+
multi_proxy=False,
|
178
|
+
):
|
179
|
+
"""Implementation of https://stackoverflow.com/a/35293284/7058266
|
180
|
+
for https://stackoverflow.com/q/12848327/7058266
|
181
|
+
(Run Selenium on a proxy server that requires authentication.)"""
|
182
|
+
args = " ".join(sys.argv)
|
183
|
+
bypass_list = proxy_bypass_list
|
184
|
+
if (
|
185
|
+
not ("-n" in sys.argv or " -n=" in args or args == "-c")
|
186
|
+
and not multi_proxy
|
187
|
+
):
|
188
|
+
# Single-threaded
|
189
|
+
proxy_dir_lock = fasteners.InterProcessLock(PROXY_DIR_LOCK)
|
190
|
+
with proxy_dir_lock:
|
191
|
+
proxy_helper.create_proxy_ext(
|
192
|
+
proxy_string,
|
193
|
+
proxy_user,
|
194
|
+
proxy_pass,
|
195
|
+
bypass_list,
|
196
|
+
zip_it=False,
|
197
|
+
)
|
198
|
+
proxy_dir_path = proxy_helper.PROXY_DIR_PATH
|
199
|
+
extension_dir = __add_chrome_ext_dir(
|
200
|
+
extension_dir, proxy_dir_path
|
201
|
+
)
|
202
|
+
else:
|
203
|
+
# Multi-threaded
|
204
|
+
proxy_dir_lock = fasteners.InterProcessLock(PROXY_DIR_LOCK)
|
205
|
+
with proxy_dir_lock:
|
206
|
+
with suppress(Exception):
|
207
|
+
shared_utils.make_writable(PROXY_DIR_LOCK)
|
208
|
+
if multi_proxy:
|
209
|
+
__set_proxy_filenames()
|
210
|
+
if not os.path.exists(proxy_helper.PROXY_DIR_PATH):
|
211
|
+
proxy_helper.create_proxy_ext(
|
212
|
+
proxy_string,
|
213
|
+
proxy_user,
|
214
|
+
proxy_pass,
|
215
|
+
bypass_list,
|
216
|
+
zip_it=False,
|
217
|
+
)
|
218
|
+
extension_dir = __add_chrome_ext_dir(
|
219
|
+
extension_dir, proxy_helper.PROXY_DIR_PATH
|
220
|
+
)
|
221
|
+
return extension_dir
|
222
|
+
|
223
|
+
|
142
224
|
async def start(
|
143
225
|
config: Optional[Config] = None,
|
144
226
|
*,
|
@@ -156,6 +238,8 @@ async def start(
|
|
156
238
|
xvfb: Optional[int] = None, # Use a special virtual display on Linux
|
157
239
|
headed: Optional[bool] = None, # Override default Xvfb mode on Linux
|
158
240
|
expert: Optional[bool] = None, # Open up closed Shadow-root elements
|
241
|
+
proxy: Optional[str] = None, # "host:port" or "user:pass@host:port"
|
242
|
+
extension_dir: Optional[str] = None, # Chrome extension directory
|
159
243
|
**kwargs: Optional[dict],
|
160
244
|
) -> Browser:
|
161
245
|
"""
|
@@ -200,6 +284,18 @@ async def start(
|
|
200
284
|
if IS_LINUX and not headless and not headed and not xvfb:
|
201
285
|
xvfb = True # The default setting on Linux
|
202
286
|
__activate_virtual_display_as_needed(headless, headed, xvfb, xvfb_metrics)
|
287
|
+
if proxy and "@" in str(proxy):
|
288
|
+
user_with_pass = proxy.split("@")[0]
|
289
|
+
if ":" in user_with_pass:
|
290
|
+
proxy_user = user_with_pass.split(":")[0]
|
291
|
+
proxy_pass = user_with_pass.split(":")[1]
|
292
|
+
proxy_string = proxy.split("@")[1]
|
293
|
+
extension_dir = __add_chrome_proxy_extension(
|
294
|
+
extension_dir,
|
295
|
+
proxy_string,
|
296
|
+
proxy_user,
|
297
|
+
proxy_pass,
|
298
|
+
)
|
203
299
|
if not config:
|
204
300
|
config = Config(
|
205
301
|
user_data_dir,
|
@@ -213,13 +309,19 @@ async def start(
|
|
213
309
|
host=host,
|
214
310
|
port=port,
|
215
311
|
expert=expert,
|
312
|
+
proxy=proxy,
|
313
|
+
extension_dir=extension_dir,
|
216
314
|
**kwargs,
|
217
315
|
)
|
316
|
+
driver = None
|
218
317
|
try:
|
219
|
-
|
318
|
+
driver = await Browser.create(config)
|
220
319
|
except Exception:
|
221
320
|
time.sleep(0.15)
|
222
|
-
|
321
|
+
driver = await Browser.create(config)
|
322
|
+
if proxy and "@" in str(proxy):
|
323
|
+
time.sleep(0.11)
|
324
|
+
return driver
|
223
325
|
|
224
326
|
|
225
327
|
async def start_async(*args, **kwargs) -> Browser:
|
@@ -40,6 +40,8 @@ class Config:
|
|
40
40
|
host: str = AUTO,
|
41
41
|
port: int = AUTO,
|
42
42
|
expert: bool = AUTO,
|
43
|
+
proxy: Optional[str] = None,
|
44
|
+
extension_dir: Optional[str] = None,
|
43
45
|
**kwargs: dict,
|
44
46
|
):
|
45
47
|
"""
|
@@ -91,6 +93,8 @@ class Config:
|
|
91
93
|
self.host = host
|
92
94
|
self.port = port
|
93
95
|
self.expert = expert
|
96
|
+
self.proxy = proxy
|
97
|
+
self.extension_dir = extension_dir
|
94
98
|
self._extensions = []
|
95
99
|
# When using posix-ish operating system and running as root,
|
96
100
|
# you must use no_sandbox=True
|
@@ -195,6 +199,12 @@ class Config:
|
|
195
199
|
"--disable-web-security",
|
196
200
|
"--disable-site-isolation-trials",
|
197
201
|
]
|
202
|
+
if self.proxy:
|
203
|
+
args.append("--proxy-server=%s" % self.proxy.split("@")[-1])
|
204
|
+
args.append("--ignore-certificate-errors")
|
205
|
+
args.append("--ignore-ssl-errors=yes")
|
206
|
+
if self.extension_dir:
|
207
|
+
args.append("--load-extension=%s" % self.extension_dir)
|
198
208
|
if self._browser_args:
|
199
209
|
args.extend([arg for arg in self._browser_args if arg not in args])
|
200
210
|
if self.headless:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: seleniumbase
|
3
|
-
Version: 4.34.
|
3
|
+
Version: 4.34.16
|
4
4
|
Summary: A complete web automation framework for end-to-end testing.
|
5
5
|
Home-page: https://github.com/seleniumbase/SeleniumBase
|
6
6
|
Author: Michael Mintz
|
@@ -68,7 +68,7 @@ Requires-Dist: attrs>=25.1.0
|
|
68
68
|
Requires-Dist: certifi>=2025.1.31
|
69
69
|
Requires-Dist: exceptiongroup>=1.2.2
|
70
70
|
Requires-Dist: websockets~=13.1; python_version < "3.9"
|
71
|
-
Requires-Dist: websockets>=
|
71
|
+
Requires-Dist: websockets>=15.0; python_version >= "3.9"
|
72
72
|
Requires-Dist: filelock~=3.16.1; python_version < "3.9"
|
73
73
|
Requires-Dist: filelock>=3.17.0; python_version >= "3.9"
|
74
74
|
Requires-Dist: fasteners>=0.19
|
@@ -99,8 +99,8 @@ Requires-Dist: sniffio==1.3.1
|
|
99
99
|
Requires-Dist: h11==0.14.0
|
100
100
|
Requires-Dist: outcome==1.3.0.post0
|
101
101
|
Requires-Dist: trio==0.27.0; python_version < "3.9"
|
102
|
-
Requires-Dist: trio==0.
|
103
|
-
Requires-Dist: trio-websocket==0.
|
102
|
+
Requires-Dist: trio==0.29.0; python_version >= "3.9"
|
103
|
+
Requires-Dist: trio-websocket==0.12.1
|
104
104
|
Requires-Dist: wsproto==1.2.0
|
105
105
|
Requires-Dist: websocket-client==1.8.0
|
106
106
|
Requires-Dist: selenium==4.27.1; python_version < "3.9"
|
@@ -137,7 +137,7 @@ Requires-Dist: pytest-cov>=5.0.0; python_version < "3.9" and extra == "coverage"
|
|
137
137
|
Requires-Dist: pytest-cov>=6.0.0; python_version >= "3.9" and extra == "coverage"
|
138
138
|
Provides-Extra: flake8
|
139
139
|
Requires-Dist: flake8==5.0.4; python_version < "3.9" and extra == "flake8"
|
140
|
-
Requires-Dist: flake8==7.1.
|
140
|
+
Requires-Dist: flake8==7.1.2; python_version >= "3.9" and extra == "flake8"
|
141
141
|
Requires-Dist: mccabe==0.7.0; extra == "flake8"
|
142
142
|
Requires-Dist: pyflakes==2.5.0; python_version < "3.9" and extra == "flake8"
|
143
143
|
Requires-Dist: pyflakes==3.2.0; python_version >= "3.9" and extra == "flake8"
|
@@ -3,7 +3,7 @@ sbase/__main__.py,sha256=G0bVB1-DM4PGwQ1KyOupaWCs4ePbChZNNWuX2htim5U,647
|
|
3
3
|
sbase/steps.py,sha256=_WvAjydKqZfTdnZW9LPKkRty-g-lfdUPmLqnZj6ulcs,43013
|
4
4
|
seleniumbase/__init__.py,sha256=OtJh8nGKL4xtZpw8KPqmn7Q6R-86t4cWUDyVF5MbMTo,2398
|
5
5
|
seleniumbase/__main__.py,sha256=dn1p6dgCchmcH1zzTzzQvFwwdQQqnTGH6ULV9m4hv24,654
|
6
|
-
seleniumbase/__version__.py,sha256=
|
6
|
+
seleniumbase/__version__.py,sha256=yo5-NDclqDbu-vlvPFL7dji8w3SHeRhS6yV5yaJdYxU,47
|
7
7
|
seleniumbase/behave/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
8
|
seleniumbase/behave/behave_helper.py,sha256=elkl8P9eLulRAioLstE9baYNM9N_PHBmAOcajX-pH_Y,24198
|
9
9
|
seleniumbase/behave/behave_sb.py,sha256=qQF85LoohJBfrPK5ZcPi50v-pWtOrC9qcN1B3Ki_3tY,59401
|
@@ -36,7 +36,7 @@ seleniumbase/console_scripts/sb_print.py,sha256=tNy-bMDgwHJO3bZxMpmo9weSE8uhbH0C
|
|
36
36
|
seleniumbase/console_scripts/sb_recorder.py,sha256=fnHb5-kh11Hit-E9Ha-e4QXzqLcZvtij6mb5qNd4B1Q,11032
|
37
37
|
seleniumbase/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
38
38
|
seleniumbase/core/application_manager.py,sha256=e_0sjtI8cjY5BNyZj1QBR0j6_oCScxGmSXYEpcYwuZE,576
|
39
|
-
seleniumbase/core/browser_launcher.py,sha256=
|
39
|
+
seleniumbase/core/browser_launcher.py,sha256=zRDRfNGsCHKn5w1R_78l5SnbieQ3bm74NMmJs4O-sQ8,235755
|
40
40
|
seleniumbase/core/capabilities_parser.py,sha256=meIS2uHapTCq2ldfNAToC7r0cKmZDRXuYNKExM1GHDY,6038
|
41
41
|
seleniumbase/core/colored_traceback.py,sha256=DrRWfg7XEnKcgY59Xj7Jdk09H-XqHYBSUpB-DiZt6iY,2020
|
42
42
|
seleniumbase/core/create_db_tables.sql,sha256=VWPtrdiW_HQ6yETHjqTu-VIrTwvd8I8o1NfBeaVSHpU,972
|
@@ -46,11 +46,11 @@ seleniumbase/core/encoded_images.py,sha256=rDKJ4cNJSuKiRcFViYU7bjyTS9_moI57gUPRX
|
|
46
46
|
seleniumbase/core/jqc_helper.py,sha256=2DDQr9Q2jSSZqFzX588jLlUM9oJvyrRWq2aORSIPUdI,10322
|
47
47
|
seleniumbase/core/log_helper.py,sha256=SW8wx2f2HfU3ERbANjxEC-jDbjy_IzaNYRKPlayfRRI,23442
|
48
48
|
seleniumbase/core/mysql.py,sha256=8Fzj3p5dhtDWfMpFqFYxpSwa9s1UltiHsWJ56_aPOqk,3993
|
49
|
-
seleniumbase/core/proxy_helper.py,sha256=
|
49
|
+
seleniumbase/core/proxy_helper.py,sha256=4VkpMwavz0fx8wcOqJ_jyBT0HIXwcxmAcpd1gjJizdc,8332
|
50
50
|
seleniumbase/core/recorder_helper.py,sha256=fNGjbapXmEsht54x1o6Igk198QdnPxDDnjUOzQxNhNQ,25055
|
51
51
|
seleniumbase/core/report_helper.py,sha256=AIl6Qava2yW1uSzbLpJBlPlYDz0KE-rVhogh8hsGWBo,12201
|
52
52
|
seleniumbase/core/s3_manager.py,sha256=bkeI8I4y19ebWuQG1oEZV5qJbotC6eN8vin31OCNWJk,3521
|
53
|
-
seleniumbase/core/sb_cdp.py,sha256=
|
53
|
+
seleniumbase/core/sb_cdp.py,sha256=5OLmRH5JSJYwqDomY2O9cx_0lNlAwNYjJbUTGmFUZPQ,79126
|
54
54
|
seleniumbase/core/sb_driver.py,sha256=yvTDRblBzG6bDX7XcLiAA6QcBelSJj_HHL_04lcfeeE,13760
|
55
55
|
seleniumbase/core/session_helper.py,sha256=s9zD3PVZEWVzG2h81cCUskbNWLfdjC_LwwQjKptHCak,558
|
56
56
|
seleniumbase/core/settings_parser.py,sha256=gqVohHVlE_5L5Cqe2L24uYrRzvoK-saX8E_Df7_-_3I,7609
|
@@ -65,11 +65,11 @@ seleniumbase/extensions/disable_csp.zip,sha256=5RvomXnm2PdivUVcxTV6jfvD8WhTEsQYH
|
|
65
65
|
seleniumbase/extensions/recorder.zip,sha256=OOyzF-Ize2cSRu1CqhzSAq5vusI9hqLLd2OIApUHesI,11918
|
66
66
|
seleniumbase/extensions/sbase_ext.zip,sha256=3s1N8zrVaMz8RQEOIoBzC3KDjtmHwVZRvVsX25Odr_s,8175
|
67
67
|
seleniumbase/fixtures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
68
|
-
seleniumbase/fixtures/base_case.py,sha256=
|
68
|
+
seleniumbase/fixtures/base_case.py,sha256=AJ33rXML0feRLo6WdCcQhxmBwEtQdn_gXuOy_iFPInY,722065
|
69
69
|
seleniumbase/fixtures/constants.py,sha256=WMrItuNyKq3XVJ64NluLIRc4gJCxDw8K8qXED0b9S2w,13752
|
70
70
|
seleniumbase/fixtures/css_to_xpath.py,sha256=9ouDB1xl4MJ2os6JOgTIAyHKOQfuxtxvXC3O5hSnEKA,1954
|
71
71
|
seleniumbase/fixtures/errors.py,sha256=KyxuEVx_e3MPhVrJfNIa_3ltMpbCFxfy_jxK8RFNTns,555
|
72
|
-
seleniumbase/fixtures/js_utils.py,sha256=
|
72
|
+
seleniumbase/fixtures/js_utils.py,sha256=QxHC0Wz_rDQ5dB6B1CK_UFs9zzryuElr-fj7MUtf_lA,52204
|
73
73
|
seleniumbase/fixtures/page_actions.py,sha256=LPcFSkUvBkxLrOt4laQHHN-NLmqInT41E2vlPiOlLFY,66753
|
74
74
|
seleniumbase/fixtures/page_utils.py,sha256=H1iV8f9vDyEy87DBntyiBXC_tg8HskcebUOAJVn0hxE,12160
|
75
75
|
seleniumbase/fixtures/shared_utils.py,sha256=G6CsE-Adt-GfuZF-71jXWKSIQW7YZPx8FIM24pVd_yI,8368
|
@@ -115,9 +115,9 @@ seleniumbase/undetected/reactor.py,sha256=NropaXcO54pzmDq6quR27qPJxab6636H7LRAaq
|
|
115
115
|
seleniumbase/undetected/webelement.py,sha256=OOpUYbEiOG52KsYYyuDW9tYLdA2SMnukvwQHUdPVn9E,1389
|
116
116
|
seleniumbase/undetected/cdp_driver/__init__.py,sha256=c0TjMwPfVFyoqYOJ7PQ-Jln_L_dpN3ebHyaD-juQoM0,64
|
117
117
|
seleniumbase/undetected/cdp_driver/_contradict.py,sha256=lP4b0h5quAy573ETn_TBbYV889cL1AuPLVInpJ0ZkiU,3183
|
118
|
-
seleniumbase/undetected/cdp_driver/browser.py,sha256=
|
119
|
-
seleniumbase/undetected/cdp_driver/cdp_util.py,sha256=
|
120
|
-
seleniumbase/undetected/cdp_driver/config.py,sha256=
|
118
|
+
seleniumbase/undetected/cdp_driver/browser.py,sha256=ruPunmJKwE67Veh1MjSkZAF5W38FMwc32lHgy1YULho,30261
|
119
|
+
seleniumbase/undetected/cdp_driver/cdp_util.py,sha256=zlYc_oTqtCSjV_T7lzPbFyJlj_78NHMxKkrpleXcfpQ,21374
|
120
|
+
seleniumbase/undetected/cdp_driver/config.py,sha256=t8KV1Vqa5SQRBq3-gjkHHmj9h85AplAM01asO3AWufs,12507
|
121
121
|
seleniumbase/undetected/cdp_driver/connection.py,sha256=sOTUGjbUqKA2hPvDcRCdqw1VQjVGJs7mbgVvzS7ldtE,23360
|
122
122
|
seleniumbase/undetected/cdp_driver/element.py,sha256=FIC6v7OmumLCT-_vIc3H4oju_oBbaLpWJUJIKm2c_q4,40467
|
123
123
|
seleniumbase/undetected/cdp_driver/tab.py,sha256=rcASsWY_mC7L0wXpFSWM5mtojzA47qG9BWEMXe7ZGF8,50906
|
@@ -135,9 +135,9 @@ seleniumbase/utilities/selenium_grid/start-grid-hub.bat,sha256=Ftq-GrAKRYH2ssDPr
|
|
135
135
|
seleniumbase/utilities/selenium_grid/start-grid-hub.sh,sha256=KADv0RUHONLL2_I443QFK8PryBpDmKn5Gy0s4o0vDSM,106
|
136
136
|
seleniumbase/utilities/selenium_ide/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
137
137
|
seleniumbase/utilities/selenium_ide/convert_ide.py,sha256=pZFnqEJQEKZPyNFjkLD29s2HPQgCrWW9XJWpCPhWOoM,31691
|
138
|
-
seleniumbase-4.34.
|
139
|
-
seleniumbase-4.34.
|
140
|
-
seleniumbase-4.34.
|
141
|
-
seleniumbase-4.34.
|
142
|
-
seleniumbase-4.34.
|
143
|
-
seleniumbase-4.34.
|
138
|
+
seleniumbase-4.34.16.dist-info/LICENSE,sha256=BRblZsX7HyPUjQmYTiyWr_e9tzWvmR3R4SFclM2R3W0,1085
|
139
|
+
seleniumbase-4.34.16.dist-info/METADATA,sha256=qF4wtXCAPxi0YzvlBRfk_z-drHDdQH4wTTkhCcWHO3g,86522
|
140
|
+
seleniumbase-4.34.16.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
141
|
+
seleniumbase-4.34.16.dist-info/entry_points.txt,sha256=CNrh2EKNaHYEhO6pP1RJyVLB99LkDDYX7TnUK8xfjqk,623
|
142
|
+
seleniumbase-4.34.16.dist-info/top_level.txt,sha256=4N97aBOQ8ETCnDnokBsWb07lJfTaq3C1ZzYRxvLMxqU,19
|
143
|
+
seleniumbase-4.34.16.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|