Skip to content

Make logging improvements to the sb pytest fixture #652

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/github_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def test_github(self):
self.open("https://github.com/")
self.type("input.header-search-input", "SeleniumBase\n")
self.slow_click('a[href="/seleniumbase/SeleniumBase"]')
self.click_if_visible('[data-action="click:signup-prompt#dismiss"]')
self.assert_element("div.repository-content")
self.assert_text("SeleniumBase", "h1")
self.slow_click('a[title="seleniumbase"]')
Expand Down
8 changes: 4 additions & 4 deletions examples/nth_child_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ def test_locate_rows_with_colors(self):
self.demo_mode = True
self.highlight(tbody)
self.post_message("Part 1: Assert text in given row.")
self.assert_text("teal", "tr:nth-child(2)")
self.assert_text("aqua", "tr:nth-child(4)")
self.assert_text("mint", "tr:nth-child(14)")
self.assert_text("jade", "tr:nth-child(36)")
self.assert_text("teal", tbody + " tr:nth-child(2)")
self.assert_text("aqua", tbody + " tr:nth-child(4)")
self.assert_text("mint", tbody + " tr:nth-child(14)")
self.assert_text("jade", tbody + " tr:nth-child(36)")
soup = self.get_beautiful_soup(self.get_page_source())
self.post_message("Part 2: Find row with given text.")
self.locate_first_row_with_color("rust", tbody, soup)
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
pip>=20.2.2
packaging>=20.4
setuptools>=44.1.1;python_version<"3.5"
setuptools>=49.3.2;python_version>="3.5"
setuptools>=49.6.0;python_version>="3.5"
setuptools-scm>=4.1.2
wheel>=0.34.2
wheel>=0.35.0
six==1.15.0
nose==1.3.7
ipdb==0.13.3
Expand Down
47 changes: 32 additions & 15 deletions seleniumbase/core/log_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,41 @@ def log_test_failure_data(test, test_logpath, driver, browser, url=None):
data_to_save.append("Last Page: %s" % last_page)
data_to_save.append(" Browser: %s" % browser)
data_to_save.append("Timestamp: %s" % int(time.time()))
if sys.version_info[0] >= 3 and hasattr(test, '_outcome'):
if test._outcome.errors:
try:
exc_message = test._outcome.errors[0][1][1]
traceback_address = test._outcome.errors[0][1][2]
traceback_list = traceback.format_list(
traceback.extract_tb(traceback_address)[1:])
traceback_message = ''.join(traceback_list).strip()
except Exception:
exc_message = "(Unknown Exception)"
traceback_message = "(Unknown Traceback)"
data_to_save.append("Traceback: " + traceback_message)
data_to_save.append("Exception: " + str(exc_message))
if sys.version_info[0] >= 3 and hasattr(test, '_outcome') and (
hasattr(test._outcome, 'errors') and test._outcome.errors):
try:
exc_message = test._outcome.errors[0][1][1]
traceback_address = test._outcome.errors[0][1][2]
traceback_list = traceback.format_list(
traceback.extract_tb(traceback_address)[1:])
traceback_message = ''.join(traceback_list).strip()
except Exception:
exc_message = "(Unknown Exception)"
traceback_message = "(Unknown Traceback)"
data_to_save.append("Traceback: " + traceback_message)
data_to_save.append("Exception: " + str(exc_message))
else:
data_to_save.append("Traceback: " + ''.join(
the_traceback = None
the_traceback = ''.join(
traceback.format_exception(sys.exc_info()[0],
sys.exc_info()[1],
sys.exc_info()[2])))
sys.exc_info()[2]))
if not the_traceback or len(str(the_traceback)) < 30 or (
the_traceback.endswith("StopIteration\n")):
good_stack = []
the_stacks = traceback.format_list(
traceback.extract_tb(sys.last_traceback))
for stack in the_stacks:
if "/site-packages/pluggy/" not in stack:
if "/site-packages/_pytest/" not in stack:
good_stack.append(stack)
the_traceback = ''.join(good_stack)
data_to_save.append("Traceback: " + the_traceback)
last_value = sys.last_value
if last_value:
data_to_save.append("Exception: " + str(last_value))
else:
data_to_save.append("Traceback: " + the_traceback)
log_file.writelines("\r\n".join(data_to_save))
log_file.close()

