seleniumbase 4.32.2__py3-none-any.whl → 4.32.4__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 +10 -2
- seleniumbase/core/sb_cdp.py +65 -13
- seleniumbase/fixtures/base_case.py +67 -13
- seleniumbase/fixtures/shared_utils.py +18 -0
- seleniumbase/plugins/driver_manager.py +8 -7
- seleniumbase/undetected/__init__.py +13 -6
- seleniumbase/undetected/cdp.py +0 -1
- seleniumbase/undetected/cdp_driver/cdp_util.py +29 -18
- seleniumbase/undetected/cdp_driver/config.py +13 -0
- seleniumbase/undetected/cdp_driver/connection.py +14 -1
- seleniumbase/undetected/cdp_driver/tab.py +1 -1
- seleniumbase/undetected/dprocess.py +0 -1
- seleniumbase/undetected/options.py +3 -2
- seleniumbase/undetected/patcher.py +0 -1
- seleniumbase/undetected/reactor.py +0 -1
- {seleniumbase-4.32.2.dist-info → seleniumbase-4.32.4.dist-info}/METADATA +48 -46
- {seleniumbase-4.32.2.dist-info → seleniumbase-4.32.4.dist-info}/RECORD +22 -22
- {seleniumbase-4.32.2.dist-info → seleniumbase-4.32.4.dist-info}/LICENSE +0 -0
- {seleniumbase-4.32.2.dist-info → seleniumbase-4.32.4.dist-info}/WHEEL +0 -0
- {seleniumbase-4.32.2.dist-info → seleniumbase-4.32.4.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.32.2.dist-info → seleniumbase-4.32.4.dist-info}/top_level.txt +0 -0
seleniumbase/__version__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# seleniumbase package
|
2
|
-
__version__ = "4.32.
|
2
|
+
__version__ = "4.32.4"
|
@@ -542,6 +542,7 @@ def uc_open_with_cdp_mode(driver, url=None):
|
|
542
542
|
driver.cdp_base = loop.run_until_complete(
|
543
543
|
cdp_util.start(host=cdp_host, port=cdp_port)
|
544
544
|
)
|
545
|
+
|
545
546
|
page = loop.run_until_complete(driver.cdp_base.get(url))
|
546
547
|
loop.run_until_complete(page.activate())
|
547
548
|
if not safe_url:
|
@@ -549,7 +550,7 @@ def uc_open_with_cdp_mode(driver, url=None):
|
|
549
550
|
cdp = types.SimpleNamespace()
|
550
551
|
CDPM = sb_cdp.CDPMethods(loop, page, driver)
|
551
552
|
cdp.get = CDPM.get
|
552
|
-
cdp.open = CDPM.
|
553
|
+
cdp.open = CDPM.open
|
553
554
|
cdp.reload = CDPM.reload
|
554
555
|
cdp.refresh = CDPM.refresh
|
555
556
|
cdp.add_handler = CDPM.add_handler
|
@@ -590,6 +591,7 @@ def uc_open_with_cdp_mode(driver, url=None):
|
|
590
591
|
cdp.medimize = CDPM.medimize
|
591
592
|
cdp.set_window_rect = CDPM.set_window_rect
|
592
593
|
cdp.reset_window_size = CDPM.reset_window_size
|
594
|
+
cdp.set_locale = CDPM.set_locale
|
593
595
|
cdp.set_attributes = CDPM.set_attributes
|
594
596
|
cdp.internalize_links = CDPM.internalize_links
|
595
597
|
cdp.get_window = CDPM.get_window
|
@@ -2179,8 +2181,13 @@ def _set_chrome_options(
|
|
2179
2181
|
or IS_LINUX # switches to Xvfb (non-headless)
|
2180
2182
|
)
|
2181
2183
|
):
|
2184
|
+
chrome_options.add_argument("--no-pings")
|
2182
2185
|
chrome_options.add_argument("--disable-popup-blocking")
|
2183
|
-
chrome_options.add_argument("--homepage=chrome://
|
2186
|
+
chrome_options.add_argument("--homepage=chrome://version/")
|
2187
|
+
chrome_options.add_argument("--animation-duration-scale=0")
|
2188
|
+
chrome_options.add_argument("--wm-window-animations-disabled")
|
2189
|
+
chrome_options.add_argument("--enable-privacy-sandbox-ads-apis")
|
2190
|
+
chrome_options.add_argument("--disable-background-timer-throttling")
|
2184
2191
|
# Skip remaining options that trigger anti-bot services
|
2185
2192
|
return chrome_options
|
2186
2193
|
chrome_options.add_argument("--test-type")
|
@@ -4523,6 +4530,7 @@ def get_local_driver(
|
|
4523
4530
|
and uc_chrome_version
|
4524
4531
|
and uc_chrome_version >= 117
|
4525
4532
|
and (headless or headless2)
|
4533
|
+
and chromium_arg != "decoy"
|
4526
4534
|
):
|
4527
4535
|
from seleniumbase.console_scripts import (
|
4528
4536
|
sb_install
|
seleniumbase/core/sb_cdp.py
CHANGED
@@ -76,13 +76,21 @@ class CDPMethods():
|
|
76
76
|
|
77
77
|
def get(self, url):
|
78
78
|
url = shared_utils.fix_url_as_needed(url)
|
79
|
-
|
79
|
+
driver = self.driver
|
80
|
+
if hasattr(driver, "cdp_base"):
|
81
|
+
driver = driver.cdp_base
|
82
|
+
self.page = self.loop.run_until_complete(driver.get(url))
|
80
83
|
url_protocol = url.split(":")[0]
|
81
84
|
safe_url = True
|
82
85
|
if url_protocol not in ["about", "data", "chrome"]:
|
83
86
|
safe_url = False
|
84
87
|
if not safe_url:
|
85
88
|
time.sleep(constants.UC.CDP_MODE_OPEN_WAIT)
|
89
|
+
self.__slow_mode_pause_if_set()
|
90
|
+
self.loop.run_until_complete(self.page.wait())
|
91
|
+
|
92
|
+
def open(self, url):
|
93
|
+
self.get(url)
|
86
94
|
|
87
95
|
def reload(self, ignore_cache=True, script_to_evaluate_on_load=None):
|
88
96
|
self.loop.run_until_complete(
|
@@ -111,18 +119,28 @@ class CDPMethods():
|
|
111
119
|
with the closest text-length to the text being searched for."""
|
112
120
|
self.__add_light_pause()
|
113
121
|
selector = self.__convert_to_css_if_xpath(selector)
|
122
|
+
early_failure = False
|
114
123
|
if (":contains(" in selector):
|
115
124
|
tag_name = selector.split(":contains(")[0].split(" ")[-1]
|
116
125
|
text = selector.split(":contains(")[1].split(")")[0][1:-1]
|
117
126
|
with suppress(Exception):
|
118
127
|
self.loop.run_until_complete(
|
119
|
-
self.page.select(tag_name, timeout=
|
128
|
+
self.page.select(tag_name, timeout=timeout)
|
120
129
|
)
|
121
|
-
self.loop.run_until_complete(
|
122
|
-
|
123
|
-
|
130
|
+
self.loop.run_until_complete(
|
131
|
+
self.page.find(text, timeout=timeout)
|
132
|
+
)
|
133
|
+
elements = []
|
134
|
+
with suppress(Exception):
|
135
|
+
elements = self.find_elements_by_text(text, tag_name=tag_name)
|
136
|
+
if elements:
|
137
|
+
return self.__add_sync_methods(elements[0])
|
138
|
+
else:
|
139
|
+
early_failure = True
|
124
140
|
failure = False
|
125
141
|
try:
|
142
|
+
if early_failure:
|
143
|
+
raise Exception("Failed!")
|
126
144
|
element = self.loop.run_until_complete(
|
127
145
|
self.page.find(
|
128
146
|
selector, best_match=best_match, timeout=timeout
|
@@ -230,9 +248,11 @@ class CDPMethods():
|
|
230
248
|
)
|
231
249
|
|
232
250
|
def __click(self, element):
|
233
|
-
|
251
|
+
result = (
|
234
252
|
self.loop.run_until_complete(element.click_async())
|
235
253
|
)
|
254
|
+
self.loop.run_until_complete(self.page.wait())
|
255
|
+
return result
|
236
256
|
|
237
257
|
def __flash(self, element):
|
238
258
|
return (
|
@@ -250,9 +270,11 @@ class CDPMethods():
|
|
250
270
|
)
|
251
271
|
|
252
272
|
def __mouse_click(self, element):
|
253
|
-
|
273
|
+
result = (
|
254
274
|
self.loop.run_until_complete(element.mouse_click_async())
|
255
275
|
)
|
276
|
+
self.loop.run_until_complete(self.page.wait())
|
277
|
+
return result
|
256
278
|
|
257
279
|
def __mouse_drag(self, element, destination):
|
258
280
|
return (
|
@@ -353,33 +375,51 @@ class CDPMethods():
|
|
353
375
|
|
354
376
|
def tile_windows(self, windows=None, max_columns=0):
|
355
377
|
"""Tile windows and return the grid of tiled windows."""
|
378
|
+
driver = self.driver
|
379
|
+
if hasattr(driver, "cdp_base"):
|
380
|
+
driver = driver.cdp_base
|
356
381
|
return self.loop.run_until_complete(
|
357
|
-
|
382
|
+
driver.tile_windows(windows, max_columns)
|
358
383
|
)
|
359
384
|
|
360
385
|
def get_all_cookies(self, *args, **kwargs):
|
386
|
+
driver = self.driver
|
387
|
+
if hasattr(driver, "cdp_base"):
|
388
|
+
driver = driver.cdp_base
|
361
389
|
return self.loop.run_until_complete(
|
362
|
-
|
390
|
+
driver.cookies.get_all(*args, **kwargs)
|
363
391
|
)
|
364
392
|
|
365
393
|
def set_all_cookies(self, *args, **kwargs):
|
394
|
+
driver = self.driver
|
395
|
+
if hasattr(driver, "cdp_base"):
|
396
|
+
driver = driver.cdp_base
|
366
397
|
return self.loop.run_until_complete(
|
367
|
-
|
398
|
+
driver.cookies.set_all(*args, **kwargs)
|
368
399
|
)
|
369
400
|
|
370
401
|
def save_cookies(self, *args, **kwargs):
|
402
|
+
driver = self.driver
|
403
|
+
if hasattr(driver, "cdp_base"):
|
404
|
+
driver = driver.cdp_base
|
371
405
|
return self.loop.run_until_complete(
|
372
|
-
|
406
|
+
driver.cookies.save(*args, **kwargs)
|
373
407
|
)
|
374
408
|
|
375
409
|
def load_cookies(self, *args, **kwargs):
|
410
|
+
driver = self.driver
|
411
|
+
if hasattr(driver, "cdp_base"):
|
412
|
+
driver = driver.cdp_base
|
376
413
|
return self.loop.run_until_complete(
|
377
|
-
|
414
|
+
driver.cookies.load(*args, **kwargs)
|
378
415
|
)
|
379
416
|
|
380
417
|
def clear_cookies(self, *args, **kwargs):
|
418
|
+
driver = self.driver
|
419
|
+
if hasattr(driver, "cdp_base"):
|
420
|
+
driver = driver.cdp_base
|
381
421
|
return self.loop.run_until_complete(
|
382
|
-
|
422
|
+
driver.cookies.clear(*args, **kwargs)
|
383
423
|
)
|
384
424
|
|
385
425
|
def sleep(self, seconds):
|
@@ -408,17 +448,20 @@ class CDPMethods():
|
|
408
448
|
self.__add_light_pause()
|
409
449
|
element.click()
|
410
450
|
self.__slow_mode_pause_if_set()
|
451
|
+
self.loop.run_until_complete(self.page.wait())
|
411
452
|
|
412
453
|
def click_active_element(self):
|
413
454
|
self.loop.run_until_complete(
|
414
455
|
self.page.evaluate("document.activeElement.click()")
|
415
456
|
)
|
416
457
|
self.__slow_mode_pause_if_set()
|
458
|
+
self.loop.run_until_complete(self.page.wait())
|
417
459
|
|
418
460
|
def click_if_visible(self, selector):
|
419
461
|
if self.is_element_visible(selector):
|
420
462
|
self.find_element(selector).click()
|
421
463
|
self.__slow_mode_pause_if_set()
|
464
|
+
self.loop.run_until_complete(self.page.wait())
|
422
465
|
|
423
466
|
def mouse_click(self, selector, timeout=settings.SMALL_TIMEOUT):
|
424
467
|
"""(Attempt simulating a mouse click)"""
|
@@ -427,6 +470,7 @@ class CDPMethods():
|
|
427
470
|
self.__add_light_pause()
|
428
471
|
element.mouse_click()
|
429
472
|
self.__slow_mode_pause_if_set()
|
473
|
+
self.loop.run_until_complete(self.page.wait())
|
430
474
|
|
431
475
|
def nested_click(self, parent_selector, selector):
|
432
476
|
"""
|
@@ -436,6 +480,7 @@ class CDPMethods():
|
|
436
480
|
element = self.find_element(parent_selector)
|
437
481
|
element.query_selector(selector).mouse_click()
|
438
482
|
self.__slow_mode_pause_if_set()
|
483
|
+
self.loop.run_until_complete(self.page.wait())
|
439
484
|
|
440
485
|
def get_nested_element(self, parent_selector, selector):
|
441
486
|
"""(Can be used to find an element inside an iframe)"""
|
@@ -483,6 +528,7 @@ class CDPMethods():
|
|
483
528
|
text = text[:-1] + "\r\n"
|
484
529
|
element.send_keys(text)
|
485
530
|
self.__slow_mode_pause_if_set()
|
531
|
+
self.loop.run_until_complete(self.page.wait())
|
486
532
|
|
487
533
|
def press_keys(self, selector, text, timeout=settings.SMALL_TIMEOUT):
|
488
534
|
"""Similar to send_keys(), but presses keys at human speed."""
|
@@ -499,6 +545,7 @@ class CDPMethods():
|
|
499
545
|
element.send_keys("\r\n")
|
500
546
|
time.sleep(0.0375)
|
501
547
|
self.__slow_mode_pause_if_set()
|
548
|
+
self.loop.run_until_complete(self.page.wait())
|
502
549
|
|
503
550
|
def type(self, selector, text, timeout=settings.SMALL_TIMEOUT):
|
504
551
|
"""Similar to send_keys(), but clears the text field first."""
|
@@ -510,6 +557,7 @@ class CDPMethods():
|
|
510
557
|
text = text[:-1] + "\r\n"
|
511
558
|
element.send_keys(text)
|
512
559
|
self.__slow_mode_pause_if_set()
|
560
|
+
self.loop.run_until_complete(self.page.wait())
|
513
561
|
|
514
562
|
def evaluate(self, expression):
|
515
563
|
"""Run a JavaScript expression and return the result."""
|
@@ -760,6 +808,10 @@ class CDPMethods():
|
|
760
808
|
)
|
761
809
|
)
|
762
810
|
|
811
|
+
def set_locale(self, locale):
|
812
|
+
"""(Settings will take effect on the next page load)"""
|
813
|
+
self.loop.run_until_complete(self.page.set_locale(locale))
|
814
|
+
|
763
815
|
def set_attributes(self, selector, attribute, value):
|
764
816
|
"""This method uses JavaScript to set/update a common attribute.
|
765
817
|
All matching selectors from querySelectorAll() are used.
|
@@ -4099,6 +4099,7 @@ class BaseCase(unittest.TestCase):
|
|
4099
4099
|
or not any(os.scandir(user_data_dir))
|
4100
4100
|
)
|
4101
4101
|
and self.browser == "chrome"
|
4102
|
+
and shared_utils.is_chrome_130_or_newer(binary_location)
|
4102
4103
|
):
|
4103
4104
|
import tempfile
|
4104
4105
|
if not user_data_dir:
|
@@ -4108,7 +4109,7 @@ class BaseCase(unittest.TestCase):
|
|
4108
4109
|
try:
|
4109
4110
|
decoy_driver = browser_launcher.get_driver(
|
4110
4111
|
browser_name=browser_name,
|
4111
|
-
headless=
|
4112
|
+
headless=False,
|
4112
4113
|
locale_code=locale_code,
|
4113
4114
|
use_grid=use_grid,
|
4114
4115
|
protocol=protocol,
|
@@ -4134,7 +4135,7 @@ class BaseCase(unittest.TestCase):
|
|
4134
4135
|
log_cdp_events=log_cdp_events,
|
4135
4136
|
no_sandbox=no_sandbox,
|
4136
4137
|
disable_gpu=disable_gpu,
|
4137
|
-
headless1=
|
4138
|
+
headless1=False,
|
4138
4139
|
headless2=True,
|
4139
4140
|
incognito=incognito,
|
4140
4141
|
guest_mode=guest_mode,
|
@@ -4147,12 +4148,12 @@ class BaseCase(unittest.TestCase):
|
|
4147
4148
|
host_resolver_rules=host_resolver_rules,
|
4148
4149
|
block_images=block_images,
|
4149
4150
|
do_not_track=do_not_track,
|
4150
|
-
chromium_arg=
|
4151
|
+
chromium_arg="decoy",
|
4151
4152
|
firefox_arg=firefox_arg,
|
4152
4153
|
firefox_pref=firefox_pref,
|
4153
4154
|
user_data_dir=user_data_dir,
|
4154
|
-
extension_zip=
|
4155
|
-
extension_dir=
|
4155
|
+
extension_zip=None,
|
4156
|
+
extension_dir=None,
|
4156
4157
|
disable_features=disable_features,
|
4157
4158
|
binary_location=binary_location,
|
4158
4159
|
driver_version=driver_version,
|
@@ -4166,12 +4167,13 @@ class BaseCase(unittest.TestCase):
|
|
4166
4167
|
device_pixel_ratio=d_p_r,
|
4167
4168
|
browser=browser_name,
|
4168
4169
|
)
|
4169
|
-
time.sleep(0.
|
4170
|
+
time.sleep(0.16)
|
4170
4171
|
except Exception:
|
4171
4172
|
pass
|
4172
4173
|
finally:
|
4173
4174
|
with suppress(Exception):
|
4174
4175
|
decoy_driver.quit()
|
4176
|
+
time.sleep(0.08)
|
4175
4177
|
# Launch a web browser
|
4176
4178
|
new_driver = browser_launcher.get_driver(
|
4177
4179
|
browser_name=browser_name,
|
@@ -4513,8 +4515,15 @@ class BaseCase(unittest.TestCase):
|
|
4513
4515
|
cookies_file.writelines(json_cookies)
|
4514
4516
|
cookies_file.close()
|
4515
4517
|
|
4516
|
-
def load_cookies(self, name="cookies.txt"):
|
4517
|
-
"""
|
4518
|
+
def load_cookies(self, name="cookies.txt", expiry=False):
|
4519
|
+
"""
|
4520
|
+
Loads the page cookies from the "saved_cookies" folder.
|
4521
|
+
Usage for setting expiry:
|
4522
|
+
If expiry == 0 or False: Delete "expiry".
|
4523
|
+
If expiry == -1 (or < 0): Do not modify "expiry".
|
4524
|
+
If expiry > 0: Set "expiry" to expiry minutes in the future.
|
4525
|
+
If expiry == True: Set "expiry" to 24 hours in the future.
|
4526
|
+
"""
|
4518
4527
|
cookies = self.get_saved_cookies(name)
|
4519
4528
|
self.wait_for_ready_state_complete()
|
4520
4529
|
origin = self.get_origin()
|
@@ -4523,8 +4532,14 @@ class BaseCase(unittest.TestCase):
|
|
4523
4532
|
if "domain" in cookie:
|
4524
4533
|
if cookie["domain"] not in origin:
|
4525
4534
|
cookie["domain"] = trim_origin
|
4526
|
-
if "expiry" in cookie:
|
4535
|
+
if "expiry" in cookie and (not expiry or expiry == 0):
|
4527
4536
|
del cookie["expiry"]
|
4537
|
+
elif isinstance(expiry, (int, float)) and expiry < 0:
|
4538
|
+
pass
|
4539
|
+
elif isinstance(expiry, (int, float)) and expiry > 0:
|
4540
|
+
cookie["expiry"] = int(time.time()) + int(expiry * 60.0)
|
4541
|
+
elif expiry:
|
4542
|
+
cookie["expiry"] = int(time.time()) + 86400
|
4528
4543
|
self.driver.add_cookie(cookie)
|
4529
4544
|
|
4530
4545
|
def delete_all_cookies(self):
|
@@ -4585,18 +4600,57 @@ class BaseCase(unittest.TestCase):
|
|
4585
4600
|
def get_cookies(self):
|
4586
4601
|
return self.driver.get_cookies()
|
4587
4602
|
|
4588
|
-
def add_cookie(self, cookie_dict):
|
4603
|
+
def add_cookie(self, cookie_dict, expiry=False):
|
4589
4604
|
"""Usage examples:
|
4590
4605
|
self.add_cookie({'name': 'foo', 'value': 'bar'})
|
4591
4606
|
self.add_cookie({'name': 'foo', 'value': 'bar', 'path': '/'})
|
4592
4607
|
self.add_cookie({'name': 'foo', 'value': 'bar', 'secure': True})
|
4593
4608
|
self.add_cookie({'name': 'foo', 'value': 'bar', 'sameSite': 'Strict'})
|
4609
|
+
Usage for setting expiry:
|
4610
|
+
If expiry == 0 or False: Delete "expiry".
|
4611
|
+
If expiry == -1 (or < 0): Do not modify "expiry".
|
4612
|
+
If expiry > 0: Set "expiry" to expiry minutes in the future.
|
4613
|
+
If expiry == True: Set "expiry" to 24 hours in the future.
|
4594
4614
|
"""
|
4615
|
+
cookie = cookie_dict
|
4616
|
+
if "domain" in cookie:
|
4617
|
+
origin = self.get_origin()
|
4618
|
+
trim_origin = origin.split("://")[-1]
|
4619
|
+
if cookie["domain"] not in origin:
|
4620
|
+
cookie["domain"] = trim_origin
|
4621
|
+
if "expiry" in cookie and (not expiry or expiry == 0):
|
4622
|
+
del cookie["expiry"]
|
4623
|
+
elif isinstance(expiry, (int, float)) and expiry < 0:
|
4624
|
+
pass
|
4625
|
+
elif isinstance(expiry, (int, float)) and expiry > 0:
|
4626
|
+
cookie["expiry"] = int(time.time()) + int(expiry * 60.0)
|
4627
|
+
elif expiry:
|
4628
|
+
cookie["expiry"] = int(time.time()) + 86400
|
4595
4629
|
self.driver.add_cookie(cookie_dict)
|
4596
4630
|
|
4597
|
-
def add_cookies(self, cookies):
|
4598
|
-
|
4599
|
-
|
4631
|
+
def add_cookies(self, cookies, expiry=False):
|
4632
|
+
"""
|
4633
|
+
Usage for setting expiry:
|
4634
|
+
If expiry == 0 or False: Delete "expiry".
|
4635
|
+
If expiry == -1 (or < 0): Do not modify "expiry".
|
4636
|
+
If expiry > 0: Set "expiry" to expiry minutes in the future.
|
4637
|
+
If expiry == True: Set "expiry" to 24 hours in the future.
|
4638
|
+
"""
|
4639
|
+
origin = self.get_origin()
|
4640
|
+
trim_origin = origin.split("://")[-1]
|
4641
|
+
for cookie in cookies:
|
4642
|
+
if "domain" in cookie:
|
4643
|
+
if cookie["domain"] not in origin:
|
4644
|
+
cookie["domain"] = trim_origin
|
4645
|
+
if "expiry" in cookie and (not expiry or expiry == 0):
|
4646
|
+
del cookie["expiry"]
|
4647
|
+
elif isinstance(expiry, (int, float)) and expiry < 0:
|
4648
|
+
pass
|
4649
|
+
elif isinstance(expiry, (int, float)) and expiry > 0:
|
4650
|
+
cookie["expiry"] = int(time.time()) + int(expiry * 60.0)
|
4651
|
+
elif expiry:
|
4652
|
+
cookie["expiry"] = int(time.time()) + 86400
|
4653
|
+
self.driver.add_cookie(cookie)
|
4600
4654
|
|
4601
4655
|
def __set_esc_skip(self):
|
4602
4656
|
if hasattr(self, "esc_end") and self.esc_end:
|
@@ -4,6 +4,7 @@ import os
|
|
4
4
|
import platform
|
5
5
|
import sys
|
6
6
|
import time
|
7
|
+
from contextlib import suppress
|
7
8
|
from seleniumbase import config as sb_config
|
8
9
|
from seleniumbase.fixtures import constants
|
9
10
|
|
@@ -99,6 +100,23 @@ def is_cdp_swap_needed(driver):
|
|
99
100
|
)
|
100
101
|
|
101
102
|
|
103
|
+
def is_chrome_130_or_newer(self, binary_location=None):
|
104
|
+
from seleniumbase.core import detect_b_ver
|
105
|
+
|
106
|
+
"""Due to changes in Chrome-130, UC Mode freezes at start-up
|
107
|
+
unless the user-data-dir already exists and is populated."""
|
108
|
+
with suppress(Exception):
|
109
|
+
if not binary_location:
|
110
|
+
ver = detect_b_ver.get_browser_version_from_os("google-chrome")
|
111
|
+
else:
|
112
|
+
ver = detect_b_ver.get_browser_version_from_binary(
|
113
|
+
binary_location
|
114
|
+
)
|
115
|
+
if ver and len(ver) > 3 and int(ver.split(".")[0]) >= 130:
|
116
|
+
return True
|
117
|
+
return False
|
118
|
+
|
119
|
+
|
102
120
|
def format_exc(exception, message):
|
103
121
|
"""Formats an exception message to make the output cleaner."""
|
104
122
|
from selenium.common.exceptions import ElementNotVisibleException
|
@@ -233,6 +233,7 @@ def Driver(
|
|
233
233
|
wire (bool): Shortcut / Duplicate of "use_wire".
|
234
234
|
pls (str): Shortcut / Duplicate of "page_load_strategy".
|
235
235
|
"""
|
236
|
+
from contextlib import suppress
|
236
237
|
from seleniumbase import config as sb_config
|
237
238
|
from seleniumbase.config import settings
|
238
239
|
from seleniumbase.fixtures import constants
|
@@ -800,6 +801,7 @@ def Driver(
|
|
800
801
|
or not any(os.scandir(user_data_dir))
|
801
802
|
)
|
802
803
|
and browser == "chrome"
|
804
|
+
and shared_utils.is_chrome_130_or_newer(binary_location)
|
803
805
|
):
|
804
806
|
import tempfile
|
805
807
|
import time
|
@@ -849,12 +851,12 @@ def Driver(
|
|
849
851
|
host_resolver_rules=host_resolver_rules,
|
850
852
|
block_images=block_images,
|
851
853
|
do_not_track=do_not_track,
|
852
|
-
chromium_arg=
|
854
|
+
chromium_arg="decoy",
|
853
855
|
firefox_arg=firefox_arg,
|
854
856
|
firefox_pref=firefox_pref,
|
855
857
|
user_data_dir=user_data_dir,
|
856
|
-
extension_zip=
|
857
|
-
extension_dir=
|
858
|
+
extension_zip=None,
|
859
|
+
extension_dir=None,
|
858
860
|
disable_features=disable_features,
|
859
861
|
binary_location=binary_location,
|
860
862
|
driver_version=driver_version,
|
@@ -868,14 +870,13 @@ def Driver(
|
|
868
870
|
device_pixel_ratio=d_p_r,
|
869
871
|
browser=browser_name,
|
870
872
|
)
|
871
|
-
time.sleep(0.
|
873
|
+
time.sleep(0.16)
|
872
874
|
except Exception:
|
873
875
|
pass
|
874
876
|
finally:
|
875
|
-
|
877
|
+
with suppress(Exception):
|
876
878
|
decoy_driver.quit()
|
877
|
-
|
878
|
-
pass
|
879
|
+
time.sleep(0.08)
|
879
880
|
|
880
881
|
driver = browser_launcher.get_driver(
|
881
882
|
browser_name=browser_name,
|
@@ -1,4 +1,3 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
1
|
import logging
|
3
2
|
import os
|
4
3
|
import re
|
@@ -433,10 +432,15 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
|
433
432
|
time.sleep(timeout)
|
434
433
|
with suppress(Exception):
|
435
434
|
self.service.start()
|
436
|
-
time.sleep(0.012)
|
437
435
|
with suppress(Exception):
|
438
436
|
self.start_session()
|
439
|
-
|
437
|
+
with suppress(Exception):
|
438
|
+
if self.current_url.startswith("chrome-extension://"):
|
439
|
+
self.close()
|
440
|
+
self.service.stop()
|
441
|
+
self.service.start()
|
442
|
+
self.start_session()
|
443
|
+
self._is_connected = True
|
440
444
|
|
441
445
|
def disconnect(self):
|
442
446
|
"""Stops the chromedriver service that runs in the background.
|
@@ -445,7 +449,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
|
445
449
|
with suppress(Exception):
|
446
450
|
self.service.stop()
|
447
451
|
self._is_connected = False
|
448
|
-
time.sleep(0.012)
|
449
452
|
|
450
453
|
def connect(self):
|
451
454
|
"""Starts the chromedriver service that runs in the background
|
@@ -453,11 +456,15 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
|
453
456
|
if hasattr(self, "service"):
|
454
457
|
with suppress(Exception):
|
455
458
|
self.service.start()
|
456
|
-
time.sleep(0.012)
|
457
459
|
with suppress(Exception):
|
458
460
|
self.start_session()
|
461
|
+
with suppress(Exception):
|
462
|
+
if self.current_url.startswith("chrome-extension://"):
|
463
|
+
self.close()
|
464
|
+
self.service.stop()
|
465
|
+
self.service.start()
|
466
|
+
self.start_session()
|
459
467
|
self._is_connected = True
|
460
|
-
time.sleep(0.012)
|
461
468
|
|
462
469
|
def start_session(self, capabilities=None):
|
463
470
|
if not capabilities:
|
seleniumbase/undetected/cdp.py
CHANGED
@@ -5,6 +5,7 @@ import logging
|
|
5
5
|
import time
|
6
6
|
import types
|
7
7
|
import typing
|
8
|
+
from seleniumbase.fixtures import shared_utils
|
8
9
|
from typing import Optional, List, Union, Callable
|
9
10
|
from .element import Element
|
10
11
|
from .browser import Browser
|
@@ -92,30 +93,40 @@ async def start(
|
|
92
93
|
|
93
94
|
async def start_async(*args, **kwargs) -> Browser:
|
94
95
|
headless = False
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
96
|
+
binary_location = None
|
97
|
+
if "browser_executable_path" in kwargs:
|
98
|
+
binary_location = kwargs["browser_executable_path"]
|
99
|
+
if shared_utils.is_chrome_130_or_newer(binary_location):
|
100
|
+
if "headless" in kwargs:
|
101
|
+
headless = kwargs["headless"]
|
102
|
+
decoy_args = kwargs
|
103
|
+
decoy_args["headless"] = True
|
104
|
+
driver = await start(**decoy_args)
|
105
|
+
kwargs["headless"] = headless
|
106
|
+
kwargs["user_data_dir"] = driver.config.user_data_dir
|
107
|
+
time.sleep(0.2)
|
108
|
+
driver.stop() # Due to Chrome-130, must stop & start
|
109
|
+
time.sleep(0.1)
|
104
110
|
return await start(*args, **kwargs)
|
105
111
|
|
106
112
|
|
107
113
|
def start_sync(*args, **kwargs) -> Browser:
|
108
114
|
loop = asyncio.get_event_loop()
|
109
115
|
headless = False
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
116
|
+
binary_location = None
|
117
|
+
if "browser_executable_path" in kwargs:
|
118
|
+
binary_location = kwargs["browser_executable_path"]
|
119
|
+
if shared_utils.is_chrome_130_or_newer(binary_location):
|
120
|
+
if "headless" in kwargs:
|
121
|
+
headless = kwargs["headless"]
|
122
|
+
decoy_args = kwargs
|
123
|
+
decoy_args["headless"] = True
|
124
|
+
driver = loop.run_until_complete(start(**decoy_args))
|
125
|
+
kwargs["headless"] = headless
|
126
|
+
kwargs["user_data_dir"] = driver.config.user_data_dir
|
127
|
+
time.sleep(0.2)
|
128
|
+
driver.stop() # Due to Chrome-130, must stop & start
|
129
|
+
time.sleep(0.1)
|
119
130
|
return loop.run_until_complete(start(*args, **kwargs))
|
120
131
|
|
121
132
|
|
@@ -5,6 +5,7 @@ import secrets
|
|
5
5
|
import sys
|
6
6
|
import tempfile
|
7
7
|
import zipfile
|
8
|
+
from seleniumbase.config import settings
|
8
9
|
from typing import Union, List, Optional
|
9
10
|
|
10
11
|
__all__ = [
|
@@ -101,13 +102,23 @@ class Config:
|
|
101
102
|
# Other keyword args will be accessible by attribute
|
102
103
|
self.__dict__.update(kwargs)
|
103
104
|
super().__init__()
|
105
|
+
start_width = settings.CHROME_START_WIDTH
|
106
|
+
start_height = settings.CHROME_START_HEIGHT
|
107
|
+
start_x = settings.WINDOW_START_X
|
108
|
+
start_y = settings.WINDOW_START_Y
|
104
109
|
self._default_browser_args = [
|
110
|
+
"--window-size=%s,%s" % (start_width, start_height),
|
111
|
+
"--window-position=%s,%s" % (start_x, start_y),
|
105
112
|
"--remote-allow-origins=*",
|
106
113
|
"--no-first-run",
|
107
114
|
"--no-service-autorun",
|
115
|
+
"--disable-auto-reload",
|
108
116
|
"--no-default-browser-check",
|
109
117
|
"--homepage=about:blank",
|
110
118
|
"--no-pings",
|
119
|
+
"--wm-window-animations-disabled",
|
120
|
+
"--animation-duration-scale=0",
|
121
|
+
"--enable-privacy-sandbox-ads-apis",
|
111
122
|
"--safebrowsing-disable-download-protection",
|
112
123
|
'--simulate-outdated-no-au="Tue, 31 Dec 2099 23:59:59 GMT"',
|
113
124
|
"--password-store=basic",
|
@@ -118,10 +129,12 @@ class Config:
|
|
118
129
|
"--disable-prompt-on-repost",
|
119
130
|
"--disable-password-generation",
|
120
131
|
"--disable-ipc-flooding-protection",
|
132
|
+
"--disable-background-timer-throttling",
|
121
133
|
"--disable-search-engine-choice-screen",
|
122
134
|
"--disable-backgrounding-occluded-windows",
|
123
135
|
"--disable-client-side-phishing-detection",
|
124
136
|
"--disable-top-sites",
|
137
|
+
"--disable-translate",
|
125
138
|
"--disable-renderer-backgrounding",
|
126
139
|
"--disable-background-networking",
|
127
140
|
"--disable-dev-shm-usage",
|
@@ -9,6 +9,7 @@ import sys
|
|
9
9
|
import types
|
10
10
|
from asyncio import iscoroutine, iscoroutinefunction
|
11
11
|
from typing import (
|
12
|
+
Optional,
|
12
13
|
Generator,
|
13
14
|
Union,
|
14
15
|
Awaitable,
|
@@ -291,7 +292,14 @@ class Connection(metaclass=CantTouchThis):
|
|
291
292
|
if self.listener and self.listener.running:
|
292
293
|
self.listener.cancel()
|
293
294
|
self.enabled_domains.clear()
|
294
|
-
await
|
295
|
+
await asyncio.sleep(0.015)
|
296
|
+
try:
|
297
|
+
await self.websocket.close()
|
298
|
+
except Exception:
|
299
|
+
logger.debug(
|
300
|
+
"\n❌ Error closing websocket connection to %s",
|
301
|
+
self.websocket_url
|
302
|
+
)
|
295
303
|
logger.debug(
|
296
304
|
"\n❌ Closed websocket connection to %s", self.websocket_url
|
297
305
|
)
|
@@ -336,6 +344,10 @@ class Connection(metaclass=CantTouchThis):
|
|
336
344
|
# No listener created yet.
|
337
345
|
pass
|
338
346
|
|
347
|
+
async def set_locale(self, locale: Optional[str] = None):
|
348
|
+
"""Sets the Language Locale code via set_user_agent_override."""
|
349
|
+
await self.send(cdp.network.set_user_agent_override("", locale))
|
350
|
+
|
339
351
|
def __getattr__(self, item):
|
340
352
|
""":meta private:"""
|
341
353
|
try:
|
@@ -535,6 +547,7 @@ class Listener:
|
|
535
547
|
self.idle.set()
|
536
548
|
# Pause for a moment.
|
537
549
|
# await asyncio.sleep(self.time_before_considered_idle / 10)
|
550
|
+
await asyncio.sleep(0.015)
|
538
551
|
continue
|
539
552
|
except (Exception,) as e:
|
540
553
|
logger.debug(
|
@@ -1,4 +1,3 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
1
|
import json
|
3
2
|
import os
|
4
3
|
from contextlib import suppress
|
@@ -59,7 +58,9 @@ class ChromeOptions(ChromiumOptions):
|
|
59
58
|
json.load(f), undot_prefs
|
60
59
|
)
|
61
60
|
with suppress(Exception):
|
62
|
-
with open(
|
61
|
+
with open(
|
62
|
+
prefs_file, encoding="utf-8", mode="w", errors="ignore"
|
63
|
+
) as f:
|
63
64
|
json.dump(undot_prefs, f)
|
64
65
|
# Remove experimental_options to avoid errors
|
65
66
|
del self._experimental_options["prefs"]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: seleniumbase
|
3
|
-
Version: 4.32.
|
3
|
+
Version: 4.32.4
|
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
|
@@ -79,8 +79,8 @@ Requires-Dist: parse-type>=0.6.4
|
|
79
79
|
Requires-Dist: colorama>=0.4.6
|
80
80
|
Requires-Dist: pyyaml>=6.0.2
|
81
81
|
Requires-Dist: pygments>=2.18.0
|
82
|
-
Requires-Dist: tabcompleter>=1.
|
83
|
-
Requires-Dist: pdbp>=1.
|
82
|
+
Requires-Dist: tabcompleter>=1.4.0
|
83
|
+
Requires-Dist: pdbp>=1.6.0
|
84
84
|
Requires-Dist: idna==3.10
|
85
85
|
Requires-Dist: chardet==5.2.0
|
86
86
|
Requires-Dist: charset-normalizer==3.4.0
|
@@ -236,6 +236,8 @@ Requires-Dist: zstandard==0.23.0; extra == "selenium-wire"
|
|
236
236
|
|
237
237
|
👤 Note that <span translate="no">SeleniumBase</span> <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md"><b>UC Mode</b> (Stealth Mode) has its own ReadMe</a>.
|
238
238
|
|
239
|
+
🐙 Also note that Seleniumbase <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md"><b>CDP Mode</b> has its own separate ReadMe</a>.
|
240
|
+
|
239
241
|
ℹ️ Scripts can be called via <code translate="no"><b>python</b></code>, although some <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/syntax_formats.md">Syntax Formats</a> expect <a href="https://docs.pytest.org/en/latest/how-to/usage.html" translate="no"><b>pytest</b></a> (a Python unit-testing framework included with SeleniumBase that can discover, collect, and run tests automatically).
|
240
242
|
|
241
243
|
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py">my_first_test.py</a>, which tests login, shopping, and checkout:</p>
|
@@ -489,48 +491,49 @@ pip install -e .
|
|
489
491
|
🔵 **Type ``seleniumbase`` or ``sbase`` to verify that SeleniumBase was installed successfully:**
|
490
492
|
|
491
493
|
```bash
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
COMMANDS:
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
494
|
+
___ _ _ ___
|
495
|
+
/ __| ___| |___ _ _ (_)_ _ _ __ | _ ) __ _ ______
|
496
|
+
\__ \/ -_) / -_) ' \| | \| | ' \ | _ \/ _` (_-< -_)
|
497
|
+
|___/\___|_\___|_||_|_|\_,_|_|_|_\|___/\__,_/__|___|
|
498
|
+
----------------------------------------------------
|
499
|
+
|
500
|
+
╭──────────────────────────────────────────────────╮
|
501
|
+
│ * USAGE: "seleniumbase [COMMAND] [PARAMETERS]" │
|
502
|
+
│ * OR: "sbase [COMMAND] [PARAMETERS]" │
|
503
|
+
│ │
|
504
|
+
│ COMMANDS: PARAMETERS / DESCRIPTIONS: │
|
505
|
+
│ get / install [DRIVER_NAME] [OPTIONS] │
|
506
|
+
│ methods (List common Python methods) │
|
507
|
+
│ options (List common pytest options) │
|
508
|
+
│ behave-options (List common behave options) │
|
509
|
+
│ gui / commander [OPTIONAL PATH or TEST FILE] │
|
510
|
+
│ behave-gui (SBase Commander for Behave) │
|
511
|
+
│ caseplans [OPTIONAL PATH or TEST FILE] │
|
512
|
+
│ mkdir [DIRECTORY] [OPTIONS] │
|
513
|
+
│ mkfile [FILE.py] [OPTIONS] │
|
514
|
+
│ mkrec / codegen [FILE.py] [OPTIONS] │
|
515
|
+
│ recorder (Open Recorder Desktop App.) │
|
516
|
+
│ record (If args: mkrec. Else: App.) │
|
517
|
+
│ mkpres [FILE.py] [LANG] │
|
518
|
+
│ mkchart [FILE.py] [LANG] │
|
519
|
+
│ print [FILE] [OPTIONS] │
|
520
|
+
│ translate [SB_FILE.py] [LANG] [ACTION] │
|
521
|
+
│ convert [WEBDRIVER_UNITTEST_FILE.py] │
|
522
|
+
│ extract-objects [SB_FILE.py] │
|
523
|
+
│ inject-objects [SB_FILE.py] [OPTIONS] │
|
524
|
+
│ objectify [SB_FILE.py] [OPTIONS] │
|
525
|
+
│ revert-objects [SB_FILE.py] [OPTIONS] │
|
526
|
+
│ encrypt / obfuscate │
|
527
|
+
│ decrypt / unobfuscate │
|
528
|
+
│ proxy (Start a basic proxy server) │
|
529
|
+
│ download server (Get Selenium Grid JAR file) │
|
530
|
+
│ grid-hub [start|stop] [OPTIONS] │
|
531
|
+
│ grid-node [start|stop] --hub=[HOST/IP] │
|
532
|
+
│ │
|
533
|
+
│ * EXAMPLE => "sbase get chromedriver stable" │
|
534
|
+
│ * For command info => "sbase help [COMMAND]" │
|
535
|
+
│ * For info on all commands => "sbase --help" │
|
536
|
+
╰──────────────────────────────────────────────────╯
|
534
537
|
```
|
535
538
|
|
536
539
|
<h3>🔵 Downloading webdrivers:</h3>
|
@@ -1549,7 +1552,6 @@ pytest --reruns=1 --reruns-delay=1
|
|
1549
1552
|
<span><a href="https://github.com/seleniumbase/SeleniumBase"><img src="https://seleniumbase.github.io/img/social/share_github.svg" title="SeleniumBase on GitHub" alt="SeleniumBase on GitHub" width="64" /></a></span>
|
1550
1553
|
<span><a href="https://discord.gg/EdhQTn3EyE"><img src="https://seleniumbase.github.io/other/discord_icon.png" title="SeleniumBase on Discord" alt="SeleniumBase on Discord" width="66" /></a></span>
|
1551
1554
|
<span><a href="https://www.facebook.com/SeleniumBase"><img src="https://seleniumbase.io/img/social/share_facebook.svg" title="SeleniumBase on Facebook" alt="SeleniumBase on Facebook" width="62" /></a></span>
|
1552
|
-
<span><a href="https://gitter.im/seleniumbase/SeleniumBase" target="_blank"><img src="https://seleniumbase.github.io/img/social/share_gitter.svg" title="SeleniumBase on Gitter" alt="SeleniumBase on Gitter" width="48" /></a></span>
|
1553
1555
|
</div></p>
|
1554
1556
|
|
1555
1557
|
<p><div><b><a href="https://github.com/mdmintz">https://github.com/mdmintz</a></b></div></p>
|
@@ -3,7 +3,7 @@ sbase/__main__.py,sha256=G0bVB1-DM4PGwQ1KyOupaWCs4ePbChZNNWuX2htim5U,647
|
|
3
3
|
sbase/steps.py,sha256=bKT_u5bJkKzYWEuAXi9NVVRYYxQRCM1_YJUrNFFRVPY,42865
|
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=vFbcqGUbMcYFZy91jca1HA1X3Ls9oEd6VKZaewExcIA,46
|
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=-hza7Nx2U41mSObYiPMi48v3JlPh3sJO3yzP0kqZ1Gk,59174
|
@@ -36,7 +36,7 @@ seleniumbase/console_scripts/sb_print.py,sha256=tNy-bMDgwHJO3bZxMpmo9weSE8uhbH0C
|
|
36
36
|
seleniumbase/console_scripts/sb_recorder.py,sha256=1oAA4wFzVboNhIFDwJLD3jgy9RuoavywKQG7R67bNZE,10908
|
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=xKKxAx2swUnFBpPcny-hk7KlaAnzCmCdw-tokh5ef04,214921
|
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
|
@@ -50,7 +50,7 @@ seleniumbase/core/proxy_helper.py,sha256=cXhu8ErK9Vjdm82RMaQj7hEq_yUWizSp6LyiD50
|
|
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=OolOBITtEmAtdA6nCpal7tnrWHHUHY6DXkzCFD1T4o4,34546
|
54
54
|
seleniumbase/core/sb_driver.py,sha256=-k4vHwMnuiBIkdVInTtJA-IDLrgQfyMhNxSHMIsjepw,11623
|
55
55
|
seleniumbase/core/session_helper.py,sha256=s9zD3PVZEWVzG2h81cCUskbNWLfdjC_LwwQjKptHCak,558
|
56
56
|
seleniumbase/core/settings_parser.py,sha256=KokVXpCiGZhJ-D4Bo-hizPz5r-iefzWoiTANu9zNaq4,7504
|
@@ -65,14 +65,14 @@ seleniumbase/extensions/disable_csp.zip,sha256=YMifIIgEBiLrEFrS1sfW4Exh4br1V4oK1
|
|
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=oAnwLUFtg4inRq4I2xJEqAzkwyI2PHeNWm-UPnQXVks,714722
|
69
69
|
seleniumbase/fixtures/constants.py,sha256=XYYMpB-ZDI756LvfhSK9RxdqQ_qO9fJVXgBqBYlQNkk,13609
|
70
70
|
seleniumbase/fixtures/css_to_xpath.py,sha256=9ouDB1xl4MJ2os6JOgTIAyHKOQfuxtxvXC3O5hSnEKA,1954
|
71
71
|
seleniumbase/fixtures/errors.py,sha256=KyxuEVx_e3MPhVrJfNIa_3ltMpbCFxfy_jxK8RFNTns,555
|
72
72
|
seleniumbase/fixtures/js_utils.py,sha256=5o4CTLcCyd717lJ_atOYcC6kPRiZFx-LJIlixRrP_cE,51061
|
73
73
|
seleniumbase/fixtures/page_actions.py,sha256=fOCb2NB2PpEaE8gpAVu-73VjwLzfwP1R9HsRkix_z6s,66634
|
74
74
|
seleniumbase/fixtures/page_utils.py,sha256=5m7iXpikLs80TJoRO6_gEfXE1AKeQgcH1aFbR8o1C9A,12034
|
75
|
-
seleniumbase/fixtures/shared_utils.py,sha256
|
75
|
+
seleniumbase/fixtures/shared_utils.py,sha256=QdoepYzSpt0J_iKQhhJCENY9ry0hB2juXKkEVI3TSTg,7263
|
76
76
|
seleniumbase/fixtures/unittest_helper.py,sha256=sfZ92rZeBAn_sF_yQ3I6_I7h3lyU5-cV_UMegBNoEm8,1294
|
77
77
|
seleniumbase/fixtures/words.py,sha256=FOA4mAYvl3EPVpBTvgvK6YwCL8BdlRCmed685kEe7Vg,7827
|
78
78
|
seleniumbase/fixtures/xpath_to_css.py,sha256=lML56k656fElXJ4NJF07r35FjctrbgQkXUotNk7A-as,8876
|
@@ -86,7 +86,7 @@ seleniumbase/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
|
|
86
86
|
seleniumbase/plugins/base_plugin.py,sha256=FemdftNhOaTfQIw5bWcJQPPPGQ3P0_sMEI_YYDuzZgU,14972
|
87
87
|
seleniumbase/plugins/basic_test_info.py,sha256=8ov6n417gPbqqvrlT4zrch7l2XcRt-GF2ny6rR9AMWk,2108
|
88
88
|
seleniumbase/plugins/db_reporting_plugin.py,sha256=En09qUCoojrk9-vbcnsoHdSELoGmag2GDIyu3jTiJas,7331
|
89
|
-
seleniumbase/plugins/driver_manager.py,sha256=
|
89
|
+
seleniumbase/plugins/driver_manager.py,sha256=05WK2mJMJJ2SDXgEv1WQJad5MqWCV4qIv5FnKhb985Y,37798
|
90
90
|
seleniumbase/plugins/page_source.py,sha256=loTnXxOj4kxEukuTZEiGyvKBhY3KDVDMnNlHHheTBDE,1889
|
91
91
|
seleniumbase/plugins/pytest_plugin.py,sha256=Up96HY6q3hcPo4LQoEcKqt1hm2OmY5GZz_nMXTqDSXQ,97185
|
92
92
|
seleniumbase/plugins/s3_logging_plugin.py,sha256=WDfertQgGOW_SRJpFMaekYD6vBVW9VO62POtXXy2HCM,2319
|
@@ -106,21 +106,21 @@ seleniumbase/translate/portuguese.py,sha256=x3P4qxp56UiI41GoaL7JbUvFRYsgXU1EKjTg
|
|
106
106
|
seleniumbase/translate/russian.py,sha256=TyN9n0b4GRWDEYnHRGw1rfNAscdDmP3F3Y3aySM3C7s,27978
|
107
107
|
seleniumbase/translate/spanish.py,sha256=hh3xgW1Pq122SHYVvJAxFaXhFrjniOVncVbJbfWqOUM,25528
|
108
108
|
seleniumbase/translate/translator.py,sha256=wPhZH6e5NhmebYL1kP2eGxUcVy1gfTb6XCH8ATEPpxE,49238
|
109
|
-
seleniumbase/undetected/__init__.py,sha256=
|
110
|
-
seleniumbase/undetected/cdp.py,sha256=
|
111
|
-
seleniumbase/undetected/dprocess.py,sha256=
|
112
|
-
seleniumbase/undetected/options.py,sha256=
|
113
|
-
seleniumbase/undetected/patcher.py,sha256=
|
114
|
-
seleniumbase/undetected/reactor.py,sha256=
|
109
|
+
seleniumbase/undetected/__init__.py,sha256=8zwqLzRffTOm7nFp6ldldthHVuYB2OnU6ZGV4JOpoio,22491
|
110
|
+
seleniumbase/undetected/cdp.py,sha256=RLpwZnhUvmK9tgXcZIBBQedwk2q7Jj_EXZkmzI8WUqk,4023
|
111
|
+
seleniumbase/undetected/dprocess.py,sha256=83EV8ZHJWHG1TSUv9JNClBhdgiBXlkCc6mJ--HsoP3k,1681
|
112
|
+
seleniumbase/undetected/options.py,sha256=BoNuwhrG7oOvuLvTwkvsWCF36pMkS1tHCG-XpP4_EkI,3001
|
113
|
+
seleniumbase/undetected/patcher.py,sha256=n9WfKznr4cQvaE5Gcx7iyK27zMWIc8KdI69_m817CSQ,10825
|
114
|
+
seleniumbase/undetected/reactor.py,sha256=NropaXcO54pzmDq6quR27qPJxab6636H7LRAaq-o0ng,2859
|
115
115
|
seleniumbase/undetected/webelement.py,sha256=_s6evgUkdWJpwOnzX4qR9i796PoVbz3txlzHlOBJ4BE,1370
|
116
116
|
seleniumbase/undetected/cdp_driver/__init__.py,sha256=c0TjMwPfVFyoqYOJ7PQ-Jln_L_dpN3ebHyaD-juQoM0,64
|
117
117
|
seleniumbase/undetected/cdp_driver/_contradict.py,sha256=6thDYeoEGiC7Q3tXLgoD_AhxecCFnATzBSjNympyRHA,3184
|
118
118
|
seleniumbase/undetected/cdp_driver/browser.py,sha256=2suM75F3TV-svgBXdRZoxfqErr6_USa8_jOLwHSLlIk,30025
|
119
|
-
seleniumbase/undetected/cdp_driver/cdp_util.py,sha256=
|
120
|
-
seleniumbase/undetected/cdp_driver/config.py,sha256=
|
121
|
-
seleniumbase/undetected/cdp_driver/connection.py,sha256=
|
119
|
+
seleniumbase/undetected/cdp_driver/cdp_util.py,sha256=y60sU5rIguohZDl1tgCpuDhu3Wo6TcgvZIbqXdHIv8E,11111
|
120
|
+
seleniumbase/undetected/cdp_driver/config.py,sha256=Rjvde7V-XJ0ihZdTmOmHEVWSuDWm3SprQ3njg8SN3Go,12087
|
121
|
+
seleniumbase/undetected/cdp_driver/connection.py,sha256=HnwXlD4rawGzCyiGR3Shr4iaK7KTncvSqs3CXxCZM_8,23266
|
122
122
|
seleniumbase/undetected/cdp_driver/element.py,sha256=9oD9GxguctunrlHV3lWXlZgb9cNEjD5x03Oy84OqyVA,39631
|
123
|
-
seleniumbase/undetected/cdp_driver/tab.py,sha256=
|
123
|
+
seleniumbase/undetected/cdp_driver/tab.py,sha256=wUNF8GHrbhaUqg57A9ZTYHKhNPjZIcOHwrz3pj1SAg0,50526
|
124
124
|
seleniumbase/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
125
125
|
seleniumbase/utilities/selenium_grid/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
126
126
|
seleniumbase/utilities/selenium_grid/download_selenium_server.py,sha256=ZdoInIbhtmdKCIPxxtJHhd2sqotqcNXWMYbwWrkh9O0,1727
|
@@ -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.32.
|
139
|
-
seleniumbase-4.32.
|
140
|
-
seleniumbase-4.32.
|
141
|
-
seleniumbase-4.32.
|
142
|
-
seleniumbase-4.32.
|
143
|
-
seleniumbase-4.32.
|
138
|
+
seleniumbase-4.32.4.dist-info/LICENSE,sha256=odSYtWibXBnQ1gBg6CnDZ82n8kLF_if5-2nbqnEyD8k,1085
|
139
|
+
seleniumbase-4.32.4.dist-info/METADATA,sha256=P-aaLSxLcDhNervTnQwolcdOOYQTBgbvIwi7_LGKsgg,86271
|
140
|
+
seleniumbase-4.32.4.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
|
141
|
+
seleniumbase-4.32.4.dist-info/entry_points.txt,sha256=CNrh2EKNaHYEhO6pP1RJyVLB99LkDDYX7TnUK8xfjqk,623
|
142
|
+
seleniumbase-4.32.4.dist-info/top_level.txt,sha256=4N97aBOQ8ETCnDnokBsWb07lJfTaq3C1ZzYRxvLMxqU,19
|
143
|
+
seleniumbase-4.32.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|