seleniumbase 4.15.14__py3-none-any.whl → 4.16.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.
- sbase/__init__.py +1 -0
- seleniumbase/__init__.py +1 -0
- seleniumbase/__version__.py +1 -1
- seleniumbase/behave/behave_sb.py +12 -19
- seleniumbase/common/exceptions.py +5 -0
- seleniumbase/config/settings.py +7 -0
- seleniumbase/console_scripts/ReadMe.md +2 -2
- seleniumbase/console_scripts/run.py +5 -4
- seleniumbase/console_scripts/sb_behave_gui.py +6 -9
- seleniumbase/console_scripts/sb_caseplans.py +2 -5
- seleniumbase/console_scripts/sb_commander.py +5 -8
- seleniumbase/console_scripts/sb_install.py +43 -54
- seleniumbase/console_scripts/sb_mkchart.py +12 -7
- seleniumbase/console_scripts/sb_mkfile.py +1 -2
- seleniumbase/console_scripts/sb_mkpres.py +6 -1
- seleniumbase/console_scripts/sb_print.py +2 -0
- seleniumbase/console_scripts/sb_recorder.py +3 -2
- seleniumbase/core/browser_launcher.py +13 -27
- seleniumbase/core/capabilities_parser.py +2 -3
- seleniumbase/core/detect_b_ver.py +3 -4
- seleniumbase/core/jqc_helper.py +2 -4
- seleniumbase/core/mysql.py +1 -1
- seleniumbase/core/proxy_helper.py +65 -0
- seleniumbase/core/recorder_helper.py +1 -1
- seleniumbase/core/s3_manager.py +29 -23
- seleniumbase/core/session_helper.py +2 -6
- seleniumbase/core/settings_parser.py +2 -0
- seleniumbase/fixtures/base_case.py +31 -13
- seleniumbase/fixtures/constants.py +1 -1
- seleniumbase/fixtures/css_to_xpath.py +1 -2
- seleniumbase/fixtures/errors.py +2 -7
- seleniumbase/fixtures/js_utils.py +8 -16
- seleniumbase/fixtures/page_actions.py +3 -6
- seleniumbase/fixtures/page_utils.py +1 -1
- seleniumbase/fixtures/shared_utils.py +26 -79
- seleniumbase/fixtures/xpath_to_css.py +1 -3
- seleniumbase/plugins/base_plugin.py +1 -1
- seleniumbase/plugins/basic_test_info.py +1 -1
- seleniumbase/plugins/db_reporting_plugin.py +2 -2
- seleniumbase/plugins/driver_manager.py +2 -1
- seleniumbase/plugins/page_source.py +2 -4
- seleniumbase/plugins/pytest_plugin.py +9 -8
- seleniumbase/plugins/s3_logging_plugin.py +20 -9
- seleniumbase/plugins/sb_manager.py +2 -2
- seleniumbase/plugins/screen_shots.py +2 -2
- seleniumbase/plugins/selenium_plugin.py +5 -8
- seleniumbase/translate/translator.py +397 -396
- seleniumbase/undetected/__init__.py +17 -37
- seleniumbase/utilities/selenium_grid/grid_hub.py +2 -1
- seleniumbase/utilities/selenium_grid/grid_node.py +2 -1
- {seleniumbase-4.15.14.dist-info → seleniumbase-4.16.0.dist-info}/METADATA +8 -8
- {seleniumbase-4.15.14.dist-info → seleniumbase-4.16.0.dist-info}/RECORD +56 -56
- {seleniumbase-4.15.14.dist-info → seleniumbase-4.16.0.dist-info}/LICENSE +0 -0
- {seleniumbase-4.15.14.dist-info → seleniumbase-4.16.0.dist-info}/WHEEL +0 -0
- {seleniumbase-4.15.14.dist-info → seleniumbase-4.16.0.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.15.14.dist-info → seleniumbase-4.16.0.dist-info}/top_level.txt +0 -0
@@ -1,12 +1,10 @@
|
|
1
|
-
"""
|
2
|
-
This module contains a set of methods that can be used for page loads and
|
3
|
-
for waiting for elements to appear on a page.
|
1
|
+
"""This module contains useful methods for waiting on elements to load.
|
4
2
|
|
5
|
-
These methods improve
|
3
|
+
These methods improve and expand on existing WebDriver commands.
|
6
4
|
Improvements include making WebDriver commands more robust and more reliable
|
7
5
|
by giving page elements enough time to load before taking action on them.
|
8
6
|
|
9
|
-
The default option for searching for elements is by
|
7
|
+
The default option for searching for elements is by "css selector".
|
10
8
|
This can be changed by overriding the "By" parameter from this import:
|
11
9
|
> from selenium.webdriver.common.by import By
|
12
10
|
Options are:
|
@@ -19,7 +17,6 @@ By.XPATH # "xpath"
|
|
19
17
|
By.TAG_NAME # "tag name"
|
20
18
|
By.PARTIAL_LINK_TEXT # "partial link text"
|
21
19
|
"""
|
22
|
-
|
23
20
|
import codecs
|
24
21
|
import os
|
25
22
|
import time
|
@@ -1,13 +1,15 @@
|
|
1
|
-
"""Shared utility methods
|
2
|
-
import
|
1
|
+
"""Shared utility methods"""
|
2
|
+
import os
|
3
|
+
import platform
|
3
4
|
import sys
|
4
|
-
|
5
|
-
from seleniumbase.fixtures import constants
|
5
|
+
import time
|
6
6
|
from seleniumbase import config as sb_config
|
7
|
+
from seleniumbase.fixtures import constants
|
7
8
|
|
8
9
|
|
9
10
|
def pip_install(package, version=None):
|
10
11
|
import fasteners
|
12
|
+
import subprocess
|
11
13
|
|
12
14
|
pip_install_lock = fasteners.InterProcessLock(
|
13
15
|
constants.PipInstall.LOCKFILE
|
@@ -24,17 +26,30 @@ def pip_install(package, version=None):
|
|
24
26
|
)
|
25
27
|
|
26
28
|
|
29
|
+
def is_arm_mac():
|
30
|
+
"""(M1 / M2 Macs use the ARM processor)"""
|
31
|
+
return (
|
32
|
+
"darwin" in sys.platform
|
33
|
+
and (
|
34
|
+
"arm" in platform.processor().lower()
|
35
|
+
or "arm64" in platform.version().lower()
|
36
|
+
)
|
37
|
+
)
|
38
|
+
|
39
|
+
|
40
|
+
def is_mac():
|
41
|
+
return "darwin" in sys.platform
|
42
|
+
|
43
|
+
|
44
|
+
def is_linux():
|
45
|
+
return "linux" in sys.platform
|
46
|
+
|
47
|
+
|
27
48
|
def is_windows():
|
28
|
-
|
29
|
-
if "win32" in platform or "win64" in platform or "x64" in platform:
|
30
|
-
return True
|
31
|
-
else:
|
32
|
-
return False
|
49
|
+
return "win32" in sys.platform
|
33
50
|
|
34
51
|
|
35
52
|
def get_terminal_width():
|
36
|
-
import os
|
37
|
-
|
38
53
|
width = 80 # default
|
39
54
|
try:
|
40
55
|
width = os.get_terminal_size().columns
|
@@ -48,72 +63,6 @@ def get_terminal_width():
|
|
48
63
|
return width
|
49
64
|
|
50
65
|
|
51
|
-
def display_proxy_warning(proxy_string):
|
52
|
-
import warnings
|
53
|
-
|
54
|
-
message = (
|
55
|
-
'\nWARNING: Proxy String ["%s"] is NOT in the expected '
|
56
|
-
'"ip_address:port" or "server:port" format, '
|
57
|
-
"(OR the key does not exist in "
|
58
|
-
"seleniumbase.config.proxy_list.PROXY_LIST)." % proxy_string
|
59
|
-
)
|
60
|
-
if settings.RAISE_INVALID_PROXY_STRING_EXCEPTION:
|
61
|
-
raise Exception(message)
|
62
|
-
else:
|
63
|
-
message += " *** DEFAULTING to NOT USING a Proxy Server! ***"
|
64
|
-
warnings.simplefilter("always", Warning) # See Warnings
|
65
|
-
warnings.warn(message, category=Warning, stacklevel=2)
|
66
|
-
warnings.simplefilter("default", Warning) # Set Default
|
67
|
-
|
68
|
-
|
69
|
-
def validate_proxy_string(proxy_string):
|
70
|
-
import re
|
71
|
-
from seleniumbase.config import proxy_list
|
72
|
-
from seleniumbase.fixtures import page_utils
|
73
|
-
|
74
|
-
if proxy_string in proxy_list.PROXY_LIST.keys():
|
75
|
-
proxy_string = proxy_list.PROXY_LIST[proxy_string]
|
76
|
-
if not proxy_string:
|
77
|
-
return None
|
78
|
-
valid = False
|
79
|
-
val_ip = re.match(
|
80
|
-
r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$", proxy_string
|
81
|
-
)
|
82
|
-
if not val_ip:
|
83
|
-
if proxy_string.startswith("http://"):
|
84
|
-
proxy_string = proxy_string.split("http://")[1]
|
85
|
-
elif proxy_string.startswith("https://"):
|
86
|
-
proxy_string = proxy_string.split("https://")[1]
|
87
|
-
elif "://" in proxy_string:
|
88
|
-
if not proxy_string.startswith("socks4://") and not (
|
89
|
-
proxy_string.startswith("socks5://")
|
90
|
-
):
|
91
|
-
proxy_string = proxy_string.split("://")[1]
|
92
|
-
chunks = proxy_string.split(":")
|
93
|
-
if len(chunks) == 2:
|
94
|
-
if re.match(r"^\d+$", chunks[1]):
|
95
|
-
if page_utils.is_valid_url("http://" + proxy_string):
|
96
|
-
valid = True
|
97
|
-
elif len(chunks) == 3:
|
98
|
-
if re.match(r"^\d+$", chunks[2]):
|
99
|
-
if page_utils.is_valid_url("http:" + ":".join(chunks[1:])):
|
100
|
-
if chunks[0] == "http":
|
101
|
-
valid = True
|
102
|
-
elif chunks[0] == "https":
|
103
|
-
valid = True
|
104
|
-
elif chunks[0] == "socks4":
|
105
|
-
valid = True
|
106
|
-
elif chunks[0] == "socks5":
|
107
|
-
valid = True
|
108
|
-
else:
|
109
|
-
proxy_string = val_ip.group()
|
110
|
-
valid = True
|
111
|
-
if not valid:
|
112
|
-
display_proxy_warning(proxy_string)
|
113
|
-
proxy_string = None
|
114
|
-
return proxy_string
|
115
|
-
|
116
|
-
|
117
66
|
def format_exc(exception, message):
|
118
67
|
"""Formats an exception message to make the output cleaner."""
|
119
68
|
from selenium.common.exceptions import ElementNotVisibleException
|
@@ -198,8 +147,6 @@ def check_if_time_limit_exceeded():
|
|
198
147
|
and sb_config.time_limit
|
199
148
|
and not sb_config.recorder_mode
|
200
149
|
):
|
201
|
-
import time
|
202
|
-
|
203
150
|
time_limit = sb_config.time_limit
|
204
151
|
now_ms = int(time.time() * 1000)
|
205
152
|
if now_ms > sb_config.start_time_ms + sb_config.time_limit_ms:
|
@@ -1,4 +1,4 @@
|
|
1
|
-
"""
|
1
|
+
"""DB Reporting Plugin for SeleniumBase tests that use pynose / nosetests"""
|
2
2
|
import time
|
3
3
|
import uuid
|
4
4
|
from nose.plugins import Plugin
|
@@ -76,7 +76,7 @@ class DBReporting(Plugin):
|
|
76
76
|
self.testcase_manager.insert_execution_data(exec_payload)
|
77
77
|
|
78
78
|
def startTest(self, test):
|
79
|
-
"""At the start of the test, set
|
79
|
+
"""At the start of the test, set testcase details."""
|
80
80
|
from seleniumbase.core.application_manager import ApplicationManager
|
81
81
|
from seleniumbase.core.testcase_manager import TestcaseDataPayload
|
82
82
|
|
@@ -111,6 +111,7 @@ def Driver(
|
|
111
111
|
pls=None, # Shortcut / Duplicate of "page_load_strategy".
|
112
112
|
):
|
113
113
|
from seleniumbase.fixtures import constants
|
114
|
+
from seleniumbase.fixtures import shared_utils
|
114
115
|
|
115
116
|
sys_argv = sys.argv
|
116
117
|
browser_changes = 0
|
@@ -251,7 +252,7 @@ def Driver(
|
|
251
252
|
recorder_mode = True
|
252
253
|
recorder_ext = True
|
253
254
|
if (
|
254
|
-
|
255
|
+
shared_utils.is_linux()
|
255
256
|
and not headed
|
256
257
|
and not headless
|
257
258
|
and not headless2
|
@@ -1,4 +1,4 @@
|
|
1
|
-
"""
|
1
|
+
"""PageSource Plugin for SeleniumBase tests that run with pynose / nosetests"""
|
2
2
|
import os
|
3
3
|
import codecs
|
4
4
|
from nose.plugins import Plugin
|
@@ -7,7 +7,7 @@ from seleniumbase.core import log_helper
|
|
7
7
|
|
8
8
|
|
9
9
|
class PageSource(Plugin):
|
10
|
-
"""Capture the page source
|
10
|
+
"""Capture the page source after a test fails."""
|
11
11
|
name = "page_source" # Usage: --with-page_source
|
12
12
|
logfile_name = settings.PAGE_SOURCE_NAME
|
13
13
|
|
@@ -24,7 +24,6 @@ class PageSource(Plugin):
|
|
24
24
|
try:
|
25
25
|
page_source = test.driver.page_source
|
26
26
|
except Exception:
|
27
|
-
# Since we can't get the page source from here, skip saving it
|
28
27
|
return
|
29
28
|
test_logpath = self.options.log_path + "/" + test.id()
|
30
29
|
if not os.path.exists(test_logpath):
|
@@ -41,7 +40,6 @@ class PageSource(Plugin):
|
|
41
40
|
try:
|
42
41
|
page_source = test.driver.page_source
|
43
42
|
except Exception:
|
44
|
-
# Since we can't get the page source from here, don't save it.
|
45
43
|
return
|
46
44
|
test_logpath = self.options.log_path + "/" + test.id()
|
47
45
|
if not os.path.exists(test_logpath):
|
@@ -8,10 +8,8 @@ from seleniumbase import config as sb_config
|
|
8
8
|
from seleniumbase.config import settings
|
9
9
|
from seleniumbase.core import log_helper
|
10
10
|
from seleniumbase.fixtures import constants
|
11
|
+
from seleniumbase.fixtures import shared_utils
|
11
12
|
|
12
|
-
is_windows = False
|
13
|
-
if sys.platform in ["win32", "win64", "x64"]:
|
14
|
-
is_windows = True
|
15
13
|
python3_11_or_newer = False
|
16
14
|
if sys.version_info >= (3, 11):
|
17
15
|
python3_11_or_newer = True
|
@@ -99,8 +97,8 @@ def pytest_addoption(parser):
|
|
99
97
|
--incognito (Enable Chrome's Incognito mode.)
|
100
98
|
--guest (Enable Chrome's Guest mode.)
|
101
99
|
--devtools (Open Chrome's DevTools when the browser opens.)
|
102
|
-
--
|
103
|
-
--reuse-class-session
|
100
|
+
--rs | --reuse-session (Reuse browser session for all tests.)
|
101
|
+
--rcs | --reuse-class-session (Reuse session for tests in class.)
|
104
102
|
--crumbs (Delete all cookies between tests reusing a session.)
|
105
103
|
--disable-beforeunload (Disable the "beforeunload" event on Chrome.)
|
106
104
|
--window-size=WIDTH,HEIGHT (Set the browser's starting window size.)
|
@@ -1854,7 +1852,10 @@ def pytest_runtest_teardown(item):
|
|
1854
1852
|
and self.driver
|
1855
1853
|
and "--pdb" not in sys_argv
|
1856
1854
|
):
|
1857
|
-
if not
|
1855
|
+
if not (
|
1856
|
+
shared_utils.is_windows()
|
1857
|
+
or self.driver.service.process
|
1858
|
+
):
|
1858
1859
|
self.driver.quit()
|
1859
1860
|
except Exception:
|
1860
1861
|
pass
|
@@ -1864,7 +1865,7 @@ def pytest_runtest_teardown(item):
|
|
1864
1865
|
):
|
1865
1866
|
try:
|
1866
1867
|
if (
|
1867
|
-
not is_windows
|
1868
|
+
not shared_utils.is_windows()
|
1868
1869
|
or sb_config._sb_pdb_driver.service.process
|
1869
1870
|
):
|
1870
1871
|
sb_config._sb_pdb_driver.quit()
|
@@ -1982,7 +1983,7 @@ def _perform_pytest_unconfigure_():
|
|
1982
1983
|
if sb_config.shared_driver:
|
1983
1984
|
try:
|
1984
1985
|
if (
|
1985
|
-
not is_windows
|
1986
|
+
not shared_utils.is_windows()
|
1986
1987
|
or sb_config.browser == "ie"
|
1987
1988
|
or sb_config.shared_driver.service.process
|
1988
1989
|
):
|
@@ -1,8 +1,6 @@
|
|
1
|
-
"""
|
1
|
+
"""S3 Logging Plugin for SeleniumBase tests that run with pynose / nosetests"""
|
2
2
|
import uuid
|
3
|
-
import logging
|
4
3
|
import os
|
5
|
-
from seleniumbase.core.s3_manager import S3LoggingBucket
|
6
4
|
from nose.plugins import Plugin
|
7
5
|
|
8
6
|
|
@@ -14,25 +12,38 @@ class S3Logging(Plugin):
|
|
14
12
|
"""Get the options."""
|
15
13
|
super().configure(options, conf)
|
16
14
|
self.options = options
|
15
|
+
self.test_id = None
|
16
|
+
|
17
|
+
def save_data_to_logs(self, data, file_name):
|
18
|
+
from seleniumbase.fixtures import page_utils
|
19
|
+
|
20
|
+
test_logpath = os.path.join(self.options.log_path, self.test_id)
|
21
|
+
file_name = str(file_name)
|
22
|
+
destination_folder = test_logpath
|
23
|
+
page_utils._save_data_as(data, destination_folder, file_name)
|
17
24
|
|
18
25
|
def afterTest(self, test):
|
19
|
-
"""
|
26
|
+
"""Upload logs to the S3 bucket after tests complete."""
|
27
|
+
from seleniumbase.core.s3_manager import S3LoggingBucket
|
28
|
+
|
29
|
+
self.test_id = test.test.id()
|
20
30
|
s3_bucket = S3LoggingBucket()
|
21
31
|
guid = str(uuid.uuid4().hex)
|
22
|
-
path = os.path.join(self.options.log_path,
|
32
|
+
path = os.path.join(self.options.log_path, self.test_id)
|
23
33
|
uploaded_files = []
|
24
34
|
for logfile in os.listdir(path):
|
25
35
|
logfile_name = "%s/%s/%s" % (
|
26
36
|
guid,
|
27
|
-
|
37
|
+
self.test_id,
|
28
38
|
logfile.split(path)[-1],
|
29
39
|
)
|
30
40
|
s3_bucket.upload_file(logfile_name, os.path.join(path, logfile))
|
31
41
|
uploaded_files.append(logfile_name)
|
32
42
|
s3_bucket.save_uploaded_file_names(uploaded_files)
|
33
|
-
index_file = s3_bucket.upload_index_file(
|
34
|
-
|
35
|
-
|
43
|
+
index_file = s3_bucket.upload_index_file(
|
44
|
+
test.id(), guid, path, self.save_data_to_logs
|
45
|
+
)
|
46
|
+
print("\n*** Log files uploaded: ***\n%s\n" % index_file)
|
36
47
|
|
37
48
|
# If the SB database plugin is also being used,
|
38
49
|
# attach a link to the logs index database row.
|
@@ -329,11 +329,11 @@ def SB(
|
|
329
329
|
record_sleep = True
|
330
330
|
else:
|
331
331
|
record_sleep = False
|
332
|
-
if
|
332
|
+
if not shared_utils.is_linux():
|
333
333
|
# The Xvfb virtual display server is for Linux OS Only!
|
334
334
|
xvfb = False
|
335
335
|
if (
|
336
|
-
|
336
|
+
shared_utils.is_linux()
|
337
337
|
and not headed
|
338
338
|
and not headless
|
339
339
|
and not headless2
|
@@ -1,11 +1,11 @@
|
|
1
|
-
"""
|
1
|
+
"""Screenshot Plugin for SeleniumBase tests that run with pynose / nosetests"""
|
2
2
|
import os
|
3
3
|
from nose.plugins import Plugin
|
4
4
|
from seleniumbase.config import settings
|
5
5
|
|
6
6
|
|
7
7
|
class ScreenShots(Plugin):
|
8
|
-
"""This plugin takes a screenshot when a test fails
|
8
|
+
"""This plugin takes a screenshot when a test fails."""
|
9
9
|
name = "screen_shots"
|
10
10
|
logfile_name = settings.SCREENSHOT_NAME
|
11
11
|
|
@@ -1,14 +1,11 @@
|
|
1
|
-
"""
|
1
|
+
"""Selenium Plugin for SeleniumBase tests that run with pynose / nosetests"""
|
2
2
|
import sys
|
3
3
|
from nose.plugins import Plugin
|
4
4
|
from seleniumbase import config as sb_config
|
5
5
|
from seleniumbase.config import settings
|
6
6
|
from seleniumbase.core import proxy_helper
|
7
7
|
from seleniumbase.fixtures import constants
|
8
|
-
|
9
|
-
is_windows = False
|
10
|
-
if sys.platform in ["win32", "win64", "x64"]:
|
11
|
-
is_windows = True
|
8
|
+
from seleniumbase.fixtures import shared_utils
|
12
9
|
|
13
10
|
|
14
11
|
class SeleniumBrowser(Plugin):
|
@@ -1150,7 +1147,7 @@ class SeleniumBrowser(Plugin):
|
|
1150
1147
|
if str(self.options.port) == "443":
|
1151
1148
|
test.test.protocol = "https"
|
1152
1149
|
if (
|
1153
|
-
|
1150
|
+
shared_utils.is_linux()
|
1154
1151
|
and not self.options.headed
|
1155
1152
|
and not self.options.headless
|
1156
1153
|
and not self.options.headless2
|
@@ -1198,7 +1195,7 @@ class SeleniumBrowser(Plugin):
|
|
1198
1195
|
sb_config.headless_active = False
|
1199
1196
|
self.headless_active = False
|
1200
1197
|
if (
|
1201
|
-
|
1198
|
+
shared_utils.is_linux()
|
1202
1199
|
and (not self.options.headed or self.options.xvfb)
|
1203
1200
|
):
|
1204
1201
|
width = settings.HEADLESS_START_WIDTH
|
@@ -1235,7 +1232,7 @@ class SeleniumBrowser(Plugin):
|
|
1235
1232
|
try:
|
1236
1233
|
# If the browser window is still open, close it now.
|
1237
1234
|
if (
|
1238
|
-
not is_windows
|
1235
|
+
not shared_utils.is_windows()
|
1239
1236
|
or test.test.browser == "ie"
|
1240
1237
|
or self.driver.service.process
|
1241
1238
|
):
|