seleniumbase 4.19.1__py3-none-any.whl → 4.20.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.
Files changed (33) hide show
  1. seleniumbase/__version__.py +1 -1
  2. seleniumbase/behave/behave_sb.py +17 -9
  3. seleniumbase/console_scripts/logo_helper.py +8 -1
  4. seleniumbase/console_scripts/run.py +5 -2
  5. seleniumbase/console_scripts/sb_behave_gui.py +7 -1
  6. seleniumbase/console_scripts/sb_caseplans.py +7 -1
  7. seleniumbase/console_scripts/sb_commander.py +7 -1
  8. seleniumbase/console_scripts/sb_install.py +4 -1
  9. seleniumbase/console_scripts/sb_mkchart.py +7 -1
  10. seleniumbase/console_scripts/sb_mkdir.py +7 -1
  11. seleniumbase/console_scripts/sb_mkfile.py +7 -1
  12. seleniumbase/console_scripts/sb_mkpres.py +7 -1
  13. seleniumbase/console_scripts/sb_mkrec.py +7 -1
  14. seleniumbase/console_scripts/sb_print.py +7 -1
  15. seleniumbase/console_scripts/sb_recorder.py +7 -1
  16. seleniumbase/core/browser_launcher.py +102 -14
  17. seleniumbase/core/sb_driver.py +38 -0
  18. seleniumbase/fixtures/base_case.py +23 -23
  19. seleniumbase/fixtures/constants.py +13 -0
  20. seleniumbase/fixtures/js_utils.py +1 -1
  21. seleniumbase/fixtures/page_actions.py +30 -0
  22. seleniumbase/plugins/driver_manager.py +2 -5
  23. seleniumbase/plugins/pytest_plugin.py +14 -14
  24. seleniumbase/plugins/sb_manager.py +16 -8
  25. seleniumbase/plugins/selenium_plugin.py +4 -13
  26. seleniumbase/translate/translator.py +7 -1
  27. seleniumbase/undetected/__init__.py +6 -11
  28. {seleniumbase-4.19.1.dist-info → seleniumbase-4.20.0.dist-info}/METADATA +5 -5
  29. {seleniumbase-4.19.1.dist-info → seleniumbase-4.20.0.dist-info}/RECORD +33 -33
  30. {seleniumbase-4.19.1.dist-info → seleniumbase-4.20.0.dist-info}/LICENSE +0 -0
  31. {seleniumbase-4.19.1.dist-info → seleniumbase-4.20.0.dist-info}/WHEEL +0 -0
  32. {seleniumbase-4.19.1.dist-info → seleniumbase-4.20.0.dist-info}/entry_points.txt +0 -0
  33. {seleniumbase-4.19.1.dist-info → seleniumbase-4.20.0.dist-info}/top_level.txt +0 -0
@@ -3844,7 +3844,7 @@ class BaseCase(unittest.TestCase):
3844
3844
  if enable_3d_apis is None:
3845
3845
  enable_3d_apis = self.enable_3d_apis
3846
3846
  if swiftshader is None:
3847
- swiftshader = self.swiftshader
3847
+ swiftshader = self._swiftshader
3848
3848
  if ad_block_on is None:
3849
3849
  ad_block_on = self.ad_block_on
3850
3850
  if block_images is None:
@@ -3887,12 +3887,8 @@ class BaseCase(unittest.TestCase):
3887
3887
  if d_p_r is None:
3888
3888
  d_p_r = self.__device_pixel_ratio
3889
3889
  if is_mobile and not user_agent:
3890
- # Use the Pixel 4 user agent by default if not specified
3891
- user_agent = (
3892
- "Mozilla/5.0 (Linux; Android 11; Pixel 4 XL) "
3893
- "AppleWebKit/537.36 (KHTML, like Gecko) "
3894
- "Chrome/89.0.4389.105 Mobile Safari/537.36"
3895
- )
3890
+ # Use a Pixel user agent by default if not specified
3891
+ user_agent = constants.Mobile.AGENT
3896
3892
  valid_browsers = constants.ValidBrowsers.valid_browsers
3897
3893
  if browser_name not in valid_browsers:
3898
3894
  raise Exception(
@@ -14153,7 +14149,7 @@ class BaseCase(unittest.TestCase):
14153
14149
  constants.Dashboard.LOCKFILE
14154
14150
  )
