seleniumbase 4.33.11__py3-none-any.whl → 4.33.13__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 +21 -3
- seleniumbase/core/log_helper.py +15 -2
- seleniumbase/core/sb_cdp.py +84 -44
- seleniumbase/fixtures/base_case.py +37 -5
- seleniumbase/fixtures/page_actions.py +7 -2
- seleniumbase/plugins/sb_manager.py +13 -0
- seleniumbase/undetected/cdp_driver/cdp_util.py +3 -0
- {seleniumbase-4.33.11.dist-info → seleniumbase-4.33.13.dist-info}/LICENSE +1 -1
- {seleniumbase-4.33.11.dist-info → seleniumbase-4.33.13.dist-info}/METADATA +54 -22
- {seleniumbase-4.33.11.dist-info → seleniumbase-4.33.13.dist-info}/RECORD +14 -14
- {seleniumbase-4.33.11.dist-info → seleniumbase-4.33.13.dist-info}/WHEEL +1 -1
- {seleniumbase-4.33.11.dist-info → seleniumbase-4.33.13.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.33.11.dist-info → seleniumbase-4.33.13.dist-info}/top_level.txt +0 -0
seleniumbase/__version__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# seleniumbase package
|
2
|
-
__version__ = "4.33.
|
2
|
+
__version__ = "4.33.13"
|
@@ -533,10 +533,26 @@ def uc_open_with_cdp_mode(driver, url=None):
|
|
533
533
|
if url_protocol not in ["about", "data", "chrome"]:
|
534
534
|
safe_url = False
|
535
535
|
|
536
|
+
headless = False
|
537
|
+
headed = None
|
538
|
+
xvfb = None
|
539
|
+
if hasattr(sb_config, "headless"):
|
540
|
+
headless = sb_config.headless
|
541
|
+
if hasattr(sb_config, "headed"):
|
542
|
+
headed = sb_config.headed
|
543
|
+
if hasattr(sb_config, "xvfb"):
|
544
|
+
xvfb = sb_config.xvfb
|
545
|
+
|
536
546
|
loop = asyncio.new_event_loop()
|
537
547
|
asyncio.set_event_loop(loop)
|
538
548
|
driver.cdp_base = loop.run_until_complete(
|
539
|
-
cdp_util.start(
|
549
|
+
cdp_util.start(
|
550
|
+
host=cdp_host,
|
551
|
+
port=cdp_port,
|
552
|
+
headless=headless,
|
553
|
+
headed=headed,
|
554
|
+
xvfb=xvfb,
|
555
|
+
)
|
540
556
|
)
|
541
557
|
loop.run_until_complete(driver.cdp_base.wait(0))
|
542
558
|
|
@@ -863,13 +879,15 @@ def __install_pyautogui_if_missing():
|
|
863
879
|
xvfb_height = 768
|
864
880
|
sb_config._xvfb_height = xvfb_height
|
865
881
|
with suppress(Exception):
|
866
|
-
|
882
|
+
_xvfb_display = Display(
|
867
883
|
visible=True,
|
868
884
|
size=(xvfb_width, xvfb_height),
|
869
885
|
backend="xvfb",
|
870
886
|
use_xauth=True,
|
871
887
|
)
|
872
|
-
|
888
|
+
_xvfb_display.start()
|
889
|
+
sb_config._virtual_display = _xvfb_display
|
890
|
+
sb_config.headless_active = True
|
873
891
|
|
874
892
|
|
875
893
|
def install_pyautogui_if_missing(driver):
|
seleniumbase/core/log_helper.py
CHANGED
@@ -15,6 +15,11 @@ if sys.version_info >= (3, 11):
|
|
15
15
|
py311_patch2 = constants.PatchPy311.PATCH
|
16
16
|
|
17
17
|
|
18
|
+
def __is_cdp_swap_needed(driver):
|
19
|
+
"""If the driver is disconnected, use a CDP method when available."""
|
20
|
+
return shared_utils.is_cdp_swap_needed(driver)
|
21
|
+
|
22
|
+
|
18
23
|
def log_screenshot(test_logpath, driver, screenshot=None, get=False):
|
19
24
|
screenshot_name = settings.SCREENSHOT_NAME
|
20
25
|
screenshot_path = os.path.join(test_logpath, screenshot_name)
|
@@ -356,7 +361,11 @@ def log_page_source(test_logpath, driver, source=None):
|
|
356
361
|
page_source = source
|
357
362
|
else:
|
358
363
|
try:
|
359
|
-
page_source =
|
364
|
+
page_source = None
|
365
|
+
if __is_cdp_swap_needed(driver):
|
366
|
+
page_source = driver.cdp.get_page_source()
|
367
|
+
else:
|
368
|
+
page_source = driver.page_source
|
360
369
|
page_source = get_html_source_with_base_href(driver, page_source)
|
361
370
|
except Exception:
|
362
371
|
source = constants.Warnings.PAGE_SOURCE_UNDEFINED
|
@@ -448,7 +457,11 @@ def get_test_name(test):
|
|
448
457
|
|
449
458
|
def get_last_page(driver):
|
450
459
|
try:
|
451
|
-
last_page =
|
460
|
+
last_page = None
|
461
|
+
if __is_cdp_swap_needed(driver):
|
462
|
+
last_page = driver.cdp.get_current_url()
|
463
|
+
else:
|
464
|
+
last_page = driver.current_url
|
452
465
|
except Exception:
|
453
466
|
last_page = "[WARNING! Browser Not Open!]"
|
454
467
|
if len(last_page) < 5:
|
seleniumbase/core/sb_cdp.py
CHANGED
@@ -127,14 +127,14 @@ class CDPMethods():
|
|
127
127
|
def add_handler(self, event, handler):
|
128
128
|
self.page.add_handler(event, handler)
|
129
129
|
|
130
|
-
def find_element(
|
131
|
-
self, selector, best_match=False, timeout=settings.SMALL_TIMEOUT
|
132
|
-
):
|
130
|
+
def find_element(self, selector, best_match=False, timeout=None):
|
133
131
|
"""Similar to select(), but also finds elements by text content.
|
134
132
|
When using text-based searches, if best_match=False, then will
|
135
133
|
find the first element with the text. If best_match=True, then
|
136
134
|
if multiple elements have that text, then will use the element
|
137
135
|
with the closest text-length to the text being searched for."""
|
136
|
+
if not timeout:
|
137
|
+
timeout = settings.SMALL_TIMEOUT
|
138
138
|
self.__add_light_pause()
|
139
139
|
selector = self.__convert_to_css_if_xpath(selector)
|
140
140
|
early_failure = False
|
@@ -167,12 +167,12 @@ class CDPMethods():
|
|
167
167
|
self.__slow_mode_pause_if_set()
|
168
168
|
return element
|
169
169
|
|
170
|
-
def find_element_by_text(
|
171
|
-
self, text, tag_name=None, timeout=settings.SMALL_TIMEOUT
|
172
|
-
):
|
170
|
+
def find_element_by_text(self, text, tag_name=None, timeout=None):
|
173
171
|
"""Returns an element by matching text.
|
174
172
|
Optionally, provide a tag_name to narrow down the search to an
|
175
173
|
element with the given tag. (Eg: a, button, div, script, span)"""
|
174
|
+
if not timeout:
|
175
|
+
timeout = settings.SMALL_TIMEOUT
|
176
176
|
self.__add_light_pause()
|
177
177
|
time_now = time.time()
|
178
178
|
self.assert_text(text, timeout=timeout)
|
@@ -218,7 +218,9 @@ class CDPMethods():
|
|
218
218
|
% (text, tag_name, timeout, plural)
|
219
219
|
)
|
220
220
|
|
221
|
-
def find_all(self, selector, timeout=
|
221
|
+
def find_all(self, selector, timeout=None):
|
222
|
+
if not timeout:
|
223
|
+
timeout = settings.SMALL_TIMEOUT
|
222
224
|
self.__add_light_pause()
|
223
225
|
selector = self.__convert_to_css_if_xpath(selector)
|
224
226
|
elements = self.loop.run_until_complete(
|
@@ -272,8 +274,10 @@ class CDPMethods():
|
|
272
274
|
updated_elements.append(element)
|
273
275
|
return updated_elements
|
274
276
|
|
275
|
-
def select(self, selector, timeout=
|
277
|
+
def select(self, selector, timeout=None):
|
276
278
|
"""Similar to find_element(), but without text-based search."""
|
279
|
+
if not timeout:
|
280
|
+
timeout = settings.SMALL_TIMEOUT
|
277
281
|
self.__add_light_pause()
|
278
282
|
selector = self.__convert_to_css_if_xpath(selector)
|
279
283
|
if (":contains(" in selector):
|
@@ -307,7 +311,9 @@ class CDPMethods():
|
|
307
311
|
self.__slow_mode_pause_if_set()
|
308
312
|
return element
|
309
313
|
|
310
|
-
def select_all(self, selector, timeout=
|
314
|
+
def select_all(self, selector, timeout=None):
|
315
|
+
if not timeout:
|
316
|
+
timeout = settings.SMALL_TIMEOUT
|
311
317
|
self.__add_light_pause()
|
312
318
|
selector = self.__convert_to_css_if_xpath(selector)
|
313
319
|
elements = self.loop.run_until_complete(
|
@@ -319,10 +325,14 @@ class CDPMethods():
|
|
319
325
|
updated_elements.append(element)
|
320
326
|
return updated_elements
|
321
327
|
|
322
|
-
def find_elements(self, selector, timeout=
|
328
|
+
def find_elements(self, selector, timeout=None):
|
329
|
+
if not timeout:
|
330
|
+
timeout = settings.SMALL_TIMEOUT
|
323
331
|
return self.select_all(selector, timeout=timeout)
|
324
332
|
|
325
|
-
def find_visible_elements(self, selector, timeout=
|
333
|
+
def find_visible_elements(self, selector, timeout=None):
|
334
|
+
if not timeout:
|
335
|
+
timeout = settings.SMALL_TIMEOUT
|
326
336
|
visible_elements = []
|
327
337
|
elements = self.select_all(selector, timeout=timeout)
|
328
338
|
for element in elements:
|
@@ -587,12 +597,12 @@ class CDPMethods():
|
|
587
597
|
driver.cookies.load(*args, **kwargs)
|
588
598
|
)
|
589
599
|
|
590
|
-
def clear_cookies(self
|
600
|
+
def clear_cookies(self):
|
591
601
|
driver = self.driver
|
592
602
|
if hasattr(driver, "cdp_base"):
|
593
603
|
driver = driver.cdp_base
|
594
604
|
return self.loop.run_until_complete(
|
595
|
-
driver.cookies.clear(
|
605
|
+
driver.cookies.clear()
|
596
606
|
)
|
597
607
|
|
598
608
|
def sleep(self, seconds):
|
@@ -616,7 +626,9 @@ class CDPMethods():
|
|
616
626
|
self.page.evaluate(js_code)
|
617
627
|
)
|
618
628
|
|
619
|
-
def click(self, selector, timeout=
|
629
|
+
def click(self, selector, timeout=None):
|
630
|
+
if not timeout:
|
631
|
+
timeout = settings.SMALL_TIMEOUT
|
620
632
|
self.__slow_mode_pause_if_set()
|
621
633
|
element = self.find_element(selector, timeout=timeout)
|
622
634
|
element.scroll_into_view()
|
@@ -672,8 +684,10 @@ class CDPMethods():
|
|
672
684
|
except Exception:
|
673
685
|
break
|
674
686
|
|
675
|
-
def mouse_click(self, selector, timeout=
|
687
|
+
def mouse_click(self, selector, timeout=None):
|
676
688
|
"""(Attempt simulating a mouse click)"""
|
689
|
+
if not timeout:
|
690
|
+
timeout = settings.SMALL_TIMEOUT
|
677
691
|
self.__slow_mode_pause_if_set()
|
678
692
|
element = self.find_element(selector, timeout=timeout)
|
679
693
|
element.scroll_into_view()
|
@@ -771,7 +785,9 @@ class CDPMethods():
|
|
771
785
|
with suppress(Exception):
|
772
786
|
self.loop.run_until_complete(self.page.evaluate(js_code))
|
773
787
|
|
774
|
-
def send_keys(self, selector, text, timeout=
|
788
|
+
def send_keys(self, selector, text, timeout=None):
|
789
|
+
if not timeout:
|
790
|
+
timeout = settings.SMALL_TIMEOUT
|
775
791
|
self.__slow_mode_pause_if_set()
|
776
792
|
element = self.select(selector, timeout=timeout)
|
777
793
|
element.scroll_into_view()
|
@@ -781,8 +797,10 @@ class CDPMethods():
|
|
781
797
|
self.__slow_mode_pause_if_set()
|
782
798
|
self.loop.run_until_complete(self.page.wait())
|
783
799
|
|
784
|
-
def press_keys(self, selector, text, timeout=
|
800
|
+
def press_keys(self, selector, text, timeout=None):
|
785
801
|
"""Similar to send_keys(), but presses keys at human speed."""
|
802
|
+
if not timeout:
|
803
|
+
timeout = settings.SMALL_TIMEOUT
|
786
804
|
self.__slow_mode_pause_if_set()
|
787
805
|
element = self.select(selector, timeout=timeout)
|
788
806
|
element.scroll_into_view()
|
@@ -799,8 +817,10 @@ class CDPMethods():
|
|
799
817
|
self.__slow_mode_pause_if_set()
|
800
818
|
self.loop.run_until_complete(self.page.wait())
|
801
819
|
|
802
|
-
def type(self, selector, text, timeout=
|
820
|
+
def type(self, selector, text, timeout=None):
|
803
821
|
"""Similar to send_keys(), but clears the text field first."""
|
822
|
+
if not timeout:
|
823
|
+
timeout = settings.SMALL_TIMEOUT
|
804
824
|
self.__slow_mode_pause_if_set()
|
805
825
|
element = self.select(selector, timeout=timeout)
|
806
826
|
element.scroll_into_view()
|
@@ -812,8 +832,10 @@ class CDPMethods():
|
|
812
832
|
self.__slow_mode_pause_if_set()
|
813
833
|
self.loop.run_until_complete(self.page.wait())
|
814
834
|
|
815
|
-
def set_value(self, selector, text, timeout=
|
835
|
+
def set_value(self, selector, text, timeout=None):
|
816
836
|
"""Similar to send_keys(), but clears the text field first."""
|
837
|
+
if not timeout:
|
838
|
+
timeout = settings.SMALL_TIMEOUT
|
817
839
|
self.__slow_mode_pause_if_set()
|
818
840
|
selector = self.__convert_to_css_if_xpath(selector)
|
819
841
|
element = self.select(selector, timeout=timeout)
|
@@ -1036,7 +1058,9 @@ class CDPMethods():
|
|
1036
1058
|
coordinates["y"] = y if y else 0
|
1037
1059
|
return coordinates
|
1038
1060
|
|
1039
|
-
def get_element_rect(self, selector, timeout=
|
1061
|
+
def get_element_rect(self, selector, timeout=None):
|
1062
|
+
if not timeout:
|
1063
|
+
timeout = settings.SMALL_TIMEOUT
|
1040
1064
|
selector = self.__convert_to_css_if_xpath(selector)
|
1041
1065
|
self.select(selector, timeout=timeout)
|
1042
1066
|
self.__add_light_pause()
|
@@ -1049,23 +1073,29 @@ class CDPMethods():
|
|
1049
1073
|
)
|
1050
1074
|
return coordinates
|
1051
1075
|
|
1052
|
-
def get_element_size(self, selector):
|
1053
|
-
|
1076
|
+
def get_element_size(self, selector, timeout=None):
|
1077
|
+
if not timeout:
|
1078
|
+
timeout = settings.SMALL_TIMEOUT
|
1079
|
+
element_rect = self.get_element_rect(selector, timeout=timeout)
|
1054
1080
|
coordinates = {}
|
1055
1081
|
coordinates["width"] = element_rect["width"]
|
1056
1082
|
coordinates["height"] = element_rect["height"]
|
1057
1083
|
return coordinates
|
1058
1084
|
|
1059
|
-
def get_element_position(self, selector):
|
1060
|
-
|
1085
|
+
def get_element_position(self, selector, timeout=None):
|
1086
|
+
if not timeout:
|
1087
|
+
timeout = settings.SMALL_TIMEOUT
|
1088
|
+
element_rect = self.get_element_rect(selector, timeout=timeout)
|
1061
1089
|
coordinates = {}
|
1062
1090
|
coordinates["x"] = element_rect["x"]
|
1063
1091
|
coordinates["y"] = element_rect["y"]
|
1064
1092
|
return coordinates
|
1065
1093
|
|
1066
|
-
def get_gui_element_rect(self, selector):
|
1094
|
+
def get_gui_element_rect(self, selector, timeout=None):
|
1067
1095
|
"""(Coordinates are relative to the screen. Not the window.)"""
|
1068
|
-
|
1096
|
+
if not timeout:
|
1097
|
+
timeout = settings.SMALL_TIMEOUT
|
1098
|
+
element_rect = self.get_element_rect(selector, timeout=timeout)
|
1069
1099
|
e_width = element_rect["width"]
|
1070
1100
|
e_height = element_rect["height"]
|
1071
1101
|
window_rect = self.get_window_rect()
|
@@ -1079,9 +1109,11 @@ class CDPMethods():
|
|
1079
1109
|
y = y + window_rect["scrollY"]
|
1080
1110
|
return ({"height": e_height, "width": e_width, "x": x, "y": y})
|
1081
1111
|
|
1082
|
-
def get_gui_element_center(self, selector):
|
1112
|
+
def get_gui_element_center(self, selector, timeout=None):
|
1083
1113
|
"""(Coordinates are relative to the screen. Not the window.)"""
|
1084
|
-
|
1114
|
+
if not timeout:
|
1115
|
+
timeout = settings.SMALL_TIMEOUT
|
1116
|
+
element_rect = self.get_gui_element_rect(selector, timeout=timeout)
|
1085
1117
|
e_width = element_rect["width"]
|
1086
1118
|
e_height = element_rect["height"]
|
1087
1119
|
e_x = element_rect["x"]
|
@@ -1629,9 +1661,9 @@ class CDPMethods():
|
|
1629
1661
|
return True
|
1630
1662
|
return False
|
1631
1663
|
|
1632
|
-
def wait_for_element_visible(
|
1633
|
-
|
1634
|
-
|
1664
|
+
def wait_for_element_visible(self, selector, timeout=None):
|
1665
|
+
if not timeout:
|
1666
|
+
timeout = settings.SMALL_TIMEOUT
|
1635
1667
|
try:
|
1636
1668
|
self.select(selector, timeout=timeout)
|
1637
1669
|
except Exception:
|
@@ -1642,8 +1674,10 @@ class CDPMethods():
|
|
1642
1674
|
time.sleep(0.1)
|
1643
1675
|
raise Exception("Element {%s} was not visible!" % selector)
|
1644
1676
|
|
1645
|
-
def assert_element(self, selector, timeout=
|
1677
|
+
def assert_element(self, selector, timeout=None):
|
1646
1678
|
"""Same as assert_element_visible()"""
|
1679
|
+
if not timeout:
|
1680
|
+
timeout = settings.SMALL_TIMEOUT
|
1647
1681
|
try:
|
1648
1682
|
self.select(selector, timeout=timeout)
|
1649
1683
|
except Exception:
|
@@ -1654,8 +1688,10 @@ class CDPMethods():
|
|
1654
1688
|
time.sleep(0.1)
|
1655
1689
|
raise Exception("Element {%s} was not visible!" % selector)
|
1656
1690
|
|
1657
|
-
def assert_element_visible(self, selector, timeout=
|
1691
|
+
def assert_element_visible(self, selector, timeout=None):
|
1658
1692
|
"""Same as assert_element()"""
|
1693
|
+
if not timeout:
|
1694
|
+
timeout = settings.SMALL_TIMEOUT
|
1659
1695
|
try:
|
1660
1696
|
self.select(selector, timeout=timeout)
|
1661
1697
|
except Exception:
|
@@ -1666,16 +1702,20 @@ class CDPMethods():
|
|
1666
1702
|
time.sleep(0.1)
|
1667
1703
|
raise Exception("Element {%s} was not visible!" % selector)
|
1668
1704
|
|
1669
|
-
def assert_element_present(self, selector, timeout=
|
1705
|
+
def assert_element_present(self, selector, timeout=None):
|
1670
1706
|
"""Assert element is present in the DOM. (Visibility NOT required)"""
|
1707
|
+
if not timeout:
|
1708
|
+
timeout = settings.SMALL_TIMEOUT
|
1671
1709
|
try:
|
1672
1710
|
self.select(selector, timeout=timeout)
|
1673
1711
|
except Exception:
|
1674
1712
|
raise Exception("Element {%s} was not found!" % selector)
|
1675
1713
|
return True
|
1676
1714
|
|
1677
|
-
def assert_element_absent(self, selector, timeout=
|
1715
|
+
def assert_element_absent(self, selector, timeout=None):
|
1678
1716
|
"""Assert element is not present in the DOM."""
|
1717
|
+
if not timeout:
|
1718
|
+
timeout = settings.SMALL_TIMEOUT
|
1679
1719
|
start_ms = time.time() * 1000.0
|
1680
1720
|
stop_ms = start_ms + (timeout * 1000.0)
|
1681
1721
|
for i in range(int(timeout * 10)):
|
@@ -1693,10 +1733,10 @@ class CDPMethods():
|
|
1693
1733
|
% (selector, timeout, plural)
|
1694
1734
|
)
|
1695
1735
|
|
1696
|
-
def assert_element_not_visible(
|
1697
|
-
self, selector, timeout=settings.SMALL_TIMEOUT
|
1698
|
-
):
|
1736
|
+
def assert_element_not_visible(self, selector, timeout=None):
|
1699
1737
|
"""Assert element is not visible on page. (May still be in DOM)"""
|
1738
|
+
if not timeout:
|
1739
|
+
timeout = settings.SMALL_TIMEOUT
|
1700
1740
|
start_ms = time.time() * 1000.0
|
1701
1741
|
stop_ms = start_ms + (timeout * 1000.0)
|
1702
1742
|
for i in range(int(timeout * 10)):
|
@@ -1791,9 +1831,9 @@ class CDPMethods():
|
|
1791
1831
|
if expected not in actual:
|
1792
1832
|
raise Exception(error % (expected, actual))
|
1793
1833
|
|
1794
|
-
def assert_text(
|
1795
|
-
|
1796
|
-
|
1834
|
+
def assert_text(self, text, selector="body", timeout=None):
|
1835
|
+
if not timeout:
|
1836
|
+
timeout = settings.SMALL_TIMEOUT
|
1797
1837
|
start_ms = time.time() * 1000.0
|
1798
1838
|
stop_ms = start_ms + (timeout * 1000.0)
|
1799
1839
|
text = text.strip()
|
@@ -1816,9 +1856,9 @@ class CDPMethods():
|
|
1816
1856
|
% (text, selector, element.text_all)
|
1817
1857
|
)
|
1818
1858
|
|
1819
|
-
def assert_exact_text(
|
1820
|
-
|
1821
|
-
|
1859
|
+
def assert_exact_text(self, text, selector="body", timeout=None):
|
1860
|
+
if not timeout:
|
1861
|
+
timeout = settings.SMALL_TIMEOUT
|
1822
1862
|
start_ms = time.time() * 1000.0
|
1823
1863
|
stop_ms = start_ms + (timeout * 1000.0)
|
1824
1864
|
text = text.strip()
|
@@ -4492,7 +4492,8 @@ class BaseCase(unittest.TestCase):
|
|
4492
4492
|
@Params
|
4493
4493
|
name - The file name to save the current page's HTML to.
|
4494
4494
|
folder - The folder to save the file to. (Default = current folder)"""
|
4495
|
-
self.
|
4495
|
+
if not self.__is_cdp_swap_needed():
|
4496
|
+
self.wait_for_ready_state_complete()
|
4496
4497
|
return page_actions.save_page_source(self.driver, name, folder)
|
4497
4498
|
|
4498
4499
|
def save_cookies(self, name="cookies.txt"):
|
@@ -4550,6 +4551,9 @@ class BaseCase(unittest.TestCase):
|
|
4550
4551
|
def delete_all_cookies(self):
|
4551
4552
|
"""Deletes all cookies in the web browser.
|
4552
4553
|
Does NOT delete the saved cookies file."""
|
4554
|
+
if self.__is_cdp_swap_needed():
|
4555
|
+
self.cdp.clear_cookies()
|
4556
|
+
return
|
4553
4557
|
self.wait_for_ready_state_complete()
|
4554
4558
|
self.driver.delete_all_cookies()
|
4555
4559
|
if self.recorder_mode:
|
@@ -4561,7 +4565,6 @@ class BaseCase(unittest.TestCase):
|
|
4561
4565
|
def delete_saved_cookies(self, name="cookies.txt"):
|
4562
4566
|
"""Deletes the cookies file from the "saved_cookies" folder.
|
4563
4567
|
Does NOT delete the cookies from the web browser."""
|
4564
|
-
self.wait_for_ready_state_complete()
|
4565
4568
|
if name.endswith("/"):
|
4566
4569
|
raise Exception("Invalid filename for Cookies!")
|
4567
4570
|
if "/" in name:
|
@@ -4600,14 +4603,20 @@ class BaseCase(unittest.TestCase):
|
|
4600
4603
|
return json.loads(json_cookies)
|
4601
4604
|
|
4602
4605
|
def get_cookie(self, name):
|
4606
|
+
self.__check_scope()
|
4607
|
+
self._check_browser()
|
4603
4608
|
return self.driver.get_cookie(name)
|
4604
4609
|
|
4605
4610
|
def get_cookies(self):
|
4611
|
+
self.__check_scope()
|
4612
|
+
self._check_browser()
|
4606
4613
|
return self.driver.get_cookies()
|
4607
4614
|
|
4608
4615
|
def get_cookie_string(self):
|
4616
|
+
self.__check_scope()
|
4609
4617
|
if self.__is_cdp_swap_needed():
|
4610
4618
|
return self.cdp.get_cookie_string()
|
4619
|
+
self._check_browser()
|
4611
4620
|
return self.execute_script("return document.cookie;")
|
4612
4621
|
|
4613
4622
|
def add_cookie(self, cookie_dict, expiry=False):
|
@@ -4622,6 +4631,8 @@ class BaseCase(unittest.TestCase):
|
|
4622
4631
|
If expiry > 0: Set "expiry" to expiry minutes in the future.
|
4623
4632
|
If expiry == True: Set "expiry" to 24 hours in the future.
|
4624
4633
|
"""
|
4634
|
+
self.__check_scope()
|
4635
|
+
self._check_browser()
|
4625
4636
|
cookie = cookie_dict
|
4626
4637
|
if "domain" in cookie:
|
4627
4638
|
origin = self.get_origin()
|
@@ -4646,6 +4657,8 @@ class BaseCase(unittest.TestCase):
|
|
4646
4657
|
If expiry > 0: Set "expiry" to expiry minutes in the future.
|
4647
4658
|
If expiry == True: Set "expiry" to 24 hours in the future.
|
4648
4659
|
"""
|
4660
|
+
self.__check_scope()
|
4661
|
+
self._check_browser()
|
4649
4662
|
origin = self.get_origin()
|
4650
4663
|
trim_origin = origin.split("://")[-1]
|
4651
4664
|
for cookie in cookies:
|
@@ -13782,7 +13795,8 @@ class BaseCase(unittest.TestCase):
|
|
13782
13795
|
if self.get_current_url() == "about:blank":
|
13783
13796
|
self.switch_to_window(current_window)
|
13784
13797
|
except Exception:
|
13785
|
-
|
13798
|
+
with suppress(Exception):
|
13799
|
+
self.switch_to_window(current_window)
|
13786
13800
|
|
13787
13801
|
def __needs_minimum_wait(self):
|
13788
13802
|
if (
|
@@ -13991,9 +14005,10 @@ class BaseCase(unittest.TestCase):
|
|
13991
14005
|
visible=0, size=(width, height)
|
13992
14006
|
)
|
13993
14007
|
self._xvfb_display.start()
|
13994
|
-
sb_config._virtual_display = self._xvfb_display
|
13995
14008
|
self.headless_active = True
|
13996
|
-
|
14009
|
+
if not self.undetectable:
|
14010
|
+
sb_config._virtual_display = self._xvfb_display
|
14011
|
+
sb_config.headless_active = True
|
13997
14012
|
|
13998
14013
|
def __activate_virtual_display(self):
|
13999
14014
|
if self.undetectable and not (self.headless or self.headless2):
|
@@ -14016,6 +14031,8 @@ class BaseCase(unittest.TestCase):
|
|
14016
14031
|
"\nX11 display failed! Will use regular xvfb!"
|
14017
14032
|
)
|
14018
14033
|
self.__activate_standard_virtual_display()
|
14034
|
+
else:
|
14035
|
+
self.headless_active = True
|
14019
14036
|
except Exception as e:
|
14020
14037
|
if hasattr(e, "msg"):
|
14021
14038
|
print("\n" + str(e.msg))
|
@@ -16588,6 +16605,7 @@ class BaseCase(unittest.TestCase):
|
|
16588
16605
|
self.__quit_all_drivers()
|
16589
16606
|
# Resume tearDown() for all test runners, (Pytest / Pynose / Behave)
|
16590
16607
|
if hasattr(self, "_xvfb_display") and self._xvfb_display:
|
16608
|
+
# Stop the Xvfb virtual display launched from BaseCase
|
16591
16609
|
try:
|
16592
16610
|
if hasattr(self._xvfb_display, "stop"):
|
16593
16611
|
self._xvfb_display.stop()
|
@@ -16597,6 +16615,20 @@ class BaseCase(unittest.TestCase):
|
|
16597
16615
|
pass
|
16598
16616
|
except Exception:
|
16599
16617
|
pass
|
16618
|
+
if (
|
16619
|
+
hasattr(sb_config, "_virtual_display")
|
16620
|
+
and sb_config._virtual_display
|
16621
|
+
and hasattr(sb_config._virtual_display, "stop")
|
16622
|
+
):
|
16623
|
+
# CDP Mode may launch a 2nd Xvfb virtual display
|
16624
|
+
try:
|
16625
|
+
sb_config._virtual_display.stop()
|
16626
|
+
sb_config._virtual_display = None
|
16627
|
+
sb_config.headless_active = False
|
16628
|
+
except AttributeError:
|
16629
|
+
pass
|
16630
|
+
except Exception:
|
16631
|
+
pass
|
16600
16632
|
if self.__visual_baseline_copies:
|
16601
16633
|
sb_config._visual_baseline_copies = True
|
16602
16634
|
if has_exception:
|
@@ -1342,7 +1342,8 @@ def save_page_source(driver, name, folder=None):
|
|
1342
1342
|
"""
|
1343
1343
|
from seleniumbase.core import log_helper
|
1344
1344
|
|
1345
|
-
|
1345
|
+
if not __is_cdp_swap_needed(driver):
|
1346
|
+
_reconnect_if_disconnected(driver) # If disconnected without CDP
|
1346
1347
|
if not name.endswith(".html"):
|
1347
1348
|
name = name + ".html"
|
1348
1349
|
if folder:
|
@@ -1353,7 +1354,11 @@ def save_page_source(driver, name, folder=None):
|
|
1353
1354
|
html_file_path = os.path.join(file_path, name)
|
1354
1355
|
else:
|
1355
1356
|
html_file_path = name
|
1356
|
-
page_source =
|
1357
|
+
page_source = None
|
1358
|
+
if __is_cdp_swap_needed(driver):
|
1359
|
+
page_source = driver.cdp.get_page_source()
|
1360
|
+
else:
|
1361
|
+
page_source = driver.page_source
|
1357
1362
|
html_file = codecs.open(html_file_path, "w+", "utf-8")
|
1358
1363
|
rendered_source = log_helper.get_html_source_with_base_href(
|
1359
1364
|
driver, page_source
|
@@ -1256,6 +1256,19 @@ def SB(
|
|
1256
1256
|
print(traceback.format_exc().strip())
|
1257
1257
|
if test and not test_passed:
|
1258
1258
|
print("********** ERROR: The test AND the tearDown() FAILED!")
|
1259
|
+
if (
|
1260
|
+
hasattr(sb_config, "_virtual_display")
|
1261
|
+
and sb_config._virtual_display
|
1262
|
+
and hasattr(sb_config._virtual_display, "stop")
|
1263
|
+
):
|
1264
|
+
try:
|
1265
|
+
sb_config._virtual_display.stop()
|
1266
|
+
sb_config._virtual_display = None
|
1267
|
+
sb_config.headless_active = False
|
1268
|
+
except AttributeError:
|
1269
|
+
pass
|
1270
|
+
except Exception:
|
1271
|
+
pass
|
1259
1272
|
end_time = time.time()
|
1260
1273
|
run_time = end_time - start_time
|
1261
1274
|
sb_config = sb_config_backup
|
@@ -84,6 +84,9 @@ def __activate_virtual_display_as_needed(
|
|
84
84
|
"\nX11 display failed! Will use regular xvfb!"
|
85
85
|
)
|
86
86
|
__activate_standard_virtual_display()
|
87
|
+
else:
|
88
|
+
sb_config._virtual_display = _xvfb_display
|
89
|
+
sb_config.headless_active = True
|
87
90
|
except Exception as e:
|
88
91
|
if hasattr(e, "msg"):
|
89
92
|
print("\n" + str(e.msg))
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: seleniumbase
|
3
|
-
Version: 4.33.
|
3
|
+
Version: 4.33.13
|
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
|
@@ -62,9 +62,9 @@ License-File: LICENSE
|
|
62
62
|
Requires-Dist: pip>=24.3.1
|
63
63
|
Requires-Dist: packaging>=24.2
|
64
64
|
Requires-Dist: setuptools~=70.2; python_version < "3.10"
|
65
|
-
Requires-Dist: setuptools>=75.
|
65
|
+
Requires-Dist: setuptools>=75.8.0; python_version >= "3.10"
|
66
66
|
Requires-Dist: wheel>=0.45.1
|
67
|
-
Requires-Dist: attrs>=24.
|
67
|
+
Requires-Dist: attrs>=24.3.0
|
68
68
|
Requires-Dist: certifi>=2024.12.14
|
69
69
|
Requires-Dist: exceptiongroup>=1.2.2
|
70
70
|
Requires-Dist: websockets~=13.1; python_version < "3.9"
|
@@ -75,26 +75,30 @@ Requires-Dist: mycdp>=1.1.0
|
|
75
75
|
Requires-Dist: pynose>=1.5.3
|
76
76
|
Requires-Dist: platformdirs>=4.3.6
|
77
77
|
Requires-Dist: typing-extensions>=4.12.2
|
78
|
-
Requires-Dist: sbvirtualdisplay>=1.
|
78
|
+
Requires-Dist: sbvirtualdisplay>=1.4.0
|
79
|
+
Requires-Dist: MarkupSafe==2.1.5; python_version < "3.9"
|
80
|
+
Requires-Dist: MarkupSafe>=3.0.2; python_version >= "3.9"
|
81
|
+
Requires-Dist: Jinja2>=3.1.5
|
79
82
|
Requires-Dist: six>=1.17.0
|
80
83
|
Requires-Dist: parse>=1.20.2
|
81
84
|
Requires-Dist: parse-type>=0.6.4
|
82
85
|
Requires-Dist: colorama>=0.4.6
|
83
86
|
Requires-Dist: pyyaml>=6.0.2
|
84
|
-
Requires-Dist: pygments>=2.
|
87
|
+
Requires-Dist: pygments>=2.19.1
|
85
88
|
Requires-Dist: pyreadline3>=3.5.3; platform_system == "Windows"
|
86
89
|
Requires-Dist: tabcompleter>=1.4.0
|
87
90
|
Requires-Dist: pdbp>=1.6.1
|
88
91
|
Requires-Dist: idna==3.10
|
89
92
|
Requires-Dist: chardet==5.2.0
|
90
|
-
Requires-Dist: charset-normalizer==3.4.
|
93
|
+
Requires-Dist: charset-normalizer==3.4.1
|
91
94
|
Requires-Dist: urllib3<2,>=1.26.20; python_version < "3.10"
|
92
|
-
Requires-Dist: urllib3<2.
|
95
|
+
Requires-Dist: urllib3<2.4.0,>=1.26.20; python_version >= "3.10"
|
93
96
|
Requires-Dist: requests==2.32.3
|
94
97
|
Requires-Dist: sniffio==1.3.1
|
95
98
|
Requires-Dist: h11==0.14.0
|
96
99
|
Requires-Dist: outcome==1.3.0.post0
|
97
|
-
Requires-Dist: trio==0.27.0
|
100
|
+
Requires-Dist: trio==0.27.0; python_version < "3.9"
|
101
|
+
Requires-Dist: trio==0.28.0; python_version >= "3.9"
|
98
102
|
Requires-Dist: trio-websocket==0.11.1
|
99
103
|
Requires-Dist: wsproto==1.2.0
|
100
104
|
Requires-Dist: websocket-client==1.8.0
|
@@ -126,7 +130,7 @@ Requires-Dist: allure-python-commons>=2.13.5; extra == "allure"
|
|
126
130
|
Requires-Dist: allure-behave>=2.13.5; extra == "allure"
|
127
131
|
Provides-Extra: coverage
|
128
132
|
Requires-Dist: coverage>=7.6.1; python_version < "3.9" and extra == "coverage"
|
129
|
-
Requires-Dist: coverage>=7.6.
|
133
|
+
Requires-Dist: coverage>=7.6.10; python_version >= "3.9" and extra == "coverage"
|
130
134
|
Requires-Dist: pytest-cov>=5.0.0; python_version < "3.9" and extra == "coverage"
|
131
135
|
Requires-Dist: pytest-cov>=6.0.0; python_version >= "3.9" and extra == "coverage"
|
132
136
|
Provides-Extra: flake8
|
@@ -150,7 +154,7 @@ Requires-Dist: cffi==1.17.1; extra == "pdfminer"
|
|
150
154
|
Requires-Dist: pycparser==2.22; extra == "pdfminer"
|
151
155
|
Provides-Extra: pillow
|
152
156
|
Requires-Dist: Pillow>=10.4.0; python_version < "3.9" and extra == "pillow"
|
153
|
-
Requires-Dist: Pillow>=11.
|
157
|
+
Requires-Dist: Pillow>=11.1.0; python_version >= "3.9" and extra == "pillow"
|
154
158
|
Provides-Extra: pip-system-certs
|
155
159
|
Requires-Dist: pip-system-certs==4.0; platform_system == "Windows" and extra == "pip-system-certs"
|
156
160
|
Provides-Extra: proxy
|
@@ -173,6 +177,18 @@ Requires-Dist: hyperframe==6.0.1; extra == "selenium-wire"
|
|
173
177
|
Requires-Dist: kaitaistruct==0.10; extra == "selenium-wire"
|
174
178
|
Requires-Dist: pyasn1==0.6.1; extra == "selenium-wire"
|
175
179
|
Requires-Dist: zstandard==0.23.0; extra == "selenium-wire"
|
180
|
+
Dynamic: author
|
181
|
+
Dynamic: author-email
|
182
|
+
Dynamic: classifier
|
183
|
+
Dynamic: home-page
|
184
|
+
Dynamic: keywords
|
185
|
+
Dynamic: license
|
186
|
+
Dynamic: maintainer
|
187
|
+
Dynamic: platform
|
188
|
+
Dynamic: provides-extra
|
189
|
+
Dynamic: requires-dist
|
190
|
+
Dynamic: requires-python
|
191
|
+
Dynamic: summary
|
176
192
|
|
177
193
|
<!-- SeleniumBase Docs -->
|
178
194
|
|
@@ -236,7 +252,7 @@ Requires-Dist: zstandard==0.23.0; extra == "selenium-wire"
|
|
236
252
|
|
237
253
|
📚 Learn from [**over 200 examples** in the **SeleniumBase/examples/** folder](https://github.com/seleniumbase/SeleniumBase/tree/master/examples).
|
238
254
|
|
239
|
-
🐙 Note that <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md"><b>UC Mode</b></a>
|
255
|
+
🐙 Note that <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md"><b>UC Mode</b></a> / <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md"><b>CDP Mode</b></a> (Stealth Mode) have their own ReadMe files.
|
240
256
|
|
241
257
|
ℹ️ Most scripts run with raw <code translate="no"><b>python</b></code>, although some scripts use <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/syntax_formats.md">Syntax Formats</a> that 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).
|
242
258
|
|
@@ -247,21 +263,37 @@ Requires-Dist: zstandard==0.23.0; extra == "selenium-wire"
|
|
247
263
|
```python
|
248
264
|
from seleniumbase import SB
|
249
265
|
|
250
|
-
with SB(test=True
|
266
|
+
with SB(test=True) as sb:
|
251
267
|
sb.open("https://google.com/ncr")
|
252
268
|
sb.type('[title="Search"]', "SeleniumBase GitHub page\n")
|
253
|
-
sb.click('[href*="github.com/seleniumbase/
|
254
|
-
sb.save_screenshot_to_logs() #
|
269
|
+
sb.click('[href*="github.com/seleniumbase/"]')
|
270
|
+
sb.save_screenshot_to_logs() # ./latest_logs/
|
255
271
|
print(sb.get_page_title())
|
256
272
|
```
|
257
273
|
|
258
274
|
> `python raw_google.py`
|
259
275
|
|
260
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py"><img src="https://seleniumbase.github.io/cdn/gif/google_search.gif" alt="SeleniumBase Test" title="SeleniumBase Test" width="
|
276
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py"><img src="https://seleniumbase.github.io/cdn/gif/google_search.gif" alt="SeleniumBase Test" title="SeleniumBase Test" width="420" /></a>
|
261
277
|
|
262
278
|
--------
|
263
279
|
|
264
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/
|
280
|
+
<p align="left">📗 Here's an example of bypassing Cloudflare's challenge page: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_gitlab.py">SeleniumBase/examples/cdp_mode/raw_gitlab.py</a></p>
|
281
|
+
|
282
|
+
```python
|
283
|
+
from seleniumbase import SB
|
284
|
+
|
285
|
+
with SB(uc=True, test=True, locale_code="en") as sb:
|
286
|
+
url = "https://gitlab.com/users/sign_in"
|
287
|
+
sb.activate_cdp_mode(url)
|
288
|
+
sb.uc_gui_click_captcha()
|
289
|
+
sb.sleep(2)
|
290
|
+
```
|
291
|
+
|
292
|
+
<img src="https://seleniumbase.github.io/other/cf_sec.jpg" title="SeleniumBase" width="332"> <img src="https://seleniumbase.github.io/other/gitlab_bypass.png" title="SeleniumBase" width="288">
|
293
|
+
|
294
|
+
--------
|
295
|
+
|
296
|
+
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py">test_get_swag.py</a>, which tests an e-commerce site:</p>
|
265
297
|
|
266
298
|
```python
|
267
299
|
from seleniumbase import BaseCase
|
@@ -287,7 +319,7 @@ class MyTestClass(BaseCase):
|
|
287
319
|
|
288
320
|
> `pytest test_get_swag.py`
|
289
321
|
|
290
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test" title="SeleniumBase Test" width="
|
322
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test" title="SeleniumBase Test" width="480" /></a>
|
291
323
|
|
292
324
|
> (The default browser is ``--chrome`` if not set.)
|
293
325
|
|
@@ -299,7 +331,7 @@ class MyTestClass(BaseCase):
|
|
299
331
|
pytest test_coffee_cart.py --demo
|
300
332
|
```
|
301
333
|
|
302
|
-
<p align="left"><a href="https://seleniumbase.io/coffee/" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/coffee_cart.gif" width="
|
334
|
+
<p align="left"><a href="https://seleniumbase.io/coffee/" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/coffee_cart.gif" width="480" alt="SeleniumBase Coffee Cart Test" title="SeleniumBase Coffee Cart Test" /></a></p>
|
303
335
|
|
304
336
|
> <p>(<code translate="no">--demo</code> mode slows down tests and highlights actions)</p>
|
305
337
|
|
@@ -313,7 +345,7 @@ pytest test_coffee_cart.py --demo
|
|
313
345
|
pytest test_demo_site.py
|
314
346
|
```
|
315
347
|
|
316
|
-
<p align="left"><a href="https://seleniumbase.io/demo_page" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/demo_page_5.gif" width="
|
348
|
+
<p align="left"><a href="https://seleniumbase.io/demo_page" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/demo_page_5.gif" width="480" alt="SeleniumBase Example" title="SeleniumBase Example" /></a></p>
|
317
349
|
|
318
350
|
> Easy to type, click, select, toggle, drag & drop, and more.
|
319
351
|
|
@@ -569,7 +601,7 @@ cd examples/
|
|
569
601
|
pytest my_first_test.py
|
570
602
|
```
|
571
603
|
|
572
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test" title="SeleniumBase Test" width="
|
604
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test" title="SeleniumBase Test" width="480" /></a>
|
573
605
|
|
574
606
|
<p align="left"><b>Here's the full code for <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py">my_first_test.py</a>:</b></p>
|
575
607
|
|
@@ -987,7 +1019,7 @@ You can run it from the ``examples/`` folder like this:
|
|
987
1019
|
pytest test_fail.py
|
988
1020
|
```
|
989
1021
|
|
990
|
-
🔵 You'll notice that a logs folder,
|
1022
|
+
🔵 You'll notice that a logs folder, ``./latest_logs/``, was created to hold information (and screenshots) about the failing test. During test runs, past results get moved to the archived_logs folder if you have ARCHIVE_EXISTING_LOGS set to True in [settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/settings.py), or if your run tests with ``--archive-logs``. If you choose not to archive existing logs, they will be deleted and replaced by the logs of the latest test run.
|
991
1023
|
|
992
1024
|
--------
|
993
1025
|
|
@@ -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=fdIgU6XLjQLyRj6V05cYPC9_n4yf9X6eAsNFamcuZgo,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=-hza7Nx2U41mSObYiPMi48v3JlPh3sJO3yzP0kqZ1Gk,59174
|
@@ -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=RqsyaqqFvQ-L9LcVXS8Yr5s9abykUEF5_72RO6cYUqs,224989
|
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
|
@@ -44,13 +44,13 @@ seleniumbase/core/detect_b_ver.py,sha256=RxeGRMbBUTMrXh5KsS1P1SH7eEKYbzL1vQw1gTd
|
|
44
44
|
seleniumbase/core/download_helper.py,sha256=qSR54kQISucF4RQaLCOuuerSu6DR41juGi_30HVvWYY,2943
|
45
45
|
seleniumbase/core/encoded_images.py,sha256=rDKJ4cNJSuKiRcFViYU7bjyTS9_moI57gUPRXVg3u2k,14209
|
46
46
|
seleniumbase/core/jqc_helper.py,sha256=2DDQr9Q2jSSZqFzX588jLlUM9oJvyrRWq2aORSIPUdI,10322
|
47
|
-
seleniumbase/core/log_helper.py,sha256=
|
47
|
+
seleniumbase/core/log_helper.py,sha256=SW8wx2f2HfU3ERbANjxEC-jDbjy_IzaNYRKPlayfRRI,23442
|
48
48
|
seleniumbase/core/mysql.py,sha256=8Fzj3p5dhtDWfMpFqFYxpSwa9s1UltiHsWJ56_aPOqk,3993
|
49
49
|
seleniumbase/core/proxy_helper.py,sha256=kZnfkflB3XhuL2h-3inmx3UOLS8VAZ385BGCc4H8TvU,8267
|
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=f6l4GUJP-jg-ivukpbwVLyFNvnlzUnXjm5Y2oUw0I88,76028
|
54
54
|
seleniumbase/core/sb_driver.py,sha256=NGa4adi8OAi2WFtFkEguXg3JCd1p-JuZweIpGNifEfU,13488
|
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,12 +65,12 @@ 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=IfOwY0b31ngawTZY0thwHvcRGOSCUd647sm_iGKIMk0,719922
|
69
69
|
seleniumbase/fixtures/constants.py,sha256=e1LppavlrAcI4XBJMq7u5j8SffaQ7SPQps1y0YvZYfY,13649
|
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=asZJ0LDFv2BPQOzUVKK_9ie8ToGcmFousDnGdb3Vabg,51534
|
73
|
-
seleniumbase/fixtures/page_actions.py,sha256=
|
73
|
+
seleniumbase/fixtures/page_actions.py,sha256=LPcFSkUvBkxLrOt4laQHHN-NLmqInT41E2vlPiOlLFY,66753
|
74
74
|
seleniumbase/fixtures/page_utils.py,sha256=5m7iXpikLs80TJoRO6_gEfXE1AKeQgcH1aFbR8o1C9A,12034
|
75
75
|
seleniumbase/fixtures/shared_utils.py,sha256=G6CsE-Adt-GfuZF-71jXWKSIQW7YZPx8FIM24pVd_yI,8368
|
76
76
|
seleniumbase/fixtures/unittest_helper.py,sha256=sfZ92rZeBAn_sF_yQ3I6_I7h3lyU5-cV_UMegBNoEm8,1294
|
@@ -90,7 +90,7 @@ seleniumbase/plugins/driver_manager.py,sha256=s20s0pJYaNrG0WNwyIC04oUMRVFjtm6V_n
|
|
90
90
|
seleniumbase/plugins/page_source.py,sha256=loTnXxOj4kxEukuTZEiGyvKBhY3KDVDMnNlHHheTBDE,1889
|
91
91
|
seleniumbase/plugins/pytest_plugin.py,sha256=JjpglUqHkfl6rzdg1SkJ7PMtNRpceOgLNbUi2DyKpJI,105416
|
92
92
|
seleniumbase/plugins/s3_logging_plugin.py,sha256=WDfertQgGOW_SRJpFMaekYD6vBVW9VO62POtXXy2HCM,2319
|
93
|
-
seleniumbase/plugins/sb_manager.py,sha256=
|
93
|
+
seleniumbase/plugins/sb_manager.py,sha256=Z19CfRSaqcxdn_YvzXVt4B9Nu3Bhs97QIO5tHlvbuyk,54871
|
94
94
|
seleniumbase/plugins/screen_shots.py,sha256=1hrXw-hzuZ1BR6Yh7AyWX2ABnvnP73-RCbwdz958gj4,1127
|
95
95
|
seleniumbase/plugins/selenium_plugin.py,sha256=GhGW2ATy2kM7UH7NrZ2je402nN2LMlVHpM-yxlU3I9E,59069
|
96
96
|
seleniumbase/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -116,7 +116,7 @@ seleniumbase/undetected/webelement.py,sha256=_s6evgUkdWJpwOnzX4qR9i796PoVbz3txlz
|
|
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
118
|
seleniumbase/undetected/cdp_driver/browser.py,sha256=quD0e2aoehXQrs9zxGsobF0kZY11gmJ58Q_JQhheQYg,30144
|
119
|
-
seleniumbase/undetected/cdp_driver/cdp_util.py,sha256=
|
119
|
+
seleniumbase/undetected/cdp_driver/cdp_util.py,sha256=X7bd5qt-kegTiOEcsoLUHrAJ5YTruEub-9oL4TBDTYk,16886
|
120
120
|
seleniumbase/undetected/cdp_driver/config.py,sha256=oHFJ3UH0OmLmEGgG5S6SZwbyBs9ZYMsbUJ02QCA7iZc,12044
|
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
|
@@ -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.33.
|
139
|
-
seleniumbase-4.33.
|
140
|
-
seleniumbase-4.33.
|
141
|
-
seleniumbase-4.33.
|
142
|
-
seleniumbase-4.33.
|
143
|
-
seleniumbase-4.33.
|
138
|
+
seleniumbase-4.33.13.dist-info/LICENSE,sha256=BRblZsX7HyPUjQmYTiyWr_e9tzWvmR3R4SFclM2R3W0,1085
|
139
|
+
seleniumbase-4.33.13.dist-info/METADATA,sha256=bMOMidFBkEka4HeTU6dLn4Vj1JPxenoqxYyRZ66Q8y4,86361
|
140
|
+
seleniumbase-4.33.13.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
141
|
+
seleniumbase-4.33.13.dist-info/entry_points.txt,sha256=CNrh2EKNaHYEhO6pP1RJyVLB99LkDDYX7TnUK8xfjqk,623
|
142
|
+
seleniumbase-4.33.13.dist-info/top_level.txt,sha256=4N97aBOQ8ETCnDnokBsWb07lJfTaq3C1ZzYRxvLMxqU,19
|
143
|
+
seleniumbase-4.33.13.dist-info/RECORD,,
|
File without changes
|
File without changes
|