seleniumbase 4.24.10__py3-none-any.whl → 4.33.15__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- sbase/__init__.py +1 -0
- sbase/steps.py +7 -0
- seleniumbase/__init__.py +16 -7
- seleniumbase/__version__.py +1 -1
- seleniumbase/behave/behave_sb.py +97 -32
- seleniumbase/common/decorators.py +16 -7
- seleniumbase/config/proxy_list.py +3 -3
- seleniumbase/config/settings.py +4 -0
- seleniumbase/console_scripts/logo_helper.py +47 -8
- seleniumbase/console_scripts/run.py +345 -335
- seleniumbase/console_scripts/sb_behave_gui.py +5 -12
- seleniumbase/console_scripts/sb_caseplans.py +6 -13
- seleniumbase/console_scripts/sb_commander.py +5 -12
- seleniumbase/console_scripts/sb_install.py +62 -54
- seleniumbase/console_scripts/sb_mkchart.py +13 -20
- seleniumbase/console_scripts/sb_mkdir.py +11 -17
- seleniumbase/console_scripts/sb_mkfile.py +69 -43
- seleniumbase/console_scripts/sb_mkpres.py +13 -20
- seleniumbase/console_scripts/sb_mkrec.py +88 -21
- seleniumbase/console_scripts/sb_objectify.py +30 -30
- seleniumbase/console_scripts/sb_print.py +5 -12
- seleniumbase/console_scripts/sb_recorder.py +16 -11
- seleniumbase/core/browser_launcher.py +1658 -221
- seleniumbase/core/detect_b_ver.py +7 -8
- seleniumbase/core/log_helper.py +42 -27
- seleniumbase/core/mysql.py +1 -4
- seleniumbase/core/proxy_helper.py +35 -30
- seleniumbase/core/recorder_helper.py +24 -5
- seleniumbase/core/sb_cdp.py +1951 -0
- seleniumbase/core/sb_driver.py +162 -8
- seleniumbase/core/settings_parser.py +6 -0
- seleniumbase/core/style_sheet.py +10 -0
- seleniumbase/extensions/recorder.zip +0 -0
- seleniumbase/fixtures/base_case.py +1234 -632
- seleniumbase/fixtures/constants.py +10 -1
- seleniumbase/fixtures/js_utils.py +171 -144
- seleniumbase/fixtures/page_actions.py +177 -13
- seleniumbase/fixtures/page_utils.py +25 -53
- seleniumbase/fixtures/shared_utils.py +97 -11
- seleniumbase/js_code/active_css_js.py +1 -1
- seleniumbase/js_code/recorder_js.py +1 -1
- seleniumbase/plugins/base_plugin.py +2 -3
- seleniumbase/plugins/driver_manager.py +340 -65
- seleniumbase/plugins/pytest_plugin.py +276 -47
- seleniumbase/plugins/sb_manager.py +412 -99
- seleniumbase/plugins/selenium_plugin.py +122 -17
- seleniumbase/translate/translator.py +0 -7
- seleniumbase/undetected/__init__.py +59 -52
- seleniumbase/undetected/cdp.py +0 -1
- seleniumbase/undetected/cdp_driver/__init__.py +1 -0
- seleniumbase/undetected/cdp_driver/_contradict.py +110 -0
- seleniumbase/undetected/cdp_driver/browser.py +829 -0
- seleniumbase/undetected/cdp_driver/cdp_util.py +458 -0
- seleniumbase/undetected/cdp_driver/config.py +334 -0
- seleniumbase/undetected/cdp_driver/connection.py +639 -0
- seleniumbase/undetected/cdp_driver/element.py +1168 -0
- seleniumbase/undetected/cdp_driver/tab.py +1323 -0
- seleniumbase/undetected/dprocess.py +4 -7
- seleniumbase/undetected/options.py +6 -8
- seleniumbase/undetected/patcher.py +11 -13
- seleniumbase/undetected/reactor.py +0 -1
- seleniumbase/undetected/webelement.py +16 -3
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/LICENSE +1 -1
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/METADATA +299 -252
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/RECORD +68 -70
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/WHEEL +1 -1
- sbase/ReadMe.txt +0 -2
- seleniumbase/ReadMe.md +0 -25
- seleniumbase/common/ReadMe.md +0 -71
- seleniumbase/console_scripts/ReadMe.md +0 -731
- seleniumbase/drivers/ReadMe.md +0 -27
- seleniumbase/extensions/ReadMe.md +0 -12
- seleniumbase/masterqa/ReadMe.md +0 -61
- seleniumbase/resources/ReadMe.md +0 -31
- seleniumbase/resources/favicon.ico +0 -0
- seleniumbase/utilities/selenium_grid/ReadMe.md +0 -84
- seleniumbase/utilities/selenium_ide/ReadMe.md +0 -111
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/entry_points.txt +0 -0
- {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
|
-
|
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
|
-
|
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
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
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
|
-
|
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
|
-
"""
|
170
|
-
:param:
|
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"
|
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
|
-
#
|
279
|
-
#
|
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,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
|
-
|
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.
|
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.
|
36
|
+
self._parent.reconnect(0.2)
|
24
37
|
else:
|
25
38
|
self._parent.reconnect(reconnect_time)
|