14155
14151
  self.enable_3d_apis = sb_config.enable_3d_apis
14156
- self.swiftshader = sb_config.swiftshader
14152
+ self._swiftshader = sb_config.swiftshader
14157
14153
  self.user_data_dir = sb_config.user_data_dir
14158
14154
  self.extension_zip = sb_config.extension_zip
14159
14155
  self.extension_dir = sb_config.extension_dir
@@ -14282,6 +14278,10 @@ class BaseCase(unittest.TestCase):
14282
14278
  settings.SMALL_TIMEOUT = sb_config._SMALL_TIMEOUT
14283
14279
  settings.LARGE_TIMEOUT = sb_config._LARGE_TIMEOUT
14284
14280
 
14281
+ if not hasattr(self, "_swiftshader"):
14282
+ # Not swiftshader: options.add_argument("--disable-gpu")
14283
+ self._swiftshader = False
14284
+
14285
14285
  if not hasattr(sb_config, "_recorded_actions"):
14286
14286
  # Only filled when Recorder Mode is enabled
14287
14287
  sb_config._recorded_actions = {}
@@ -14347,15 +14347,9 @@ class BaseCase(unittest.TestCase):
14347
14347
  self.mobile_emulator = True
14348
14348
  except Exception:
14349
14349
  raise Exception(exception_string)
14350
- if self.mobile_emulator:
14351
- if not self.user_agent:
14352
- # Use the Pixel 4 user agent by default if not specified
14353
- self.user_agent = (
14354
- "Mozilla/5.0 (Linux; Android 11; Pixel 4 XL) "
14355
- "AppleWebKit/537.36 (KHTML, like Gecko) "
14356
- "Chrome/89.0.4389.105 Mobile Safari/537.36"
14357
- )
14358
-
14350
+ if self.mobile_emulator and not self.user_agent:
14351
+ # Use a Pixel user agent by default if not specified
14352
+ self.user_agent = constants.Mobile.AGENT
14359
14353
  if self.browser in ["firefox", "ie", "safari"]:
14360
14354
  # The Recorder Mode browser extension is only for Chrome/Edge.
14361
14355
  if self.recorder_mode:
@@ -14468,7 +14462,7 @@ class BaseCase(unittest.TestCase):
14468
14462
  devtools=self.devtools,
14469
14463
  remote_debug=self.remote_debug,
14470
14464
  enable_3d_apis=self.enable_3d_apis,
14471
- swiftshader=self.swiftshader,
14465
+ swiftshader=self._swiftshader,
14472
14466
  ad_block_on=self.ad_block_on,
14473
14467
  block_images=self.block_images,
14474
14468
  do_not_track=self.do_not_track,
@@ -15310,11 +15304,11 @@ class BaseCase(unittest.TestCase):
15310
15304
  # Post Mortem Debug Mode ("python --pdb")
15311
15305
 
15312
15306
  def __activate_debug_mode_in_teardown(self):
15313
- """Activate Debug Mode in tearDown() when using "--final-debug"."""
15307
+ """Activate Final Trace / Debug Mode"""
15314
15308
  import pdb
15315
15309
 
15316
15310
  pdb.set_trace()
15317
- # Final Debug Mode ("--final-debug")
15311
+ # Final Trace ("--ftrace")
15318
15312
 
15319
15313
  def has_exception(self):
