seleniumbase 4.27.5__py3-none-any.whl → 4.28.0a1__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/__init__.py +3 -0
- seleniumbase/__version__.py +1 -1
- seleniumbase/behave/behave_sb.py +2 -1
- seleniumbase/core/browser_launcher.py +214 -21
- seleniumbase/core/sb_driver.py +58 -5
- seleniumbase/extensions/recorder.zip +0 -0
- seleniumbase/fixtures/base_case.py +112 -24
- seleniumbase/fixtures/constants.py +6 -0
- seleniumbase/fixtures/page_actions.py +37 -3
- seleniumbase/js_code/active_css_js.py +1 -1
- seleniumbase/js_code/recorder_js.py +1 -1
- seleniumbase/plugins/driver_manager.py +40 -31
- seleniumbase/plugins/pytest_plugin.py +2 -1
- seleniumbase/plugins/sb_manager.py +59 -55
- seleniumbase/plugins/selenium_plugin.py +2 -1
- {seleniumbase-4.27.5.dist-info → seleniumbase-4.28.0a1.dist-info}/METADATA +15 -9
- {seleniumbase-4.27.5.dist-info → seleniumbase-4.28.0a1.dist-info}/RECORD +21 -21
- {seleniumbase-4.27.5.dist-info → seleniumbase-4.28.0a1.dist-info}/WHEEL +1 -1
- {seleniumbase-4.27.5.dist-info → seleniumbase-4.28.0a1.dist-info}/LICENSE +0 -0
- {seleniumbase-4.27.5.dist-info → seleniumbase-4.28.0a1.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.27.5.dist-info → seleniumbase-4.28.0a1.dist-info}/top_level.txt +0 -0
seleniumbase/__init__.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import collections
|
2
|
+
import os
|
2
3
|
import pdb
|
3
4
|
try:
|
4
5
|
import pdbp # (Pdb+) --- Python Debugger Plus
|
@@ -34,11 +35,13 @@ if sys.version_info[0] < 3 and "pdbp" in locals():
|
|
34
35
|
pdb.DefaultConfig.truncate_long_lines = False
|
35
36
|
pdb.DefaultConfig.sticky_by_default = True
|
36
37
|
colored_traceback.add_hook()
|
38
|
+
os.environ["SE_AVOID_STATS"] = "true" # Disable Selenium Manager stats
|
37
39
|
if sys.version_info >= (3, 7):
|
38
40
|
webdriver.TouchActions = None # Lifeline for past selenium-wire versions
|
39
41
|
if sys.version_info >= (3, 10):
|
40
42
|
collections.Callable = collections.abc.Callable # Lifeline for nosetests
|
41
43
|
del collections # Undo "import collections" / Simplify "dir(seleniumbase)"
|
44
|
+
del os # Undo "import os" / Simplify "dir(seleniumbase)"
|
42
45
|
del sys # Undo "import sys" / Simplify "dir(seleniumbase)"
|
43
46
|
del webdriver # Undo "import webdriver" / Simplify "dir(seleniumbase)"
|
44
47
|
|
seleniumbase/__version__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# seleniumbase package
|
2
|
-
__version__ = "4.
|
2
|
+
__version__ = "4.28.0a1"
|
seleniumbase/behave/behave_sb.py
CHANGED
@@ -861,13 +861,14 @@ def get_configured_sb(context):
|
|
861
861
|
and not sb.headless
|
862
862
|
and not sb.headless2
|
863
863
|
and not sb.xvfb
|
864
|
+
and not sb.undetectable
|
864
865
|
):
|
865
866
|
print(
|
866
867
|
'(Linux uses "-D headless" by default. '
|
867
868
|
'To override, use "-D headed" / "-D gui". '
|
868
869
|
'For Xvfb mode instead, use "-D xvfb". '
|
869
870
|
"Or you can hide this info by using"
|
870
|
-
'"-D headless" / "-D headless2".)'
|
871
|
+
'"-D headless" / "-D headless2" / "-D uc".)'
|
871
872
|
)
|
872
873
|
sb.headless = True
|
873
874
|
# Recorder Mode can still optimize scripts in --headless2 mode.
|
@@ -11,6 +11,7 @@ import urllib3
|
|
11
11
|
import warnings
|
12
12
|
from selenium import webdriver
|
13
13
|
from selenium.common.exceptions import ElementClickInterceptedException
|
14
|
+
from selenium.common.exceptions import InvalidSessionIdException
|
14
15
|
from selenium.webdriver.chrome.service import Service as ChromeService
|
15
16
|
from selenium.webdriver.common.options import ArgOptions
|
16
17
|
from selenium.webdriver.common.service import utils as service_utils
|
@@ -28,6 +29,7 @@ from seleniumbase.core import proxy_helper
|
|
28
29
|
from seleniumbase.core import sb_driver
|
29
30
|
from seleniumbase.fixtures import constants
|
30
31
|
from seleniumbase.fixtures import js_utils
|
32
|
+
from seleniumbase.fixtures import page_actions
|
31
33
|
from seleniumbase.fixtures import shared_utils
|
32
34
|
|
33
35
|
urllib3.disable_warnings()
|
@@ -130,9 +132,13 @@ def extend_driver(driver):
|
|
130
132
|
page.assert_element_not_visible = DM.assert_element_not_visible
|
131
133
|
page.assert_text = DM.assert_text
|
132
134
|
page.assert_exact_text = DM.assert_exact_text
|
135
|
+
page.assert_non_empty_text = DM.assert_non_empty_text
|
136
|
+
page.assert_text_not_visible = DM.assert_text_not_visible
|
133
137
|
page.wait_for_element = DM.wait_for_element
|
134
138
|
page.wait_for_text = DM.wait_for_text
|
135
139
|
page.wait_for_exact_text = DM.wait_for_exact_text
|
140
|
+
page.wait_for_non_empty_text = DM.wait_for_non_empty_text
|
141
|
+
page.wait_for_text_not_visible = DM.wait_for_text_not_visible
|
136
142
|
page.wait_for_and_accept_alert = DM.wait_for_and_accept_alert
|
137
143
|
page.wait_for_and_dismiss_alert = DM.wait_for_and_dismiss_alert
|
138
144
|
page.is_element_present = DM.is_element_present
|
@@ -140,12 +146,20 @@ def extend_driver(driver):
|
|
140
146
|
page.is_text_visible = DM.is_text_visible
|
141
147
|
page.is_exact_text_visible = DM.is_exact_text_visible
|
142
148
|
page.is_attribute_present = DM.is_attribute_present
|
149
|
+
page.is_non_empty_text_visible = DM.is_non_empty_text_visible
|
143
150
|
page.get_text = DM.get_text
|
144
151
|
page.find_element = DM.find_element
|
145
152
|
page.find_elements = DM.find_elements
|
146
153
|
page.locator = DM.locator
|
147
154
|
page.get_page_source = DM.get_page_source
|
148
155
|
page.get_title = DM.get_title
|
156
|
+
page.switch_to_default_window = DM.switch_to_default_window
|
157
|
+
page.switch_to_newest_window = DM.switch_to_newest_window
|
158
|
+
page.open_new_window = DM.open_new_window
|
159
|
+
page.open_new_tab = DM.open_new_tab
|
160
|
+
page.switch_to_window = DM.switch_to_window
|
161
|
+
page.switch_to_tab = DM.switch_to_tab
|
162
|
+
page.switch_to_frame = DM.switch_to_frame
|
149
163
|
driver.page = page
|
150
164
|
js = types.SimpleNamespace()
|
151
165
|
js.js_click = DM.js_click
|
@@ -169,12 +183,16 @@ def extend_driver(driver):
|
|
169
183
|
driver.assert_element_not_visible = DM.assert_element_not_visible
|
170
184
|
driver.assert_text = DM.assert_text
|
171
185
|
driver.assert_exact_text = DM.assert_exact_text
|
186
|
+
driver.assert_non_empty_text = DM.assert_non_empty_text
|
187
|
+
driver.assert_text_not_visible = DM.assert_text_not_visible
|
172
188
|
driver.wait_for_element = DM.wait_for_element
|
173
189
|
driver.wait_for_element_visible = DM.wait_for_element_visible
|
174
190
|
driver.wait_for_element_present = DM.wait_for_element_present
|
175
191
|
driver.wait_for_selector = DM.wait_for_selector
|
176
192
|
driver.wait_for_text = DM.wait_for_text
|
177
193
|
driver.wait_for_exact_text = DM.wait_for_exact_text
|
194
|
+
driver.wait_for_non_empty_text = DM.wait_for_non_empty_text
|
195
|
+
driver.wait_for_text_not_visible = DM.wait_for_text_not_visible
|
178
196
|
driver.wait_for_and_accept_alert = DM.wait_for_and_accept_alert
|
179
197
|
driver.wait_for_and_dismiss_alert = DM.wait_for_and_dismiss_alert
|
180
198
|
driver.is_element_present = DM.is_element_present
|
@@ -182,8 +200,10 @@ def extend_driver(driver):
|
|
182
200
|
driver.is_text_visible = DM.is_text_visible
|
183
201
|
driver.is_exact_text_visible = DM.is_exact_text_visible
|
184
202
|
driver.is_attribute_present = DM.is_attribute_present
|
185
|
-
driver.
|
203
|
+
driver.is_non_empty_text_visible = DM.is_non_empty_text_visible
|
204
|
+
driver.is_online = DM.is_online
|
186
205
|
driver.js_click = DM.js_click
|
206
|
+
driver.get_text = DM.get_text
|
187
207
|
driver.get_active_element_css = DM.get_active_element_css
|
188
208
|
driver.get_locale_code = DM.get_locale_code
|
189
209
|
driver.get_origin = DM.get_origin
|
@@ -195,6 +215,12 @@ def extend_driver(driver):
|
|
195
215
|
driver.get_attribute = DM.get_attribute
|
196
216
|
driver.get_page_source = DM.get_page_source
|
197
217
|
driver.get_title = DM.get_title
|
218
|
+
driver.switch_to_default_window = DM.switch_to_default_window
|
219
|
+
driver.switch_to_newest_window = DM.switch_to_newest_window
|
220
|
+
driver.open_new_window = DM.open_new_window
|
221
|
+
driver.open_new_tab = DM.open_new_tab
|
222
|
+
driver.switch_to_window = DM.switch_to_window
|
223
|
+
driver.switch_to_tab = DM.switch_to_tab
|
198
224
|
driver.switch_to_frame = DM.switch_to_frame
|
199
225
|
if hasattr(driver, "proxy"):
|
200
226
|
driver.set_wire_proxy = DM.set_wire_proxy
|
@@ -409,7 +435,7 @@ def uc_open(driver, url):
|
|
409
435
|
if (url.startswith("http:") or url.startswith("https:")):
|
410
436
|
with driver:
|
411
437
|
script = 'window.location.href = "%s";' % url
|
412
|
-
js_utils.call_me_later(driver, script,
|
438
|
+
js_utils.call_me_later(driver, script, 5)
|
413
439
|
else:
|
414
440
|
driver.default_get(url) # The original one
|
415
441
|
return None
|
@@ -440,22 +466,28 @@ def uc_open_with_reconnect(driver, url, reconnect_time=None):
|
|
440
466
|
url = "https://" + url
|
441
467
|
if (url.startswith("http:") or url.startswith("https:")):
|
442
468
|
script = 'window.open("%s","_blank");' % url
|
443
|
-
js_utils.call_me_later(driver, script,
|
469
|
+
js_utils.call_me_later(driver, script, 4)
|
444
470
|
time.sleep(0.007)
|
445
471
|
driver.close()
|
446
472
|
if reconnect_time == "disconnect":
|
447
473
|
driver.disconnect()
|
448
|
-
time.sleep(0.
|
474
|
+
time.sleep(0.008)
|
449
475
|
else:
|
450
476
|
driver.reconnect(reconnect_time)
|
451
|
-
|
477
|
+
time.sleep(0.004)
|
478
|
+
try:
|
479
|
+
driver.switch_to.window(driver.window_handles[-1])
|
480
|
+
except InvalidSessionIdException:
|
481
|
+
time.sleep(0.05)
|
482
|
+
driver.switch_to.window(driver.window_handles[-1])
|
452
483
|
else:
|
453
484
|
driver.default_get(url) # The original one
|
454
485
|
return None
|
455
486
|
|
456
487
|
|
457
|
-
def uc_open_with_disconnect(driver, url):
|
488
|
+
def uc_open_with_disconnect(driver, url, timeout=None):
|
458
489
|
"""Open a url and disconnect chromedriver.
|
490
|
+
Then waits for the duration of the timeout.
|
459
491
|
Note: You can't perform Selenium actions again
|
460
492
|
until after you've called driver.connect()."""
|
461
493
|
if url.startswith("//"):
|
@@ -464,11 +496,16 @@ def uc_open_with_disconnect(driver, url):
|
|
464
496
|
url = "https://" + url
|
465
497
|
if (url.startswith("http:") or url.startswith("https:")):
|
466
498
|
script = 'window.open("%s","_blank");' % url
|
467
|
-
js_utils.call_me_later(driver, script,
|
499
|
+
js_utils.call_me_later(driver, script, 4)
|
468
500
|
time.sleep(0.007)
|
469
501
|
driver.close()
|
470
502
|
driver.disconnect()
|
471
|
-
|
503
|
+
min_timeout = 0.008
|
504
|
+
if timeout and not str(timeout).replace(".", "", 1).isdigit():
|
505
|
+
timeout = min_timeout
|
506
|
+
if not timeout or timeout < min_timeout:
|
507
|
+
timeout = min_timeout
|
508
|
+
time.sleep(timeout)
|
472
509
|
else:
|
473
510
|
driver.default_get(url) # The original one
|
474
511
|
return None
|
@@ -490,7 +527,7 @@ def uc_click(
|
|
490
527
|
pass
|
491
528
|
element = driver.wait_for_selector(selector, by=by, timeout=timeout)
|
492
529
|
tag_name = element.tag_name
|
493
|
-
if not tag_name == "span": #
|
530
|
+
if not tag_name == "span" and not tag_name == "input": # Must be "visible"
|
494
531
|
element = driver.wait_for_element(selector, by=by, timeout=timeout)
|
495
532
|
try:
|
496
533
|
element.uc_click(
|
@@ -509,7 +546,143 @@ def uc_click(
|
|
509
546
|
driver.reconnect(reconnect_time)
|
510
547
|
|
511
548
|
|
512
|
-
def
|
549
|
+
def install_pyautogui_if_missing():
|
550
|
+
pip_find_lock = fasteners.InterProcessLock(
|
551
|
+
constants.PipInstall.FINDLOCK
|
552
|
+
)
|
553
|
+
with pip_find_lock: # Prevent issues with multiple processes
|
554
|
+
try:
|
555
|
+
import pyautogui
|
556
|
+
try:
|
557
|
+
use_pyautogui_ver = constants.PyAutoGUI.VER
|
558
|
+
if pyautogui.__version__ != use_pyautogui_ver:
|
559
|
+
shared_utils.pip_install(
|
560
|
+
"pyautogui", version=use_pyautogui_ver
|
561
|
+
)
|
562
|
+
del pyautogui
|
563
|
+
except Exception:
|
564
|
+
pass
|
565
|
+
except Exception:
|
566
|
+
print("\nPyAutoGUI required! Installing now...")
|
567
|
+
shared_utils.pip_install(
|
568
|
+
"pyautogui", version=constants.PyAutoGUI.VER
|
569
|
+
)
|
570
|
+
|
571
|
+
|
572
|
+
def get_configured_pyautogui(pyautogui_copy):
|
573
|
+
if (
|
574
|
+
IS_LINUX
|
575
|
+
and hasattr(pyautogui_copy, "_pyautogui_x11")
|
576
|
+
and "DISPLAY" in os.environ.keys()
|
577
|
+
):
|
578
|
+
if (
|
579
|
+
hasattr(sb_config, "_pyautogui_x11_display")
|
580
|
+
and sb_config._pyautogui_x11_display
|
581
|
+
and hasattr(pyautogui_copy._pyautogui_x11, "_display")
|
582
|
+
and (
|
583
|
+
sb_config._pyautogui_x11_display
|
584
|
+
== pyautogui_copy._pyautogui_x11._display
|
585
|
+
)
|
586
|
+
):
|
587
|
+
pass
|
588
|
+
else:
|
589
|
+
import Xlib.display
|
590
|
+
pyautogui_copy._pyautogui_x11._display = (
|
591
|
+
Xlib.display.Display(os.environ['DISPLAY'])
|
592
|
+
)
|
593
|
+
sb_config._pyautogui_x11_display = (
|
594
|
+
pyautogui_copy._pyautogui_x11._display
|
595
|
+
)
|
596
|
+
return pyautogui_copy
|
597
|
+
|
598
|
+
|
599
|
+
def uc_gui_press_key(driver, key):
|
600
|
+
install_pyautogui_if_missing()
|
601
|
+
import pyautogui
|
602
|
+
pyautogui = get_configured_pyautogui(pyautogui)
|
603
|
+
gui_lock = fasteners.InterProcessLock(
|
604
|
+
constants.MultiBrowser.PYAUTOGUILOCK
|
605
|
+
)
|
606
|
+
with gui_lock:
|
607
|
+
pyautogui.press(key)
|
608
|
+
|
609
|
+
|
610
|
+
def uc_gui_press_keys(driver, keys):
|
611
|
+
install_pyautogui_if_missing()
|
612
|
+
import pyautogui
|
613
|
+
pyautogui = get_configured_pyautogui(pyautogui)
|
614
|
+
gui_lock = fasteners.InterProcessLock(
|
615
|
+
constants.MultiBrowser.PYAUTOGUILOCK
|
616
|
+
)
|
617
|
+
with gui_lock:
|
618
|
+
for key in keys:
|
619
|
+
pyautogui.press(key)
|
620
|
+
|
621
|
+
|
622
|
+
def uc_gui_write(driver, text):
|
623
|
+
install_pyautogui_if_missing()
|
624
|
+
import pyautogui
|
625
|
+
pyautogui = get_configured_pyautogui(pyautogui)
|
626
|
+
gui_lock = fasteners.InterProcessLock(
|
627
|
+
constants.MultiBrowser.PYAUTOGUILOCK
|
628
|
+
)
|
629
|
+
with gui_lock:
|
630
|
+
pyautogui.write(text)
|
631
|
+
|
632
|
+
|
633
|
+
def uc_gui_handle_cf(driver, frame="iframe"):
|
634
|
+
source = driver.get_page_source()
|
635
|
+
if (
|
636
|
+
"//challenges.cloudflare.com" not in source
|
637
|
+
and 'aria-label="Cloudflare"' not in source
|
638
|
+
):
|
639
|
+
return
|
640
|
+
install_pyautogui_if_missing()
|
641
|
+
import pyautogui
|
642
|
+
pyautogui = get_configured_pyautogui(pyautogui)
|
643
|
+
gui_lock = fasteners.InterProcessLock(
|
644
|
+
constants.MultiBrowser.PYAUTOGUILOCK
|
645
|
+
)
|
646
|
+
with gui_lock: # Prevent issues with multiple processes
|
647
|
+
needs_switch = False
|
648
|
+
is_in_frame = js_utils.is_in_frame(driver)
|
649
|
+
if is_in_frame and driver.is_element_present("#challenge-stage"):
|
650
|
+
driver.switch_to.parent_frame()
|
651
|
+
needs_switch = True
|
652
|
+
is_in_frame = js_utils.is_in_frame(driver)
|
653
|
+
if not is_in_frame:
|
654
|
+
# Make sure the window is on top
|
655
|
+
page_actions.switch_to_window(
|
656
|
+
driver,
|
657
|
+
driver.current_window_handle,
|
658
|
+
timeout=settings.SMALL_TIMEOUT,
|
659
|
+
)
|
660
|
+
if not is_in_frame or needs_switch:
|
661
|
+
# Currently not in frame (or nested frame outside CF one)
|
662
|
+
try:
|
663
|
+
driver.switch_to_frame(frame)
|
664
|
+
except Exception:
|
665
|
+
if driver.is_element_present("iframe"):
|
666
|
+
driver.switch_to_frame("iframe")
|
667
|
+
else:
|
668
|
+
return
|
669
|
+
try:
|
670
|
+
driver.execute_script('document.querySelector("input").focus()')
|
671
|
+
except Exception:
|
672
|
+
try:
|
673
|
+
driver.switch_to.default_content()
|
674
|
+
except Exception:
|
675
|
+
return
|
676
|
+
driver.disconnect()
|
677
|
+
try:
|
678
|
+
pyautogui.press(" ")
|
679
|
+
except Exception:
|
680
|
+
pass
|
681
|
+
reconnect_time = (float(constants.UC.RECONNECT_TIME) / 2.0) + 0.5
|
682
|
+
driver.reconnect(reconnect_time)
|
683
|
+
|
684
|
+
|
685
|
+
def uc_switch_to_frame(driver, frame="iframe", reconnect_time=None):
|
513
686
|
from selenium.webdriver.remote.webelement import WebElement
|
514
687
|
if isinstance(frame, WebElement):
|
515
688
|
if not reconnect_time:
|
@@ -847,7 +1020,7 @@ def _set_chrome_options(
|
|
847
1020
|
prefs["download.prompt_for_download"] = False
|
848
1021
|
prefs["credentials_enable_service"] = False
|
849
1022
|
prefs["local_discovery.notifications_enabled"] = False
|
850
|
-
prefs["safebrowsing.enabled"] =
|
1023
|
+
prefs["safebrowsing.enabled"] = True
|
851
1024
|
prefs["safebrowsing.disable_download_protection"] = True
|
852
1025
|
prefs["omnibox-max-zero-suggest-matches"] = 0
|
853
1026
|
prefs["omnibox-use-existing-autocomplete-client"] = 0
|
@@ -1145,6 +1318,7 @@ def _set_chrome_options(
|
|
1145
1318
|
chrome_options.add_argument("--auto-open-devtools-for-tabs")
|
1146
1319
|
if user_agent:
|
1147
1320
|
chrome_options.add_argument("--user-agent=%s" % user_agent)
|
1321
|
+
chrome_options.add_argument("--safebrowsing-disable-download-protection")
|
1148
1322
|
chrome_options.add_argument("--disable-browser-side-navigation")
|
1149
1323
|
chrome_options.add_argument("--disable-save-password-bubble")
|
1150
1324
|
chrome_options.add_argument("--disable-single-click-autofill")
|
@@ -1183,10 +1357,9 @@ def _set_chrome_options(
|
|
1183
1357
|
included_disabled_features.append("DownloadBubbleV2")
|
1184
1358
|
included_disabled_features.append("InsecureDownloadWarnings")
|
1185
1359
|
included_disabled_features.append("InterestFeedContentSuggestions")
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
included_disabled_features.append("SidePanelPinning")
|
1360
|
+
included_disabled_features.append("PrivacySandboxSettings4")
|
1361
|
+
included_disabled_features.append("SidePanelPinning")
|
1362
|
+
included_disabled_features.append("UserAgentClientHint")
|
1190
1363
|
for item in extra_disabled_features:
|
1191
1364
|
if item not in included_disabled_features:
|
1192
1365
|
included_disabled_features.append(item)
|
@@ -1374,7 +1547,7 @@ def _set_firefox_options(
|
|
1374
1547
|
f_pref_value = False
|
1375
1548
|
elif f_pref_value.isdigit():
|
1376
1549
|
f_pref_value = int(f_pref_value)
|
1377
|
-
elif f_pref_value.
|
1550
|
+
elif f_pref_value.replace(".", "", 1).isdigit():
|
1378
1551
|
f_pref_value = float(f_pref_value)
|
1379
1552
|
else:
|
1380
1553
|
pass # keep as string
|
@@ -2438,7 +2611,7 @@ def get_local_driver(
|
|
2438
2611
|
"credentials_enable_service": False,
|
2439
2612
|
"local_discovery.notifications_enabled": False,
|
2440
2613
|
"safebrowsing.disable_download_protection": True,
|
2441
|
-
"safebrowsing.enabled":
|
2614
|
+
"safebrowsing.enabled": True,
|
2442
2615
|
"omnibox-max-zero-suggest-matches": 0,
|
2443
2616
|
"omnibox-use-existing-autocomplete-client": 0,
|
2444
2617
|
"omnibox-trending-zero-prefix-suggestions-on-ntp": 0,
|
@@ -2707,6 +2880,7 @@ def get_local_driver(
|
|
2707
2880
|
edge_options.add_argument(
|
2708
2881
|
"--disable-autofill-keyboard-accessory-view[8]"
|
2709
2882
|
)
|
2883
|
+
edge_options.add_argument("--safebrowsing-disable-download-protection")
|
2710
2884
|
edge_options.add_argument("--disable-browser-side-navigation")
|
2711
2885
|
edge_options.add_argument("--disable-translate")
|
2712
2886
|
if not enable_ws:
|
@@ -2848,10 +3022,9 @@ def get_local_driver(
|
|
2848
3022
|
included_disabled_features.append("OptimizationGuideModelDownloading")
|
2849
3023
|
included_disabled_features.append("InsecureDownloadWarnings")
|
2850
3024
|
included_disabled_features.append("InterestFeedContentSuggestions")
|
2851
|
-
|
2852
|
-
|
2853
|
-
|
2854
|
-
included_disabled_features.append("SidePanelPinning")
|
3025
|
+
included_disabled_features.append("PrivacySandboxSettings4")
|
3026
|
+
included_disabled_features.append("SidePanelPinning")
|
3027
|
+
included_disabled_features.append("UserAgentClientHint")
|
2855
3028
|
for item in extra_disabled_features:
|
2856
3029
|
if item not in included_disabled_features:
|
2857
3030
|
included_disabled_features.append(item)
|
@@ -3822,6 +3995,26 @@ def get_local_driver(
|
|
3822
3995
|
driver.uc_click = lambda *args, **kwargs: uc_click(
|
3823
3996
|
driver, *args, **kwargs
|
3824
3997
|
)
|
3998
|
+
driver.uc_gui_press_key = (
|
3999
|
+
lambda *args, **kwargs: uc_gui_press_key(
|
4000
|
+
driver, *args, **kwargs
|
4001
|
+
)
|
4002
|
+
)
|
4003
|
+
driver.uc_gui_press_keys = (
|
4004
|
+
lambda *args, **kwargs: uc_gui_press_keys(
|
4005
|
+
driver, *args, **kwargs
|
4006
|
+
)
|
4007
|
+
)
|
4008
|
+
driver.uc_gui_write = (
|
4009
|
+
lambda *args, **kwargs: uc_gui_write(
|
4010
|
+
driver, *args, **kwargs
|
4011
|
+
)
|
4012
|
+
)
|
4013
|
+
driver.uc_gui_handle_cf = (
|
4014
|
+
lambda *args, **kwargs: uc_gui_handle_cf(
|
4015
|
+
driver, *args, **kwargs
|
4016
|
+
)
|
4017
|
+
)
|
3825
4018
|
driver.uc_switch_to_frame = (
|
3826
4019
|
lambda *args, **kwargs: uc_switch_to_frame(
|
3827
4020
|
driver, *args, **kwargs
|
seleniumbase/core/sb_driver.py
CHANGED
@@ -94,6 +94,16 @@ class DriverMethods():
|
|
94
94
|
def assert_exact_text(self, *args, **kwargs):
|
95
95
|
page_actions.assert_exact_text(self.driver, *args, **kwargs)
|
96
96
|
|
97
|
+
def assert_non_empty_text(self, *args, **kwargs):
|
98
|
+
return page_actions.assert_non_empty_text(
|
99
|
+
self.driver, *args, **kwargs
|
100
|
+
)
|
101
|
+
|
102
|
+
def assert_text_not_visible(self, *args, **kwargs):
|
103
|
+
return page_actions.assert_text_not_visible(
|
104
|
+
self.driver, *args, **kwargs
|
105
|
+
)
|
106
|
+
|
97
107
|
def wait_for_element(self, *args, **kwargs):
|
98
108
|
return page_actions.wait_for_element(self.driver, *args, **kwargs)
|
99
109
|
|
@@ -112,6 +122,16 @@ class DriverMethods():
|
|
112
122
|
def wait_for_exact_text(self, *args, **kwargs):
|
113
123
|
return page_actions.wait_for_exact_text(self.driver, *args, **kwargs)
|
114
124
|
|
125
|
+
def wait_for_non_empty_text(self, *args, **kwargs):
|
126
|
+
return page_actions.wait_for_non_empty_text(
|
127
|
+
self.driver, *args, **kwargs
|
128
|
+
)
|
129
|
+
|
130
|
+
def wait_for_text_not_visible(self, *args, **kwargs):
|
131
|
+
return page_actions.wait_for_text_not_visible(
|
132
|
+
self.driver, *args, **kwargs
|
133
|
+
)
|
134
|
+
|
115
135
|
def wait_for_and_accept_alert(self, *args, **kwargs):
|
116
136
|
return page_actions.wait_for_and_accept_alert(
|
117
137
|
self.driver, *args, **kwargs
|
@@ -134,14 +154,22 @@ class DriverMethods():
|
|
134
154
|
def is_exact_text_visible(self, *args, **kwargs):
|
135
155
|
return page_actions.is_exact_text_visible(self.driver, *args, **kwargs)
|
136
156
|
|
137
|
-
def
|
138
|
-
return page_actions.
|
157
|
+
def is_attribute_present(self, *args, **kwargs):
|
158
|
+
return page_actions.has_attribute(self.driver, *args, **kwargs)
|
159
|
+
|
160
|
+
def is_non_empty_text_visible(self, *args, **kwargs):
|
161
|
+
return page_actions.is_non_empty_text_visible(
|
162
|
+
self.driver, *args, **kwargs
|
163
|
+
)
|
164
|
+
|
165
|
+
def is_online(self):
|
166
|
+
return self.driver.execute_script("return navigator.onLine;")
|
139
167
|
|
140
168
|
def js_click(self, *args, **kwargs):
|
141
169
|
return page_actions.js_click(self.driver, *args, **kwargs)
|
142
170
|
|
143
|
-
def
|
144
|
-
return page_actions.
|
171
|
+
def get_text(self, *args, **kwargs):
|
172
|
+
return page_actions.get_text(self.driver, *args, **kwargs)
|
145
173
|
|
146
174
|
def get_active_element_css(self, *args, **kwargs):
|
147
175
|
return js_utils.get_active_element_css(self.driver, *args, **kwargs)
|
@@ -182,7 +210,32 @@ class DriverMethods():
|
|
182
210
|
if self.is_element_visible(selector, by=by):
|
183
211
|
self.highlight(selector, by=by, loops=loops, scroll=scroll)
|
184
212
|
|
185
|
-
def
|
213
|
+
def switch_to_default_window(self):
|
214
|
+
self.driver.switch_to.window(self.driver.window_handles[0])
|
215
|
+
|
216
|
+
def switch_to_newest_window(self):
|
217
|
+
self.driver.switch_to.window(self.driver.window_handles[-1])
|
218
|
+
|
219
|
+
def open_new_window(self, switch_to=True):
|
220
|
+
if switch_to:
|
221
|
+
try:
|
222
|
+
self.driver.switch_to.new_window("tab")
|
223
|
+
except Exception:
|
224
|
+
self.driver.execute_script("window.open('');")
|
225
|
+
self.switch_to_newest_window()
|
226
|
+
else:
|
227
|
+
self.driver.execute_script("window.open('');")
|
228
|
+
|
229
|
+
def open_new_tab(self, switch_to=True):
|
230
|
+
self.open_new_window(switch_to=switch_to)
|
231
|
+
|
232
|
+
def switch_to_window(self, *args, **kwargs):
|
233
|
+
page_actions.switch_to_window(self.driver, *args, **kwargs)
|
234
|
+
|
235
|
+
def switch_to_tab(self, *args, **kwargs):
|
236
|
+
self.switch_to_window(*args, **kwargs)
|
237
|
+
|
238
|
+
def switch_to_frame(self, frame="iframe"):
|
186
239
|
if isinstance(frame, WebElement):
|
187
240
|
self.driver.switch_to.frame(frame)
|
188
241
|
else:
|
Binary file
|