3
3
import os
4
4
import re
5
5
import warnings
6
- from collections import defaultdict
7
- from functools import partial
8
6
from pathlib import Path
9
7
10
8
import pytest
17
15
from pytest_html .table import Header
18
16
from pytest_html .table import Html
19
17
from pytest_html .table import Row
18
+ from pytest_html .util import _ansi_styles
20
19
from pytest_html .util import cleanup_unserializable
21
20
22
- try :
23
- from ansi2html import Ansi2HTMLConverter , style
24
-
25
- converter = Ansi2HTMLConverter (inline = False , escaped = False )
26
- _handle_ansi = partial (converter .convert , full = False )
27
- _ansi_styles = style .get_styles ()
28
- except ImportError :
29
- from _pytest .logging import _remove_ansi_escape_sequences
30
-
31
- _handle_ansi = _remove_ansi_escape_sequences
32
- _ansi_styles = []
33
-
34
21
35
22
class BaseReport :
36
- class ReportData :
37
- def __init__ (self , title , config ):
38
- self ._config = config
39
- self ._data = {
40
- "title" : title ,
41
- "collectedItems" : 0 ,
42
- "runningState" : "not_started" ,
43
- "environment" : {},
44
- "tests" : defaultdict (list ),
45
- "resultsTableHeader" : {},
46
- "additionalSummary" : defaultdict (list ),
47
- }
48
-
49
- collapsed = config .getini ("render_collapsed" )
50
- if collapsed :
51
- if collapsed .lower () == "true" :
52
- warnings .warn (
53
- "'render_collapsed = True' is deprecated and support "
54
- "will be removed in the next major release. "
55
- "Please use 'render_collapsed = all' instead." ,
56
- DeprecationWarning ,
57
- )
58
- self .set_data (
59
- "collapsed" , [outcome .lower () for outcome in collapsed .split ("," )]
60
- )
61
-
62
- @property
63
- def title (self ):
64
- return self ._data ["title" ]
65
-
66
- @title .setter
67
- def title (self , title ):
68
- self ._data ["title" ] = title
69
-
70
- @property
71
- def config (self ):
72
- return self ._config
73
-
74
- @property
75
- def data (self ):
76
- return self ._data
77
-
78
- def set_data (self , key , value ):
79
- self ._data [key ] = value
80
-
81
- def add_test (self , test_data , report , row , remove_log = False ):
82
- for sortable , value in row .sortables .items ():
83
- test_data [sortable ] = value
84
-
85
- # regardless of pass or fail we must add teardown logging to "call"
86
- if report .when == "teardown" and not remove_log :
87
- self .update_test_log (report )
88
-
89
- # passed "setup" and "teardown" are not added to the html
90
- if report .when == "call" or (
91
- report .when in ["setup" , "teardown" ] and report .outcome != "passed"
92
- ):
93
- if not remove_log :
94
- processed_logs = _process_logs (report )
95
- test_data ["log" ] = _handle_ansi (processed_logs )
96
- self ._data ["tests" ][report .nodeid ].append (test_data )
97
- return True
98
-
99
- return False
100
-
101
- def update_test_log (self , report ):
102
- log = []
103
- for test in self ._data ["tests" ][report .nodeid ]:
104
- if test ["testId" ] == report .nodeid and "log" in test :
105
- for section in report .sections :
106
- header , content = section
107
- if "teardown" in header :
108
- log .append (f"{ ' ' + header + ' ' :-^80} " )
109
- log .append (content )
110
- test ["log" ] += _handle_ansi ("\n " .join (log ))
111
-
112
- def __init__ (self , report_path , config , default_css = "style.css" ):
23
+ def __init__ (self , report_path , config , report_data , default_css = "style.css" ):
113
24
self ._report_path = Path (os .path .expandvars (report_path )).expanduser ()
114
25
self ._report_path .parent .mkdir (parents = True , exist_ok = True )
115
26
self ._resources_path = Path (__file__ ).parent .joinpath ("resources" )
@@ -122,7 +33,8 @@ def __init__(self, report_path, config, default_css="style.css"):
122
33
config .getini ("max_asset_filename_length" )
123
34
)
124
35
125
- self ._report = self .ReportData (self ._report_path .name , config )
36
+ self ._report = report_data
37
+ self ._report .title = self ._report_path .name
126
38
127
39
@property
128
40
def css (self ):
@@ -336,25 +248,6 @@ def _is_error(report):
336
248
return report .when in ["setup" , "teardown" ] and report .outcome == "failed"
337
249
338
250
339
- def _process_logs (report ):
340
- log = []
341
- if report .longreprtext :
342
- log .append (report .longreprtext .replace ("<" , "<" ).replace (">" , ">" ) + "\n " )
343
- for section in report .sections :
344
- header , content = section
345
- log .append (f"{ ' ' + header + ' ' :-^80} " )
346
- log .append (content )
347
-
348
- # weird formatting related to logs
349
- if "log" in header :
350
- log .append ("" )
351
- if "call" in header :
352
- log .append ("" )
353
- if not log :
354
- log .append ("No log output captured." )
355
- return "\n " .join (log )
356
-
357
-
358
251
def _process_outcome (report ):
359
252
if _is_error (report ):
360
253
return "Error"
0 commit comments