15320
15314
  """(This method should ONLY be used in custom tearDown() methods.)
@@ -15736,7 +15730,6 @@ class BaseCase(unittest.TestCase):
15736
15730
  # (Pynose / Behave / Pure Python)
15737
15731
  if hasattr(self, "is_behave") and self.is_behave:
15738
15732
  import colorama
15739
-
15740
15733
  if sb_config.behave_scenario.status.name == "failed":
15741
15734
  has_exception = True
15742
15735
  sb_config._has_exception = True
@@ -15744,7 +15737,8 @@ class BaseCase(unittest.TestCase):
15744
15737
  if is_windows:
15745
15738
  c1 = colorama.Fore.RED + colorama.Back.LIGHTRED_EX
15746
15739
  cr = colorama.Style.RESET_ALL
15747
- colorama.init(autoreset=True)
15740
+ if hasattr(colorama, "just_fix_windows_console"):
15741
+ colorama.just_fix_windows_console()
15748
15742
  msg = msg.replace("❌", c1 + "><" + cr)
15749
15743
  print(msg)
15750
15744
  else:
@@ -15752,7 +15746,8 @@ class BaseCase(unittest.TestCase):
15752
15746
  if is_windows:
15753
15747
  c2 = colorama.Fore.GREEN + colorama.Back.LIGHTGREEN_EX
15754
15748
  cr = colorama.Style.RESET_ALL
15755
- colorama.init(autoreset=True)
15749
+ if hasattr(colorama, "just_fix_windows_console"):
15750
+ colorama.just_fix_windows_console()
15756
15751
  msg = msg.replace("✅", c2 + "<>" + cr)
15757
15752
  print(msg)
15758
15753
  if self.dashboard:
@@ -15808,6 +15803,11 @@ class BaseCase(unittest.TestCase):
15808
15803
  and sb_config._do_sb_post_mortem
15809
15804
  ):
15810
15805
  self.__activate_sb_mgr_post_mortem_debug_mode()
15806
+ elif (
15807
+ hasattr(sb_config, "_do_sb_final_trace")
15808
+ and sb_config._do_sb_final_trace
15809
+ ):
15810
+ self.__activate_debug_mode_in_teardown()
15811
15811
  # (Pynose / Behave / Pure Python) Close all open browser windows
15812
15812
  self.__quit_all_drivers()
15813
15813
  # Resume tearDown() for all test runners, (Pytest / Pynose / Behave)
@@ -346,6 +346,19 @@ class SeleniumWire:
346
346
  VER = "5.1.0"
347
347
 
348
348
 
349
+ class Mobile:
350
+ # Default values for mobile settings
351
+ WIDTH = 390
352
+ HEIGHT = 715
353
+ RATIO = 3
354
+ AGENT = (
355
+ "Mozilla/5.0 (Linux; Android 13; Pixel 7 XL "
356
+ "Build/SP2A.220505.006.A1; wv) "
357
+ "AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 "
358
+ "Chrome/110.0.5028.105 Mobile Safari/537.36"
359
+ )
360
+
361
+
349
362
  class ValidBrowsers:
350
363
  valid_browsers = [
351
364
  "chrome",
@@ -910,7 +910,7 @@ def post_messenger_success_message(driver, message, msg_dur=None):
910
910
  theme = "future"
911
911
  location = "bottom_right"
912
912
  if hasattr(sb_config, "mobile_emulator") and sb_config.mobile_emulator:
913
- location = "top_center"
913
+ location = "top_right"
914
914
  set_messenger_theme(driver, theme=theme, location=location)
915
915
  post_message(driver, message, msg_dur, style="success")
916
916
  time.sleep(msg_dur + 0.07)
@@ -1533,6 +1533,27 @@ def click_link(driver, link_text, timeout=settings.SMALL_TIMEOUT):
1533
1533
  element.click()
1534
1534
 
1535
1535
 
1536
+ def click_if_visible(
1537
+ driver, selector, by="css selector", timeout=0
1538
+ ):
1539
+ selector, by = page_utils.recalculate_selector(selector, by)
1540
+ if is_element_visible(driver, selector, by=by):
1541
+ click(driver, selector, by=by, timeout=1)
1542
+ elif timeout > 0:
1543
+ try:
1544
+ wait_for_element_visible(
1545
+ driver, selector, by=by, timeout=timeout
1546
+ )
1547
+ except Exception:
1548
+ pass
1549
+ if is_element_visible(driver, selector, by=by):
1550
+ click(driver, selector, by=by, timeout=1)
1551
+
1552
+
1553
+ def click_active_element(driver):
1554
+ driver.execute_script("document.activeElement.click();")
1555
+
1556
+
1536
1557
  def js_click(
1537
1558
  driver, selector, by="css selector", timeout=settings.SMALL_TIMEOUT
1538
1559
  ):
@@ -1611,6 +1632,15 @@ def submit(driver, selector, by="css selector"):
1611
1632
  element.submit()
1612
1633
 
1613
1634
 
1635
+ def has_attribute(
1636
+ driver, selector, attribute, value=None, by="css selector"
1637
+ ):
1638
+ selector, by = page_utils.recalculate_selector(selector, by)
1639
+ return is_attribute_present(
1640
+ driver, selector, attribute, value=value, by=by
1641
+ )
1642
+
1643
+
1614
1644
  def assert_element_visible(
1615
1645
  driver, selector, by="css selector", timeout=settings.SMALL_TIMEOUT
1616
1646
  ):
@@ -89,14 +89,14 @@ def Driver(
89
89
  uc_cdp_events=None, # Capture CDP events in undetected-chromedriver mode.
90
90
  uc_subprocess=None, # Use undetected-chromedriver as a subprocess.
91
91
  no_sandbox=None, # (DEPRECATED) - "--no-sandbox" is always used now.
92
- disable_gpu=None, # (DEPRECATED) - GPU is disabled if no "swiftshader".
92
+ disable_gpu=None, # (DEPRECATED) - GPU is disabled if not "swiftshader".
93
93
  incognito=None, # Enable Chromium's Incognito mode.
94
94
  guest_mode=None, # Enable Chromium's Guest mode.
95
95
  dark_mode=None, # Enable Chromium's Dark mode.
96
96
  devtools=None, # Open Chromium's DevTools when the browser opens.
97
97
  remote_debug=None, # Enable Chrome's Debugger on "http://localhost:9222".
98
98
  enable_3d_apis=None, # Enable WebGL and 3D APIs.
99
- swiftshader=None, # Use Chrome's "--use-gl=swiftshader" feature.
99
+ swiftshader=None, # Chrome: --use-gl=angle / --use-angle=swiftshader-webgl
100
100
  ad_block_on=None, # Block some types of display ads from loading.
101
101
  block_images=None, # Block images from loading during tests.
102
102
  do_not_track=None, # Tell websites that you don't want to be tracked.
@@ -341,9 +341,6 @@ def Driver(
341
341
  uc_cdp_events = True
342
342
  else:
343
343
  uc_cdp_events = False
344
- if undetectable and is_mobile:
345
- is_mobile = False
346
- user_agent = None
347
344
  if use_auto_ext is None:
348
345
  if "--use-auto-ext" in sys_argv:
349
346
  use_auto_ext = True
@@ -10,6 +10,7 @@ from seleniumbase.core import log_helper
10
10
  from seleniumbase.fixtures import constants
11
11
  from seleniumbase.fixtures import shared_utils
12
12
 
13
+ is_windows = shared_utils.is_windows()
13
14
  python3_11_or_newer = False
14
15
  if sys.version_info >= (3, 11):
15
16
  python3_11_or_newer = True
@@ -94,7 +95,7 @@ def pytest_addoption(parser):
94
95
  --dashboard (Enable the SeleniumBase Dashboard. Saved at: dashboard.html)
95
96
  --dash-title=STRING (Set the title shown for the generated dashboard.)
96
97
  --enable-3d-apis (Enables WebGL and 3D APIs.)
97
- --swiftshader (Use Chrome's "--use-gl=swiftshader" feature.)
98
+ --swiftshader (Chrome "--use-gl=angle" / "--use-angle=swiftshader-webgl")
98
99
  --incognito (Enable Chrome's Incognito mode.)
99
100
  --guest (Enable Chrome's Guest mode.)
100
101
  --dark (Enable Chrome's Dark mode.)
@@ -119,7 +120,10 @@ def pytest_addoption(parser):
119
120
  cr = ""
120
121
  if "linux" not in sys.platform:
121
122
  # This will be seen when typing "pytest --help" on the command line.
122
- colorama.init(autoreset=True)
123
+ if is_windows and hasattr(colorama, "just_fix_windows_console"):
124
+ colorama.just_fix_windows_console()
125
+ else:
126
+ colorama.init(autoreset=True)
123
127
  c1 = colorama.Fore.BLUE + colorama.Back.LIGHTCYAN_EX
124
128
  c2 = colorama.Fore.BLUE + colorama.Back.LIGHTGREEN_EX
125
129
  c3 = colorama.Fore.MAGENTA + colorama.Back.LIGHTYELLOW_EX
@@ -550,7 +554,7 @@ def pytest_addoption(parser):
550
554
  help="""Designates the three device metrics of the mobile
