seleniumbase 4.30.7__py3-none-any.whl → 4.31.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.
- sbase/__init__.py +1 -0
- seleniumbase/__init__.py +2 -3
- seleniumbase/__version__.py +1 -1
- seleniumbase/behave/behave_sb.py +47 -9
- seleniumbase/config/settings.py +4 -0
- seleniumbase/console_scripts/sb_behave_gui.py +5 -5
- seleniumbase/console_scripts/sb_caseplans.py +6 -6
- seleniumbase/console_scripts/sb_commander.py +5 -5
- seleniumbase/console_scripts/sb_install.py +10 -2
- seleniumbase/console_scripts/sb_recorder.py +4 -4
- seleniumbase/core/browser_launcher.py +153 -104
- seleniumbase/core/mysql.py +1 -4
- seleniumbase/core/recorder_helper.py +24 -5
- seleniumbase/core/sb_driver.py +2 -3
- seleniumbase/core/settings_parser.py +4 -0
- seleniumbase/fixtures/base_case.py +307 -492
- seleniumbase/fixtures/js_utils.py +19 -52
- seleniumbase/fixtures/page_actions.py +3 -6
- seleniumbase/fixtures/page_utils.py +20 -58
- seleniumbase/plugins/base_plugin.py +2 -3
- seleniumbase/plugins/driver_manager.py +169 -3
- seleniumbase/plugins/pytest_plugin.py +34 -21
- seleniumbase/plugins/sb_manager.py +170 -3
- seleniumbase/plugins/selenium_plugin.py +52 -6
- seleniumbase/undetected/__init__.py +13 -38
- seleniumbase/undetected/dprocess.py +4 -6
- seleniumbase/undetected/options.py +3 -6
- seleniumbase/undetected/patcher.py +2 -3
- {seleniumbase-4.30.7.dist-info → seleniumbase-4.31.0.dist-info}/METADATA +108 -123
- {seleniumbase-4.30.7.dist-info → seleniumbase-4.31.0.dist-info}/RECORD +34 -45
- {seleniumbase-4.30.7.dist-info → seleniumbase-4.31.0.dist-info}/WHEEL +1 -1
- sbase/ReadMe.txt +0 -2
- seleniumbase/ReadMe.md +0 -25
- seleniumbase/common/ReadMe.md +0 -71
- seleniumbase/console_scripts/ReadMe.md +0 -734
- seleniumbase/drivers/ReadMe.md +0 -27
- seleniumbase/extensions/ReadMe.md +0 -12
- seleniumbase/masterqa/ReadMe.md +0 -61
- seleniumbase/resources/ReadMe.md +0 -31
- seleniumbase/resources/favicon.ico +0 -0
- seleniumbase/utilities/selenium_grid/ReadMe.md +0 -84
- seleniumbase/utilities/selenium_ide/ReadMe.md +0 -111
- {seleniumbase-4.30.7.dist-info → seleniumbase-4.31.0.dist-info}/LICENSE +0 -0
- {seleniumbase-4.30.7.dist-info → seleniumbase-4.31.0.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.30.7.dist-info → seleniumbase-4.31.0.dist-info}/top_level.txt +0 -0
@@ -2,6 +2,7 @@
|
|
2
2
|
import re
|
3
3
|
import requests
|
4
4
|
import time
|
5
|
+
from contextlib import suppress
|
5
6
|
from selenium.common.exceptions import NoSuchElementException
|
6
7
|
from selenium.common.exceptions import WebDriverException
|
7
8
|
from selenium.webdriver.common.by import By
|
@@ -56,11 +57,9 @@ def execute_async_script(driver, script, timeout=settings.LARGE_TIMEOUT):
|
|
56
57
|
def wait_for_angularjs(driver, timeout=settings.LARGE_TIMEOUT, **kwargs):
|
57
58
|
if hasattr(settings, "SKIP_JS_WAITS") and settings.SKIP_JS_WAITS:
|
58
59
|
return
|
59
|
-
|
60
|
+
with suppress(Exception):
|
60
61
|
# This closes pop-up alerts
|
61
62
|
driver.execute_script("")
|
62
|
-
except Exception:
|
63
|
-
pass
|
64
63
|
if (
|
65
64
|
(hasattr(driver, "_is_using_uc") and driver._is_using_uc)
|
66
65
|
or not settings.WAIT_FOR_ANGULARJS
|
@@ -92,10 +91,8 @@ def wait_for_angularjs(driver, timeout=settings.LARGE_TIMEOUT, **kwargs):
|
|
92
91
|
"handler": handler,
|
93
92
|
"suffix": suffix,
|
94
93
|
}
|
95
|
-
|
94
|
+
with suppress(Exception):
|
96
95
|
execute_async_script(driver, script, timeout=timeout)
|
97
|
-
except Exception:
|
98
|
-
pass
|
99
96
|
|
100
97
|
|
101
98
|
def convert_to_css_selector(selector, by=By.CSS_SELECTOR):
|
@@ -191,14 +188,12 @@ def raise_unable_to_load_jquery_exception(driver):
|
|
191
188
|
def activate_jquery(driver):
|
192
189
|
# If "jQuery is not defined" on a website, use this method to activate it.
|
193
190
|
# This method is needed because jQuery is not always defined on web sites.
|
194
|
-
|
191
|
+
with suppress(Exception):
|
195
192
|
# Let's first find out if jQuery is already defined.
|
196
193
|
driver.execute_script("jQuery('html');")
|
197
194
|
# Since that command worked, jQuery is defined. Let's return.
|
198
195
|
return
|
199
|
-
|
200
|
-
# jQuery is not currently defined. Let's proceed by defining it.
|
201
|
-
pass
|
196
|
+
# jQuery is not defined. It will be loaded in the next part.
|
202
197
|
jquery_js = constants.JQuery.MIN_JS
|
203
198
|
add_js_link(driver, jquery_js)
|
204
199
|
for x in range(36):
|
@@ -390,11 +385,9 @@ def highlight(driver, selector, by="css selector", loops=4):
|
|
390
385
|
|
391
386
|
|
392
387
|
def highlight_with_js(driver, selector, loops=4, o_bs=""):
|
393
|
-
|
388
|
+
with suppress(Exception):
|
394
389
|
# This closes any pop-up alerts
|
395
390
|
driver.execute_script("")
|
396
|
-
except Exception:
|
397
|
-
pass
|
398
391
|
if selector == "html":
|
399
392
|
selector = "body"
|
400
393
|
selector_no_spaces = selector.replace(" ", "")
|
@@ -490,11 +483,9 @@ def highlight_with_js(driver, selector, loops=4, o_bs=""):
|
|
490
483
|
|
491
484
|
|
492
485
|
def highlight_element_with_js(driver, element, loops=4, o_bs=""):
|
493
|
-
|
486
|
+
with suppress(Exception):
|
494
487
|
# This closes any pop-up alerts
|
495
488
|
driver.execute_script("")
|
496
|
-
except Exception:
|
497
|
-
pass
|
498
489
|
script = (
|
499
490
|
"""arguments[0].style.boxShadow =
|
500
491
|
'0px 0px 6px 6px rgba(128, 128, 128, 0.5)';"""
|
@@ -566,11 +557,9 @@ def highlight_element_with_js(driver, element, loops=4, o_bs=""):
|
|
566
557
|
|
567
558
|
|
568
559
|
def highlight_with_jquery(driver, selector, loops=4, o_bs=""):
|
569
|
-
|
560
|
+
with suppress(Exception):
|
570
561
|
# This closes any pop-up alerts
|
571
562
|
driver.execute_script("")
|
572
|
-
except Exception:
|
573
|
-
pass
|
574
563
|
if selector == "html":
|
575
564
|
selector = "body"
|
576
565
|
selector_no_spaces = selector.replace(" ", "")
|
@@ -908,11 +897,9 @@ def set_messenger_theme(
|
|
908
897
|
time.sleep(0.03)
|
909
898
|
activate_messenger(driver)
|
910
899
|
time.sleep(0.15)
|
911
|
-
|
900
|
+
with suppress(Exception):
|
912
901
|
driver.execute_script(msg_style)
|
913
902
|
time.sleep(0.02)
|
914
|
-
except Exception:
|
915
|
-
pass
|
916
903
|
time.sleep(0.05)
|
917
904
|
|
918
905
|
|
@@ -949,7 +936,7 @@ def post_messenger_success_message(driver, message, msg_dur=None):
|
|
949
936
|
if not msg_dur:
|
950
937
|
msg_dur = settings.DEFAULT_MESSAGE_DURATION
|
951
938
|
msg_dur = float(msg_dur)
|
952
|
-
|
939
|
+
with suppress(Exception):
|
953
940
|
theme = "future"
|
954
941
|
location = "bottom_right"
|
955
942
|
if hasattr(sb_config, "mobile_emulator") and sb_config.mobile_emulator:
|
@@ -957,28 +944,22 @@ def post_messenger_success_message(driver, message, msg_dur=None):
|
|
957
944
|
set_messenger_theme(driver, theme=theme, location=location)
|
958
945
|
post_message(driver, message, msg_dur, style="success")
|
959
946
|
time.sleep(msg_dur + 0.07)
|
960
|
-
except Exception:
|
961
|
-
pass
|
962
947
|
|
963
948
|
|
964
949
|
def post_messenger_error_message(driver, message, msg_dur=None):
|
965
950
|
if not msg_dur:
|
966
951
|
msg_dur = settings.DEFAULT_MESSAGE_DURATION
|
967
952
|
msg_dur = float(msg_dur)
|
968
|
-
|
953
|
+
with suppress(Exception):
|
969
954
|
set_messenger_theme(driver, theme="block", location="top_center")
|
970
955
|
post_message(driver, message, msg_dur, style="error")
|
971
956
|
time.sleep(msg_dur + 0.07)
|
972
|
-
except Exception:
|
973
|
-
pass
|
974
957
|
|
975
958
|
|
976
959
|
def highlight_with_js_2(driver, message, selector, o_bs, msg_dur):
|
977
|
-
|
960
|
+
with suppress(Exception):
|
978
961
|
# This closes any pop-up alerts
|
979
962
|
driver.execute_script("")
|
980
|
-
except Exception:
|
981
|
-
pass
|
982
963
|
if selector == "html":
|
983
964
|
selector = "body"
|
984
965
|
selector_no_spaces = selector.replace(" ", "")
|
@@ -991,11 +972,9 @@ def highlight_with_js_2(driver, message, selector, o_bs, msg_dur):
|
|
991
972
|
else:
|
992
973
|
early_exit = True # Changing the box-shadow changes the selector
|
993
974
|
if early_exit:
|
994
|
-
|
975
|
+
with suppress(Exception):
|
995
976
|
activate_jquery(driver)
|
996
977
|
post_messenger_success_message(driver, message, msg_dur)
|
997
|
-
except Exception:
|
998
|
-
pass
|
999
978
|
return
|
1000
979
|
script = (
|
1001
980
|
"""document.querySelector('%s').style.boxShadow =
|
@@ -1047,11 +1026,9 @@ def highlight_with_js_2(driver, message, selector, o_bs, msg_dur):
|
|
1047
1026
|
except Exception:
|
1048
1027
|
return
|
1049
1028
|
time.sleep(0.0181)
|
1050
|
-
|
1029
|
+
with suppress(Exception):
|
1051
1030
|
activate_jquery(driver)
|
1052
1031
|
post_messenger_success_message(driver, message, msg_dur)
|
1053
|
-
except Exception:
|
1054
|
-
pass
|
1055
1032
|
script = """document.querySelector('%s').style.boxShadow = '%s';""" % (
|
1056
1033
|
selector,
|
1057
1034
|
o_bs,
|
@@ -1063,11 +1040,9 @@ def highlight_with_js_2(driver, message, selector, o_bs, msg_dur):
|
|
1063
1040
|
|
1064
1041
|
|
1065
1042
|
def highlight_element_with_js_2(driver, message, element, o_bs, msg_dur):
|
1066
|
-
|
1043
|
+
with suppress(Exception):
|
1067
1044
|
# This closes any pop-up alerts
|
1068
1045
|
driver.execute_script("")
|
1069
|
-
except Exception:
|
1070
|
-
pass
|
1071
1046
|
script = (
|
1072
1047
|
"""arguments[0].style.boxShadow =
|
1073
1048
|
'0px 0px 6px 6px rgba(128, 128, 128, 0.5)';"""
|
@@ -1113,11 +1088,9 @@ def highlight_element_with_js_2(driver, message, element, o_bs, msg_dur):
|
|
1113
1088
|
except Exception:
|
1114
1089
|
return
|
1115
1090
|
time.sleep(0.0181)
|
1116
|
-
|
1091
|
+
with suppress(Exception):
|
1117
1092
|
activate_jquery(driver)
|
1118
1093
|
post_messenger_success_message(driver, message, msg_dur)
|
1119
|
-
except Exception:
|
1120
|
-
pass
|
1121
1094
|
script = """arguments[0].style.boxShadow = '%s';""" % (o_bs)
|
1122
1095
|
try:
|
1123
1096
|
driver.execute_script(script, element)
|
@@ -1138,11 +1111,9 @@ def highlight_with_jquery_2(driver, message, selector, o_bs, msg_dur):
|
|
1138
1111
|
else:
|
1139
1112
|
early_exit = True # Changing the box-shadow changes the selector
|
1140
1113
|
if early_exit:
|
1141
|
-
|
1114
|
+
with suppress(Exception):
|
1142
1115
|
activate_jquery(driver)
|
1143
1116
|
post_messenger_success_message(driver, message, msg_dur)
|
1144
|
-
except Exception:
|
1145
|
-
pass
|
1146
1117
|
return
|
1147
1118
|
script = (
|
1148
1119
|
"""jQuery('%s').css('box-shadow',
|
@@ -1195,11 +1166,9 @@ def highlight_with_jquery_2(driver, message, selector, o_bs, msg_dur):
|
|
1195
1166
|
return
|
1196
1167
|
time.sleep(0.0181)
|
1197
1168
|
|
1198
|
-
|
1169
|
+
with suppress(Exception):
|
1199
1170
|
activate_jquery(driver)
|
1200
1171
|
post_messenger_success_message(driver, message, msg_dur)
|
1201
|
-
except Exception:
|
1202
|
-
pass
|
1203
1172
|
|
1204
1173
|
script = """jQuery('%s').css('box-shadow', '%s');""" % (selector, o_bs)
|
1205
1174
|
try:
|
@@ -1484,12 +1453,10 @@ def get_drag_and_drop_with_offset_script(selector, x, y):
|
|
1484
1453
|
|
1485
1454
|
|
1486
1455
|
def clear_out_console_logs(driver):
|
1487
|
-
|
1456
|
+
with suppress(Exception):
|
1488
1457
|
# Clear out the current page log before navigating to a new page
|
1489
1458
|
# (To make sure that assert_no_js_errors() uses current results)
|
1490
1459
|
driver.get_log("browser")
|
1491
|
-
except Exception:
|
1492
|
-
pass
|
1493
1460
|
|
1494
1461
|
|
1495
1462
|
def _jq_format(code):
|
@@ -21,6 +21,7 @@ import codecs
|
|
21
21
|
import fasteners
|
22
22
|
import os
|
23
23
|
import time
|
24
|
+
from contextlib import suppress
|
24
25
|
from selenium.common.exceptions import ElementNotInteractableException
|
25
26
|
from selenium.common.exceptions import ElementNotVisibleException
|
26
27
|
from selenium.common.exceptions import NoAlertPresentException
|
@@ -1409,12 +1410,10 @@ def switch_to_frame(driver, frame, timeout=settings.SMALL_TIMEOUT):
|
|
1409
1410
|
else:
|
1410
1411
|
by = "css selector"
|
1411
1412
|
if is_element_visible(driver, frame, by=by):
|
1412
|
-
|
1413
|
+
with suppress(Exception):
|
1413
1414
|
element = driver.find_element(by=by, value=frame)
|
1414
1415
|
driver.switch_to.frame(element)
|
1415
1416
|
return True
|
1416
|
-
except Exception:
|
1417
|
-
pass
|
1418
1417
|
now_ms = time.time() * 1000.0
|
1419
1418
|
if now_ms >= stop_ms:
|
1420
1419
|
break
|
@@ -1548,12 +1547,10 @@ def click_if_visible(
|
|
1548
1547
|
if is_element_visible(driver, selector, by=by):
|
1549
1548
|
click(driver, selector, by=by, timeout=1)
|
1550
1549
|
elif timeout > 0:
|
1551
|
-
|
1550
|
+
with suppress(Exception):
|
1552
1551
|
wait_for_element_visible(
|
1553
1552
|
driver, selector, by=by, timeout=timeout
|
1554
1553
|
)
|
1555
|
-
except Exception:
|
1556
|
-
pass
|
1557
1554
|
if is_element_visible(driver, selector, by=by):
|
1558
1555
|
click(driver, selector, by=by, timeout=1)
|
1559
1556
|
|
@@ -16,7 +16,7 @@ def get_domain_url(url):
|
|
16
16
|
Into this:
|
17
17
|
https://blog.xkcd.com
|
18
18
|
"""
|
19
|
-
if not url.startswith("http://"
|
19
|
+
if not url.startswith(("http://", "https://")):
|
20
20
|
return url
|
21
21
|
url_header = url.split("://")[0]
|
22
22
|
simple_url = url.split("://")[1]
|
@@ -40,45 +40,25 @@ def swap_selector_and_by_if_reversed(selector, by):
|
|
40
40
|
|
41
41
|
def is_xpath_selector(selector):
|
42
42
|
"""Determine if a selector is an xpath selector."""
|
43
|
-
|
44
|
-
selector.startswith("/")
|
45
|
-
or selector.startswith("./")
|
46
|
-
or selector.startswith("(")
|
47
|
-
):
|
48
|
-
return True
|
49
|
-
return False
|
43
|
+
return selector.startswith(("/", "./", "("))
|
50
44
|
|
51
45
|
|
52
46
|
def is_link_text_selector(selector):
|
53
47
|
"""Determine if a selector is a link text selector."""
|
54
|
-
|
55
|
-
selector.startswith("link=")
|
56
|
-
or selector.startswith("link_text=")
|
57
|
-
or selector.startswith("text=")
|
58
|
-
):
|
59
|
-
return True
|
60
|
-
return False
|
48
|
+
return selector.startswith(("link=", "link_text=", "text="))
|
61
49
|
|
62
50
|
|
63
51
|
def is_partial_link_text_selector(selector):
|
64
52
|
"""Determine if a selector is a partial link text selector."""
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
or selector.startswith("p_link=")
|
70
|
-
or selector.startswith("p_link_text=")
|
71
|
-
or selector.startswith("p_text=")
|
72
|
-
):
|
73
|
-
return True
|
74
|
-
return False
|
53
|
+
return selector.startswith((
|
54
|
+
"partial_link=", "partial_link_text=", "partial_text=",
|
55
|
+
"p_link=", "p_link_text=", "p_text="
|
56
|
+
))
|
75
57
|
|
76
58
|
|
77
59
|
def is_name_selector(selector):
|
78
60
|
"""Determine if a selector is a name selector."""
|
79
|
-
|
80
|
-
return True
|
81
|
-
return False
|
61
|
+
return selector.startswith(("name=", "&"))
|
82
62
|
|
83
63
|
|
84
64
|
def recalculate_selector(selector, by, xp_ok=True):
|
@@ -108,10 +88,9 @@ def recalculate_selector(selector, by, xp_ok=True):
|
|
108
88
|
name = get_name_from_selector(selector)
|
109
89
|
selector = '[name="%s"]' % name
|
110
90
|
by = By.CSS_SELECTOR
|
111
|
-
if xp_ok:
|
112
|
-
|
113
|
-
|
114
|
-
by = By.XPATH
|
91
|
+
if xp_ok and ":contains(" in selector and by == By.CSS_SELECTOR:
|
92
|
+
selector = css_to_xpath.convert_css_to_xpath(selector)
|
93
|
+
by = By.XPATH
|
115
94
|
if by == "":
|
116
95
|
by = By.CSS_SELECTOR
|
117
96
|
if not is_valid_by(by):
|
@@ -130,21 +109,10 @@ def looks_like_a_page_url(url):
|
|
130
109
|
possible typos when calling self.get(url), which will try to
|
131
110
|
navigate to the page if a URL is detected, but will instead call
|
132
111
|
self.get_element(URL_AS_A_SELECTOR) if the input is not a URL."""
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
or url.startswith("about:")
|
138
|
-
or url.startswith("blob:")
|
139
|
-
or url.startswith("chrome:")
|
140
|
-
or url.startswith("data:")
|
141
|
-
or url.startswith("edge:")
|
142
|
-
or url.startswith("file:")
|
143
|
-
or url.startswith("view-source:")
|
144
|
-
):
|
145
|
-
return True
|
146
|
-
else:
|
147
|
-
return False
|
112
|
+
return url.startswith((
|
113
|
+
"http:", "https:", "://", "about:", "blob:", "chrome:",
|
114
|
+
"data:", "edge:", "file:", "view-source:"
|
115
|
+
))
|
148
116
|
|
149
117
|
|
150
118
|
def get_link_text_from_selector(selector):
|
@@ -195,18 +163,12 @@ def is_valid_url(url):
|
|
195
163
|
r"(?:/?|[/?]\S+)$",
|
196
164
|
re.IGNORECASE,
|
197
165
|
)
|
198
|
-
|
166
|
+
return (
|
199
167
|
regex.match(url)
|
200
|
-
or url.startswith(
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
or url.startswith("edge:")
|
205
|
-
or url.startswith("file:")
|
206
|
-
):
|
207
|
-
return True
|
208
|
-
else:
|
209
|
-
return False
|
168
|
+
or url.startswith((
|
169
|
+
"about:", "blob:", "chrome:", "data:", "edge:", "file:"
|
170
|
+
))
|
171
|
+
)
|
210
172
|
|
211
173
|
|
212
174
|
def _get_unique_links(page_url, soup):
|
@@ -2,6 +2,7 @@
|
|
2
2
|
import ast
|
3
3
|
import sys
|
4
4
|
import time
|
5
|
+
from contextlib import suppress
|
5
6
|
from nose.plugins import Plugin
|
6
7
|
from seleniumbase import config as sb_config
|
7
8
|
from seleniumbase.config import settings
|
@@ -305,14 +306,12 @@ class Base(Plugin):
|
|
305
306
|
if python3_11_or_newer and py311_patch2:
|
306
307
|
# Handle a bug on Python 3.11 where exceptions aren't seen
|
307
308
|
sb_config._browser_version = None
|
308
|
-
|
309
|
+
with suppress(Exception):
|
309
310
|
test._BaseCase__set_last_page_screenshot()
|
310
311
|
test._BaseCase__set_last_page_url()
|
311
312
|
test._BaseCase__set_last_page_source()
|
312
313
|
sb_config._browser_version = test._get_browser_version()
|
313
314
|
test._log_fail_data()
|
314
|
-
except Exception:
|
315
|
-
pass
|
316
315
|
sb_config._excinfo_tb = err
|
317
316
|
log_path = None
|
318
317
|
if hasattr(sb_config, "_test_logpath"):
|
@@ -7,7 +7,7 @@ Usage --> ``with DriverContext() as driver:``
|
|
7
7
|
|
8
8
|
Example -->
|
9
9
|
|
10
|
-
```
|
10
|
+
```python
|
11
11
|
from seleniumbase import DriverContext
|
12
12
|
|
13
13
|
with DriverContext() as driver:
|
@@ -27,7 +27,7 @@ Usage --> ``driver = Driver()``
|
|
27
27
|
|
28
28
|
Example -->
|
29
29
|
|
30
|
-
```
|
30
|
+
```python
|
31
31
|
from seleniumbase import Driver
|
32
32
|
|
33
33
|
driver = Driver()
|
@@ -75,7 +75,7 @@ def Driver(
|
|
75
75
|
proxy=None, # Use proxy. Format: "SERVER:PORT" or "USER:PASS@SERVER:PORT".
|
76
76
|
proxy_bypass_list=None, # Skip proxy when using the listed domains.
|
77
77
|
proxy_pac_url=None, # Use PAC file. (Format: URL or USERNAME:PASSWORD@URL)
|
78
|
-
multi_proxy=
|
78
|
+
multi_proxy=None, # Allow multiple proxies with auth when multi-threaded.
|
79
79
|
agent=None, # Modify the web browser's User-Agent string.
|
80
80
|
cap_file=None, # The desired capabilities to use with a Selenium Grid.
|
81
81
|
cap_string=None, # The desired capabilities to use with a Selenium Grid.
|
@@ -115,6 +115,8 @@ def Driver(
|
|
115
115
|
page_load_strategy=None, # Set Chrome PLS to "normal", "eager", or "none".
|
116
116
|
use_wire=None, # Use selenium-wire's webdriver over selenium webdriver.
|
117
117
|
external_pdf=None, # Set Chrome "plugins.always_open_pdf_externally":True.
|
118
|
+
window_position=None, # Set the browser's starting window position: "X,Y"
|
119
|
+
window_size=None, # Set the browser's starting window size: "Width,Height"
|
118
120
|
is_mobile=None, # Use the mobile device emulator while running tests.
|
119
121
|
mobile=None, # Shortcut / Duplicate of "is_mobile".
|
120
122
|
d_width=None, # Set device width
|
@@ -131,7 +133,98 @@ def Driver(
|
|
131
133
|
wire=None, # Shortcut / Duplicate of "use_wire".
|
132
134
|
pls=None, # Shortcut / Duplicate of "page_load_strategy".
|
133
135
|
):
|
136
|
+
"""
|
137
|
+
* SeleniumBase Driver as a Python Context Manager or a returnable object. *
|
138
|
+
|
139
|
+
Example 1: (context manager format)
|
140
|
+
-----------------------------------
|
141
|
+
.. code-block:: python
|
142
|
+
from seleniumbase import DriverContext
|
143
|
+
|
144
|
+
with DriverContext() as driver:
|
145
|
+
driver.get("https://google.com/ncr")
|
146
|
+
|
147
|
+
Example 2: (as a Python returnable)
|
148
|
+
-----------------------------------
|
149
|
+
.. code-block:: python
|
150
|
+
from seleniumbase import Driver
|
151
|
+
|
152
|
+
driver = Driver()
|
153
|
+
driver.get("https://google.com/ncr")
|
154
|
+
|
155
|
+
Optional Parameters:
|
156
|
+
--------------------
|
157
|
+
browser: # Choose from "chrome", "edge", "firefox", or "safari".
|
158
|
+
headless: # The original headless mode for Chromium and Firefox.
|
159
|
+
headless2: # Chromium's new headless mode. (Has more features)
|
160
|
+
headed: # Run tests in headed/GUI mode on Linux, where not default.
|
161
|
+
locale_code: # Set the Language Locale Code for the web browser.
|
162
|
+
protocol: # The Selenium Grid protocol: "http" or "https".
|
163
|
+
servername: # The Selenium Grid server/IP used for tests.
|
164
|
+
port: # The Selenium Grid port used by the test server.
|
165
|
+
proxy: # Use proxy. Format: "SERVER:PORT" or "USER:PASS@SERVER:PORT".
|
166
|
+
proxy_bypass_list: # Skip proxy when using the listed domains.
|
167
|
+
proxy_pac_url: # Use PAC file. (Format: URL or USERNAME:PASSWORD@URL)
|
168
|
+
multi_proxy: # Allow multiple proxies with auth when multi-threaded.
|
169
|
+
agent: # Modify the web browser's User-Agent string.
|
170
|
+
cap_file: # The desired capabilities to use with a Selenium Grid.
|
171
|
+
cap_string: # The desired capabilities to use with a Selenium Grid.
|
172
|
+
recorder_ext: # Enables the SeleniumBase Recorder Chromium extension.
|
173
|
+
disable_js: # Disable JavaScript on websites. Pages might break!
|
174
|
+
disable_csp: # Disable the Content Security Policy of websites.
|
175
|
+
enable_ws: # Enable Web Security on Chromium-based browsers.
|
176
|
+
disable_ws: # Reverse of "enable_ws". (None and False are different)
|
177
|
+
enable_sync: # Enable "Chrome Sync" on websites.
|
178
|
+
use_auto_ext: # Use Chrome's automation extension.
|
179
|
+
undetectable: # Use undetected-chromedriver to evade bot-detection.
|
180
|
+
uc_cdp_events: # Capture CDP events in undetected-chromedriver mode.
|
181
|
+
uc_subprocess: # Use undetected-chromedriver as a subprocess.
|
182
|
+
log_cdp_events: # Capture {"performance": "ALL", "browser": "ALL"}
|
183
|
+
no_sandbox: # (DEPRECATED) - "--no-sandbox" is always used now.
|
184
|
+
disable_gpu: # (DEPRECATED) - GPU is disabled if not "swiftshader".
|
185
|
+
incognito: # Enable Chromium's Incognito mode.
|
186
|
+
guest_mode: # Enable Chromium's Guest mode.
|
187
|
+
dark_mode: # Enable Chromium's Dark mode.
|
188
|
+
devtools: # Open Chromium's DevTools when the browser opens.
|
189
|
+
remote_debug: # Enable Chrome's Debugger on "http://localhost:9222".
|
190
|
+
enable_3d_apis: # Enable WebGL and 3D APIs.
|
191
|
+
swiftshader: # Chrome: --use-gl=angle / --use-angle=swiftshader-webgl
|
192
|
+
ad_block_on: # Block some types of display ads from loading.
|
193
|
+
host_resolver_rules: # Set host-resolver-rules, comma-separated.
|
194
|
+
block_images: # Block images from loading during tests.
|
195
|
+
do_not_track: # Tell websites that you don't want to be tracked.
|
196
|
+
chromium_arg: # "ARG=N,ARG2" (Set Chromium args, ","-separated.)
|
197
|
+
firefox_arg: # "ARG=N,ARG2" (Set Firefox args, comma-separated.)
|
198
|
+
firefox_pref: # SET (Set Firefox PREFERENCE:VALUE set, ","-separated)
|
199
|
+
user_data_dir: # Set the Chrome user data directory to use.
|
200
|
+
extension_zip: # Load a Chrome Extension .zip|.crx, comma-separated.
|
201
|
+
extension_dir: # Load a Chrome Extension directory, comma-separated.
|
202
|
+
disable_features: # "F1,F2" (Disable Chrome features, ","-separated.)
|
203
|
+
binary_location: # Set path of the Chromium browser binary to use.
|
204
|
+
driver_version: # Set the chromedriver or uc_driver version to use.
|
205
|
+
page_load_strategy: # Set Chrome PLS to "normal", "eager", or "none".
|
206
|
+
use_wire: # Use selenium-wire's webdriver over selenium webdriver.
|
207
|
+
external_pdf: # Set Chrome "plugins.always_open_pdf_externally":True.
|
208
|
+
window_position: # Set the browser's starting window position: "X,Y"
|
209
|
+
window_size: # Set the browser's starting window size: "Width,Height"
|
210
|
+
is_mobile: # Use the mobile device emulator while running tests.
|
211
|
+
mobile: # Shortcut / Duplicate of "is_mobile".
|
212
|
+
d_width: # Set device width
|
213
|
+
d_height: # Set device height
|
214
|
+
d_p_r: # Set device pixel ratio
|
215
|
+
uc: # Shortcut / Duplicate of "undetectable".
|
216
|
+
undetected: # Shortcut / Duplicate of "undetectable".
|
217
|
+
uc_cdp: # Shortcut / Duplicate of "uc_cdp_events".
|
218
|
+
uc_sub: # Shortcut / Duplicate of "uc_subprocess".
|
219
|
+
log_cdp: # Shortcut / Duplicate of "log_cdp_events".
|
220
|
+
ad_block: # Shortcut / Duplicate of "ad_block_on".
|
221
|
+
server: # Shortcut / Duplicate of "servername".
|
222
|
+
guest: # Shortcut / Duplicate of "guest_mode".
|
223
|
+
wire: # Shortcut / Duplicate of "use_wire".
|
224
|
+
pls: # Shortcut / Duplicate of "page_load_strategy".
|
225
|
+
"""
|
134
226
|
from seleniumbase import config as sb_config
|
227
|
+
from seleniumbase.config import settings
|
135
228
|
from seleniumbase.fixtures import constants
|
136
229
|
from seleniumbase.fixtures import shared_utils
|
137
230
|
|
@@ -329,6 +422,79 @@ def Driver(
|
|
329
422
|
break
|
330
423
|
count += 1
|
331
424
|
disable_features = d_f
|
425
|
+
w_p = window_position
|
426
|
+
if w_p is None and "--window-position" in arg_join:
|
427
|
+
count = 0
|
428
|
+
for arg in sys_argv:
|
429
|
+
if arg.startswith("--window-position="):
|
430
|
+
w_p = arg.split("--window-position=")[1]
|
431
|
+
break
|
432
|
+
elif arg == "--window-position" and len(sys_argv) > count + 1:
|
433
|
+
w_p = sys_argv[count + 1]
|
434
|
+
if w_p.startswith("-"):
|
435
|
+
w_p = None
|
436
|
+
break
|
437
|
+
count += 1
|
438
|
+
window_position = w_p
|
439
|
+
if window_position:
|
440
|
+
if window_position.count(",") != 1:
|
441
|
+
message = (
|
442
|
+
'\n\n window_position expects an "x,y" string!'
|
443
|
+
'\n (Your input was: "%s")\n' % window_position
|
444
|
+
)
|
445
|
+
raise Exception(message)
|
446
|
+
window_position = window_position.replace(" ", "")
|
447
|
+
win_x = None
|
448
|
+
win_y = None
|
449
|
+
try:
|
450
|
+
win_x = int(window_position.split(",")[0])
|
451
|
+
win_y = int(window_position.split(",")[1])
|
452
|
+
except Exception:
|
453
|
+
message = (
|
454
|
+
'\n\n Expecting integer values for "x,y"!'
|
455
|
+
'\n (window_position input was: "%s")\n'
|
456
|
+
% window_position
|
457
|
+
)
|
458
|
+
raise Exception(message)
|
459
|
+
settings.WINDOW_START_X = win_x
|
460
|
+
settings.WINDOW_START_Y = win_y
|
461
|
+
w_s = window_size
|
462
|
+
if w_s is None and "--window-size" in arg_join:
|
463
|
+
count = 0
|
464
|
+
for arg in sys_argv:
|
465
|
+
if arg.startswith("--window-size="):
|
466
|
+
w_s = arg.split("--window-size=")[1]
|
467
|
+
break
|
468
|
+
elif arg == "--window-size" and len(sys_argv) > count + 1:
|
469
|
+
w_s = sys_argv[count + 1]
|
470
|
+
if w_s.startswith("-"):
|
471
|
+
w_s = None
|
472
|
+
break
|
473
|
+
count += 1
|
474
|
+
window_size = w_s
|
475
|
+
if window_size:
|
476
|
+
if window_size.count(",") != 1:
|
477
|
+
message = (
|
478
|
+
'\n\n window_size expects a "width,height" string!'
|
479
|
+
'\n (Your input was: "%s")\n' % window_size
|
480
|
+
)
|
481
|
+
raise Exception(message)
|
482
|
+
window_size = window_size.replace(" ", "")
|
483
|
+
width = None
|
484
|
+
height = None
|
485
|
+
try:
|
486
|
+
width = int(window_size.split(",")[0])
|
487
|
+
height = int(window_size.split(",")[1])
|
488
|
+
except Exception:
|
489
|
+
message = (
|
490
|
+
'\n\n Expecting integer values for "width,height"!'
|
491
|
+
'\n (window_size input was: "%s")\n' % window_size
|
492
|
+
)
|
493
|
+
raise Exception(message)
|
494
|
+
settings.CHROME_START_WIDTH = width
|
495
|
+
settings.CHROME_START_HEIGHT = height
|
496
|
+
settings.HEADLESS_START_WIDTH = width
|
497
|
+
settings.HEADLESS_START_HEIGHT = height
|
332
498
|
if agent is None and "--agent" in arg_join:
|
333
499
|
count = 0
|
334
500
|
for arg in sys_argv:
|