seleniumbase 4.24.10__py3-none-any.whl → 4.33.15__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- sbase/__init__.py +1 -0
- sbase/steps.py +7 -0
- seleniumbase/__init__.py +16 -7
- seleniumbase/__version__.py +1 -1
- seleniumbase/behave/behave_sb.py +97 -32
- seleniumbase/common/decorators.py +16 -7
- seleniumbase/config/proxy_list.py +3 -3
- seleniumbase/config/settings.py +4 -0
- seleniumbase/console_scripts/logo_helper.py +47 -8
- seleniumbase/console_scripts/run.py +345 -335
- seleniumbase/console_scripts/sb_behave_gui.py +5 -12
- seleniumbase/console_scripts/sb_caseplans.py +6 -13
- seleniumbase/console_scripts/sb_commander.py +5 -12
- seleniumbase/console_scripts/sb_install.py +62 -54
- seleniumbase/console_scripts/sb_mkchart.py +13 -20
- seleniumbase/console_scripts/sb_mkdir.py +11 -17
- seleniumbase/console_scripts/sb_mkfile.py +69 -43
- seleniumbase/console_scripts/sb_mkpres.py +13 -20
- seleniumbase/console_scripts/sb_mkrec.py +88 -21
- seleniumbase/console_scripts/sb_objectify.py +30 -30
- seleniumbase/console_scripts/sb_print.py +5 -12
- seleniumbase/console_scripts/sb_recorder.py +16 -11
- seleniumbase/core/browser_launcher.py +1658 -221
- seleniumbase/core/detect_b_ver.py +7 -8
- seleniumbase/core/log_helper.py +42 -27
- seleniumbase/core/mysql.py +1 -4
- seleniumbase/core/proxy_helper.py +35 -30
- seleniumbase/core/recorder_helper.py +24 -5
- seleniumbase/core/sb_cdp.py +1951 -0
- seleniumbase/core/sb_driver.py +162 -8
- seleniumbase/core/settings_parser.py +6 -0
- seleniumbase/core/style_sheet.py +10 -0
- seleniumbase/extensions/recorder.zip +0 -0
- seleniumbase/fixtures/base_case.py +1234 -632
- seleniumbase/fixtures/constants.py +10 -1
- seleniumbase/fixtures/js_utils.py +171 -144
- seleniumbase/fixtures/page_actions.py +177 -13
- seleniumbase/fixtures/page_utils.py +25 -53
- seleniumbase/fixtures/shared_utils.py +97 -11
- seleniumbase/js_code/active_css_js.py +1 -1
- seleniumbase/js_code/recorder_js.py +1 -1
- seleniumbase/plugins/base_plugin.py +2 -3
- seleniumbase/plugins/driver_manager.py +340 -65
- seleniumbase/plugins/pytest_plugin.py +276 -47
- seleniumbase/plugins/sb_manager.py +412 -99
- seleniumbase/plugins/selenium_plugin.py +122 -17
- seleniumbase/translate/translator.py +0 -7
- seleniumbase/undetected/__init__.py +59 -52
- seleniumbase/undetected/cdp.py +0 -1
- seleniumbase/undetected/cdp_driver/__init__.py +1 -0
- seleniumbase/undetected/cdp_driver/_contradict.py +110 -0
- seleniumbase/undetected/cdp_driver/browser.py +829 -0
- seleniumbase/undetected/cdp_driver/cdp_util.py +458 -0
- seleniumbase/undetected/cdp_driver/config.py +334 -0
- seleniumbase/undetected/cdp_driver/connection.py +639 -0
- seleniumbase/undetected/cdp_driver/element.py +1168 -0
- seleniumbase/undetected/cdp_driver/tab.py +1323 -0
- seleniumbase/undetected/dprocess.py +4 -7
- seleniumbase/undetected/options.py +6 -8
- seleniumbase/undetected/patcher.py +11 -13
- seleniumbase/undetected/reactor.py +0 -1
- seleniumbase/undetected/webelement.py +16 -3
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/LICENSE +1 -1
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/METADATA +299 -252
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/RECORD +68 -70
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.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 -731
- 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.24.10.dist-info → seleniumbase-4.33.15.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/top_level.txt +0 -0
seleniumbase/core/sb_driver.py
CHANGED
@@ -1,14 +1,21 @@
|
|
1
1
|
"""Add new methods to extend the driver"""
|
2
|
+
from contextlib import suppress
|
2
3
|
from selenium.webdriver.remote.webelement import WebElement
|
4
|
+
from seleniumbase.config import settings
|
3
5
|
from seleniumbase.fixtures import js_utils
|
4
6
|
from seleniumbase.fixtures import page_actions
|
5
7
|
from seleniumbase.fixtures import page_utils
|
8
|
+
from seleniumbase.fixtures import shared_utils
|
6
9
|
|
7
10
|
|
8
11
|
class DriverMethods():
|
9
12
|
def __init__(self, driver):
|
10
13
|
self.driver = driver
|
11
14
|
|
15
|
+
def __is_cdp_swap_needed(self):
|
16
|
+
"""If the driver is disconnected, use a CDP method when available."""
|
17
|
+
return shared_utils.is_cdp_swap_needed(self.driver)
|
18
|
+
|
12
19
|
def find_element(self, by=None, value=None):
|
13
20
|
if not value:
|
14
21
|
value = by
|
@@ -36,20 +43,29 @@ class DriverMethods():
|
|
36
43
|
selector, by = page_utils.swap_selector_and_by_if_reversed(
|
37
44
|
selector, by
|
38
45
|
)
|
39
|
-
|
46
|
+
with suppress(Exception):
|
40
47
|
return self.driver.default_find_element(by=by, value=selector)
|
41
|
-
except Exception:
|
42
|
-
pass
|
43
48
|
raise Exception('No such Element: {%s} (by="%s")!' % (selector, by))
|
44
49
|
|
45
50
|
def get_attribute(self, selector, attribute, by="css selector"):
|
46
51
|
element = self.locator(selector, by=by)
|
47
52
|
return element.get_attribute(attribute)
|
48
53
|
|
54
|
+
def get_current_url(self):
|
55
|
+
if self.__is_cdp_swap_needed():
|
56
|
+
current_url = self.driver.cdp.get_current_url()
|
57
|
+
else:
|
58
|
+
current_url = self.driver.current_url
|
59
|
+
return current_url
|
60
|
+
|
49
61
|
def get_page_source(self):
|
62
|
+
if self.__is_cdp_swap_needed():
|
63
|
+
return self.driver.cdp.get_page_source()
|
50
64
|
return self.driver.page_source
|
51
65
|
|
52
66
|
def get_title(self):
|
67
|
+
if self.__is_cdp_swap_needed():
|
68
|
+
return self.driver.cdp.get_title()
|
53
69
|
return self.driver.title
|
54
70
|
|
55
71
|
def open_url(self, *args, **kwargs):
|
@@ -94,6 +110,16 @@ class DriverMethods():
|
|
94
110
|
def assert_exact_text(self, *args, **kwargs):
|
95
111
|
page_actions.assert_exact_text(self.driver, *args, **kwargs)
|
96
112
|
|
113
|
+
def assert_non_empty_text(self, *args, **kwargs):
|
114
|
+
return page_actions.assert_non_empty_text(
|
115
|
+
self.driver, *args, **kwargs
|
116
|
+
)
|
117
|
+
|
118
|
+
def assert_text_not_visible(self, *args, **kwargs):
|
119
|
+
return page_actions.assert_text_not_visible(
|
120
|
+
self.driver, *args, **kwargs
|
121
|
+
)
|
122
|
+
|
97
123
|
def wait_for_element(self, *args, **kwargs):
|
98
124
|
return page_actions.wait_for_element(self.driver, *args, **kwargs)
|
99
125
|
|
@@ -112,6 +138,16 @@ class DriverMethods():
|
|
112
138
|
def wait_for_exact_text(self, *args, **kwargs):
|
113
139
|
return page_actions.wait_for_exact_text(self.driver, *args, **kwargs)
|
114
140
|
|
141
|
+
def wait_for_non_empty_text(self, *args, **kwargs):
|
142
|
+
return page_actions.wait_for_non_empty_text(
|
143
|
+
self.driver, *args, **kwargs
|
144
|
+
)
|
145
|
+
|
146
|
+
def wait_for_text_not_visible(self, *args, **kwargs):
|
147
|
+
return page_actions.wait_for_text_not_visible(
|
148
|
+
self.driver, *args, **kwargs
|
149
|
+
)
|
150
|
+
|
115
151
|
def wait_for_and_accept_alert(self, *args, **kwargs):
|
116
152
|
return page_actions.wait_for_and_accept_alert(
|
117
153
|
self.driver, *args, **kwargs
|
@@ -134,28 +170,111 @@ class DriverMethods():
|
|
134
170
|
def is_exact_text_visible(self, *args, **kwargs):
|
135
171
|
return page_actions.is_exact_text_visible(self.driver, *args, **kwargs)
|
136
172
|
|
137
|
-
def
|
138
|
-
return page_actions.
|
173
|
+
def is_attribute_present(self, *args, **kwargs):
|
174
|
+
return page_actions.has_attribute(self.driver, *args, **kwargs)
|
175
|
+
|
176
|
+
def is_non_empty_text_visible(self, *args, **kwargs):
|
177
|
+
return page_actions.is_non_empty_text_visible(
|
178
|
+
self.driver, *args, **kwargs
|
179
|
+
)
|
180
|
+
|
181
|
+
def is_valid_url(self, url):
|
182
|
+
"""Return True if the url is a valid url."""
|
183
|
+
return page_utils.is_valid_url(url)
|
184
|
+
|
185
|
+
def is_alert_present(self):
|
186
|
+
try:
|
187
|
+
self.driver.switch_to.alert
|
188
|
+
return True
|
189
|
+
except Exception:
|
190
|
+
return False
|
191
|
+
|
192
|
+
def is_online(self):
|
193
|
+
if self.__is_cdp_swap_needed():
|
194
|
+
return self.driver.cdp.evaluate("navigator.onLine;")
|
195
|
+
return self.driver.execute_script("return navigator.onLine;")
|
196
|
+
|
197
|
+
def is_connected(self):
|
198
|
+
"""
|
199
|
+
Return True if WebDriver is connected to the browser.
|
200
|
+
Note that the stealthy CDP-Driver isn't a WebDriver.
|
201
|
+
In CDP Mode, the CDP-Driver controls the web browser.
|
202
|
+
The CDP-Driver can be connected while WebDriver isn't.
|
203
|
+
"""
|
204
|
+
if shared_utils.is_windows():
|
205
|
+
return (
|
206
|
+
not hasattr(self.driver, "_is_connected")
|
207
|
+
or self.driver._is_connected
|
208
|
+
)
|
209
|
+
try:
|
210
|
+
self.driver.window_handles
|
211
|
+
return True
|
212
|
+
except Exception:
|
213
|
+
return False
|
214
|
+
|
215
|
+
def is_uc_mode_active(self):
|
216
|
+
"""Return True if the driver is using UC Mode. False otherwise."""
|
217
|
+
return (
|
218
|
+
hasattr(self.driver, "_is_using_uc")
|
219
|
+
and self.driver._is_using_uc
|
220
|
+
)
|
221
|
+
|
222
|
+
def is_cdp_mode_active(self):
|
223
|
+
"""CDP Mode is a special mode within UC Mode. Activated separately.
|
224
|
+
Return True if CDP Mode is loaded in the driver. False otherwise."""
|
225
|
+
return (
|
226
|
+
hasattr(self.driver, "_is_using_cdp")
|
227
|
+
and self.driver._is_using_cdp
|
228
|
+
)
|
139
229
|
|
140
230
|
def js_click(self, *args, **kwargs):
|
141
231
|
return page_actions.js_click(self.driver, *args, **kwargs)
|
142
232
|
|
143
|
-
def
|
144
|
-
return page_actions.
|
233
|
+
def get_text(self, *args, **kwargs):
|
234
|
+
return page_actions.get_text(self.driver, *args, **kwargs)
|
145
235
|
|
146
236
|
def get_active_element_css(self, *args, **kwargs):
|
237
|
+
if self.__is_cdp_swap_needed():
|
238
|
+
return self.driver.cdp.get_active_element_css()
|
147
239
|
return js_utils.get_active_element_css(self.driver, *args, **kwargs)
|
148
240
|
|
149
241
|
def get_locale_code(self, *args, **kwargs):
|
242
|
+
if self.__is_cdp_swap_needed():
|
243
|
+
return self.driver.cdp.get_locale_code()
|
150
244
|
return js_utils.get_locale_code(self.driver, *args, **kwargs)
|
151
245
|
|
246
|
+
def get_screen_rect(self, *args, **kwargs):
|
247
|
+
if self.__is_cdp_swap_needed():
|
248
|
+
return self.driver.cdp.get_screen_rect()
|
249
|
+
return js_utils.get_screen_rect(self.driver, *args, **kwargs)
|
250
|
+
|
152
251
|
def get_origin(self, *args, **kwargs):
|
252
|
+
if self.__is_cdp_swap_needed():
|
253
|
+
return self.driver.cdp.get_origin()
|
153
254
|
return js_utils.get_origin(self.driver, *args, **kwargs)
|
154
255
|
|
155
256
|
def get_user_agent(self, *args, **kwargs):
|
257
|
+
if self.__is_cdp_swap_needed():
|
258
|
+
return self.driver.cdp.get_user_agent()
|
156
259
|
return js_utils.get_user_agent(self.driver, *args, **kwargs)
|
157
260
|
|
261
|
+
def get_cookie_string(self, *args, **kwargs):
|
262
|
+
if self.__is_cdp_swap_needed():
|
263
|
+
return self.driver.cdp.get_cookie_string()
|
264
|
+
return js_utils.get_cookie_string(self.driver, *args, **kwargs)
|
265
|
+
|
158
266
|
def highlight(self, *args, **kwargs):
|
267
|
+
if self.__is_cdp_swap_needed():
|
268
|
+
selector = None
|
269
|
+
if "selector" in kwargs:
|
270
|
+
selector = kwargs["selector"]
|
271
|
+
else:
|
272
|
+
selector = args[0]
|
273
|
+
if ":contains(" not in selector:
|
274
|
+
self.driver.cdp.highlight(selector)
|
275
|
+
return
|
276
|
+
else:
|
277
|
+
self.driver.connect()
|
159
278
|
if "scroll" in kwargs:
|
160
279
|
kwargs.pop("scroll")
|
161
280
|
w_args = kwargs.copy()
|
@@ -182,13 +301,48 @@ class DriverMethods():
|
|
182
301
|
if self.is_element_visible(selector, by=by):
|
183
302
|
self.highlight(selector, by=by, loops=loops, scroll=scroll)
|
184
303
|
|
185
|
-
def
|
304
|
+
def switch_to_default_window(self):
|
305
|
+
self.driver.switch_to.window(self.driver.window_handles[0])
|
306
|
+
|
307
|
+
def switch_to_newest_window(self):
|
308
|
+
self.driver.switch_to.window(self.driver.window_handles[-1])
|
309
|
+
|
310
|
+
def open_new_window(self, switch_to=True):
|
311
|
+
if switch_to:
|
312
|
+
try:
|
313
|
+
self.driver.switch_to.new_window("tab")
|
314
|
+
except Exception:
|
315
|
+
self.driver.execute_script("window.open('');")
|
316
|
+
self.switch_to_newest_window()
|
317
|
+
else:
|
318
|
+
self.driver.execute_script("window.open('');")
|
319
|
+
|
320
|
+
def open_new_tab(self, switch_to=True):
|
321
|
+
self.open_new_window(switch_to=switch_to)
|
322
|
+
|
323
|
+
def switch_to_window(self, *args, **kwargs):
|
324
|
+
page_actions.switch_to_window(self.driver, *args, **kwargs)
|
325
|
+
|
326
|
+
def switch_to_tab(self, *args, **kwargs):
|
327
|
+
self.switch_to_window(*args, **kwargs)
|
328
|
+
|
329
|
+
def switch_to_frame(self, frame="iframe"):
|
186
330
|
if isinstance(frame, WebElement):
|
187
331
|
self.driver.switch_to.frame(frame)
|
188
332
|
else:
|
189
333
|
iframe = self.locator(frame)
|
190
334
|
self.driver.switch_to.frame(iframe)
|
191
335
|
|
336
|
+
def reset_window_size(self):
|
337
|
+
if self.__is_cdp_swap_needed():
|
338
|
+
self.driver.cdp.reset_window_size()
|
339
|
+
return
|
340
|
+
x = settings.WINDOW_START_X
|
341
|
+
y = settings.WINDOW_START_Y
|
342
|
+
width = settings.CHROME_START_WIDTH
|
343
|
+
height = settings.CHROME_START_HEIGHT
|
344
|
+
self.driver.set_window_rect(x, y, width, height)
|
345
|
+
|
192
346
|
def set_wire_proxy(self, string):
|
193
347
|
"""Set a proxy server for selenium-wire mode ("--wire")
|
194
348
|
Examples: (ONLY avilable if using selenium-wire mode!)
|
@@ -71,6 +71,8 @@ def set_settings(settings_file):
|
|
71
71
|
settings.LARGE_TIMEOUT = override_settings[key]
|
72
72
|
elif key == "EXTREME_TIMEOUT":
|
73
73
|
settings.EXTREME_TIMEOUT = override_settings[key]
|
74
|
+
elif key == "PAGE_LOAD_TIMEOUT":
|
75
|
+
settings.PAGE_LOAD_TIMEOUT = override_settings[key]
|
74
76
|
elif key == "ARCHIVE_EXISTING_LOGS":
|
75
77
|
settings.ARCHIVE_EXISTING_LOGS = override_settings[key]
|
76
78
|
elif key == "ARCHIVE_EXISTING_DOWNLOADS":
|
@@ -113,6 +115,10 @@ def set_settings(settings_file):
|
|
113
115
|
settings.RAISE_INVALID_PROXY_STRING_EXCEPTION = override_settings[
|
114
116
|
key
|
115
117
|
]
|
118
|
+
elif key == "WINDOW_START_X":
|
119
|
+
settings.WINDOW_START_X = override_settings[key]
|
120
|
+
elif key == "WINDOW_START_Y":
|
121
|
+
settings.WINDOW_START_Y = override_settings[key]
|
116
122
|
elif key == "CHROME_START_WIDTH":
|
117
123
|
settings.CHROME_START_WIDTH = override_settings[key]
|
118
124
|
elif key == "CHROME_START_HEIGHT":
|
seleniumbase/core/style_sheet.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import sys
|
2
|
+
import textwrap
|
2
3
|
from seleniumbase.fixtures import constants
|
3
4
|
|
4
5
|
|
@@ -116,6 +117,7 @@ def get_report_style():
|
|
116
117
|
}
|
117
118
|
</style>"""
|
118
119
|
)
|
120
|
+
style = textwrap.dedent(style)
|
119
121
|
Saved.report_style = style
|
120
122
|
return style
|
121
123
|
|
@@ -132,6 +134,7 @@ def get_bt_backdrop_style():
|
|
132
134
|
box-shadow: 0 0 0 88422px rgba(0, 0, 0, 0.42);
|
133
135
|
pointer-events: auto !important;
|
134
136
|
}"""
|
137
|
+
bt_backdrop_style = textwrap.dedent(bt_backdrop_style)
|
135
138
|
Saved.bt_backdrop_style = bt_backdrop_style
|
136
139
|
return bt_backdrop_style
|
137
140
|
|
@@ -150,6 +153,7 @@ def get_dt_backdrop_style():
|
|
150
153
|
button.driver-prev-btn.driver-disabled {
|
151
154
|
visibility: hidden;
|
152
155
|
}"""
|
156
|
+
dt_backdrop_style = textwrap.dedent(dt_backdrop_style)
|
153
157
|
Saved.dt_backdrop_style = dt_backdrop_style
|
154
158
|
return dt_backdrop_style
|
155
159
|
|
@@ -167,6 +171,7 @@ def get_messenger_style():
|
|
167
171
|
box-shadow: 2px 2px 9px 4px rgba(32, 142, 120, 0.28),
|
168
172
|
2px 2px 9px 4px rgba(200, 240, 80, 0.34) !important;
|
169
173
|
}""" % font_family
|
174
|
+
messenger_style = textwrap.dedent(messenger_style)
|
170
175
|
Saved.messenger_style = messenger_style
|
171
176
|
return messenger_style
|
172
177
|
|
@@ -181,6 +186,7 @@ def get_sh_style_test():
|
|
181
186
|
scrollTo: true
|
182
187
|
}
|
183
188
|
});"""
|
189
|
+
sh_style_test = textwrap.dedent(sh_style_test)
|
184
190
|
Saved.sh_style_test = sh_style_test
|
185
191
|
return sh_style_test
|
186
192
|
|
@@ -193,6 +199,7 @@ def get_hops_backdrop_style():
|
|
193
199
|
.hopscotch-bubble-container {
|
194
200
|
font-size: 110%;
|
195
201
|
}"""
|
202
|
+
hops_backdrop_style = textwrap.dedent(hops_backdrop_style)
|
196
203
|
Saved.hops_backdrop_style = hops_backdrop_style
|
197
204
|
return hops_backdrop_style
|
198
205
|
|
@@ -227,6 +234,7 @@ def get_introjs_style():
|
|
227
234
|
box-sizing: content-box;
|
228
235
|
position: absolute;
|
229
236
|
}"""
|
237
|
+
introjs_style = textwrap.dedent(introjs_style)
|
230
238
|
Saved.introjs_style = introjs_style
|
231
239
|
return introjs_style
|
232
240
|
|
@@ -261,6 +269,7 @@ def get_sh_backdrop_style():
|
|
261
269
|
body.shepherd-active {
|
262
270
|
pointer-events: none !important;
|
263
271
|
}"""
|
272
|
+
sh_backdrop_style = textwrap.dedent(sh_backdrop_style)
|
264
273
|
Saved.sh_backdrop_style = sh_backdrop_style
|
265
274
|
return sh_backdrop_style
|
266
275
|
|
@@ -387,5 +396,6 @@ def get_pytest_style():
|
|
387
396
|
.desc.active .sort-icon {
|
388
397
|
border-top: 8px solid #999;
|
389
398
|
}"""
|
399
|
+
pytest_style = textwrap.dedent(pytest_style)
|
390
400
|
Saved.pytest_style = pytest_style
|
391
401
|
return pytest_style
|
Binary file
|