551
555
  emulator: CSS Width, CSS Height, and Pixel-Ratio.
552
556
  Format: A comma-separated string with the 3 values.
553
- Example: "375,734,3"
557
+ Examples: "375,734,5" or "411,731,3" or "390,715,3"
554
558
  Default: None. (Will use default values if None)""",
555
559
  )
556
560
  parser.addoption(
@@ -1395,10 +1399,6 @@ def pytest_addoption(parser):
1395
1399
  "\n If you need both, override get_new_driver() from BaseCase:"
1396
1400
  "\n https://seleniumbase.io/help_docs/syntax_formats/#sb_sf_09\n"
1397
1401
  )
1398
- if undetectable and "--mobile" in sys_argv:
1399
- raise Exception(
1400
- "\n SeleniumBase doesn't support mixing --uc with --mobile\n"
1401
- )
1402
1402
 
1403
1403
 
1404
1404
  def pytest_configure(config):
@@ -1817,7 +1817,10 @@ def pytest_collection_finish(session):
1817
1817
  c1 = ""
1818
1818
  cr = ""
1819
1819
  if "linux" not in sys.platform:
1820
- colorama.init(autoreset=True)
1820
+ if is_windows and hasattr(colorama, "just_fix_windows_console"):
1821
+ colorama.just_fix_windows_console()
1822
+ else:
1823
+ colorama.init(autoreset=True)
1821
1824
  c1 = colorama.Fore.BLUE + colorama.Back.LIGHTCYAN_EX
1822
1825
  cr = colorama.Style.RESET_ALL
1823
1826
  if sb_config._multithreaded:
@@ -1861,10 +1864,7 @@ def pytest_runtest_teardown(item):
1861
1864
  and self.driver
1862
1865
  and "--pdb" not in sys_argv
1863
1866
  ):
1864
- if not (
1865
- shared_utils.is_windows()
1866
- or self.driver.service.process
1867
- ):
1867
+ if not (is_windows or self.driver.service.process):
1868
1868
  self.driver.quit()
1869
1869
  except Exception:
1870
1870
  pass
@@ -1874,7 +1874,7 @@ def pytest_runtest_teardown(item):
1874
1874
  ):
1875
1875
  try:
1876
1876
  if (
1877
- not shared_utils.is_windows()
1877
+ not is_windows
1878
1878
  or sb_config._sb_pdb_driver.service.process
1879
1879
  ):
1880
1880
  sb_config._sb_pdb_driver.quit()
@@ -1992,7 +1992,7 @@ def _perform_pytest_unconfigure_():
1992
1992
  if sb_config.shared_driver:
1993
1993
  try:
1994
1994
  if (
1995
- not shared_utils.is_windows()
1995
+ not is_windows
1996
1996
  or sb_config.browser == "ie"
1997
1997
  or sb_config.shared_driver.service.process
1998
1998
  ):
@@ -60,7 +60,7 @@ def SB(
60
60
  devtools=None, # Open Chromium's DevTools when the browser opens.
61
61
  remote_debug=None, # Enable Chrome's Debugger on "http://localhost:9222".
62
62
  enable_3d_apis=None, # Enable WebGL and 3D APIs.
63
- swiftshader=None, # Use Chrome's "--use-gl=swiftshader" feature.
63
+ swiftshader=None, # Chrome: --use-gl=angle / --use-angle=swiftshader-webgl
64
64
  ad_block_on=None, # Block some types of display ads from loading.
65
65
  block_images=None, # Block images from loading during tests.
66
66
  do_not_track=None, # Tell websites that you don't want to be tracked.
@@ -127,6 +127,7 @@ def SB(
127
127
 
128
128
  sb_config_backup = sb_config
129
129
  sb_config._do_sb_post_mortem = False
130
+ is_windows = shared_utils.is_windows()
130
131
  sys_argv = sys.argv
131
132
  archive_logs = False
132
133
  existing_runner = False
@@ -307,6 +308,8 @@ def SB(
307
308
  is_mobile = True
308
309
  else:
309
310
  is_mobile = False
311
+ if is_mobile:
312
+ sb_config.mobile_emulator = True
310
313
  proxy_string = proxy
311
314
  user_agent = agent
312
315
  recorder_mode = False
@@ -369,7 +372,6 @@ def SB(
369
372
  sb_config.proxy_driver = True
370
373
  if variables and type(variables) is str and len(variables) > 0:
371
374
  import ast
372
-
373
375
  bad_input = False
374
376
  if (
375
377
  not variables.startswith("{")
@@ -457,9 +459,6 @@ def SB(
457
459
  uc_cdp_events = True
458
460
  else:
459
461
  uc_cdp_events = False
460
- if undetectable and is_mobile:
461
- is_mobile = False
462
- user_agent = None
463
462
  if use_auto_ext is None:
464
463
  if "--use-auto-ext" in sys_argv:
465
464
  use_auto_ext = True
@@ -799,7 +798,7 @@ def SB(
799
798
  sb.proxy_pac_url = sb_config.proxy_pac_url
800
799
  sb.multi_proxy = sb_config.multi_proxy
801
800
  sb.enable_3d_apis = sb_config.enable_3d_apis
802
- sb.swiftshader = sb_config.swiftshader
801
+ sb._swiftshader = sb_config.swiftshader
803
802
  sb.ad_block_on = sb_config.ad_block_on
804
803
  sb.highlights = sb_config.highlights
805
804
  sb.interval = sb_config.interval
@@ -814,8 +813,10 @@ def SB(
814
813
  terminal_width = shared_utils.get_terminal_width()
815
814
  if test:
816
815
  import colorama
817
-
818
- colorama.init(autoreset=True)
816
+ if is_windows and hasattr(colorama, "just_fix_windows_console"):
817
+ colorama.just_fix_windows_console()
818
+ else:
819
+ colorama.init(autoreset=True)
819
820
  c1 = colorama.Fore.GREEN
820
821
  b1 = colorama.Style.BRIGHT
821
822
  cr = colorama.Style.RESET_ALL
@@ -872,6 +873,13 @@ def SB(
872
873
  finally:
873
874
  if sb._has_failure and "--pdb" in sys_argv:
874
875
  sb_config._do_sb_post_mortem = True
876
+ elif (
877
+ "--final-debug" in sys_argv
878
+ or "--final-trace" in sys_argv
879
+ or "--fdebug" in sys_argv
880
+ or "--ftrace" in sys_argv
881
+ ):
882
+ sb_config._do_sb_final_trace = True
875
883
  try:
876
884
  sb.tearDown()
877
885
  except Exception as t_e:
@@ -71,7 +71,7 @@ class SeleniumBrowser(Plugin):
71
71
  --uc-cdp-events (Capture CDP events when running in "--undetected" mode.)
72
72
  --remote-debug (Sync to Chrome Remote Debugger chrome://inspect/#devices)
73
73
  --enable-3d-apis (Enables WebGL and 3D APIs.)
74
- --swiftshader (Use Chrome's "--use-gl=swiftshader" feature.)
74
+ --swiftshader (Chrome "--use-gl=angle" / "--use-angle=swiftshader-webgl")
75
75
  --incognito (Enable Chrome's Incognito mode.)
76
76
  --guest (Enable Chrome's Guest mode.)
77
77
  --dark (Enable Chrome's Dark mode.)
@@ -296,7 +296,7 @@ class SeleniumBrowser(Plugin):
296
296
  help="""Designates the three device metrics of the mobile
