1717 python3_11_or_newer = True
1818py311_patch2 = constants .PatchPy311 .PATCH
1919sys_argv = sys .argv
20+ full_time = None
2021pytest_plugins = ["pytester" ] # Adds the "testdir" fixture
2122
2223
@@ -2038,13 +2039,17 @@ def pytest_runtest_teardown(item):
20382039 if (
20392040 "-s" in sys_argv
20402041 or "--capture=no" in sys_argv
2042+ or "--capture=tee-sys" in sys_argv
20412043 or (
20422044 hasattr (sb_config .pytest_config , "invocation_params" )
20432045 and (
20442046 "-s" in sb_config .pytest_config .invocation_params .args
20452047 or "--capture=no" in (
20462048 sb_config .pytest_config .invocation_params .args
20472049 )
2050+ or "--capture=tee-sys" in (
2051+ sb_config .pytest_config .invocation_params .args
2052+ )
20482053 )
20492054 )
20502055 ):
@@ -2053,6 +2058,10 @@ def pytest_runtest_teardown(item):
20532058 sys .stdout .write ("\n => Fail Page: %s\n " % sb_config ._fail_page )
20542059
20552060
2061+ def pytest_html_duration_format (duration ):
2062+ return "%.2f" % duration
2063+
2064+
20562065def pytest_sessionfinish (session ):
20572066 pass
20582067
@@ -2103,9 +2112,11 @@ def pytest_terminal_summary(terminalreporter):
21032112 )
21042113
21052114
2106- def _perform_pytest_unconfigure_ ():
2115+ def _perform_pytest_unconfigure_ (config ):
21072116 from seleniumbase .core import proxy_helper
21082117
2118+ reporter = config .pluginmanager .get_plugin ("terminalreporter" )
2119+ duration = time .time () - reporter ._sessionstarttime
21092120 if (
21102121 (hasattr (sb_config , "multi_proxy" ) and not sb_config .multi_proxy )
21112122 or not hasattr (sb_config , "multi_proxy" )
@@ -2133,6 +2144,63 @@ def _perform_pytest_unconfigure_():
21332144 log_helper .clear_empty_logs ()
21342145 # Dashboard post-processing: Disable time-based refresh and stamp complete
21352146 if not hasattr (sb_config , "dashboard" ) or not sb_config .dashboard :
2147+ html_report_path = None
2148+ the_html_r = None
2149+ abs_path = os .path .abspath ("." )
2150+ if sb_config ._html_report_name :
2151+ html_report_path = os .path .join (
2152+ abs_path , sb_config ._html_report_name
2153+ )
2154+ if (
2155+ sb_config ._using_html_report
2156+ and html_report_path
2157+ and os .path .exists (html_report_path )
2158+ ):
2159+ with open (html_report_path , "r" , encoding = "utf-8" ) as f :
2160+ the_html_r = f .read ()
2161+ assets_chunk = "if (assets.length === 1) {"
2162+ remove_media = "container.classList.remove('media-container')"
2163+ rm_n_left = '<div class="media-container__nav--left"><</div>'
2164+ rm_n_right = '<div class="media-container__nav--right">></div>'
2165+ the_html_r = the_html_r .replace (
2166+ assets_chunk ,
2167+ "%s %s" % (assets_chunk , remove_media ),
2168+ )
2169+ the_html_r = the_html_r .replace (rm_n_left , "" )
2170+ the_html_r = the_html_r .replace (rm_n_right , "" )
2171+ the_html_r = the_html_r .replace ("<ul>$" , "$" )
2172+ the_html_r = the_html_r .replace ("}<ul>" , "}" )
2173+ the_html_r = the_html_r .replace (
2174+ "<li>${val}</li>" , "${val}, "
2175+ )
2176+ the_html_r = the_html_r .replace (
2177+ "<div>${value}</div>" , "<span>${value}</span"
2178+ )
2179+ ph_link = '<a href="https://pypi.python.org/pypi/pytest-html">'
2180+ sb_link = (
2181+ '<a href="https://github.com/seleniumbase/SeleniumBase">'
2182+ 'SeleniumBase</a>'
2183+ )
2184+ the_html_r = the_html_r .replace (
2185+ ph_link , "%s and %s" % (sb_link , ph_link )
2186+ )
2187+ the_html_r = the_html_r .replace (
2188+ "mediaName.innerText" , "//mediaName.innerText"
2189+ )
2190+ the_html_r = the_html_r .replace (
2191+ "counter.innerText" , "//counter.innerText"
2192+ )
2193+ run_count = '<p class="run-count">'
2194+ run_c_loc = the_html_r .find (run_count )
2195+ rc_loc = the_html_r .find (" took " , run_c_loc )
2196+ end_rc_loc = the_html_r .find (".</p>" , rc_loc )
2197+ run_time = "%.2f" % duration
2198+ new_time = " ran in %s seconds" % run_time
2199+ the_html_r = (
2200+ the_html_r [:rc_loc ] + new_time + the_html_r [end_rc_loc :]
2201+ )
2202+ with open (html_report_path , "w" , encoding = "utf-8" ) as f :
2203+ f .write (the_html_r ) # Finalize the HTML report
21362204 # Done with "pytest_unconfigure" unless using the Dashboard
21372205 return
21382206 stamp = ""
@@ -2237,7 +2305,7 @@ def _perform_pytest_unconfigure_():
22372305 elif "\\ " in h_r_name and h_r_name .endswith (".html" ):
22382306 h_r_name = h_r_name .split ("\\ " )[- 1 ]
22392307 the_html_r = the_html_r .replace (
2240- " <h1>%s</h1>" % h_r_name ,
2308+ ' <h1 id="title" >%s</h1>' % h_r_name ,
22412309 sb_config ._saved_dashboard_pie ,
22422310 )
22432311 the_html_r = the_html_r .replace (
@@ -2247,6 +2315,47 @@ def _perform_pytest_unconfigure_():
22472315 )
22482316 if sb_config ._dash_final_summary :
22492317 the_html_r += sb_config ._dash_final_summary
2318+ assets_chunk = "if (assets.length === 1) {"
2319+ remove_media = "container.classList.remove('media-container')"
2320+ rm_n_left = '<div class="media-container__nav--left"><</div>'
2321+ rm_n_right = '<div class="media-container__nav--right">></div>'
2322+ the_html_r = the_html_r .replace (
2323+ assets_chunk ,
2324+ "%s %s" % (assets_chunk , remove_media ),
2325+ )
2326+ the_html_r = the_html_r .replace (rm_n_left , "" )
2327+ the_html_r = the_html_r .replace (rm_n_right , "" )
2328+ the_html_r = the_html_r .replace ("<ul>$" , "$" )
2329+ the_html_r = the_html_r .replace ("}<ul>" , "}" )
2330+ the_html_r = the_html_r .replace (
2331+ "<li>${val}</li>" , "${val}, "
2332+ )
2333+ the_html_r = the_html_r .replace (
2334+ "<div>${value}</div>" , "<span>${value}</span"
2335+ )
2336+ ph_link = '<a href="https://pypi.python.org/pypi/pytest-html">'
2337+ sb_link = (
2338+ '<a href="https://github.com/seleniumbase/SeleniumBase">'
2339+ 'SeleniumBase</a>'
2340+ )
2341+ the_html_r = the_html_r .replace (
2342+ ph_link , "%s and %s" % (sb_link , ph_link )
2343+ )
2344+ the_html_r = the_html_r .replace (
2345+ "mediaName.innerText" , "//mediaName.innerText"
2346+ )
2347+ the_html_r = the_html_r .replace (
2348+ "counter.innerText" , "//counter.innerText"
2349+ )
2350+ run_count = '<p class="run-count">'
2351+ run_c_loc = the_html_r .find (run_count )
2352+ rc_loc = the_html_r .find (" took " , run_c_loc )
2353+ end_rc_loc = the_html_r .find (".</p>" , rc_loc )
2354+ run_time = "%.2f" % duration
2355+ new_time = " ran in %s seconds" % run_time
2356+ the_html_r = (
2357+ the_html_r [:rc_loc ] + new_time + the_html_r [end_rc_loc :]
2358+ )
22502359 with open (html_report_path , "w" , encoding = "utf-8" ) as f :
22512360 f .write (the_html_r ) # Finalize the HTML report
22522361 except KeyboardInterrupt :
@@ -2281,19 +2390,19 @@ def pytest_unconfigure(config):
22812390 with open (dashboard_path , "w" , encoding = "utf-8" ) as f :
22822391 f .write (sb_config ._dash_html )
22832392 # Dashboard Multithreaded
2284- _perform_pytest_unconfigure_ ()
2393+ _perform_pytest_unconfigure_ (config )
22852394 return
22862395 else :
22872396 # Dash Lock is missing
2288- _perform_pytest_unconfigure_ ()
2397+ _perform_pytest_unconfigure_ (config )
22892398 return
22902399 with dash_lock :
22912400 # Multi-threaded tests
2292- _perform_pytest_unconfigure_ ()
2401+ _perform_pytest_unconfigure_ (config )
22932402 return
22942403 else :
22952404 # Single-threaded tests
2296- _perform_pytest_unconfigure_ ()
2405+ _perform_pytest_unconfigure_ (config )
22972406 return
22982407
22992408
@@ -2442,12 +2551,12 @@ def pytest_runtest_makereport(item, call):
24422551 return
24432552 extra = getattr (report , "extra" , [])
24442553 if len (extra_report ) > 1 and extra_report [1 ]["content" ]:
2445- report .extra = extra + extra_report
2554+ report .extras = extra + extra_report
24462555 if sb_config ._dash_is_html_report :
24472556 # If the Dashboard URL is the same as the HTML Report URL,
24482557 # have the html report refresh back to a dashboard on update.
24492558 refresh_updates = (
24502559 '<script type="text/javascript" src="%s">'
24512560 "</script>" % constants .Dashboard .LIVE_JS
24522561 )
2453- report .extra .append (pytest_html .extras .html (refresh_updates ))
2562+ report .extras .append (pytest_html .extras .html (refresh_updates ))
0 commit comments