Skip to content

Commit 224e019

Browse files
authored
Merge pull request #779 from seleniumbase/db-overhaul
Renovate the MySQL DB system
2 parents c31bd84 + 3894c66 commit 224e019

File tree

8 files changed

+104
-38
lines changed

8 files changed

+104
-38
lines changed

docs/requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
regex>=2020.11.13
2-
tqdm>=4.55.1
2+
tqdm>=4.55.2
33
livereload==2.6.3;python_version>="3.6"
44
Markdown==3.3.3
55
readme-renderer==28.0
66
pymdown-extensions==8.1
77
mkdocs==1.1.2
8-
mkdocs-material==6.2.3
8+
mkdocs-material==6.2.4
99
mkdocs-simple-hooks==0.1.2
1010
mkdocs-material-extensions==1.0.1
1111
mkdocs-minify-plugin==0.3.0

requirements.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ pytest-rerunfailures==8.0;python_version<"3.5"
4141
pytest-rerunfailures==9.1.1;python_version>="3.5"
4242
pytest-xdist==1.34.0;python_version<"3.5"
4343
pytest-xdist==2.2.0;python_version>="3.5"
44-
parameterized==0.7.5
44+
parameterized==0.8.1
4545
soupsieve==1.9.6;python_version<"3.5"
4646
soupsieve==2.0.1;python_version>="3.5" and python_version<"3.6"
4747
soupsieve==2.1;python_version>="3.6"
@@ -66,7 +66,7 @@ pathlib2==2.3.5;python_version<"3.5"
6666
importlib-metadata==2.0.0;python_version<"3.6"
6767
virtualenv>=20.2.2
6868
pymysql==0.10.1;python_version<"3.6"
69-
pymysql==1.0.1;python_version>="3.6"
69+
pymysql==1.0.2;python_version>="3.6"
7070
coverage==5.3.1
7171
brython==3.9.1
7272
pyotp==2.4.1
@@ -76,7 +76,7 @@ toml==0.10.2
7676
Pillow==6.2.2;python_version<"3.5"
7777
Pillow==7.2.0;python_version>="3.5" and python_version<"3.6"
7878
Pillow==8.1.0;python_version>="3.6"
79-
rich==9.6.2;python_version>="3.6" and python_version<"4.0"
79+
rich==9.7.0;python_version>="3.6" and python_version<"4.0"
8080
zipp==1.2.0;python_version<"3.6"
8181
zipp==3.4.0;python_version>="3.6"
8282
flake8==3.7.9;python_version<"3.5"

seleniumbase/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# seleniumbase package
2-
__version__ = "1.51.13"
2+
__version__ = "1.51.14"

seleniumbase/fixtures/base_case.py

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ def __init__(self, *args, **kwargs):
7575
self.__last_page_screenshot_png = None
7676
self.__last_page_url = None
7777
self.__last_page_source = None
78+
self.__skip_reason = None
7879
self.__added_pytest_html_extra = None
7980
self.__deferred_assert_count = 0
8081
self.__deferred_assert_failures = []
@@ -3283,9 +3284,13 @@ def set_time_limit(self, time_limit):
32833284

32843285
def skip(self, reason=""):
32853286
""" Mark the test as Skipped. """
3286-
if self.dashboard:
3287+
if self.dashboard or (self.is_pytest and self.with_db_reporting):
32873288
test_id = self.__get_test_id_2()
32883289
sb_config._results[test_id] = "Skipped"
3290+
self.__skip_reason = reason
3291+
elif reason and not self.is_pytest:
3292+
# Only needed for nosetest db reporting
3293+
self._nose_skip_reason = reason
32893294
self.skipTest(reason)
32903295

32913296
############
@@ -6368,7 +6373,8 @@ def setUp(self, masterqa_mode=False):
63686373
self._testMethodName)
63696374
data_payload.env = application.split('.')[0]
63706375
data_payload.start_time = application.split('.')[1]
6371-
data_payload.state = constants.State.NOTRUN
6376+
data_payload.state = constants.State.UNTESTED
6377+
self.__skip_reason = None
63726378
self.testcase_manager.insert_testcase_data(data_payload)
63736379
self.case_start_time = int(time.time() * 1000)
63746380
if self.headless:
@@ -6559,6 +6565,21 @@ def __set_last_page_source(self):
65596565
except Exception:
65606566
self.__last_page_source = None
65616567

