@@ -594,10 +594,21 @@ def pytest_configure(config):
594
594
sb_config ._only_unittest = True # If any test uses BaseCase, becomes False
595
595
sb_config ._sbase_detected = False # Becomes True during SeleniumBase tests
596
596
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
597
602
598
603
arg_join = " " .join (sys .argv )
599
604
if ("-n" in sys .argv ) or ("-n=" in arg_join ):
600
605
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
601
612
602
613
if "linux" in sys .platform and (
603
614
not sb_config .headed and not sb_config .headless ):
@@ -654,10 +665,16 @@ def pytest_runtest_setup():
654
665
if not sb_config .item_count_finalized :
655
666
sb_config .item_count_finalized = True
656
667
sb_config .item_count_untested = sb_config .item_count
657
- dashboard_html = "file://" + os .getcwd () + "/dashboard.html"
668
+ dashboard_html = os .getcwd () + "/dashboard.html"
658
669
star_len = len ("Dashboard: " ) + len (dashboard_html )
659
670
stars = "*" * star_len
660
- print ("\n Dashboard: %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 ("\n Dashboard: %s%s%s\n %s" % (c1 , dashboard_html , cr , stars ))
661
678
662
679
663
680
def pytest_runtest_teardown (item ):
@@ -687,6 +704,20 @@ def pytest_sessionfinish(session):
687
704
pass
688
705
689
706
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
+
690
721
def pytest_unconfigure ():
691
722
""" This runs after all tests have completed with pytest. """
692
723
proxy_helper .remove_proxy_zip_if_present ()
@@ -702,12 +733,20 @@ def pytest_unconfigure():
702
733
sb_config .shared_driver = None
703
734
log_helper .archive_logs_if_set (sb_config .log_path , sb_config .archive_logs )
704
735
705
- # Dashboard post-processing: Disable auto- refresh and stamp complete
736
+ # Dashboard post-processing: Disable time-based refresh and stamp complete
706
737
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-->"
708
746
find_it = constants .Dashboard .META_REFRESH_HTML
709
747
swap_with = '' # Stop refreshing the page after the run is done
710
748
try :
749
+ # Part 1: Finalizing the dashboard / integrating html report
711
750
time .sleep (0.3 ) # Add time for "livejs" to detect changes
712
751
abs_path = os .path .abspath ('.' )
713
752
dashboard_path = os .path .join (abs_path , "dashboard.html" )
@@ -717,27 +756,43 @@ def pytest_unconfigure():
717
756
# If the test run doesn't complete by itself, stop refresh
718
757
the_html = the_html .replace (find_it , swap_with )
719
758
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
720
769
time .sleep (0.25 )
721
770
with open (dashboard_path , "w" , encoding = 'utf-8' ) as f :
722
771
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 )
723
792
except Exception :
724
793
pass
725
794
726
795
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
-
741
796
@pytest .fixture ()
742
797
def sb (request ):
743
798
""" SeleniumBase as a pytest fixture.
@@ -827,5 +882,12 @@ def pytest_runtest_makereport(item, call):
827
882
extra = getattr (report , 'extra' , [])
828
883
if len (extra_report ) > 1 and extra_report [1 ]["content" ]:
829
884
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 ))
830
892
except Exception :
831
893
pass
0 commit comments