297
297
  emulator: CSS Width, CSS Height, and Pixel-Ratio.
298
298
  Format: A comma-separated string with the 3 values.
299
- Example: "375,734,3"
299
+ Examples: "375,734,5" or "411,731,3" or "390,715,3"
300
300
  Default: None. (Will use default values if None)""",
301
301
  )
302
302
  parser.addoption(
@@ -1112,7 +1112,7 @@ class SeleniumBrowser(Plugin):
1112
1112
  test.test.disable_gpu = self.options.disable_gpu
1113
1113
  test.test.remote_debug = self.options.remote_debug
1114
1114
  test.test.enable_3d_apis = self.options.enable_3d_apis
1115
- test.test.swiftshader = self.options.swiftshader
1115
+ test.test._swiftshader = self.options.swiftshader
1116
1116
  test.test.incognito = self.options.incognito
1117
1117
  test.test.guest_mode = self.options.guest_mode
1118
1118
  test.test.dark_mode = self.options.dark_mode
@@ -1163,16 +1163,6 @@ class SeleniumBrowser(Plugin):
1163
1163
  )
1164
1164
  self.options.use_wire = False
1165
1165
  test.test.use_wire = False
1166
- if self.options.mobile_emulator and self.options.undetectable:
1167
- print(
1168
- "\n"
1169
- "SeleniumBase doesn't support mixing --uc with --mobile.\n"
1170
- "(Only UC Mode without Mobile will be used for this run)\n"
1171
- )
1172
- self.options.mobile_emulator = False
1173
- test.test.mobile_emulator = False
1174
- self.options.user_agent = None
1175
- test.test.user_agent = None
1176
1166
  # Recorder Mode can still optimize scripts in --headless2 mode.
1177
1167
  if self.options.recorder_mode and self.options.headless:
1178
1168
  self.options.headless = False
@@ -1205,6 +1195,7 @@ class SeleniumBrowser(Plugin):
1205
1195
  sb_config._SMALL_TIMEOUT = settings.SMALL_TIMEOUT
1206
1196
  sb_config._LARGE_TIMEOUT = settings.LARGE_TIMEOUT
1207
1197
  sb_config._context_of_runner = False # Context Manager Compatibility
1198
+ sb_config.mobile_emulator = self.options.mobile_emulator
1208
1199
  sb_config.proxy_driver = self.options.proxy_driver
1209
1200
  sb_config.multi_proxy = self.options.multi_proxy
1210
1201
  # The driver will be received later
@@ -267,7 +267,13 @@ def process_test_file(code_lines, new_lang):
267
267
 
268
268
 
269
269
  def main():
270
- colorama.init(autoreset=True)
270
+ if (
271
+ "win32" in sys.platform
272
+ and hasattr(colorama, "just_fix_windows_console")
273
+ ):
274
+ colorama.just_fix_windows_console()
275
+ else:
276
+ colorama.init(autoreset=True)
271
277
  c1 = colorama.Fore.BLUE + colorama.Back.LIGHTCYAN_EX
272
278
  c2 = colorama.Fore.BLUE + colorama.Back.LIGHTYELLOW_EX
273
279
  c3 = colorama.Fore.RED + colorama.Back.LIGHTGREEN_EX
@@ -2,6 +2,7 @@
2
2
  import logging
3
3
  import os
4
4
  import re
5
+ import requests
5
6
  import subprocess
6
7
  import sys
7
8
  import time
@@ -138,8 +139,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
138
139
  options._session = self
139
140
  debug_host = "127.0.0.1"
140
141
  debug_port = 9222
141
- import requests
142
-
143
142
  special_port_free = False # If the port isn't free, don't use 9222
144
143
  try:
145
144
  res = requests.get("http://127.0.0.1:9222", timeout=1)
@@ -151,7 +150,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
151
150
  sys_argv = sys.argv
152
151
  arg_join = " ".join(sys_argv)
153
152
  from seleniumbase import config as sb_config
154
-
155
153
  if (
156
154
  (("-n" in sys.argv) or (" -n=" in arg_join) or ("-c" in sys.argv))
157
155
  or (hasattr(sb_config, "multi_proxy") and sb_config.multi_proxy)
@@ -197,7 +195,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
197
195
  keep_user_data_dir = True
198
196
  else:
199
197
  import tempfile
200
-
201
198
  user_data_dir = os.path.normpath(tempfile.mkdtemp())
202
199
  keep_user_data_dir = False
203
200
  arg = "--user-data-dir=%s" % user_data_dir
@@ -206,7 +203,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
206
203
  if not language:
207
204
  try:
208
205
  import locale
209
-
210
206
  language = locale.getlocale()[0].replace("_", "-")
211
207
  except Exception:
212
208
  pass
@@ -241,7 +237,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
241
237
  options.handle_prefs(user_data_dir)
242
238
  try:
243
239
  import json
244
-
245
240
  with open(
246
241
  os.path.join(
247
242
  os.path.abspath(user_data_dir),
@@ -286,19 +281,22 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
286
281
  )
287
282
  self.browser_pid = browser.pid
288
283
  service_ = None
284
+ log_output = subprocess.PIPE
285
+ if sys.version_info < (3, 8):
286
+ log_output = os.devnull
289
287
  if patch_driver:
290
288
  service_ = selenium.webdriver.chrome.service.Service(
291
289
  executable_path=self.patcher.executable_path,
292
290
  service_args=["--disable-build-check"],
293
291
  port=port,
294
- log_output=os.devnull,
292
+ log_output=log_output,
295
293
  )
296
294
  else:
297
295
  service_ = selenium.webdriver.chrome.service.Service(
298
296
  executable_path=driver_executable_path,
299
297
  service_args=["--disable-build-check"],
300
298
  port=port,
301
- log_output=os.devnull,
299
+ log_output=log_output,
302
300
  )
303
301
  if hasattr(service_, "creationflags"):
304
302
  setattr(service_, "creationflags", creationflags)
@@ -321,7 +319,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
321
319
  return super().__getattribute__(item)
322
320
  else:
323
321
  import inspect
324
-
325
322
  original = super().__getattribute__(item)
326
323
  if inspect.ismethod(original) and not inspect.isclass(original):
327
324
  def newfunc(*args, **kwargs):
@@ -455,7 +452,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
455
452
  and not self.keep_user_data_dir
456
453
  ):
457
454
  import shutil
458
-
459
455
  for _ in range(5):
460
456
  try:
461
457
  shutil.rmtree(self.user_data_dir, ignore_errors=False)
@@ -506,7 +502,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
506
502
 
507
503
  def find_chrome_executable():
508
504
  from seleniumbase.core import detect_b_ver
509
-
510
505
  binary_location = detect_b_ver.get_binary_location("google-chrome", True)
511
506
  if os.path.exists(binary_location) and os.access(binary_location, os.X_OK):
512
507
  return os.path.normpath(binary_location)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: seleniumbase
3
- Version: 4.19.1
3
+ Version: 4.20.0
4
4
  Summary: A complete web automation framework for end-to-end testing.
5
5
  Home-page: https://github.com/seleniumbase/SeleniumBase
6
6
  Author: Michael Mintz
@@ -60,7 +60,7 @@ Requires-Dist: packaging >=23.2
60
60
  Requires-Dist: wheel >=0.41.2
61
61
  Requires-Dist: attrs >=23.1.0
62
62
  Requires-Dist: certifi >=2023.7.22
63
- Requires-Dist: platformdirs >=3.10.0
63
+ Requires-Dist: platformdirs >=3.11.0
64
64
  Requires-Dist: parse >=1.19.1
65
65
  Requires-Dist: parse-type >=0.6.2
66
66
  Requires-Dist: six ==1.16.0
@@ -110,7 +110,7 @@ Requires-Dist: markdown-it-py ==2.2.0 ; python_version < "3.8"
110
110
  Requires-Dist: urllib3 <2.1.0,>=1.26.16 ; python_version >= "3.10"
111
111
  Requires-Dist: setuptools >=68.2.2 ; python_version >= "3.8"
112
112
  Requires-Dist: filelock >=3.12.4 ; python_version >= "3.8"
113
- Requires-Dist: selenium ==4.13.0 ; python_version >= "3.8"
113
+ Requires-Dist: selenium ==4.14.0 ; python_version >= "3.8"
114
114
  Requires-Dist: pluggy ==1.3.0 ; python_version >= "3.8"
115
115
  Requires-Dist: soupsieve ==2.5 ; python_version >= "3.8"
116
116
  Requires-Dist: markdown-it-py ==3.0.0 ; python_version >= "3.8"
@@ -121,7 +121,7 @@ Requires-Dist: allure-behave ==2.13.2 ; extra == 'allure'
121
121
  Provides-Extra: coverage
122
122
  Requires-Dist: pytest-cov ==4.1.0 ; extra == 'coverage'
123
123
  Requires-Dist: coverage ==7.2.7 ; (python_version < "3.8") and extra == 'coverage'
124
- Requires-Dist: coverage ==7.3.1 ; (python_version >= "3.8") and extra == 'coverage'
124
+ Requires-Dist: coverage ==7.3.2 ; (python_version >= "3.8") and extra == 'coverage'
125
125
  Provides-Extra: flake8
126
126
  Requires-Dist: mccabe ==0.7.0 ; extra == 'flake8'
127
127
  Requires-Dist: flake8 ==5.0.4 ; (python_version < "3.9") and extra == 'flake8'
@@ -850,7 +850,7 @@ pytest test_coffee_cart.py --trace
850
850
  --dashboard # (Enable the SeleniumBase Dashboard. Saved at: dashboard.html)
851
851
  --dash-title=STRING # (Set the title shown for the generated dashboard.)
852
852
  --enable-3d-apis # (Enables WebGL and 3D APIs.)
853
- --swiftshader # (Use Chrome's "--use-gl=swiftshader" feature.)
853
+ --swiftshader # (Chrome "--use-gl=angle" / "--use-angle=swiftshader-webgl")
854
854
  --incognito # (Enable Chrome's Incognito mode.)
855
855
  --guest # (Enable Chrome's Guest mode.)
856
856
  --dark # (Enable Chrome's Dark mode.)