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,9 +1,11 @@
1
- #!/usr/bin/env python3
2
1
  import os
3
2
  import sys
4
3
  import atexit
5
4
  import logging
5
+ import platform
6
+ from contextlib import suppress
6
7
  from subprocess import PIPE
8
+ from subprocess import Popen
7
9
 
8
10
  CREATE_NEW_PROCESS_GROUP = 0x00000200
9
11
  DETACHED_PROCESS = 0x00000008
@@ -37,9 +39,6 @@ def start_detached(executable, *args):
37
39
  def _start_detached(executable, *args, writer=None):
38
40
  # Configure Launch
39
41
  kwargs = {}
40
- import platform
41
- from subprocess import Popen
42
-
43
42
  if platform.system() == "Windows":
44
43
  kwargs.update(
45
44
  creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP
@@ -58,11 +57,9 @@ def _cleanup():
58
57
  import signal
59
58
 
60
59
  for pid in REGISTERED:
61
- try:
60
+ with suppress(Exception):
62
61
  logging.getLogger(__name__).debug("cleaning up pid %d " % pid)
63
62
  os.kill(pid, signal.SIGTERM)
64
- except Exception:
65
- pass
66
63
 
67
64
 
68
65
  atexit.register(_cleanup)
@@ -1,6 +1,6 @@
1
- #!/usr/bin/env python3
2
1
  import json
3
2
  import os
3
+ from contextlib import suppress
4
4
  from selenium.webdriver.chromium.options import ChromiumOptions
5
5
 
6
6
 
@@ -49,7 +49,7 @@ class ChromeOptions(ChromiumOptions):
49
49
  undot_prefs, self._undot_key(key, value)
50
50
  )
51
51
  prefs_file = os.path.join(default_path, "Preferences")
52
- try:
52
+ with suppress(Exception):
53
53
  if os.path.exists(prefs_file):
