forked from dunossauro/behave-report
-
Notifications
You must be signed in to change notification settings - Fork 0
/
reporter.py
147 lines (125 loc) · 4.33 KB
/
reporter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
from sys import argv
from re import compile as r_compile
from re import MULTILINE, DOTALL
from bokeh.charts import Donut
from bokeh.embed import components
from bokeh.resources import INLINE
from pandas import DataFrame as df
from pandas import concat
# Regex
REMOVE_SCENARIOS = r_compile(
r"^@scenario.begin(.*?)@scenario.end$", MULTILINE | DOTALL)
# --- get scenarios
SCENARIOS = r_compile(r"Cen[á|a]rio: .*|Contexto: .*")
# --- get steps
STEPS = r_compile(
r"\s+(E\s|Ent[ã|a]o|Quando|Dad[o|a|as|os]|Mas)(.*?) ... (failed|passed|skipped) in (.*)")
# --- get data
ERRORS = r_compile(r'errors="(\d)"')
SKIPPED = r_compile(r'skipped="(\d)"')
NAME = r_compile(r'<testcase classname=".*?\.(.*?)"')
ERROR_DESC = r_compile(r'CDATA\[(.*)]]>.*</error>', MULTILINE | DOTALL)
L_DFS = [] # ----- Lista dos dataframes para compilação
FILO = [] # ----- Fila para o html
def head(file, tup):
"""
Cria o head do arquivo usando o parametro
"""
style_table = """
<style>
table {
border-collapse: collapse;
width: 100%;
}
th, td {
text-align: left;
padding: 8px;
}
tr:nth-child(even){background-color: #f2f2f2}
</style>
"""
file.write('<!DOCTYPE html>\n')
file.write('<html>\n')
file.write('<head>\n')
file.write('\t<meta charset="utf-8" />\n')
file.write('\t<title>Behave Report</title>\n')
# ---- Style
file.write(INLINE.render_js())
file.write(INLINE.render_css())
# ---- bootstrap
file.write('<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"\
rel="stylesheet"\
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"\
crossorigin="anonymous">')
file.write('<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js">\
</script>')
file.write('<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js">\
</script>')
file.write('{}\n'.format(style_table))
file.write('\t{}\n'.format(tup[0]))
file.write('</head>\n')
file.write('<body>\n')
file.write('\t<div align="center">\n')
file.write('\t\t<h1>BEHAVE REPORT</h1>\n')
file.write('\t{}\n'.format(tup[1]))
# ---- Parse informations
if NAME.findall(XML):
file.write('\t<h3>Feature: {}</h3><br>\n'.format(
NAME.findall(XML)[0]))
file.write('\t</div>\n')
if ERRORS.findall(XML):
file.write('\tScenarios failed: {}<br>\n'.format(
ERRORS.findall(XML)[0]))
if SKIPPED.findall(XML):
file.write('\tScenarios skipped: {}<br>\n'.format(
SKIPPED.findall(XML)[0]))
def mount_graph():
"""
Função que monta o gráfico usando os dataframes
"""
all_df = concat(L_DFS)
graph = Donut(all_df, label='state')
return components(graph, INLINE)
def mount_page(file, component):
"""
Esgota a fila enviado para o html
"""
head(HTML, component)
for saida in FILO:
file.write(saida)
file.write('<br>' * 2)
# --- Write error in code font
if ERROR_DESC.findall(XML):
file.write("""
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse1">
ERRORS</a>
</h4>
</div>
<div id="collapse1" class="panel-collapse collapse in">
""".format('ERRORS'))
for error in ERROR_DESC.findall(XML):
file.write(error.replace('\n', '<br>'))
file.write('</div>\n</div>\n</html>')
file.close()
def parse_xml(file):
"""
Função que itera a regex, cria data frames
e gera a fila de htmls para o arquivo
"""
for text in REMOVE_SCENARIOS.findall(file):
splited_text = text.lstrip()
steps = STEPS.findall(splited_text)
text_df = df(steps, columns=['step', 'text', 'state', 'time'])
L_DFS.append(text_df)
FILO.append(
"<h4>{}</h4>".format("".join(SCENARIOS.findall(splited_text))))
FILO.append(text_df.to_html(classes="table"))
if __name__ == '__main__':
XML = open(argv[1]).read()
HTML = open(argv[2], 'w')
parse_xml(XML)
COMPS = mount_graph()
mount_page(HTML, COMPS)