Expand Down
7 changes: 6 additions & 1 deletion seleniumbase/fixtures/base_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def __init__(self, *args, **kwargs):
self._language = "English"
self._presentation_slides = {}
self._presentation_transition = {}
self._sb_test_identifier = None
self._html_report_extra = [] # (Used by pytest_plugin.py)
self._default_driver = None
self._drivers_list = []
Expand Down Expand Up @@ -6315,7 +6316,9 @@ def __quit_all_drivers(self):

def __has_exception(self):
has_exception = False
if sys.version_info[0] >= 3 and hasattr(self, '_outcome'):
if hasattr(sys, 'last_traceback') and sys.last_traceback is not None:
has_exception = True
elif sys.version_info[0] >= 3 and hasattr(self, '_outcome'):
if hasattr(self._outcome, 'errors') and self._outcome.errors:
has_exception = True
else:
Expand All @@ -6326,6 +6329,8 @@ def __get_test_id(self):
test_id = "%s.%s.%s" % (self.__class__.__module__,
self.__class__.__name__,
self._testMethodName)
if self._sb_test_identifier and len(str(self._sb_test_identifier)) > 6:
test_id = self._sb_test_identifier
return test_id

def __create_log_path_as_needed(self, test_logpath):
Expand Down
54 changes: 49 additions & 5 deletions seleniumbase/plugins/pytest_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@ def pytest_configure(config):
sb_config.visual_baseline = config.getoption('visual_baseline')
sb_config.timeout_multiplier = config.getoption('timeout_multiplier')
sb_config.pytest_html_report = config.getoption('htmlpath') # --html=FILE
sb_config._sb_node = {} # sb node dictionary (Used with the sb fixture)

if sb_config.reuse_session:
arg_join = " ".join(sys.argv)
Expand Down Expand Up @@ -592,19 +593,35 @@ def sb(request):
from seleniumbase import BaseCase

class BaseClass(BaseCase):
def base_method():

def setUp(self):
super(BaseClass, self).setUp()

def tearDown(self):
self.save_teardown_screenshot()
super(BaseClass, self).tearDown()

def base_method(self):
pass

if request.cls:
request.cls.sb = BaseClass("base_method")
request.cls.sb.setUp()
request.cls.sb._needs_tearDown = True
sb_config._sb_node[request.node.nodeid] = request.cls.sb
yield request.cls.sb
request.cls.sb.tearDown()
if request.cls.sb._needs_tearDown:
request.cls.sb.tearDown()
request.cls.sb._needs_tearDown = False
else:
sb = BaseClass("base_method")
sb.setUp()
sb._needs_tearDown = True
sb_config._sb_node[request.node.nodeid] = sb
yield sb
sb.tearDown()
if sb._needs_tearDown:
sb.tearDown()
sb._needs_tearDown = False


@pytest.mark.hookwrapper
Expand All @@ -614,9 +631,36 @@ def pytest_runtest_makereport(item, call):
report = outcome.get_result()
if pytest_html and report.when == 'call':
try:
extra_report = item._testcase._html_report_extra
extra_report = None
if hasattr(item, "_testcase"):
extra_report = item._testcase._html_report_extra
elif hasattr(item.instance, "sb") or (
item.nodeid in sb_config._sb_node):
if not hasattr(item.instance, "sb"):
sb_node = sb_config._sb_node[item.nodeid]
else:
sb_node = item.instance.sb
test_id = item.nodeid
if not test_id:
test_id = "unidentified_TestCase"
test_id = test_id.replace(' ', '_')
if '[' in test_id:
import re
test_id_intro = test_id.split('[')[0]
parameter = test_id.split('[')[1]
parameter = re.sub(re.compile(r'\W'), '', parameter)
test_id = test_id_intro + "__" + parameter
test_id = test_id.replace('/', '.').replace('\\', '.')
test_id = test_id.replace('::', '.').replace('.py', '')
sb_node._sb_test_identifier = test_id
if sb_node._needs_tearDown:
sb_node.tearDown()
sb_node._needs_tearDown = False
extra_report = sb_node._html_report_extra
else:
return
extra = getattr(report, 'extra', [])
if extra_report[1]["content"]:
if len(extra_report) > 1 and extra_report[1]["content"]:
report.extra = extra + extra_report
except Exception:
pass
4 changes: 4 additions & 0 deletions seleniumbase/translate/chinese.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ def 慢单击(self, *args, **kwargs):
# slow_click(selector)
return self.slow_click(*args, **kwargs)

