seleniumbase 4.34.11__py3-none-any.whl → 4.35.0__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 +68 -37
- seleniumbase/core/proxy_helper.py +8 -6
- seleniumbase/core/sb_cdp.py +193 -69
- seleniumbase/core/sb_driver.py +7 -0
- seleniumbase/extensions/ad_block.zip +0 -0
- seleniumbase/extensions/disable_csp.zip +0 -0
- seleniumbase/fixtures/base_case.py +38 -11
- seleniumbase/fixtures/js_utils.py +31 -9
- seleniumbase/plugins/base_plugin.py +12 -15
- seleniumbase/plugins/selenium_plugin.py +1 -0
- seleniumbase/undetected/__init__.py +16 -10
- 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/undetected/webelement.py +3 -2
- {seleniumbase-4.34.11.dist-info → seleniumbase-4.35.0.dist-info}/METADATA +10 -10
- {seleniumbase-4.34.11.dist-info → seleniumbase-4.35.0.dist-info}/RECORD +22 -22
- {seleniumbase-4.34.11.dist-info → seleniumbase-4.35.0.dist-info}/LICENSE +0 -0
- {seleniumbase-4.34.11.dist-info → seleniumbase-4.35.0.dist-info}/WHEEL +0 -0
- {seleniumbase-4.34.11.dist-info → seleniumbase-4.35.0.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.34.11.dist-info → seleniumbase-4.35.0.dist-info}/top_level.txt +0 -0
seleniumbase/core/sb_cdp.py
CHANGED
@@ -56,12 +56,16 @@ class CDPMethods():
|
|
56
56
|
element, *args, **kwargs
|
57
57
|
)
|
58
58
|
element.focus = lambda: self.__focus(element)
|
59
|
+
element.gui_click = (
|
60
|
+
lambda *args, **kwargs: self.__gui_click(element, *args, **kwargs)
|
61
|
+
)
|
59
62
|
element.highlight_overlay = lambda: self.__highlight_overlay(element)
|
60
63
|
element.mouse_click = lambda: self.__mouse_click(element)
|
61
64
|
element.mouse_drag = (
|
62
65
|
lambda destination: self.__mouse_drag(element, destination)
|
63
66
|
)
|
64
67
|
element.mouse_move = lambda: self.__mouse_move(element)
|
68
|
+
element.press_keys = lambda text: self.__press_keys(element, text)
|
65
69
|
element.query_selector = (
|
66
70
|
lambda selector: self.__query_selector(element, selector)
|
67
71
|
)
|
@@ -91,6 +95,8 @@ class CDPMethods():
|
|
91
95
|
element.get_attribute = (
|
92
96
|
lambda attribute: self.__get_attribute(element, attribute)
|
93
97
|
)
|
98
|
+
# element.get_parent() should come last
|
99
|
+
element.get_parent = lambda: self.__get_parent(element)
|
94
100
|
return element
|
95
101
|
|
96
102
|
def get(self, url):
|
@@ -209,7 +215,8 @@ class CDPMethods():
|
|
209
215
|
element = self.__add_sync_methods(element.parent)
|
210
216
|
return self.__add_sync_methods(element)
|
211
217
|
elif (
|
212
|
-
element.parent
|
218
|
+
element.parent
|
219
|
+
and element.parent.parent
|
213
220
|
and tag_name in element.parent.parent.tag_name.lower()
|
214
221
|
and text.strip() in element.parent.parent.text
|
215
222
|
):
|
@@ -270,7 +277,8 @@ class CDPMethods():
|
|
270
277
|
if element not in updated_elements:
|
271
278
|
updated_elements.append(element)
|
272
279
|
elif (
|
273
|
-
element.parent
|
280
|
+
element.parent
|
281
|
+
and element.parent.parent
|
274
282
|
and tag_name in element.parent.parent.tag_name.lower()
|
275
283
|
and text.strip() in element.parent.parent.text
|
276
284
|
):
|
@@ -421,6 +429,39 @@ class CDPMethods():
|
|
421
429
|
self.loop.run_until_complete(element.focus_async())
|
422
430
|
)
|
423
431
|
|
432
|
+
def __gui_click(self, element, timeframe=None):
|
433
|
+
element.scroll_into_view()
|
434
|
+
self.__add_light_pause()
|
435
|
+
position = element.get_position()
|
436
|
+
x = position.x
|
437
|
+
y = position.y
|
438
|
+
e_width = position.width
|
439
|
+
e_height = position.height
|
440
|
+
# Relative to window
|
441
|
+
element_rect = {"height": e_height, "width": e_width, "x": x, "y": y}
|
442
|
+
window_rect = self.get_window_rect()
|
443
|
+
w_bottom_y = window_rect["y"] + window_rect["height"]
|
444
|
+
viewport_height = window_rect["innerHeight"]
|
445
|
+
x = window_rect["x"] + element_rect["x"]
|
446
|
+
y = w_bottom_y - viewport_height + element_rect["y"]
|
447
|
+
y_scroll_offset = window_rect["pageYOffset"]
|
448
|
+
y = y - y_scroll_offset
|
449
|
+
x = x + window_rect["scrollX"]
|
450
|
+
y = y + window_rect["scrollY"]
|
451
|
+
# Relative to screen
|
452
|
+
element_rect = {"height": e_height, "width": e_width, "x": x, "y": y}
|
453
|
+
e_width = element_rect["width"]
|
454
|
+
e_height = element_rect["height"]
|
455
|
+
e_x = element_rect["x"]
|
456
|
+
e_y = element_rect["y"]
|
457
|
+
x, y = ((e_x + e_width / 2.0) + 0.5), ((e_y + e_height / 2.0) + 0.5)
|
458
|
+
if not timeframe or not isinstance(timeframe, (int, float)):
|
459
|
+
timeframe = 0.25
|
460
|
+
if timeframe > 3:
|
461
|
+
timeframe = 3
|
462
|
+
self.gui_click_x_y(x, y, timeframe=timeframe)
|
463
|
+
return self.loop.run_until_complete(self.page.wait())
|
464
|
+
|
424
465
|
def __highlight_overlay(self, element):
|
425
466
|
return (
|
426
467
|
self.loop.run_until_complete(element.highlight_overlay_async())
|
@@ -443,6 +484,21 @@ class CDPMethods():
|
|
443
484
|
self.loop.run_until_complete(element.mouse_move_async())
|
444
485
|
)
|
445
486
|
|
487
|
+
def __press_keys(self, element, text):
|
488
|
+
element.scroll_into_view()
|
489
|
+
submit = False
|
490
|
+
if text.endswith("\n") or text.endswith("\r"):
|
491
|
+
submit = True
|
492
|
+
text = text[:-1]
|
493
|
+
for key in text:
|
494
|
+
element.send_keys(key)
|
495
|
+
time.sleep(0.044)
|
496
|
+
if submit:
|
497
|
+
element.send_keys("\r\n")
|
498
|
+
time.sleep(0.044)
|
499
|
+
self.__slow_mode_pause_if_set()
|
500
|
+
return self.loop.run_until_complete(self.page.sleep(0.025))
|
501
|
+
|
446
502
|
def __query_selector(self, element, selector):
|
447
503
|
selector = self.__convert_to_css_if_xpath(selector)
|
448
504
|
element2 = self.loop.run_until_complete(
|
@@ -549,6 +605,9 @@ class CDPMethods():
|
|
549
605
|
pass
|
550
606
|
return None
|
551
607
|
|
608
|
+
def __get_parent(self, element):
|
609
|
+
return self.__add_sync_methods(element.parent)
|
610
|
+
|
552
611
|
def __get_x_scroll_offset(self):
|
553
612
|
x_scroll_offset = self.loop.run_until_complete(
|
554
613
|
self.page.evaluate("window.pageXOffset")
|
@@ -769,6 +828,11 @@ class CDPMethods():
|
|
769
828
|
def highlight_overlay(self, selector):
|
770
829
|
self.find_element(selector).highlight_overlay()
|
771
830
|
|
831
|
+
def get_parent(self, element):
|
832
|
+
if isinstance(element, str):
|
833
|
+
element = self.select(element)
|
834
|
+
return self.__add_sync_methods(element.parent)
|
835
|
+
|
772
836
|
def remove_element(self, selector):
|
773
837
|
self.select(selector).remove_from_dom()
|
774
838
|
|
@@ -800,7 +864,7 @@ class CDPMethods():
|
|
800
864
|
text = text[:-1] + "\r\n"
|
801
865
|
element.send_keys(text)
|
802
866
|
self.__slow_mode_pause_if_set()
|
803
|
-
self.loop.run_until_complete(self.page.
|
867
|
+
self.loop.run_until_complete(self.page.sleep(0.025))
|
804
868
|
|
805
869
|
def press_keys(self, selector, text, timeout=None):
|
806
870
|
"""Similar to send_keys(), but presses keys at human speed."""
|
@@ -820,7 +884,7 @@ class CDPMethods():
|
|
820
884
|
element.send_keys("\r\n")
|
821
885
|
time.sleep(0.044)
|
822
886
|
self.__slow_mode_pause_if_set()
|
823
|
-
self.loop.run_until_complete(self.page.
|
887
|
+
self.loop.run_until_complete(self.page.sleep(0.025))
|
824
888
|
|
825
889
|
def type(self, selector, text, timeout=None):
|
826
890
|
"""Similar to send_keys(), but clears the text field first."""
|
@@ -835,7 +899,7 @@ class CDPMethods():
|
|
835
899
|
text = text[:-1] + "\r\n"
|
836
900
|
element.send_keys(text)
|
837
901
|
self.__slow_mode_pause_if_set()
|
838
|
-
self.loop.run_until_complete(self.page.
|
902
|
+
self.loop.run_until_complete(self.page.sleep(0.025))
|
839
903
|
|
840
904
|
def set_value(self, selector, text, timeout=None):
|
841
905
|
"""Similar to send_keys(), but clears the text field first."""
|
@@ -873,7 +937,7 @@ class CDPMethods():
|
|
873
937
|
self.__add_light_pause()
|
874
938
|
self.send_keys(selector, "\n")
|
875
939
|
self.__slow_mode_pause_if_set()
|
876
|
-
self.loop.run_until_complete(self.page.
|
940
|
+
self.loop.run_until_complete(self.page.sleep(0.025))
|
877
941
|
|
878
942
|
def evaluate(self, expression):
|
879
943
|
"""Run a JavaScript expression and return the result."""
|
@@ -1313,7 +1377,7 @@ class CDPMethods():
|
|
1313
1377
|
pyautogui.press(key)
|
1314
1378
|
time.sleep(0.044)
|
1315
1379
|
self.__slow_mode_pause_if_set()
|
1316
|
-
self.loop.run_until_complete(self.page.
|
1380
|
+
self.loop.run_until_complete(self.page.sleep(0.025))
|
1317
1381
|
|
1318
1382
|
def gui_press_keys(self, keys):
|
1319
1383
|
self.__install_pyautogui_if_missing()
|
@@ -1328,7 +1392,7 @@ class CDPMethods():
|
|
1328
1392
|
pyautogui.press(key)
|
1329
1393
|
time.sleep(0.044)
|
1330
1394
|
self.__slow_mode_pause_if_set()
|
1331
|
-
self.loop.run_until_complete(self.page.
|
1395
|
+
self.loop.run_until_complete(self.page.sleep(0.025))
|
1332
1396
|
|
1333
1397
|
def gui_write(self, text):
|
1334
1398
|
self.__install_pyautogui_if_missing()
|
@@ -1341,7 +1405,7 @@ class CDPMethods():
|
|
1341
1405
|
self.__make_sure_pyautogui_lock_is_writable()
|
1342
1406
|
pyautogui.write(text)
|
1343
1407
|
self.__slow_mode_pause_if_set()
|
1344
|
-
self.loop.run_until_complete(self.page.
|
1408
|
+
self.loop.run_until_complete(self.page.sleep(0.025))
|
1345
1409
|
|
1346
1410
|
def __gui_click_x_y(self, x, y, timeframe=0.25, uc_lock=False):
|
1347
1411
|
self.__install_pyautogui_if_missing()
|
@@ -1671,59 +1735,93 @@ class CDPMethods():
|
|
1671
1735
|
return True
|
1672
1736
|
return False
|
1673
1737
|
|
1674
|
-
def
|
1675
|
-
|
1676
|
-
|
1738
|
+
def is_text_visible(self, text, selector="body"):
|
1739
|
+
selector = self.__convert_to_css_if_xpath(selector)
|
1740
|
+
text = text.strip()
|
1741
|
+
element = None
|
1677
1742
|
try:
|
1678
|
-
self.
|
1743
|
+
element = self.find_element(selector, timeout=0.1)
|
1679
1744
|
except Exception:
|
1680
|
-
|
1681
|
-
|
1682
|
-
if
|
1683
|
-
return
|
1684
|
-
|
1685
|
-
raise Exception("Element {%s} was not visible!" % selector)
|
1745
|
+
return False
|
1746
|
+
with suppress(Exception):
|
1747
|
+
if text in element.text_all:
|
1748
|
+
return True
|
1749
|
+
return False
|
1686
1750
|
|
1687
|
-
def
|
1688
|
-
|
1751
|
+
def is_exact_text_visible(self, text, selector="body"):
|
1752
|
+
selector = self.__convert_to_css_if_xpath(selector)
|
1753
|
+
text = text.strip()
|
1754
|
+
element = None
|
1755
|
+
try:
|
1756
|
+
element = self.find_element(selector, timeout=0.1)
|
1757
|
+
except Exception:
|
1758
|
+
return False
|
1759
|
+
with suppress(Exception):
|
1760
|
+
if text == element.text_all.strip():
|
1761
|
+
return True
|
1762
|
+
return False
|
1763
|
+
|
1764
|
+
def wait_for_text(self, text, selector="body", timeout=None):
|
1689
1765
|
if not timeout:
|
1690
1766
|
timeout = settings.SMALL_TIMEOUT
|
1767
|
+
start_ms = time.time() * 1000.0
|
1768
|
+
stop_ms = start_ms + (timeout * 1000.0)
|
1769
|
+
text = text.strip()
|
1770
|
+
element = None
|
1691
1771
|
try:
|
1692
|
-
self.
|
1772
|
+
element = self.find_element(selector, timeout=timeout)
|
1693
1773
|
except Exception:
|
1694
|
-
raise Exception("Element {%s}
|
1695
|
-
for i in range(
|
1696
|
-
|
1774
|
+
raise Exception("Element {%s} not found!" % selector)
|
1775
|
+
for i in range(int(timeout * 10)):
|
1776
|
+
with suppress(Exception):
|
1777
|
+
element = self.find_element(selector, timeout=0.1)
|
1778
|
+
if text in element.text_all:
|
1697
1779
|
return True
|
1780
|
+
now_ms = time.time() * 1000.0
|
1781
|
+
if now_ms >= stop_ms:
|
1782
|
+
break
|
1698
1783
|
time.sleep(0.1)
|
1699
|
-
raise Exception(
|
1784
|
+
raise Exception(
|
1785
|
+
"Text {%s} not found in {%s}! Actual text: {%s}"
|
1786
|
+
% (text, selector, element.text_all)
|
1787
|
+
)
|
1700
1788
|
|
1701
|
-
def
|
1702
|
-
"""Same as assert_element()"""
|
1789
|
+
def wait_for_text_not_visible(self, text, selector="body", timeout=None):
|
1703
1790
|
if not timeout:
|
1704
1791
|
timeout = settings.SMALL_TIMEOUT
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
if self.is_element_visible(selector):
|
1792
|
+
text = text.strip()
|
1793
|
+
start_ms = time.time() * 1000.0
|
1794
|
+
stop_ms = start_ms + (timeout * 1000.0)
|
1795
|
+
for i in range(int(timeout * 10)):
|
1796
|
+
if not self.is_text_visible(text, selector):
|
1711
1797
|
return True
|
1798
|
+
now_ms = time.time() * 1000.0
|
1799
|
+
if now_ms >= stop_ms:
|
1800
|
+
break
|
1712
1801
|
time.sleep(0.1)
|
1713
|
-
|
1802
|
+
plural = "s"
|
1803
|
+
if timeout == 1:
|
1804
|
+
plural = ""
|
1805
|
+
raise Exception(
|
1806
|
+
"Text {%s} in {%s} was still visible after %s second%s!"
|
1807
|
+
% (text, selector, timeout, plural)
|
1808
|
+
)
|
1714
1809
|
|
1715
|
-
def
|
1716
|
-
"""Assert element is present in the DOM. (Visibility NOT required)"""
|
1810
|
+
def wait_for_element_visible(self, selector, timeout=None):
|
1717
1811
|
if not timeout:
|
1718
1812
|
timeout = settings.SMALL_TIMEOUT
|
1719
1813
|
try:
|
1720
1814
|
self.select(selector, timeout=timeout)
|
1721
1815
|
except Exception:
|
1722
1816
|
raise Exception("Element {%s} was not found!" % selector)
|
1723
|
-
|
1817
|
+
for i in range(30):
|
1818
|
+
if self.is_element_visible(selector):
|
1819
|
+
return self.select(selector)
|
1820
|
+
time.sleep(0.1)
|
1821
|
+
raise Exception("Element {%s} was not visible!" % selector)
|
1724
1822
|
|
1725
|
-
def
|
1726
|
-
"""
|
1823
|
+
def wait_for_element_not_visible(self, selector, timeout=None):
|
1824
|
+
"""Wait for element to not be visible on page. (May still be in DOM)"""
|
1727
1825
|
if not timeout:
|
1728
1826
|
timeout = settings.SMALL_TIMEOUT
|
1729
1827
|
start_ms = time.time() * 1000.0
|
@@ -1731,6 +1829,8 @@ class CDPMethods():
|
|
1731
1829
|
for i in range(int(timeout * 10)):
|
1732
1830
|
if not self.is_element_present(selector):
|
1733
1831
|
return True
|
1832
|
+
elif not self.is_element_visible(selector):
|
1833
|
+
return True
|
1734
1834
|
now_ms = time.time() * 1000.0
|
1735
1835
|
if now_ms >= stop_ms:
|
1736
1836
|
break
|
@@ -1739,12 +1839,12 @@ class CDPMethods():
|
|
1739
1839
|
if timeout == 1:
|
1740
1840
|
plural = ""
|
1741
1841
|
raise Exception(
|
1742
|
-
"Element {%s} was still
|
1842
|
+
"Element {%s} was still visible after %s second%s!"
|
1743
1843
|
% (selector, timeout, plural)
|
1744
1844
|
)
|
1745
1845
|
|
1746
|
-
def
|
1747
|
-
"""
|
1846
|
+
def wait_for_element_absent(self, selector, timeout=None):
|
1847
|
+
"""Wait for element to not be present in the DOM."""
|
1748
1848
|
if not timeout:
|
1749
1849
|
timeout = settings.SMALL_TIMEOUT
|
1750
1850
|
start_ms = time.time() * 1000.0
|
@@ -1752,8 +1852,6 @@ class CDPMethods():
|
|
1752
1852
|
for i in range(int(timeout * 10)):
|
1753
1853
|
if not self.is_element_present(selector):
|
1754
1854
|
return True
|
1755
|
-
elif not self.is_element_visible(selector):
|
1756
|
-
return True
|
1757
1855
|
now_ms = time.time() * 1000.0
|
1758
1856
|
if now_ms >= stop_ms:
|
1759
1857
|
break
|
@@ -1762,10 +1860,49 @@ class CDPMethods():
|
|
1762
1860
|
if timeout == 1:
|
1763
1861
|
plural = ""
|
1764
1862
|
raise Exception(
|
1765
|
-
"Element {%s} was still
|
1863
|
+
"Element {%s} was still present after %s second%s!"
|
1766
1864
|
% (selector, timeout, plural)
|
1767
1865
|
)
|
1768
1866
|
|
1867
|
+
def assert_element(self, selector, timeout=None):
|
1868
|
+
"""Same as assert_element_visible()"""
|
1869
|
+
self.assert_element_visible(selector, timeout=timeout)
|
1870
|
+
return True
|
1871
|
+
|
1872
|
+
def assert_element_visible(self, selector, timeout=None):
|
1873
|
+
"""Same as assert_element()"""
|
1874
|
+
if not timeout:
|
1875
|
+
timeout = settings.SMALL_TIMEOUT
|
1876
|
+
try:
|
1877
|
+
self.select(selector, timeout=timeout)
|
1878
|
+
except Exception:
|
1879
|
+
raise Exception("Element {%s} was not found!" % selector)
|
1880
|
+
for i in range(30):
|
1881
|
+
if self.is_element_visible(selector):
|
1882
|
+
return True
|
1883
|
+
time.sleep(0.1)
|
1884
|
+
raise Exception("Element {%s} was not visible!" % selector)
|
1885
|
+
|
1886
|
+
def assert_element_present(self, selector, timeout=None):
|
1887
|
+
"""Assert element is present in the DOM. (Visibility NOT required)"""
|
1888
|
+
if not timeout:
|
1889
|
+
timeout = settings.SMALL_TIMEOUT
|
1890
|
+
try:
|
1891
|
+
self.select(selector, timeout=timeout)
|
1892
|
+
except Exception:
|
1893
|
+
raise Exception("Element {%s} was not found!" % selector)
|
1894
|
+
return True
|
1895
|
+
|
1896
|
+
def assert_element_absent(self, selector, timeout=None):
|
1897
|
+
"""Assert element is not present in the DOM."""
|
1898
|
+
self.wait_for_element_absent(selector, timeout=timeout)
|
1899
|
+
return True
|
1900
|
+
|
1901
|
+
def assert_element_not_visible(self, selector, timeout=None):
|
1902
|
+
"""Assert element is not visible on page. (May still be in DOM)"""
|
1903
|
+
self.wait_for_element_not_visible(selector, timeout=timeout)
|
1904
|
+
return True
|
1905
|
+
|
1769
1906
|
def assert_element_attribute(self, selector, attribute, value=None):
|
1770
1907
|
attributes = self.get_element_attributes(selector)
|
1771
1908
|
if attribute not in attributes:
|
@@ -1842,29 +1979,9 @@ class CDPMethods():
|
|
1842
1979
|
raise Exception(error % (expected, actual))
|
1843
1980
|
|
1844
1981
|
def assert_text(self, text, selector="body", timeout=None):
|
1845
|
-
|
1846
|
-
|
1847
|
-
|
1848
|
-
stop_ms = start_ms + (timeout * 1000.0)
|
1849
|
-
text = text.strip()
|
1850
|
-
element = None
|
1851
|
-
try:
|
1852
|
-
element = self.find_element(selector, timeout=timeout)
|
1853
|
-
except Exception:
|
1854
|
-
raise Exception("Element {%s} not found!" % selector)
|
1855
|
-
for i in range(int(timeout * 10)):
|
1856
|
-
with suppress(Exception):
|
1857
|
-
element = self.find_element(selector, timeout=0.1)
|
1858
|
-
if text in element.text_all:
|
1859
|
-
return True
|
1860
|
-
now_ms = time.time() * 1000.0
|
1861
|
-
if now_ms >= stop_ms:
|
1862
|
-
break
|
1863
|
-
time.sleep(0.1)
|
1864
|
-
raise Exception(
|
1865
|
-
"Text {%s} not found in {%s}! Actual text: {%s}"
|
1866
|
-
% (text, selector, element.text_all)
|
1867
|
-
)
|
1982
|
+
"""Same as wait_for_text()"""
|
1983
|
+
self.wait_for_text(text, selector=selector, timeout=timeout)
|
1984
|
+
return True
|
1868
1985
|
|
1869
1986
|
def assert_exact_text(self, text, selector="body", timeout=None):
|
1870
1987
|
if not timeout:
|
@@ -1894,6 +2011,13 @@ class CDPMethods():
|
|
1894
2011
|
% (text, element.text_all, selector)
|
1895
2012
|
)
|
1896
2013
|
|
2014
|
+
def assert_text_not_visible(self, text, selector="body", timeout=None):
|
2015
|
+
"""Raises an exception if the text is still visible after timeout."""
|
2016
|
+
self.wait_for_text_not_visible(
|
2017
|
+
text, selector=selector, timeout=timeout
|
2018
|
+
)
|
2019
|
+
return True
|
2020
|
+
|
1897
2021
|
def assert_true(self, expression):
|
1898
2022
|
if not expression:
|
1899
2023
|
raise AssertionError("%s is not true" % expression)
|
seleniumbase/core/sb_driver.py
CHANGED
@@ -51,6 +51,13 @@ class DriverMethods():
|
|
51
51
|
element = self.locator(selector, by=by)
|
52
52
|
return element.get_attribute(attribute)
|
53
53
|
|
54
|
+
def get_parent(self, element):
|
55
|
+
if self.__is_cdp_swap_needed():
|
56
|
+
return self.driver.cdp.get_parent(element)
|
57
|
+
if isinstance(element, str):
|
58
|
+
element = self.locator(element)
|
59
|
+
return element.find_element(by="xpath", value="..")
|
60
|
+
|
54
61
|
def get_current_url(self):
|
55
62
|
if self.__is_cdp_swap_needed():
|
56
63
|
current_url = self.driver.cdp.get_current_url()
|
Binary file
|
Binary file
|
@@ -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)
|
@@ -2072,6 +2076,19 @@ class BaseCase(unittest.TestCase):
|
|
2072
2076
|
return
|
2073
2077
|
self.set_attributes('[target="_blank"]', "target", "_self")
|
2074
2078
|
|
2079
|
+
def get_parent(self, element, by="css selector", timeout=None):
|
2080
|
+
"""Returns the parent element.
|
2081
|
+
If element is a string, then finds element first via selector."""
|
2082
|
+
if self.__is_cdp_swap_needed():
|
2083
|
+
return self.cdp.get_parent(element)
|
2084
|
+
if isinstance(element, str):
|
2085
|
+
if not timeout:
|
2086
|
+
timeout = settings.LARGE_TIMEOUT
|
2087
|
+
element = self.wait_for_element_present(
|
2088
|
+
element, by=by, timeout=timeout
|
2089
|
+
)
|
2090
|
+
return element.find_element(by="xpath", value="..")
|
2091
|
+
|
2075
2092
|
def get_property(
|
2076
2093
|
self, selector, property, by="css selector", timeout=None
|
2077
2094
|
):
|
@@ -9107,7 +9124,7 @@ class BaseCase(unittest.TestCase):
|
|
9107
9124
|
original_selector = selector
|
9108
9125
|
selector, by = self.__recalculate_selector(selector, by)
|
9109
9126
|
if self.__is_cdp_swap_needed():
|
9110
|
-
self.cdp.
|
9127
|
+
self.cdp.wait_for_element_absent(selector, timeout=timeout)
|
9111
9128
|
return True
|
9112
9129
|
return page_actions.wait_for_element_absent(
|
9113
9130
|
self.driver,
|
@@ -9268,7 +9285,8 @@ class BaseCase(unittest.TestCase):
|
|
9268
9285
|
"bottom_left", "bottom_center", "bottom_right"]
|
9269
9286
|
max_messages: The limit of concurrent messages to display."""
|
9270
9287
|
self.__check_scope()
|
9271
|
-
self.
|
9288
|
+
if not self.__is_cdp_swap_needed():
|
9289
|
+
self._check_browser()
|
9272
9290
|
if not theme:
|
9273
9291
|
theme = "default" # "flat"
|
9274
9292
|
if not location:
|
@@ -9295,7 +9313,8 @@ class BaseCase(unittest.TestCase):
|
|
9295
9313
|
You can also post messages by using =>
|
9296
9314
|
self.execute_script('Messenger().post("My Message")') """
|
9297
9315
|
self.__check_scope()
|
9298
|
-
self.
|
9316
|
+
if not self.__is_cdp_swap_needed():
|
9317
|
+
self._check_browser()
|
9299
9318
|
if style not in ["info", "success", "error"]:
|
9300
9319
|
style = "info"
|
9301
9320
|
if not duration:
|
@@ -9566,7 +9585,7 @@ class BaseCase(unittest.TestCase):
|
|
9566
9585
|
self.assert_elements_present(selector, by=by, timeout=timeout)
|
9567
9586
|
return True
|
9568
9587
|
if self.__is_cdp_swap_needed():
|
9569
|
-
self.cdp.assert_element_present(selector)
|
9588
|
+
self.cdp.assert_element_present(selector, timeout=timeout)
|
9570
9589
|
return True
|
9571
9590
|
if self.__is_shadow_selector(selector):
|
9572
9591
|
self.__assert_shadow_element_present(selector)
|
@@ -9643,7 +9662,7 @@ class BaseCase(unittest.TestCase):
|
|
9643
9662
|
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
|
9644
9663
|
timeout = self.__get_new_timeout(timeout)
|
9645
9664
|
if self.__is_cdp_swap_needed():
|
9646
|
-
self.cdp.assert_element(selector)
|
9665
|
+
self.cdp.assert_element(selector, timeout=timeout)
|
9647
9666
|
return True
|
9648
9667
|
if isinstance(selector, list):
|
9649
9668
|
self.assert_elements(selector, by=by, timeout=timeout)
|
@@ -9936,7 +9955,7 @@ class BaseCase(unittest.TestCase):
|
|
9936
9955
|
messenger_post, selector, by
|
9937
9956
|
)
|
9938
9957
|
elif self.__is_cdp_swap_needed():
|
9939
|
-
self.cdp.assert_text(text, selector)
|
9958
|
+
self.cdp.assert_text(text, selector, timeout=timeout)
|
9940
9959
|
return True
|
9941
9960
|
elif not self.is_connected():
|
9942
9961
|
self.connect()
|
@@ -9986,7 +10005,7 @@ class BaseCase(unittest.TestCase):
|
|
9986
10005
|
original_selector = selector
|
9987
10006
|
selector, by = self.__recalculate_selector(selector, by)
|
9988
10007
|
if self.__is_cdp_swap_needed():
|
9989
|
-
self.cdp.assert_exact_text(text, selector)
|
10008
|
+
self.cdp.assert_exact_text(text, selector, timeout=timeout)
|
9990
10009
|
return True
|
9991
10010
|
if self.__is_shadow_selector(selector):
|
9992
10011
|
self.__assert_exact_shadow_text_visible(text, selector, timeout)
|
@@ -10226,6 +10245,9 @@ class BaseCase(unittest.TestCase):
|
|
10226
10245
|
timeout = self.__get_new_timeout(timeout)
|
10227
10246
|
original_selector = selector
|
10228
10247
|
selector, by = self.__recalculate_selector(selector, by)
|
10248
|
+
if self.__is_cdp_swap_needed():
|
10249
|
+
self.cdp.wait_for_element_absent(selector, timeout=timeout)
|
10250
|
+
return True
|
10229
10251
|
return page_actions.wait_for_element_absent(
|
10230
10252
|
self.driver,
|
10231
10253
|
selector,
|
@@ -10248,7 +10270,7 @@ class BaseCase(unittest.TestCase):
|
|
10248
10270
|
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
|
10249
10271
|
timeout = self.__get_new_timeout(timeout)
|
10250
10272
|
if self.__is_cdp_swap_needed():
|
10251
|
-
self.cdp.assert_element_absent(selector)
|
10273
|
+
self.cdp.assert_element_absent(selector, timeout=timeout)
|
10252
10274
|
return True
|
10253
10275
|
self.wait_for_element_absent(selector, by=by, timeout=timeout)
|
10254
10276
|
return True
|
@@ -10269,7 +10291,7 @@ class BaseCase(unittest.TestCase):
|
|
10269
10291
|
original_selector = selector
|
10270
10292
|
selector, by = self.__recalculate_selector(selector, by)
|
10271
10293
|
if self.__is_cdp_swap_needed():
|
10272
|
-
self.cdp.
|
10294
|
+
self.cdp.wait_for_element_not_visible(selector, timeout=timeout)
|
10273
10295
|
return True
|
10274
10296
|
return page_actions.wait_for_element_not_visible(
|
10275
10297
|
self.driver,
|
@@ -10291,7 +10313,7 @@ class BaseCase(unittest.TestCase):
|
|
10291
10313
|
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
|
10292
10314
|
timeout = self.__get_new_timeout(timeout)
|
10293
10315
|
if self.__is_cdp_swap_needed():
|
10294
|
-
self.cdp.assert_element_not_visible(selector)
|
10316
|
+
self.cdp.assert_element_not_visible(selector, timeout=timeout)
|
10295
10317
|
return True
|
10296
10318
|
self.wait_for_element_not_visible(selector, by=by, timeout=timeout)
|
10297
10319
|
if self.recorder_mode and self.__current_url_is_recordable():
|
@@ -10313,6 +10335,10 @@ class BaseCase(unittest.TestCase):
|
|
10313
10335
|
if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT:
|
10314
10336
|
timeout = self.__get_new_timeout(timeout)
|
10315
10337
|
selector, by = self.__recalculate_selector(selector, by)
|
10338
|
+
if self.__is_cdp_swap_needed():
|
10339
|
+
return self.cdp.wait_for_text(
|
10340
|
+
text, selector=selector, timeout=timeout
|
10341
|
+
)
|
10316
10342
|
return page_actions.wait_for_text_not_visible(
|
10317
10343
|
self.driver, text, selector, by, timeout
|
10318
10344
|
)
|
@@ -13896,7 +13922,8 @@ class BaseCase(unittest.TestCase):
|
|
13896
13922
|
js_utils.highlight_element_with_js(self.driver, element, loops, o_bs)
|
13897
13923
|
|
13898
13924
|
def __highlight_with_jquery(self, selector, loops, o_bs):
|
13899
|
-
self.
|
13925
|
+
if not self.__is_cdp_swap_needed():
|
13926
|
+
self.wait_for_ready_state_complete()
|
13900
13927
|
js_utils.highlight_with_jquery(self.driver, selector, loops, o_bs)
|
13901
13928
|
|
13902
13929
|
def __highlight_with_js_2(self, message, selector, o_bs):
|