6568+
def __get_exception_info(self):
6569+
exc_message = None
6570+
if sys.version_info[0] >= 3 and hasattr(self, '_outcome') and (
6571+
hasattr(self._outcome, 'errors') and self._outcome.errors):
6572+
try:
6573+
exc_message = self._outcome.errors[0][1][1]
6574+
except Exception:
6575+
exc_message = "(Unknown Exception)"
6576+
else:
6577+
try:
6578+
exc_message = sys.last_value
6579+
except Exception:
6580+
exc_message = "(Unknown Exception)"
6581+
return str(exc_message)
6582+
65626583
def __insert_test_result(self, state, err):
65636584
from seleniumbase.core.testcase_manager import TestcaseDataPayload
65646585
data_payload = TestcaseDataPayload()
@@ -6577,7 +6598,15 @@ def __insert_test_result(self, state, err):
65776598
elif "Error: " in tb_string:
65786599
data_payload.message = tb_string.split("Error: ")[-1]
65796600
else:
6580-
data_payload.message = "Unknown Error: See Stacktrace"
6601+
data_payload.message = self.__get_exception_info()
6602+
else:
6603+
test_id = self.__get_test_id_2()
6604+
if self.is_pytest and test_id in sb_config._results.keys() and (
6605+
sb_config._results[test_id] == "Skipped"):
6606+
if self.__skip_reason:
6607+
data_payload.message = "Skipped: " + self.__skip_reason
6608+
else:
6609+
data_payload.message = "Skipped: (no reason given)"
65816610
self.testcase_manager.update_testcase_data(data_payload)
65826611

65836612
def __add_pytest_html_extra(self):
@@ -7023,9 +7052,16 @@ def tearDown(self):
70237052
self.display = None
70247053
if self.with_db_reporting:
70257054
if has_exception:
7026-
self.__insert_test_result(constants.State.ERROR, True)
7055+
self.__insert_test_result(constants.State.FAILED, True)
70277056
else:
7028-
self.__insert_test_result(constants.State.PASS, False)
7057+
test_id = self.__get_test_id_2()
7058+
if test_id in sb_config._results.keys() and (
7059+
sb_config._results[test_id] == "Skipped"):
7060+
self.__insert_test_result(
7061+
constants.State.SKIPPED, False)
7062+
else:
7063+
self.__insert_test_result(
7064+
constants.State.PASSED, False)
70297065
runtime = int(time.time() * 1000) - self.execution_start_time
70307066
self.testcase_manager.update_execution_data(
70317067
self.execution_guid, runtime)

seleniumbase/fixtures/constants.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,10 @@ class Browser:
268268

269269

270270
class State:
271-
NOTRUN = "NotRun"
271+
PASSED = "Passed"
272+
FAILED = "Failed"
273+
SKIPPED = "Skipped"
274+
UNTESTED = "Untested"
272275
ERROR = "Error"
273-
FAILURE = "Fail"
274-
PASS = "Pass"
275-
SKIP = "Skip"
276276
BLOCKED = "Blocked"
277277
DEPRECATED = "Deprecated"

seleniumbase/fixtures/errors.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
"""
2-
SeleniumBase MySQL plugin-related exceptions.
2+
SeleniumBase MySQL-related exceptions.
3+
4+
This feature is DEPRECATED!
5+
Use self.skip() for skipping tests!
6+
37
Raising one of these in a test will cause the
48
test-state to be logged appropriately in the DB
5-
for tests that use the SeleniumBase MySQL plugin.
9+
for tests that use the SeleniumBase MySQL option.
610
"""
711

812

seleniumbase/plugins/db_reporting_plugin.py

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ def __init__(self):
3030
self.application = None
3131
self.testcase_manager = None
3232
self.error_handled = False
33+
self._result_set = False
34+
self._test = None
3335

3436
def options(self, parser, env):
3537
super(DBReporting, self).options(parser, env=env)
@@ -77,61 +79,85 @@ def startTest(self, test):
7779
application = ApplicationManager.generate_application_string(test)
7880
data_payload.env = application.split('.')[0]
7981
data_payload.start_time = application.split('.')[1]
80-
data_payload.state = constants.State.NOTRUN
82+
data_payload.state = constants.State.UNTESTED
8183
self.testcase_manager.insert_testcase_data(data_payload)
8284
self.case_start_time = int(time.time() * 1000)
8385
# Make the testcase guid available to other plugins
8486
test.testcase_guid = self.testcase_guid
87+
self._test = test
88+
self._test._nose_skip_reason = None
8589

8690
def finalize(self, result):
87-
""" At the end of the run, we want to
88-
update the DB row with the execution time. """
91+
""" At the end of the test run, we want to
92+
update the DB row with the total execution time. """
8993
runtime = int(time.time() * 1000) - self.execution_start_time
90-
self.testcase_manager.update_execution_data(self.execution_guid,
91-
runtime)
94+
self.testcase_manager.update_execution_data(
95+
self.execution_guid, runtime)
96+
97+
def afterTest(self, test):
98+
if not self._result_set:
99+
err = None
100+
try:
101+
err = self._test._nose_skip_reason
102+
if err:
103+
err = "Skipped: " + str(err)
104+
err = (err, err)
105+
except Exception:
106+
pass
107+
if not err:
108+
err = "Skipped: (no reason given)"
109+
err = (err, err)
110+
self.__insert_test_result(constants.State.SKIPPED, self._test, err)
92111

