Robot Framework
verbose.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 import sys
17 
18 from robot.errors import DataError
19 from robot.utils import (get_console_length, getshortdoc, isatty,
20  pad_console_length)
21 
22 from .highlighting import HighlightingStream
23 
24 
26 
27  def __init__(self, width=78, colors='AUTO', markers='AUTO', stdout=None,
28  stderr=None):
29  self._writer_writer = VerboseWriter(width, colors, markers, stdout, stderr)
30  self._started_started = False
31  self._started_keywords_started_keywords = 0
32  self._running_test_running_test = False
33 
34  def start_suite(self, suite):
35  if not self._started_started:
36  self._writer_writer.suite_separator()
37  self._started_started = True
38  self._writer_writer.info(suite.longname, suite.doc, start_suite=True)
39  self._writer_writer.suite_separator()
40 
41  def end_suite(self, suite):
42  self._writer_writer.info(suite.longname, suite.doc)
43  self._writer_writer.status(suite.status)
44  self._writer_writer.message(suite.full_message)
45  self._writer_writer.suite_separator()
46 
47  def start_test(self, test):
48  self._writer_writer.info(test.name, test.doc)
49  self._running_test_running_test = True
50 
51  def end_test(self, test):
52  self._writer_writer.status(test.status, clear=True)
53  self._writer_writer.message(test.message)
54  self._writer_writer.test_separator()
55  self._running_test_running_test = False
56 
57  def start_keyword(self, kw):
58  self._started_keywords_started_keywords += 1
59 
60  def end_keyword(self, kw):
61  self._started_keywords_started_keywords -= 1
62  if self._running_test_running_test and not self._started_keywords_started_keywords:
63  self._writer_writer.keyword_marker(kw.status)
64 
65  def message(self, msg):
66  if msg.level in ('WARN', 'ERROR'):
67  self._writer_writer.error(msg.message, msg.level, clear=self._running_test_running_test)
68 
69  def output_file(self, name, path):
70  self._writer_writer.output(name, path)
71 
72 
74 
77  _status_length = len('| PASS |')
78 
79  def __init__(self, width=78, colors='AUTO', markers='AUTO', stdout=None,
80  stderr=None):
81  self._width_width = width
82  self._stdout_stdout = HighlightingStream(stdout or sys.__stdout__, colors)
83  self._stderr_stderr = HighlightingStream(stderr or sys.__stderr__, colors)
84  self._keyword_marker_keyword_marker = KeywordMarker(self._stdout_stdout, markers)
85  self._last_info_last_info = None
86 
87  def info(self, name, doc, start_suite=False):
88  width, separator = self._get_info_width_and_separator_get_info_width_and_separator(start_suite)
89  self._last_info_last_info = self._get_info_get_info(name, doc, width) + separator
90  self._write_info_write_info()
91  self._keyword_marker_keyword_marker.reset_count()
92 
93  def _write_info(self):
94  self._stdout_stdout.write(self._last_info_last_info)
95 
96  def _get_info_width_and_separator(self, start_suite):
97  if start_suite:
98  return self._width_width, '\n'
99  return self._width_width - self._status_length_status_length - 1, ' '
100 
101  def _get_info(self, name, doc, width):
102  if get_console_length(name) > width:
103  return pad_console_length(name, width)
104  doc = getshortdoc(doc, linesep=' ')
105  info = '%s :: %s' % (name, doc) if doc else name
106  return pad_console_length(info, width)
107 
108  def suite_separator(self):
109  self._fill_fill('=')
110 
111  def test_separator(self):
112  self._fill_fill('-')
113 
114  def _fill(self, char):
115  self._stdout_stdout.write('%s\n' % (char * self._width_width))
116 
117  def status(self, status, clear=False):
118  if self._should_clear_markers_should_clear_markers(clear):
119  self._clear_status_clear_status()
120  self._stdout_stdout.write('| ', flush=False)
121  self._stdout_stdout.highlight(status, flush=False)
122  self._stdout_stdout.write(' |\n')
123 
124  def _should_clear_markers(self, clear):
125  return clear and self._keyword_marker_keyword_marker.marking_enabled
126 
127  def _clear_status(self):
128  self._clear_info_clear_info()
129  self._write_info_write_info()
130 
131  def _clear_info(self):
132  self._stdout_stdout.write('\r%s\r' % (' ' * self._width_width))
133  self._keyword_marker_keyword_marker.reset_count()
134 
135  def message(self, message):
136  if message:
137  self._stdout_stdout.write(message.strip() + '\n')
138 
139  def keyword_marker(self, status):
140  if self._keyword_marker_keyword_marker.marker_count == self._status_length_status_length:
141  self._clear_status_clear_status()
142  self._keyword_marker_keyword_marker.reset_count()
143  self._keyword_marker_keyword_marker.mark(status)
144 
145  def error(self, message, level, clear=False):
146  if self._should_clear_markers_should_clear_markers(clear):
147  self._clear_info_clear_info()
148  self._stderr_stderr.error(message, level)
149  if self._should_clear_markers_should_clear_markers(clear):
150  self._write_info_write_info()
151 
152  def output(self, name, path):
153  self._stdout_stdout.write('%-8s %s\n' % (name+':', path))
154 
155 
157 
158  def __init__(self, highlighter, markers):
159  self._highlighter_highlighter = highlighter
160  self.marking_enabledmarking_enabled = self._marking_enabled_marking_enabled(markers, highlighter)
161  self.marker_countmarker_count = 0
162 
163  def _marking_enabled(self, markers, highlighter):
164  options = {'AUTO': isatty(highlighter.stream),
165  'ON': True,
166  'OFF': False}
167  try:
168  return options[markers.upper()]
169  except KeyError:
170  raise DataError("Invalid console marker value '%s'. Available "
171  "'AUTO', 'ON' and 'OFF'." % markers)
172 
173  def mark(self, status):
174  if self.marking_enabledmarking_enabled:
175  marker, status = ('.', 'PASS') if status != 'FAIL' else ('F', 'FAIL')
176  self._highlighter_highlighter.highlight(marker, status)
177  self.marker_countmarker_count += 1
178 
179  def reset_count(self):
180  self.marker_countmarker_count = 0
def __init__(self, highlighter, markers)
Definition: verbose.py:158
def _marking_enabled(self, markers, highlighter)
Definition: verbose.py:163
def __init__(self, width=78, colors='AUTO', markers='AUTO', stdout=None, stderr=None)
Definition: verbose.py:28
def output_file(self, name, path)
Definition: verbose.py:69
def __init__(self, width=78, colors='AUTO', markers='AUTO', stdout=None, stderr=None)
Definition: verbose.py:80
def info(self, name, doc, start_suite=False)
Definition: verbose.py:87
def _get_info(self, name, doc, width)
Definition: verbose.py:101
def status(self, status, clear=False)
Definition: verbose.py:117
def _get_info_width_and_separator(self, start_suite)
Definition: verbose.py:96
def error(self, message, level, clear=False)
Definition: verbose.py:145
def info(msg, html=False, also_console=False)
Writes the message to the log file using the INFO level.
Definition: logger.py:113
def write(msg, level='INFO', html=False)
Writes the message to the log file using the given level.
Definition: logger.py:84
def error(msg, html=False)
Writes the message to the log file using the ERROR level.
Definition: logger.py:126
def isatty(stream)
Definition: misc.py:116
def getshortdoc(doc_or_item, linesep='\n')
Definition: text.py:184
def get_console_length(text)
Definition: text.py:112
def pad_console_length(text, width)
Definition: text.py:116