54
54
  with open(
55
55
  prefs_file, encoding="utf-8", mode="r", errors="ignore"
@@ -57,13 +57,11 @@ class ChromeOptions(ChromiumOptions):
57
57
  undot_prefs = self._merge_nested(
58
58
  json.load(f), undot_prefs
59
59
  )
60
- except Exception:
61
- pass
62
- try:
63
- with open(prefs_file, encoding="utf-8", mode="w") as f:
60
+ with suppress(Exception):
61
+ with open(
62
+ prefs_file, encoding="utf-8", mode="w", errors="ignore"
63
+ ) as f:
64
64
  json.dump(undot_prefs, f)
65
- except Exception:
66
- pass
67
65
  # Remove experimental_options to avoid errors
68
66
  del self._experimental_options["prefs"]
69
67
  exclude_switches = self.experimental_options.get("excludeSwitches")
@@ -1,4 +1,3 @@
1
- #!/usr/bin/env python3
2
1
  import io
3
2
  import logging
4
3
  import os
@@ -8,6 +7,7 @@ import string
8
7
  import sys
9
8
  import time
10
9
  import zipfile
10
+ from contextlib import suppress
11
11
 
12
12
  logger = logging.getLogger(__name__)
13
13
  IS_POSIX = sys.platform.startswith(("darwin", "cygwin", "linux"))
@@ -53,10 +53,8 @@ class Patcher(object):
53
53
  self.executable_path = None
54
54
  prefix = "undetected"
55
55
  if not os.path.exists(self.data_path):
56
- try:
56
+ with suppress(Exception):
57
57
  os.makedirs(self.data_path, exist_ok=True)
58
- except Exception:
59
- pass
60
58
  if not executable_path:
61
59
  self.executable_path = os.path.join(
62
60
  self.data_path, "_".join([prefix, self.exe_name])
@@ -166,9 +164,9 @@ class Patcher(object):
166
164
 
167
165
  @staticmethod
168
166
  def force_kill_instances(exe_name):
169
- """ Terminate instances of UC.
170
- :param: executable name to kill, may be a path as well
171
- :return: True on success else False """
167
+ """Terminate instances of UC.
168
+ :param: Executable name to kill. (Can be a path)
169
+ :return: True on success else False."""
172
170
  exe_name = os.path.basename(exe_name)
173
171
  if IS_POSIX:
174
172
  r = os.system("kill -f -9 $(pidof %s)" % exe_name)
@@ -189,7 +187,7 @@ class Patcher(object):
189
187
  with io.open(executable_path, "rb") as fh:
190
188
  if re.search(
191
189
  b"window.cdc_adoQpoasnfa76pfcZLmcfl_"
192
- b"(Array|Promise|Symbol|Object|Proxy|JSON)",
190
+ b"(Array|Promise|Symbol|Object|Proxy|JSON|Window)",
193
191
  fh.read()
194
192
  ):
195
193
  return False
@@ -212,14 +210,14 @@ class Patcher(object):
212
210
  file_bin = fh.read()
213
211
  file_bin = re.sub(
214
212
  b"window\\.cdc_[a-zA-Z0-9]{22}_"
215
- b"(Array|Promise|Symbol|Object|Proxy|JSON)"
216
- b" = window\\.(Array|Promise|Symbol|Object|Proxy|JSON);",
213
+ b"(Array|Promise|Symbol|Object|Proxy|JSON|Window) "
214
+ b"= window\\.(Array|Promise|Symbol|Object|Proxy|JSON|Window);",
217
215
  gen_js_whitespaces,
218
216
  file_bin,
219
217
  )
220
218
  file_bin = re.sub(
221
219
  b"window\\.cdc_[a-zA-Z0-9]{22}_"
222
- b"(Array|Promise|Symbol|Object|Proxy|JSON) \\|\\|",
220
+ b"(Array|Promise|Symbol|Object|Proxy|JSON|Window) \\|\\|",
223
221
  gen_js_whitespaces,
224
222
  file_bin,
225
223
  )
@@ -275,8 +273,8 @@ class Patcher(object):
275
273
 
276
274
  def __del__(self):
277
275
  if self._custom_exe_path:
278
- # if the driver binary is specified by user
279
- # we assume it is important enough to not delete it
276
+ # If the driver binary is specified by the user,
277
+ # then assume it is important enough to keep it.
280
278
  return
281
279
  else:
282
280
  timeout = 3
@@ -1,4 +1,3 @@
1
- #!/usr/bin/env python3
2
1
  import asyncio
3
2
  import json
4
3
  import logging
@@ -1,4 +1,6 @@
1
+ import re
1
2
  import selenium.webdriver.remote.webelement
3
+ from seleniumbase.fixtures import js_utils
2
4
 
3
5
 
4
6
  class WebElement(selenium.webdriver.remote.webelement.WebElement):
@@ -8,18 +10,29 @@ class WebElement(selenium.webdriver.remote.webelement.WebElement):
8
10
  selector=None,
9
11
  by=None,
10
12
  reconnect_time=None,
13
+ tag_name=None,
11
14
  ):
12
15
  if driver and selector and by:
13
- driver.js_click(selector, by=by, timeout=1)
16
+ delayed_click = False
17
+ if tag_name in ["span", "button", "div", "a", "b", "input"]:
18
+ delayed_click = True
19
+ if delayed_click and ":contains" not in selector:
20
+ selector = js_utils.convert_to_css_selector(selector, by)
21
+ selector = re.escape(selector)
22
+ selector = js_utils.escape_quotes_if_needed(selector)
23
+ script = 'document.querySelector("%s").click();' % selector
24
+ js_utils.call_me_later(driver, script, 111)
25
+ else:
26
+ driver.js_click(selector, by=by, timeout=1)
14
27
  else:
15
28
  super().click()
16
29
  if not reconnect_time:
17
- self._parent.reconnect(0.45)
30
+ self._parent.reconnect(0.5)
18
31
  else:
19
32
  self._parent.reconnect(reconnect_time)
20
33
 
21
34
  def uc_reconnect(self, reconnect_time=None):
22
35
  if not reconnect_time:
23
- self._parent.reconnect(0.1)
36
+ self._parent.reconnect(0.2)
24
37
  else:
25
38
  self._parent.reconnect(reconnect_time)
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2014-2024 Michael Mintz
3
+ Copyright (c) 2014-2025 Michael Mintz
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal