seleniumbase 4.24.10__py3-none-any.whl → 4.33.15__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.
Files changed (79) hide show
  1. sbase/__init__.py +1 -0
  2. sbase/steps.py +7 -0
  3. seleniumbase/__init__.py +16 -7
  4. seleniumbase/__version__.py +1 -1
  5. seleniumbase/behave/behave_sb.py +97 -32
  6. seleniumbase/common/decorators.py +16 -7
  7. seleniumbase/config/proxy_list.py +3 -3
  8. seleniumbase/config/settings.py +4 -0
  9. seleniumbase/console_scripts/logo_helper.py +47 -8
  10. seleniumbase/console_scripts/run.py +345 -335
  11. seleniumbase/console_scripts/sb_behave_gui.py +5 -12
  12. seleniumbase/console_scripts/sb_caseplans.py +6 -13
  13. seleniumbase/console_scripts/sb_commander.py +5 -12
  14. seleniumbase/console_scripts/sb_install.py +62 -54
  15. seleniumbase/console_scripts/sb_mkchart.py +13 -20
  16. seleniumbase/console_scripts/sb_mkdir.py +11 -17
  17. seleniumbase/console_scripts/sb_mkfile.py +69 -43
  18. seleniumbase/console_scripts/sb_mkpres.py +13 -20
  19. seleniumbase/console_scripts/sb_mkrec.py +88 -21
  20. seleniumbase/console_scripts/sb_objectify.py +30 -30
  21. seleniumbase/console_scripts/sb_print.py +5 -12
  22. seleniumbase/console_scripts/sb_recorder.py +16 -11
  23. seleniumbase/core/browser_launcher.py +1658 -221
  24. seleniumbase/core/detect_b_ver.py +7 -8
  25. seleniumbase/core/log_helper.py +42 -27
  26. seleniumbase/core/mysql.py +1 -4
  27. seleniumbase/core/proxy_helper.py +35 -30
  28. seleniumbase/core/recorder_helper.py +24 -5
  29. seleniumbase/core/sb_cdp.py +1951 -0
  30. seleniumbase/core/sb_driver.py +162 -8
  31. seleniumbase/core/settings_parser.py +6 -0
  32. seleniumbase/core/style_sheet.py +10 -0
  33. seleniumbase/extensions/recorder.zip +0 -0
  34. seleniumbase/fixtures/base_case.py +1234 -632
  35. seleniumbase/fixtures/constants.py +10 -1
  36. seleniumbase/fixtures/js_utils.py +171 -144
  37. seleniumbase/fixtures/page_actions.py +177 -13
  38. seleniumbase/fixtures/page_utils.py +25 -53
  39. seleniumbase/fixtures/shared_utils.py +97 -11
  40. seleniumbase/js_code/active_css_js.py +1 -1
  41. seleniumbase/js_code/recorder_js.py +1 -1
  42. seleniumbase/plugins/base_plugin.py +2 -3
  43. seleniumbase/plugins/driver_manager.py +340 -65
  44. seleniumbase/plugins/pytest_plugin.py +276 -47
  45. seleniumbase/plugins/sb_manager.py +412 -99
  46. seleniumbase/plugins/selenium_plugin.py +122 -17
  47. seleniumbase/translate/translator.py +0 -7
  48. seleniumbase/undetected/__init__.py +59 -52
  49. seleniumbase/undetected/cdp.py +0 -1
  50. seleniumbase/undetected/cdp_driver/__init__.py +1 -0
  51. seleniumbase/undetected/cdp_driver/_contradict.py +110 -0
  52. seleniumbase/undetected/cdp_driver/browser.py +829 -0
  53. seleniumbase/undetected/cdp_driver/cdp_util.py +458 -0
  54. seleniumbase/undetected/cdp_driver/config.py +334 -0
  55. seleniumbase/undetected/cdp_driver/connection.py +639 -0
  56. seleniumbase/undetected/cdp_driver/element.py +1168 -0
  57. seleniumbase/undetected/cdp_driver/tab.py +1323 -0
  58. seleniumbase/undetected/dprocess.py +4 -7
  59. seleniumbase/undetected/options.py +6 -8
  60. seleniumbase/undetected/patcher.py +11 -13
  61. seleniumbase/undetected/reactor.py +0 -1
  62. seleniumbase/undetected/webelement.py +16 -3
  63. {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/LICENSE +1 -1
  64. {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/METADATA +299 -252
  65. {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/RECORD +68 -70
  66. {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/WHEEL +1 -1
  67. sbase/ReadMe.txt +0 -2
  68. seleniumbase/ReadMe.md +0 -25
  69. seleniumbase/common/ReadMe.md +0 -71
  70. seleniumbase/console_scripts/ReadMe.md +0 -731
  71. seleniumbase/drivers/ReadMe.md +0 -27
  72. seleniumbase/extensions/ReadMe.md +0 -12
  73. seleniumbase/masterqa/ReadMe.md +0 -61
  74. seleniumbase/resources/ReadMe.md +0 -31
  75. seleniumbase/resources/favicon.ico +0 -0
  76. seleniumbase/utilities/selenium_grid/ReadMe.md +0 -84
  77. seleniumbase/utilities/selenium_ide/ReadMe.md +0 -111
  78. {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/entry_points.txt +0 -0
  79. {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/top_level.txt +0 -0
@@ -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
- try:
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 get_text(self, *args, **kwargs):
138
- return page_actions.get_text(self.driver, *args, **kwargs)
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 is_attribute_present(self, *args, **kwargs):
144
- return page_actions.has_attribute(self.driver, *args, **kwargs)
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 switch_to_frame(self, frame):
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":
@@ -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