Skip to content

Commit 244d063

Browse files
committed
Improve the SeleniumBase Dashboard functionality
1 parent def2813 commit 244d063

File tree

2 files changed

+87
-18
lines changed

2 files changed

+87
-18
lines changed

seleniumbase/fixtures/base_case.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6735,6 +6735,11 @@ def __process_dashboard(self, has_exception, init=False):
67356735
if num_untested > 0:
67366736
# Refresh every X seconds when waiting for more test results
67376737
auto_refresh_html = constants.Dashboard.META_REFRESH_HTML
6738+
else:
6739+
# The tests are complete
6740+
if sb_config._using_html_report:
6741+
# Add the pie chart to the pytest html report
6742+
sb_config._saved_dashboard_pie = self.extract_chart()
67386743
head = (
67396744
'<head><meta charset="utf-8" />'
67406745
'<meta property="og:image" '
@@ -6832,6 +6837,8 @@ def __process_dashboard(self, has_exception, init=False):
68326837
refresh_line = (
68336838
'<script type="text/javascript" src="%s">'
68346839
'</script>' % constants.Dashboard.LIVE_JS)
6840+
if num_untested == 0 and sb_config._using_html_report:
6841+
sb_config._dash_final_summary = status
68356842
add_more = add_more + refresh_line
68366843
the_html = head + self.extract_chart() + table_html + add_more
68376844
abs_path = os.path.abspath('.')

seleniumbase/plugins/pytest_plugin.py

Lines changed: 80 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -594,10 +594,21 @@ def pytest_configure(config):
594594
sb_config._only_unittest = True # If any test uses BaseCase, becomes False
595595
sb_config._sbase_detected = False # Becomes True during SeleniumBase tests
596596
sb_config._extra_dash_entries = [] # Dashboard entries for non-SBase tests
597+
sb_config._using_html_report = False # Becomes True when using html report
598+
sb_config._dash_is_html_report = False # Dashboard becomes the html report
599+
sb_config._saved_dashboard_pie = None # Copy of pie chart for html report
600+
sb_config._dash_final_summary = None # Dash status to add to html report
601+
sb_config._html_report_name = None # The name of the pytest html report
597602

598603
arg_join = " ".join(sys.argv)
599604
if ("-n" in sys.argv) or ("-n=" in arg_join):
600605
sb_config._multithreaded = True
606+
if ("--html" in sys.argv or "--html=" in arg_join):
607+
sb_config._using_html_report = True
608+
sb_config._html_report_name = config.getoption("htmlpath")
609+
if sb_config.dashboard:
610+
if sb_config._html_report_name == "dashboard.html":
611+
sb_config._dash_is_html_report = True
601612

602613
if "linux" in sys.platform and (
603614
not sb_config.headed and not sb_config.headless):
@@ -654,10 +665,16 @@ def pytest_runtest_setup():
654665
if not sb_config.item_count_finalized:
655666
sb_config.item_count_finalized = True
656667
sb_config.item_count_untested = sb_config.item_count
657-
dashboard_html = "file://" + os.getcwd() + "/dashboard.html"
668+
dashboard_html = os.getcwd() + "/dashboard.html"
658669
star_len = len("Dashboard: ") + len(dashboard_html)
659670
stars = "*" * star_len
660-
print("\nDashboard: %s\n%s" % (dashboard_html, stars))
671+
colorama.init(autoreset=True)
672+
c1 = colorama.Fore.BLUE + colorama.Back.LIGHTYELLOW_EX
673+
cr = colorama.Style.RESET_ALL
674+
if "linux" in sys.platform:
675+
c1 = ''
676+
cr = ''
677+
print("\nDashboard: %s%s%s\n%s" % (c1, dashboard_html, cr, stars))
661678

662679

663680
def pytest_runtest_teardown(item):
@@ -687,6 +704,20 @@ def pytest_sessionfinish(session):
687704
pass
688705

689706

707+
def pytest_terminal_summary(terminalreporter):
708+
if sb_config._has_exception and (
709+
sb_config.dashboard and not sb_config._only_unittest):
710+
# Print link a second time because the first one may be off-screen
711+
dashboard_file = os.getcwd() + "/dashboard.html"
712+
terminalreporter.write_sep(
713+
"-", "Dashboard: %s" % dashboard_file)
714+
if sb_config._has_exception or sb_config.save_screenshot:
715+
# Log files are generated during test failures and Screenshot Mode
716+
latest_logs_dir = os.getcwd() + "/latest_logs/"
717+
terminalreporter.write_sep(
718+
"-", "LogPath: %s" % latest_logs_dir)
719+
720+
690721
def pytest_unconfigure():
691722
""" This runs after all tests have completed with pytest. """
692723
proxy_helper.remove_proxy_zip_if_present()
@@ -702,12 +733,20 @@ def pytest_unconfigure():
702733
sb_config.shared_driver = None
703734
log_helper.archive_logs_if_set(sb_config.log_path, sb_config.archive_logs)
704735

705-
# Dashboard post-processing: Disable auto-refresh and stamp complete
736+
# Dashboard post-processing: Disable time-based refresh and stamp complete
706737
if sb_config.dashboard and not sb_config._only_unittest:
707-
stamp = "\n<!--Test Run Complete-->"
738+
stamp = ""
739+
if sb_config._dash_is_html_report:
740+
# (If the Dashboard URL is the same as the HTML Report URL:)
741+
# Have the html report refresh back to a dashboard on update
742+
stamp += (
743+
'\n<script type="text/javascript" src="%s">'
744+
'</script>' % constants.Dashboard.LIVE_JS)
745+
stamp += "\n<!--Test Run Complete-->"
708746
find_it = constants.Dashboard.META_REFRESH_HTML
709747
swap_with = '' # Stop refreshing the page after the run is done
710748
try:
749+
# Part 1: Finalizing the dashboard / integrating html report
711750
time.sleep(0.3) # Add time for "livejs" to detect changes
712751
abs_path = os.path.abspath('.')
713752
dashboard_path = os.path.join(abs_path, "dashboard.html")
@@ -717,27 +756,43 @@ def pytest_unconfigure():
717756
# If the test run doesn't complete by itself, stop refresh
718757
the_html = the_html.replace(find_it, swap_with)
719758
the_html += stamp
759+
if sb_config._dash_is_html_report and (
760+
sb_config._saved_dashboard_pie):
761+
the_html = the_html.replace(
762+
"<h1>dashboard.html</h1>",
763+
sb_config._saved_dashboard_pie)
764+
the_html = the_html.replace(
765+
"</head>", '</head><link rel="shortcut icon" '
766+
'href="https://seleniumbase.io/img/dash_pie_2.png">')
767+
if sb_config._dash_final_summary:
768+
the_html += sb_config._dash_final_summary
720769
time.sleep(0.25)
721770
with open(dashboard_path, "w", encoding='utf-8') as f:
722771
f.write(the_html)
772+
# Part 2: Appending a pytest html report with dashboard data
773+
html_report_path = os.path.join(
774+
abs_path, sb_config._html_report_name)
775+
if sb_config._using_html_report and (
776+
os.path.exists(html_report_path) and
777+
not sb_config._dash_is_html_report):
778+
# Add the dashboard pie to the pytest html report
779+
with open(html_report_path, 'r', encoding='utf-8') as f:
780+
the_html = f.read()
781+
if sb_config._saved_dashboard_pie:
782+
the_html = the_html.replace(
783+
"<h1>%s</h1>" % sb_config._html_report_name,
784+
sb_config._saved_dashboard_pie)
785+
the_html = the_html.replace(
786+
"</head>", '</head><link rel="shortcut icon" '
787+
'href="https://seleniumbase.io/img/dash_pie_2.png">')
788+
if sb_config._dash_final_summary:
789+
the_html += sb_config._dash_final_summary
790+
with open(html_report_path, "w", encoding='utf-8') as f:
791+
f.write(the_html)
723792
except Exception:
724793
pass
725794

726795

727-
def pytest_terminal_summary(terminalreporter):
728-
if sb_config._has_exception and (
729-
sb_config.dashboard and not sb_config._only_unittest):
730-
# Print link a second time because the first one may be off-screen
731-
dashboard_file = "file://" + os.getcwd() + "/dashboard.html"
732-
terminalreporter.write_sep(
733-
"-", "Dashboard: %s" % dashboard_file)
734-
if sb_config._has_exception or sb_config.save_screenshot:
735-
# Log files are generated during test failures and Screenshot Mode
736-
latest_logs_dir = os.getcwd() + "/latest_logs/"
737-
terminalreporter.write_sep(
738-
"-", "Log files: %s" % latest_logs_dir)
739-
740-
741796
@pytest.fixture()
742797
def sb(request):
743798
""" SeleniumBase as a pytest fixture.
@@ -827,5 +882,12 @@ def pytest_runtest_makereport(item, call):
827882
extra = getattr(report, 'extra', [])
828883
if len(extra_report) > 1 and extra_report[1]["content"]:
829884
report.extra = extra + extra_report
885+
if sb_config._dash_is_html_report:
886+
# (If the Dashboard URL is the same as the HTML Report URL:)
887+
# Have the html report refresh back to a dashboard on update
888+
refresh_updates = (
889+
'<script type="text/javascript" src="%s">'
890+
'</script>' % constants.Dashboard.LIVE_JS)
891+
report.extra.append(pytest_html.extras.html(refresh_updates))
830892
except Exception:
831893
pass

0 commit comments

Comments
 (0)