seleniumbase 4.44.2__py3-none-any.whl → 4.45.10__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 (42) hide show
  1. seleniumbase/__version__.py +1 -1
  2. seleniumbase/behave/behave_sb.py +14 -0
  3. seleniumbase/console_scripts/run.py +1 -0
  4. seleniumbase/console_scripts/sb_install.py +142 -11
  5. seleniumbase/console_scripts/sb_mkdir.py +76 -0
  6. seleniumbase/console_scripts/sb_mkrec.py +25 -0
  7. seleniumbase/console_scripts/sb_recorder.py +40 -3
  8. seleniumbase/core/browser_launcher.py +279 -117
  9. seleniumbase/core/detect_b_ver.py +8 -6
  10. seleniumbase/core/log_helper.py +11 -16
  11. seleniumbase/core/mysql.py +1 -1
  12. seleniumbase/core/report_helper.py +3 -7
  13. seleniumbase/core/sb_cdp.py +275 -78
  14. seleniumbase/core/sb_driver.py +36 -5
  15. seleniumbase/core/session_helper.py +2 -4
  16. seleniumbase/drivers/chromium_drivers/__init__.py +0 -0
  17. seleniumbase/fixtures/base_case.py +251 -201
  18. seleniumbase/fixtures/constants.py +1 -0
  19. seleniumbase/fixtures/js_utils.py +52 -14
  20. seleniumbase/fixtures/page_actions.py +18 -7
  21. seleniumbase/fixtures/page_utils.py +4 -2
  22. seleniumbase/fixtures/shared_utils.py +2 -4
  23. seleniumbase/masterqa/master_qa.py +16 -2
  24. seleniumbase/plugins/base_plugin.py +8 -0
  25. seleniumbase/plugins/driver_manager.py +15 -5
  26. seleniumbase/plugins/pytest_plugin.py +43 -57
  27. seleniumbase/plugins/sb_manager.py +23 -19
  28. seleniumbase/plugins/selenium_plugin.py +20 -13
  29. seleniumbase/undetected/__init__.py +11 -10
  30. seleniumbase/undetected/cdp.py +1 -12
  31. seleniumbase/undetected/cdp_driver/browser.py +330 -128
  32. seleniumbase/undetected/cdp_driver/cdp_util.py +48 -14
  33. seleniumbase/undetected/cdp_driver/config.py +78 -11
  34. seleniumbase/undetected/cdp_driver/connection.py +15 -43
  35. seleniumbase/undetected/cdp_driver/element.py +37 -22
  36. seleniumbase/undetected/cdp_driver/tab.py +414 -39
  37. {seleniumbase-4.44.2.dist-info → seleniumbase-4.45.10.dist-info}/METADATA +140 -152
  38. {seleniumbase-4.44.2.dist-info → seleniumbase-4.45.10.dist-info}/RECORD +42 -41
  39. {seleniumbase-4.44.2.dist-info → seleniumbase-4.45.10.dist-info}/licenses/LICENSE +1 -1
  40. {seleniumbase-4.44.2.dist-info → seleniumbase-4.45.10.dist-info}/WHEEL +0 -0
  41. {seleniumbase-4.44.2.dist-info → seleniumbase-4.45.10.dist-info}/entry_points.txt +0 -0
  42. {seleniumbase-4.44.2.dist-info → seleniumbase-4.45.10.dist-info}/top_level.txt +0 -0
@@ -22,6 +22,7 @@ class SeleniumBrowser(Plugin):
22
22
  --brave (Shortcut for "--browser=brave".)
23
23
  --comet (Shortcut for "--browser=comet".)
24
24
  --atlas (Shortcut for "--browser=atlas".)
25
+ --use-chromium (Shortcut for using base `Chromium`)
25
26
  --cft (Shortcut for using `Chrome for Testing`)
26
27
  --chs (Shortcut for using `Chrome-Headless-Shell`)