def 如果可见请单击(self, *args, **kwargs):
# click_if_visible(selector, by=By.CSS_SELECTOR)
return self.click_if_visible(*args, **kwargs)

def 单击链接文本(self, *args, **kwargs):
# click_link_text(link_text)
return self.click_link_text(*args, **kwargs)
Expand Down
4 changes: 4 additions & 0 deletions seleniumbase/translate/dutch.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ def klik_langzaam(self, *args, **kwargs):
# slow_click(selector)
return self.slow_click(*args, **kwargs)

def klik_indien_zichtbaar(self, *args, **kwargs):
# click_if_visible(selector, by=By.CSS_SELECTOR)
return self.click_if_visible(*args, **kwargs)

def klik_linktekst(self, *args, **kwargs):
# click_link_text(link_text)
return self.click_link_text(*args, **kwargs)
Expand Down
8 changes: 6 additions & 2 deletions seleniumbase/translate/french.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ def cliquer_lentement(self, *args, **kwargs):
# slow_click(selector)
return self.slow_click(*args, **kwargs)

def cliquer_si_affiché(self, *args, **kwargs): # noqa
# click_if_visible(selector, by=By.CSS_SELECTOR)
return self.click_if_visible(*args, **kwargs)

def cliquer_texte_du_lien(self, *args, **kwargs):
# click_link_text(link_text)
return self.click_link_text(*args, **kwargs)
Expand All @@ -49,7 +53,7 @@ def obtenir_texte(self, *args, **kwargs):
# get_text(selector, text)
return self.get_text(*args, **kwargs)

def vérifier_texte(self, *args, **kwargs): # noqa
def vérifier_texte(self, *args, **kwargs):
# assert_text(text, selector)
return self.assert_text(*args, **kwargs)

Expand Down Expand Up @@ -173,7 +177,7 @@ def soumettre(self, *args, **kwargs):
# submit(selector)
return self.submit(*args, **kwargs)

def js_clic(self, *args, **kwargs):
def js_cliquer(self, *args, **kwargs):
# js_click(selector)
return self.js_click(*args, **kwargs)

Expand Down
10 changes: 7 additions & 3 deletions seleniumbase/translate/italian.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,15 @@ def doppio_clic(self, *args, **kwargs):
# double_click(selector)
return self.double_click(*args, **kwargs)

def clicca_lentamente(self, *args, **kwargs):
def clic_lentamente(self, *args, **kwargs):
# slow_click(selector)
return self.slow_click(*args, **kwargs)

def fare_clic_testo_del_collegamento(self, *args, **kwargs):
def clic_se_visto(self, *args, **kwargs):
# click_if_visible(selector, by=By.CSS_SELECTOR)
return self.click_if_visible(*args, **kwargs)

def clic_testo_del_collegamento(self, *args, **kwargs):
# click_link_text(link_text)
return self.click_link_text(*args, **kwargs)

Expand Down Expand Up @@ -293,7 +297,7 @@ def premere_la_freccia_destra(self, *args, **kwargs):
# press_right_arrow(selector="html", times=1)
return self.press_right_arrow(*args, **kwargs)

def fare_clic_sugli_elementi_visibili(self, *args, **kwargs):
def clic_sugli_elementi_visibili(self, *args, **kwargs):
# click_visible_elements(selector)
return self.click_visible_elements(*args, **kwargs)

Expand Down
4 changes: 4 additions & 0 deletions seleniumbase/translate/japanese.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ def ゆっくりクリックして(self, *args, **kwargs):
# slow_click(selector)
return self.slow_click(*args, **kwargs)

def 表示されている場合はクリック(self, *args, **kwargs):
# click_if_visible(selector, by=By.CSS_SELECTOR)
return self.click_if_visible(*args, **kwargs)

def リンクテキストをクリックします(self, *args, **kwargs):
# click_link_text(link_text)
return self.click_link_text(*args, **kwargs)
Expand Down
4 changes: 4 additions & 0 deletions seleniumbase/translate/korean.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ def 천천히_클릭(self, *args, **kwargs):
# slow_click(selector)
return self.slow_click(*args, **kwargs)

def 보이는_경우_클릭(self, *args, **kwargs):
# click_if_visible(selector, by=By.CSS_SELECTOR)
return self.click_if_visible(*args, **kwargs)

def 링크_텍스트를_클릭합니다(self, *args, **kwargs):
# click_link_text(link_text)
return self.click_link_text(*args, **kwargs)
Expand Down
Loading