seleniumbase 4.30.8__py3-none-any.whl → 4.31.1__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 (47) hide show
  1. sbase/__init__.py +1 -0
  2. seleniumbase/__init__.py +2 -3
  3. seleniumbase/__version__.py +1 -1
  4. seleniumbase/behave/behave_sb.py +59 -11
  5. seleniumbase/config/settings.py +4 -0
  6. seleniumbase/console_scripts/logo_helper.py +47 -0
  7. seleniumbase/console_scripts/run.py +7 -4
  8. seleniumbase/console_scripts/sb_behave_gui.py +5 -5
  9. seleniumbase/console_scripts/sb_caseplans.py +6 -6
  10. seleniumbase/console_scripts/sb_commander.py +5 -5
  11. seleniumbase/console_scripts/sb_install.py +10 -2
  12. seleniumbase/console_scripts/sb_recorder.py +4 -4
  13. seleniumbase/core/browser_launcher.py +179 -108
  14. seleniumbase/core/mysql.py +1 -4
  15. seleniumbase/core/recorder_helper.py +24 -5
  16. seleniumbase/core/sb_driver.py +13 -3
  17. seleniumbase/core/settings_parser.py +4 -0
  18. seleniumbase/fixtures/base_case.py +324 -493
  19. seleniumbase/fixtures/js_utils.py +19 -52
  20. seleniumbase/fixtures/page_actions.py +3 -6
  21. seleniumbase/fixtures/page_utils.py +18 -53
  22. seleniumbase/plugins/base_plugin.py +2 -3
  23. seleniumbase/plugins/driver_manager.py +182 -5
  24. seleniumbase/plugins/pytest_plugin.py +51 -23
  25. seleniumbase/plugins/sb_manager.py +185 -5
  26. seleniumbase/plugins/selenium_plugin.py +71 -8
  27. seleniumbase/undetected/__init__.py +13 -38
  28. seleniumbase/undetected/dprocess.py +4 -6
  29. seleniumbase/undetected/options.py +3 -6
  30. seleniumbase/undetected/patcher.py +2 -3
  31. {seleniumbase-4.30.8.dist-info → seleniumbase-4.31.1.dist-info}/METADATA +111 -125
  32. {seleniumbase-4.30.8.dist-info → seleniumbase-4.31.1.dist-info}/RECORD +36 -47
  33. {seleniumbase-4.30.8.dist-info → seleniumbase-4.31.1.dist-info}/WHEEL +1 -1
  34. sbase/ReadMe.txt +0 -2
  35. seleniumbase/ReadMe.md +0 -25
  36. seleniumbase/common/ReadMe.md +0 -71
  37. seleniumbase/console_scripts/ReadMe.md +0 -734
  38. seleniumbase/drivers/ReadMe.md +0 -27
  39. seleniumbase/extensions/ReadMe.md +0 -12
  40. seleniumbase/masterqa/ReadMe.md +0 -61
  41. seleniumbase/resources/ReadMe.md +0 -31
  42. seleniumbase/resources/favicon.ico +0 -0
  43. seleniumbase/utilities/selenium_grid/ReadMe.md +0 -84
  44. seleniumbase/utilities/selenium_ide/ReadMe.md +0 -111
  45. {seleniumbase-4.30.8.dist-info → seleniumbase-4.31.1.dist-info}/LICENSE +0 -0
  46. {seleniumbase-4.30.8.dist-info → seleniumbase-4.31.1.dist-info}/entry_points.txt +0 -0
  47. {seleniumbase-4.30.8.dist-info → seleniumbase-4.31.1.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,6 @@
1
1
  """Selenium Plugin for SeleniumBase tests that run with pynose / nosetests"""
2
2
  import sys
3
+ from contextlib import suppress
3
4
  from nose.plugins import Plugin
4
5
  from seleniumbase import config as sb_config
5
6
  from seleniumbase.config import settings
@@ -42,10 +43,12 @@ class SeleniumBrowser(Plugin):
42
43
  --sjw (Skip JS Waits for readyState to be "complete" or Angular to load.)
43
44
  --wfa (Wait for AngularJS to be done loading after specific web actions.)
44
45
  --pls=PLS (Set pageLoadStrategy on Chrome: "normal", "eager", or "none".)
45
- --headless (Run tests in headless mode. The default arg on Linux OS.)
46
- --headless2 (Use the new headless mode, which supports extensions.)
46
+ --headless (The default headless mode. Linux uses this mode by default.)
47
+ --headless1 (Use Chrome's old headless mode. Fast, but has limitations.)
48
+ --headless2 (Use Chrome's new headless mode, which supports extensions.)
47
49
  --headed (Run tests in headed/GUI mode on Linux OS, where not default.)
48
50
  --xvfb (Run tests using the Xvfb virtual display server on Linux OS.)
51
+ --xvfb-metrics=STRING (Set Xvfb display size on Linux: "Width,Height".)
49
52
  --locale=LOCALE_CODE (Set the Language Locale Code for the web browser.)
50
53
  --interval=SECONDS (The autoplay interval for presentations & tour steps)
51
54
  --start-page=URL (The starting URL for the web browser when tests begin.)
@@ -82,6 +85,7 @@ class SeleniumBrowser(Plugin):
82
85
  --dark (Enable Chrome's Dark mode.)
83
86
  --devtools (Open Chrome's DevTools when the browser opens.)
84
87
  --disable-beforeunload (Disable the "beforeunload" event on Chrome.)
88
+ --window-position=X,Y (Set the browser's starting window position.)
85
89
  --window-size=WIDTH,HEIGHT (Set the browser's starting window size.)
86
90
  --maximize (Start tests with the browser window maximized.)
87
91
  --screenshot (Save a screenshot at the end of each test.)
@@ -434,6 +438,15 @@ class SeleniumBrowser(Plugin):
434
438
  UNLESS using a virtual display with Xvfb.
435
439
  Default: False on Mac/Windows. True on Linux.""",
436
440
  )
441
+ parser.addoption(
442
+ "--headless1",
443
+ action="store_true",
444
+ dest="headless1",
445
+ default=False,
446
+ help="""This option activates the old headless mode,
447
+ which is faster, but has limitations.
448
+ (May be phased out by Chrome in the future.)""",
449
+ )
437
450
  parser.addoption(
438
451
  "--headless2",
439
452
  action="store_true",
@@ -465,6 +478,17 @@ class SeleniumBrowser(Plugin):
465
478
  will no longer be enabled by default on Linux.
466
479
  Default: False. (Linux-ONLY!)""",
467
480
  )
481
+ parser.addoption(
482
+ "--xvfb-metrics",
483
+ "--xvfb_metrics",
484
+ action="store",
485
+ dest="xvfb_metrics",
486
+ default=None,
487
+ help="""Customize the Xvfb metrics (Width,Height) on Linux.
488
+ Format: A comma-separated string with the 2 values.
489
+ Examples: "1920,1080" or "1366,768" or "1024,768".
490
+ Default: None. (None: "1366,768". Min: "1024,768".)""",
491
+ )
468
492
  parser.addoption(
469
493
  "--locale_code",
470
494
  "--locale-code",
@@ -886,6 +910,17 @@ class SeleniumBrowser(Plugin):
886
910
  on Chromium browsers (Chrome or Edge).
887
911
  This is already the default Firefox option.""",
888
912
  )
913
+ parser.addoption(
914
+ "--window-position",
915
+ "--window_position",
916
+ action="store",
917
+ dest="window_position",
918
+ default=None,
919
+ help="""The option to set the starting window x,y position.
920
+ Format: A comma-separated string with the 2 values.
921
+ Example: "55,66"
922
+ Default: None. (Will use default values if None)""",
923
+ )
889
924
  parser.addoption(
890
925
  "--window-size",
891
926
  "--window_size",
@@ -984,6 +1019,7 @@ class SeleniumBrowser(Plugin):
984
1019
  browser = self.options.browser
985
1020
  test.test.browser = browser
986
1021
  test.test.headless = None
1022
+ test.test.headless1 = None
987
1023
  test.test.headless2 = None
988
1024
  # As a shortcut, you can use "--edge" instead of "--browser=edge", etc,
989
1025
  # but you can only specify one default browser. (Default: chrome)
@@ -1060,6 +1096,29 @@ class SeleniumBrowser(Plugin):
1060
1096
  '\n (Your browser choice was: "%s")\n' % browser
1061
1097
  )
1062
1098
  raise Exception(message)
1099
+ window_position = self.options.window_position
1100
+ if window_position:
1101
+ if window_position.count(",") != 1:
1102
+ message = (
1103
+ '\n\n window_position expects an "x,y" string!'
1104
+ '\n (Your input was: "%s")\n' % window_position
1105
+ )
1106
+ raise Exception(message)
1107
+ window_position = window_position.replace(" ", "")
1108
+ win_x = None
1109
+ win_y = None
1110
+ try:
1111
+ win_x = int(window_position.split(",")[0])
1112
+ win_y = int(window_position.split(",")[1])
1113
+ except Exception:
1114
+ message = (
1115
+ '\n\n Expecting integer values for "x,y"!'
1116
+ '\n (window_position input was: "%s")\n'
1117
+ % window_position
1118
+ )
1119
+ raise Exception(message)
1120
+ settings.WINDOW_START_X = win_x
1121
+ settings.WINDOW_START_Y = win_y
1063
1122
  window_size = self.options.window_size
1064
1123
  if window_size:
1065
1124
  if window_size.count(",") != 1:
@@ -1099,9 +1158,13 @@ class SeleniumBrowser(Plugin):
1099
1158
  test.test.cap_file = self.options.cap_file
1100
1159
  test.test.cap_string = self.options.cap_string
1101
1160
  test.test.headless = self.options.headless
1161
+ test.test.headless1 = self.options.headless1
1162
+ if test.test.headless1:
1163
+ test.test.headless = True
1102
1164
  test.test.headless2 = self.options.headless2
1103
1165
  if test.test.headless and test.test.browser == "safari":
1104
1166
  test.test.headless = False # Safari doesn't use headless
1167
+ test.test.headless1 = False
1105
1168
  if test.test.headless2 and test.test.browser == "firefox":
1106
1169
  test.test.headless2 = False # Only for Chromium browsers
1107
1170
  test.test.headless = True # Firefox has regular headless
@@ -1112,6 +1175,7 @@ class SeleniumBrowser(Plugin):
1112
1175
  self.options.headless2 = False
1113
1176
  test.test.headed = self.options.headed
1114
1177
  test.test.xvfb = self.options.xvfb
1178
+ test.test.xvfb_metrics = self.options.xvfb_metrics
1115
1179
  test.test.locale_code = self.options.locale_code
1116
1180
  test.test.interval = self.options.interval
1117
1181
  test.test.start_page = self.options.start_page
@@ -1192,6 +1256,7 @@ class SeleniumBrowser(Plugin):
1192
1256
  test.test.dark_mode = self.options.dark_mode
1193
1257
  test.test.devtools = self.options.devtools
1194
1258
  test.test._disable_beforeunload = self.options._disable_beforeunload
1259
+ test.test.window_position = self.options.window_position
1195
1260
  test.test.window_size = self.options.window_size
1196
1261
  test.test.maximize_option = self.options.maximize_option
1197
1262
  if self.options.save_screenshot and self.options.no_screenshot:
@@ -1244,8 +1309,10 @@ class SeleniumBrowser(Plugin):
1244
1309
  # Recorder Mode can still optimize scripts in --headless2 mode.
1245
1310
  if self.options.recorder_mode and self.options.headless:
1246
1311
  self.options.headless = False
1312
+ self.options.headless1 = False
1247
1313
  self.options.headless2 = True
1248
1314
  test.test.headless = False
1315
+ test.test.headless1 = False
1249
1316
  test.test.headless2 = True
1250
1317
  if not self.options.headless and not self.options.headless2:
1251
1318
  self.options.headed = True
@@ -1259,7 +1326,7 @@ class SeleniumBrowser(Plugin):
1259
1326
  ):
1260
1327
  width = settings.HEADLESS_START_WIDTH
1261
1328
  height = settings.HEADLESS_START_HEIGHT
1262
- try:
1329
+ with suppress(Exception):
1263
1330
  from sbvirtualdisplay import Display
1264
1331
 
1265
1332
  self._xvfb_display = Display(visible=0, size=(width, height))
@@ -1267,8 +1334,6 @@ class SeleniumBrowser(Plugin):
1267
1334
  sb_config._virtual_display = self._xvfb_display
1268
1335
  self.headless_active = True
1269
1336
  sb_config.headless_active = True
1270
- except Exception:
1271
- pass
1272
1337
  sb_config._is_timeout_changed = False
1273
1338
  sb_config._SMALL_TIMEOUT = settings.SMALL_TIMEOUT
1274
1339
  sb_config._LARGE_TIMEOUT = settings.LARGE_TIMEOUT
@@ -1301,7 +1366,7 @@ class SeleniumBrowser(Plugin):
1301
1366
  pass
1302
1367
  except Exception:
1303
1368
  pass
1304
- try:
1369
+ with suppress(Exception):
1305
1370
  if (
1306
1371
  hasattr(self, "_xvfb_display")
1307
1372
  and self._xvfb_display
@@ -1318,5 +1383,3 @@ class SeleniumBrowser(Plugin):
1318
1383
  ):
1319
1384
  sb_config._virtual_display.stop()
1320
1385
  sb_config._virtual_display = None
1321
- except Exception:
1322
- pass
@@ -10,6 +10,7 @@ import selenium.webdriver.chrome.service
10
10
  import selenium.webdriver.chrome.webdriver
11
11
  import selenium.webdriver.common.service
12
12
  import selenium.webdriver.remote.command
13
+ from contextlib import suppress
13
14
  from .cdp import CDP
14
15
  from .cdp import PageElement
15
16
  from .dprocess import start_detached
@@ -201,11 +202,9 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
201
202
  # Create a temporary folder for the user-data profile.
202
203
  options.add_argument(arg)
203
204
  if not language:
204
- try:
205
+ with suppress(Exception):
205
206
  import locale
206
207
  language = locale.getlocale()[0].replace("_", "-")
207
- except Exception:
208
- pass
209
208
  if (
210
209
  not language
211
210
  or "English" in language
@@ -242,7 +241,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
242
241
  )
243
242
  if hasattr(options, 'handle_prefs'):
244
243
  options.handle_prefs(user_data_dir)
245
- try:
244
+ with suppress(Exception):
246
245
  import json
247
246
  with open(
248
247
  os.path.join(
@@ -263,8 +262,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
263
262
  fs.seek(0, 0)
264
263
  fs.truncate()
265
264
  json.dump(config, fs)
266
- except Exception:
267
- pass
268
265
  creationflags = 0
269
266
  if "win32" in sys.platform:
270
267
  creationflags = subprocess.CREATE_NO_WINDOW
@@ -293,8 +290,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
293
290
  self.browser_pid = browser.pid
294
291
  service_ = None
295
292
  log_output = subprocess.PIPE
296
- if sys.version_info < (3, 8):
297
- log_output = os.devnull
298
293
  if patch_driver:
299
294
  service_ = selenium.webdriver.chrome.service.Service(
300
295
  executable_path=self.patcher.executable_path,
@@ -342,7 +337,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
342
337
 
343
338
  def _get_cdc_props(self):
344
339
  cdc_props = []
345
- try:
340
+ with suppress(Exception):
346
341
  cdc_props = self.execute_script(
347
342
  """
348
343
  let objectToInspect = window,
@@ -355,8 +350,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
355
350
  return result.filter(i => i.match(/^[a-z]{3}_[a-z]{22}_.*/i))
356
351
  """
357
352
  )
358
- except Exception:
359
- pass
360
353
  return cdc_props
361
354
 
362
355
  def _hook_remove_cdc_props(self, cdc_props):
@@ -427,50 +420,38 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
427
420
  - Starts the chromedriver service that runs in the background.
428
421
  - Recreates the session."""
429
422
  if hasattr(self, "service"):
430
- try:
423
+ with suppress(Exception):
431
424
  self.service.stop()
432
- except Exception:
433
- pass
434
425
  if isinstance(timeout, str):
435
426
  if timeout.lower() == "breakpoint":
436
427
  breakpoint() # To continue:
437
428
  pass # Type "c" & press ENTER!
438
429
  else:
439
430
  time.sleep(timeout)
440
- try:
431
+ with suppress(Exception):
441
432
  self.service.start()
442
- except Exception:
443
- pass
444
433
  time.sleep(0.012)
445
- try:
434
+ with suppress(Exception):
446
435
  self.start_session()
447
- except Exception:
448
- pass
449
436
  time.sleep(0.012)
450
437
 
451
438
  def disconnect(self):
452
439
  """Stops the chromedriver service that runs in the background.
453
440
  To use driver methods again, you MUST call driver.connect()"""
454
441
  if hasattr(self, "service"):
455
- try:
442
+ with suppress(Exception):
456
443
  self.service.stop()
457
- except Exception:
458
- pass
459
444
  time.sleep(0.012)
460
445
 
461
446
  def connect(self):
462
447
  """Starts the chromedriver service that runs in the background
463
448
  and recreates the session."""
464
449
  if hasattr(self, "service"):
465
- try:
450
+ with suppress(Exception):
466
451
  self.service.start()
467
- except Exception:
468
- pass
469
452
  time.sleep(0.012)
470
- try:
453
+ with suppress(Exception):
471
454
  self.start_session()
472
- except Exception:
473
- pass
474
455
  time.sleep(0.012)
475
456
 
476
457
  def start_session(self, capabilities=None):
@@ -496,12 +477,10 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
496
477
  if hasattr(self, "service") and getattr(self.service, "process", None):
497
478
  logger.debug("Stopping webdriver service")
498
479
  self.service.stop()
499
- try:
480
+ with suppress(Exception):
500
481
  if self.reactor and isinstance(self.reactor, Reactor):
501
482
  logger.debug("Shutting down Reactor")
502
483
  self.reactor.event.set()
503
- except Exception:
504
- pass
505
484
  if (
506
485
  hasattr(self, "keep_user_data_dir")
507
486
  and hasattr(self, "user_data_dir")
@@ -530,18 +509,14 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
530
509
  self.patcher = None
531
510
 
532
511
  def __del__(self):
533
- try:
512
+ with suppress(Exception):
534
513
  if "win32" in sys.platform:
535
514
  self.stop_client()
536
515
  self.command_executor.close()
537
516
  else:
538
517
  super().quit()
539
- except Exception:
540
- pass
541
- try:
518
+ with suppress(Exception):
542
519
  self.quit()
543
- except Exception:
544
- pass
545
520
 
546
521
  def __enter__(self):
547
522
  return self
@@ -3,7 +3,10 @@ import os
3
3
  import sys
4
4
  import atexit
5
5
  import logging
6
+ import platform
7
+ from contextlib import suppress
6
8
  from subprocess import PIPE
9
+ from subprocess import Popen
7
10
 
8
11
  CREATE_NEW_PROCESS_GROUP = 0x00000200
9
12
  DETACHED_PROCESS = 0x00000008
@@ -37,9 +40,6 @@ def start_detached(executable, *args):
37
40
  def _start_detached(executable, *args, writer=None):
38
41
  # Configure Launch
39
42
  kwargs = {}
40
- import platform
41
- from subprocess import Popen
42
-
43
43
  if platform.system() == "Windows":
44
44
  kwargs.update(
45
45
  creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP
@@ -58,11 +58,9 @@ def _cleanup():
58
58
  import signal
59
59
 
60
60
  for pid in REGISTERED:
61
- try:
61
+ with suppress(Exception):
62
62
  logging.getLogger(__name__).debug("cleaning up pid %d " % pid)
63
63
  os.kill(pid, signal.SIGTERM)
64
- except Exception:
65
- pass
66
64
 
67
65
 
68
66
  atexit.register(_cleanup)
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env python3
2
2
  import json
3
3
  import os
4
+ from contextlib import suppress
4
5
  from selenium.webdriver.chromium.options import ChromiumOptions
5
6
 
6
7
 
@@ -49,7 +50,7 @@ class ChromeOptions(ChromiumOptions):
49
50
  undot_prefs, self._undot_key(key, value)
50
51
  )
51
52
  prefs_file = os.path.join(default_path, "Preferences")
52
- try:
53
+ with suppress(Exception):
53
54
  if os.path.exists(prefs_file):
54
55
  with open(
55
56
  prefs_file, encoding="utf-8", mode="r", errors="ignore"
@@ -57,13 +58,9 @@ class ChromeOptions(ChromiumOptions):
57
58
  undot_prefs = self._merge_nested(
58
59
  json.load(f), undot_prefs
59
60
  )
60
- except Exception:
61
- pass
62
- try:
61
+ with suppress(Exception):
63
62
  with open(prefs_file, encoding="utf-8", mode="w") as f:
64
63
  json.dump(undot_prefs, f)
65
- except Exception:
66
- pass
67
64
  # Remove experimental_options to avoid errors
68
65
  del self._experimental_options["prefs"]
69
66
  exclude_switches = self.experimental_options.get("excludeSwitches")
@@ -8,6 +8,7 @@ import string
8
8
  import sys
9
9
  import time
10
10
  import zipfile
11
+ from contextlib import suppress
11
12
 
12
13
  logger = logging.getLogger(__name__)
13
14
  IS_POSIX = sys.platform.startswith(("darwin", "cygwin", "linux"))
@@ -53,10 +54,8 @@ class Patcher(object):
53
54
  self.executable_path = None
54
55
  prefix = "undetected"
55
56
  if not os.path.exists(self.data_path):
56
- try:
57
+ with suppress(Exception):
57
58
  os.makedirs(self.data_path, exist_ok=True)
58
- except Exception:
59
- pass
60
59
  if not executable_path:
61
60
  self.executable_path = os.path.join(
62
61
  self.data_path, "_".join([prefix, self.exe_name])