93112
def addSuccess(self, test, capt):
94113
"""
95-
After test completion, we want to record testcase run information.
114+
After each test success, record testcase run information.
96115
"""
97-
self.__insert_test_result(constants.State.PASS, test)
116+
self.__insert_test_result(constants.State.PASSED, test)
117+
self._result_set = True
118+
119+
def addFailure(self, test, err, capt=None, tbinfo=None):
120+
"""
121+
After each test failure, record testcase run information.
122+
"""
123+
self.__insert_test_result(constants.State.FAILED, test, err)
124+
self._result_set = True
98125

99126
def addError(self, test, err, capt=None):
100127
"""
101-
After a test error, we want to record testcase run information.
128+
After each test error, record testcase run information.
129+
(Test errors should be treated the same as test failures.)
102130
"""
103-
self.__insert_test_result(constants.State.ERROR, test, err)
131+
self.__insert_test_result(constants.State.FAILED, test, err)
132+
self._result_set = True
104133

105134
def handleError(self, test, err, capt=None):
106135
"""
107-
After a test error, we want to record testcase run information.
136+
After each test error, record testcase run information.
108137
"Error" also encompasses any states other than Pass or Fail, so we
109138
check for those first.
110139
"""
111140
if err[0] == errors.BlockedTest:
112141
self.__insert_test_result(constants.State.BLOCKED, test, err)
142+
self._result_set = True
113143
self.error_handled = True
114144
raise SkipTest(err[1])
115145
return True
116146

117147
elif err[0] == errors.DeprecatedTest:
118148
self.__insert_test_result(constants.State.DEPRECATED, test, err)
149+
self._result_set = True
119150
self.error_handled = True
120151
raise SkipTest(err[1])
121152
return True
122153

123154
elif err[0] == errors.SkipTest:
124-
self.__insert_test_result(constants.State.SKIP, test, err)
155+
self.__insert_test_result(constants.State.SKIPPED, test, err)
156+
self._result_set = True
125157
self.error_handled = True
126158
raise SkipTest(err[1])
127159
return True
128160

129-
def addFailure(self, test, err, capt=None, tbinfo=None):
130-
"""
131-
After a test failure, we want to record testcase run information.
132-
"""
133-
self.__insert_test_result(constants.State.FAILURE, test, err)
134-
135161
def __insert_test_result(self, state, test, err=None):
136162
data_payload = TestcaseDataPayload()
137163
data_payload.runtime = int(time.time() * 1000) - self.case_start_time

setup.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
print("\n*** Installing twine: *** (Required for PyPI uploads)\n")
5050
os.system("python -m pip install --upgrade 'twine>=1.15.0'")
5151
print("\n*** Installing tqdm: *** (Required for PyPI uploads)\n")
52-
os.system("python -m pip install --upgrade 'tqdm>=4.55.1'")
52+
os.system("python -m pip install --upgrade 'tqdm>=4.55.2'")
5353
print("\n*** Publishing The Release to PyPI: ***\n")
5454
os.system('python -m twine upload dist/*') # Requires ~/.pypirc Keys
5555
print("\n*** The Release was PUBLISHED SUCCESSFULLY to PyPI! :) ***\n")
@@ -145,7 +145,7 @@
145145
'pytest-rerunfailures==9.1.1;python_version>="3.5"',
146146
'pytest-xdist==1.34.0;python_version<"3.5"',
147147
'pytest-xdist==2.2.0;python_version>="3.5"',
148-
'parameterized==0.7.5',
148+
'parameterized==0.8.1',
149149
'soupsieve==1.9.6;python_version<"3.5"',
150150
'soupsieve==2.0.1;python_version>="3.5" and python_version<"3.6"',
151151
'soupsieve==2.1;python_version>="3.6"',
@@ -170,7 +170,7 @@
170170
'importlib-metadata==2.0.0;python_version<"3.6"', # Sync "virtualenv"
171171
'virtualenv>=20.2.2', # Sync with importlib-metadata and pathlib2
172172
'pymysql==0.10.1;python_version<"3.6"',
173-
'pymysql==1.0.1;python_version>="3.6"',
173+
'pymysql==1.0.2;python_version>="3.6"',
174174
'coverage==5.3.1',
175175
'brython==3.9.1',
176176
'pyotp==2.4.1',
@@ -180,7 +180,7 @@
180180
'Pillow==6.2.2;python_version<"3.5"',
181181
'Pillow==7.2.0;python_version>="3.5" and python_version<"3.6"',
182182
'Pillow==8.1.0;python_version>="3.6"',
183-
'rich==9.6.2;python_version>="3.6" and python_version<"4.0"',
183+
'rich==9.7.0;python_version>="3.6" and python_version<"4.0"',
184184
'zipp==1.2.0;python_version<"3.6"',
185185
'zipp==3.4.0;python_version>="3.6"',
186186
'flake8==3.7.9;python_version<"3.5"',

0 commit comments

Comments
 (0)