27
28
  --user-data-dir=DIR (Set the Chrome user data directory to use.)
@@ -180,6 +181,13 @@ class SeleniumBrowser(Plugin):
180
181
  default=False,
181
182
  help="""Shortcut for --browser=atlas""",
182
183
  )
184
+ parser.addoption(
185
+ "--use-chromium",
186
+ action="store_true",
187
+ dest="use_chromium",
188
+ default=False,
189
+ help="""Shortcut for using base `Chromium`""",
190
+ )
183
191
  parser.addoption(
184
192
  "--cft",
185
193
  action="store_true",
@@ -367,7 +375,7 @@ class SeleniumBrowser(Plugin):
367
375
  help="""Designates the three device metrics of the mobile
368
376
  emulator: CSS Width, CSS Height, and Pixel-Ratio.
369
377
  Format: A comma-separated string with the 3 values.
370
- Examples: "375,734,5" or "411,731,3" or "390,715,3"
378
+ Examples: "375,734,5" or "412,732,3" or "390,715,3"
371
379
  Default: None. (Will use default values if None)""",
372
380
  )
373
381
  parser.addoption(
@@ -1237,9 +1245,11 @@ class SeleniumBrowser(Plugin):
1237
1245
  raise Exception(message)
1238
1246
  if browser_text:
1239
1247
  browser = browser_text
1240
- if self.options.recorder_mode and browser not in ["chrome", "edge"]:
1248
+ if self.options.recorder_mode and browser not in [
1249
+ "chrome", "edge", "opera", "brave", "comet", "atlas", "chromium"
1250
+ ]:
1241
1251
  message = (
1242
- "\n\n Recorder Mode ONLY supports Chrome and Edge!"
1252
+ "\n\n Recorder Mode ONLY supports Chromium browsers!"
1243
1253
  '\n (Your browser choice was: "%s")\n' % browser
1244
1254
  )
1245
1255
  raise Exception(message)
@@ -1338,9 +1348,11 @@ class SeleniumBrowser(Plugin):
1338
1348
  test.test.extension_dir = self.options.extension_dir
1339
1349
  test.test.disable_features = self.options.disable_features
1340
1350
  test.test.binary_location = self.options.binary_location
1341
- if hasattr(sb_config, "_cdp_bin_loc") and sb_config._cdp_bin_loc:
1351
+ if getattr(sb_config, "_cdp_bin_loc", None):
1342
1352
  test.test.binary_location = sb_config._cdp_bin_loc
1343
- if self.options.use_cft and not test.test.binary_location:
1353
+ if self.options.use_chromium and not test.test.binary_location:
1354
+ test.test.binary_location = "_chromium_"
1355
+ elif self.options.use_cft and not test.test.binary_location:
1344
1356
  test.test.binary_location = "cft"
1345
1357
  elif self.options.use_chs and not test.test.binary_location:
1346
1358
  test.test.binary_location = "chs"
@@ -1515,10 +1527,7 @@ class SeleniumBrowser(Plugin):
1515
1527
 
1516
1528
  def finalize(self, result):
1517
1529
  """This runs after all tests have completed with nosetests."""
1518
- if (
1519
- (hasattr(sb_config, "multi_proxy") and not sb_config.multi_proxy)
1520
- or not hasattr(sb_config, "multi_proxy")
1521
- ):
1530
+ if not getattr(sb_config, "multi_proxy", None):
1522
1531
  proxy_helper.remove_proxy_zip_if_present()
1523
1532
 
1524
1533
  def afterTest(self, test):
@@ -1536,8 +1545,7 @@ class SeleniumBrowser(Plugin):
1536
1545
  pass
1537
1546
  with suppress(Exception):
1538
1547
  if (
1539
- hasattr(self, "_xvfb_display")
1540
- and self._xvfb_display
1548
+ getattr(self, "_xvfb_display", None)
1541
1549
  and hasattr(self._xvfb_display, "stop")
1542
1550
  ):
1543
1551
  self.headless_active = False
@@ -1545,8 +1553,7 @@ class SeleniumBrowser(Plugin):
1545
1553
  self._xvfb_display.stop()
1546
1554
  self._xvfb_display = None
1547
1555
  if (
1548
- hasattr(sb_config, "_virtual_display")
1549
- and sb_config._virtual_display
1556
+ getattr(sb_config, "_virtual_display", None)
1550
1557
  and hasattr(sb_config._virtual_display, "stop")
1551
1558
  ):
1552
1559
  sb_config._virtual_display.stop()
@@ -163,7 +163,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
163
163
  from seleniumbase import config as sb_config
164
164
  if (
165
165
  (("-n" in sys.argv) or (" -n=" in arg_join) or ("-c" in sys.argv))
166
- or (hasattr(sb_config, "multi_proxy") and sb_config.multi_proxy)
166
+ or getattr(sb_config, "multi_proxy", None)
167
167
  or not special_port_free
168
168
  ):
169
169
  debug_port = selenium.webdriver.common.service.utils.free_port()
@@ -197,9 +197,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
197
197
  except IndexError:
198
198
  pass
199
199
  if not user_data_dir:
200
- if hasattr(options, "user_data_dir") and getattr(
201
- options, "user_data_dir", None
202
- ):
200
+ if getattr(options, "user_data_dir", None):
203
201
  options.add_argument(
204
202
  "--user-data-dir=%s" % options.user_data_dir
205
203
  )
@@ -405,9 +403,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
405
403
 
406
404
  def add_cdp_listener(self, event_name, callback):
407
405
  if (
408
- hasattr(self, "reactor")
409
- and self.reactor
410
- and self.reactor is not None
406
+ getattr(self, "reactor", None)
411
407
  and isinstance(self.reactor, Reactor)
412
408
  ):
413
409
  self.reactor.add_event_handler(event_name, callback)
@@ -416,8 +412,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
416
412
 
417
413
  def clear_cdp_listeners(self):
418
414
  if (
419
- hasattr(self, "reactor")
420
- and self.reactor
415
+ getattr(self, "reactor", None)
421
416
  and isinstance(self.reactor, Reactor)
422
417
  ):
423
418
  self.reactor.handlers.clear()
@@ -526,7 +521,13 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
526
521
  with suppress(Exception):
527
522
  for window_handle in self.window_handles:
528
523
  self.switch_to.window(window_handle)
529
- if self.current_url.startswith("chrome-extension://"):
524
+ current_url = None
525
+ if hasattr(self, "cdp") and hasattr(self.cdp, "driver"):
526
+ with suppress(Exception):
527
+ current_url = self.cdp.get_current_url()
528
+ if not current_url:
529
+ current_url = self.current_url
530
+ if current_url.startswith("chrome-extension://"):
530
531
  # https://issues.chromium.org/issues/396611138
531
532
  # (Remove the Linux conditional when resolved)
532
533
  # (So that close() is always called)
@@ -1,9 +1,7 @@
1
- import fasteners
2
1
  import json
3
2
  import logging
4
3
  import requests
5
- from seleniumbase.fixtures import constants
6
- from seleniumbase.fixtures import shared_utils
4
+ import websockets
7
5
 
8
6
  log = logging.getLogger(__name__)
9
7
 
@@ -107,15 +105,6 @@ class CDP:
107
105
  return resp.json()
108
106
 
109
107
  async def send(self, method, params):
110
- pip_find_lock = fasteners.InterProcessLock(
111
- constants.PipInstall.FINDLOCK
112
- )
113
- with pip_find_lock:
114
- try:
115
- import websockets
116
- except Exception:
117
- shared_utils.pip_install("websockets")
118
- import websockets
119
108
  self._reqid += 1
120
109
  async with websockets.connect(self.wsurl) as ws:
121
110
  await ws.send(