Robot Framework
xmllogger.py
Go to the documentation of this file.
1 # Copyright 2008-2015 Nokia Networks
2 # Copyright 2016- Robot Framework Foundation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 from robot.utils import get_timestamp, NullMarkupWriter, safe_str, XmlWriter
17 from robot.version import get_full_version
18 from robot.result.visitor import ResultVisitor
19 
20 from .loggerhelper import IsLogged
21 
22 
24 
25  def __init__(self, path, log_level='TRACE', rpa=False, generator='Robot'):
26  self._log_message_is_logged_log_message_is_logged = IsLogged(log_level)
27  self._error_message_is_logged_error_message_is_logged = IsLogged('WARN')
28  self._writer_writer = self._get_writer_get_writer(path, rpa, generator)
29  self._errors_errors = []
30 
31  def _get_writer(self, path, rpa, generator):
32  if not path:
33  return NullMarkupWriter()
34  writer = XmlWriter(path, write_empty=False, usage='output')
35  writer.start('robot', {'generator': get_full_version(generator),
36  'generated': get_timestamp(),
37  'rpa': 'true' if rpa else 'false',
38  'schemaversion': '3'})
39  return writer
40 
41  def close(self):
42  self.start_errorsstart_errorsstart_errors()
43  for msg in self._errors_errors:
44  self._write_message_write_message(msg)
45  self.end_errorsend_errorsend_errors()
46  self._writer_writer.end('robot')
47  self._writer_writer.close()
48 
49  def set_log_level(self, level):
50  return self._log_message_is_logged_log_message_is_logged.set_level(level)
51 
52  def message(self, msg):
53  if self._error_message_is_logged_error_message_is_logged(msg.level):
54  self._errors_errors.append(msg)
55 
56  def log_message(self, msg):
57  if self._log_message_is_logged_log_message_is_logged(msg.level):
58  self._write_message_write_message(msg)
59 
60  def _write_message(self, msg):
61  attrs = {'timestamp': msg.timestamp or 'N/A', 'level': msg.level}
62  if msg.html:
63  attrs['html'] = 'true'
64  self._writer_writer.element('msg', msg.message, attrs)
65 
66  def start_keyword(self, kw):
67  attrs = {'name': kw.kwname, 'library': kw.libname}
68  if kw.type != 'KEYWORD':
69  attrs['type'] = kw.type
70  if kw.sourcename:
71  attrs['sourcename'] = kw.sourcename
72  self._writer_writer.start('kw', attrs)
73  self._write_list_write_list('var', kw.assign)
74  self._write_list_write_list('arg', [safe_str(a) for a in kw.args])
75  self._write_list_write_list('tag', kw.tags)
76  # Must be after tags to allow adding message when using --flattenkeywords.
77  self._writer_writer.element('doc', kw.doc)
78 
79  def end_keyword(self, kw):
80  if kw.timeout:
81  self._writer_writer.element('timeout', attrs={'value': str(kw.timeout)})
82  self._write_status_write_status(kw)
83  self._writer_writer.end('kw')
84 
85  def start_if(self, if_):
86  self._writer_writer.start('if')
87  self._writer_writer.element('doc', if_.doc)
88 
89  def end_if(self, if_):
90  self._write_status_write_status(if_)
91  self._writer_writer.end('if')
92 
93  def start_if_branch(self, branch):
94  self._writer_writer.start('branch', {'type': branch.type,
95  'condition': branch.condition})
96  self._writer_writer.element('doc', branch.doc)
97 
98  def end_if_branch(self, branch):
99  self._write_status_write_status(branch)
100  self._writer_writer.end('branch')
101 
102  def start_for(self, for_):
103  self._writer_writer.start('for', {'flavor': for_.flavor})
104  for name in for_.variables:
105  self._writer_writer.element('var', name)
106  for value in for_.values:
107  self._writer_writer.element('value', value)
108  self._writer_writer.element('doc', for_.doc)
109 
110  def end_for(self, for_):
111  self._write_status_write_status(for_)
112  self._writer_writer.end('for')
113 
114  def start_for_iteration(self, iteration):
115  self._writer_writer.start('iter')
116  for name, value in iteration.variables.items():
117  self._writer_writer.element('var', value, {'name': name})
118  self._writer_writer.element('doc', iteration.doc)
119 
120  def end_for_iteration(self, iteration):
121  self._write_status_write_status(iteration)
122  self._writer_writer.end('iter')
123 
124  def start_try(self, root):
125  self._writer_writer.start('try')
126 
127  def end_try(self, root):
128  self._write_status_write_status(root)
129  self._writer_writer.end('try')
130 
131  def start_try_branch(self, branch):
132  if branch.type == branch.EXCEPT:
133  self._writer_writer.start('branch', attrs={
134  'type': 'EXCEPT', 'variable': branch.variable,
135  'pattern_type': branch.pattern_type
136  })
137  self._write_list_write_list('pattern', branch.patterns)
138  else:
139  self._writer_writer.start('branch', attrs={'type': branch.type})
140 
141  def end_try_branch(self, branch):
142  self._write_status_write_status(branch)
143  self._writer_writer.end('branch')
144 
145  def start_while(self, while_):
146  self._writer_writer.start('while', attrs={
147  'condition': while_.condition,
148  'limit': while_.limit
149  })
150  self._writer_writer.element('doc', while_.doc)
151 
152  def end_while(self, while_):
153  self._write_status_write_status(while_)
154  self._writer_writer.end('while')
155 
156  def start_while_iteration(self, iteration):
157  self._writer_writer.start('iter')
158  self._writer_writer.element('doc', iteration.doc)
159 
160  def end_while_iteration(self, iteration):
161  self._write_status_write_status(iteration)
162  self._writer_writer.end('iter')
163 
164  def start_return(self, return_):
165  self._writer_writer.start('return')
166  for value in return_.values:
167  self._writer_writer.element('value', value)
168 
169  def end_return(self, return_):
170  self._write_status_write_status(return_)
171  self._writer_writer.end('return')
172 
173  def start_continue(self, continue_):
174  self._writer_writer.start('continue')
175 
176  def end_continue(self, continue_):
177  self._write_status_write_status(continue_)
178  self._writer_writer.end('continue')
179 
180  def start_break(self, break_):
181  self._writer_writer.start('break')
182 
183  def end_break(self, break_):
184  self._write_status_write_status(break_)
185  self._writer_writer.end('break')
186 
187  def start_test(self, test):
188  self._writer_writer.start('test', {'id': test.id, 'name': test.name,
189  'line': str(test.lineno or '')})
190 
191  def end_test(self, test):
192  self._writer_writer.element('doc', test.doc)
193  self._write_list_write_list('tag', test.tags)
194  if test.timeout:
195  self._writer_writer.element('timeout', attrs={'value': str(test.timeout)})
196  self._write_status_write_status(test)
197  self._writer_writer.end('test')
198 
199  def start_suite(self, suite):
200  attrs = {'id': suite.id, 'name': suite.name, 'source': suite.source}
201  self._writer_writer.start('suite', attrs)
202 
203  def end_suite(self, suite):
204  self._writer_writer.element('doc', suite.doc)
205  for name, value in suite.metadata.items():
206  self._writer_writer.element('meta', value, {'name': name})
207  self._write_status_write_status(suite)
208  self._writer_writer.end('suite')
209 
210  def start_statistics(self, stats):
211  self._writer_writer.start('statistics')
212 
213  def end_statistics(self, stats):
214  self._writer_writer.end('statistics')
215 
216  def start_total_statistics(self, total_stats):
217  self._writer_writer.start('total')
218 
219  def end_total_statistics(self, total_stats):
220  self._writer_writer.end('total')
221 
222  def start_tag_statistics(self, tag_stats):
223  self._writer_writer.start('tag')
224 
225  def end_tag_statistics(self, tag_stats):
226  self._writer_writer.end('tag')
227 
228  def start_suite_statistics(self, tag_stats):
229  self._writer_writer.start('suite')
230 
231  def end_suite_statistics(self, tag_stats):
232  self._writer_writer.end('suite')
233 
234  def visit_stat(self, stat):
235  self._writer_writer.element('stat', stat.name,
236  stat.get_attributes(values_as_strings=True))
237 
238  def start_errors(self, errors=None):
239  self._writer_writer.start('errors')
240 
241  def end_errors(self, errors=None):
242  self._writer_writer.end('errors')
243 
244  def _write_list(self, tag, items):
245  for item in items:
246  self._writer_writer.element(tag, item)
247 
248  def _write_status(self, item):
249  attrs = {'status': item.status, 'starttime': item.starttime or 'N/A',
250  'endtime': item.endtime or 'N/A'}
251  if not (item.starttime and item.endtime):
252  attrs['elapsedtime'] = str(item.elapsedtime)
253  self._writer_writer.element('status', item.message, attrs)
def end_errors(self, errors=None)
Definition: xmllogger.py:241
def start_while_iteration(self, iteration)
Called when a WHILE loop iteration starts.
Definition: xmllogger.py:156
def set_log_level(self, level)
Definition: xmllogger.py:49
def start_continue(self, continue_)
Called when a CONTINUE element starts.
Definition: xmllogger.py:173
def end_test(self, test)
Called when a test ends.
Definition: xmllogger.py:191
def start_suite(self, suite)
Called when a suite starts.
Definition: xmllogger.py:199
def _get_writer(self, path, rpa, generator)
Definition: xmllogger.py:31
def end_continue(self, continue_)
Called when a CONTINUE element ends.
Definition: xmllogger.py:176
def __init__(self, path, log_level='TRACE', rpa=False, generator='Robot')
Definition: xmllogger.py:25
def start_break(self, break_)
Called when a BREAK element starts.
Definition: xmllogger.py:180
def end_tag_statistics(self, tag_stats)
Definition: xmllogger.py:225
def end_try_branch(self, branch)
Called when TRY, EXCEPT, ELSE and FINALLY branches end.
Definition: xmllogger.py:141
def start_for(self, for_)
Called when a FOR loop starts.
Definition: xmllogger.py:102
def end_return(self, return_)
Called when a RETURN element ends.
Definition: xmllogger.py:169
def end_while_iteration(self, iteration)
Called when a WHILE loop iteration ends.
Definition: xmllogger.py:160
def end_for(self, for_)
Called when a FOR loop ends.
Definition: xmllogger.py:110
def end_suite(self, suite)
Called when a suite ends.
Definition: xmllogger.py:203
def start_try_branch(self, branch)
Called when TRY, EXCEPT, ELSE or FINALLY branches start.
Definition: xmllogger.py:131
def start_errors(self, errors=None)
Definition: xmllogger.py:238
def start_return(self, return_)
Called when a RETURN element starts.
Definition: xmllogger.py:164
def end_try(self, root)
Called when a TRY/EXCEPT structure ends.
Definition: xmllogger.py:127
def start_if(self, if_)
Called when an IF/ELSE structure starts.
Definition: xmllogger.py:85
def _write_list(self, tag, items)
Definition: xmllogger.py:244
def start_tag_statistics(self, tag_stats)
Definition: xmllogger.py:222
def start_try(self, root)
Called when a TRY/EXCEPT structure starts.
Definition: xmllogger.py:124
def end_total_statistics(self, total_stats)
Definition: xmllogger.py:219
def start_while(self, while_)
Called when a WHILE loop starts.
Definition: xmllogger.py:145
def end_for_iteration(self, iteration)
Called when a FOR loop iteration ends.
Definition: xmllogger.py:120
def end_if_branch(self, branch)
Called when an IF/ELSE branch ends.
Definition: xmllogger.py:98
def end_statistics(self, stats)
Definition: xmllogger.py:213
def end_if(self, if_)
Called when an IF/ELSE structure ends.
Definition: xmllogger.py:89
def start_total_statistics(self, total_stats)
Definition: xmllogger.py:216
def start_for_iteration(self, iteration)
Called when a FOR loop iteration starts.
Definition: xmllogger.py:114
def end_break(self, break_)
Called when a BREAK element ends.
Definition: xmllogger.py:183
def start_test(self, test)
Called when a test starts.
Definition: xmllogger.py:187
def start_keyword(self, kw)
Called when a keyword starts.
Definition: xmllogger.py:66
def start_suite_statistics(self, tag_stats)
Definition: xmllogger.py:228
def end_keyword(self, kw)
Called when a keyword ends.
Definition: xmllogger.py:79
def end_suite_statistics(self, tag_stats)
Definition: xmllogger.py:231
def start_if_branch(self, branch)
Called when an IF/ELSE branch starts.
Definition: xmllogger.py:93
def start_statistics(self, stats)
Definition: xmllogger.py:210
def end_while(self, while_)
Called when a WHILE loop ends.
Definition: xmllogger.py:152
Abstract class to conveniently travel :class:~robot.result.executionresult.Result objects.
Definition: visitor.py:41
def end_errors(self, errors)
Definition: visitor.py:122
def start_errors(self, errors)
Definition: visitor.py:119
def get_timestamp(daysep='', daytimesep=' ', timesep=':', millissep='.')
Definition: robottime.py:335
def safe_str(item)
Definition: unic.py:21
def get_full_version(program=None, naked=False)
Definition: version.py:30